Autor Tema: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232  (Leído 25855 veces)

0 Usuarios y 7 Visitantes están viendo este tema.

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS2
« Respuesta #30 en: 07 de Diciembre de 2010, 11:58:30 »
Gracias de nuevo. Por tanto conecto CS con cualquier pin del pic? por ejemplo el RA2. Lo declaro en el programa y controlo lo del cs=0 en el programa o ya directamente esta a 0?

Yo conectaria el cs con uno de los pines del pic ( supongo RA2) y declararia:
static bit CS @ PORTBIT(PORTA, 2);

Y lo declararia como entrada en el TRISA<2> bit set.

es correcto?
Gracias de antemano.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS2
« Respuesta #31 en: 07 de Diciembre de 2010, 12:47:53 »
Gracias de nuevo. Por tanto conecto CS con cualquier pin del pic? por ejemplo el RA2. Lo declaro en el programa y controlo lo del cs=0 en el programa o ya directamente esta a 0?

Yo conectaria el cs con uno de los pines del pic ( supongo RA2) y declararia:
static bit CS @ PORTBIT(PORTA, 2);

Y lo declararia como entrada en el TRISA<2> bit set.

es correcto?
Gracias de antemano.


  No, lo tenés que declarar como salida. Porque desde el pic va a salir la señal hacia el TC77.
  Con lo cual para leer los 2 bytes que envía el TC77 deberías hacer algo así...

  CS = 0;
  byte_alto = read_spi;
  byte_bajo = read_spi;
  CS = 1;

De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #32 en: 07 de Diciembre de 2010, 13:13:56 »
y como junto los dos bytes en uno de solo? tendria que crear una variable de 16bits no? y guardarlo ahi...
En vez de hacerlo como tu dices podria poner una unica variable que leyera el contenido de read_spi, de 16 bits?

Gracias

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #33 en: 07 de Diciembre de 2010, 13:28:07 »
y como junto los dos bytes en uno de solo? tendria que crear una variable de 16bits no? y guardarlo ahi...
En vez de hacerlo como tu dices podria poner una unica variable que leyera el contenido de read_spi, de 16 bits?

Gracias

  Para juntar los dos bytes es sencillo, declaras una variable tipo int y en el programa hacés
"variableint = (byte_alto << 8 ) + byte_bajo".

  Me parece que cada transferencia de SPI es de 8 bits, entonces no podrías hacer toda la lectura seguida. Tené en cuenta que el dato leído se almacena en el registro SSPBUF que es de 8 bits.

Código: C
  1. int lectura_sensor;
  2. .....
  3. .....
  4. .....
  5. CS = 0;
  6. byte_alto = read_spi();
  7. byte_bajo = read_spi();
  8. CS = 1;
  9. lectura_sensor = (byte_alto << 8) + byte_bajo;

Lo que sí podrías hacer es una rutina read_sensor(); que llamase 2 veces a read_spi() y que devuelva un int. Algo así:

Código: C
  1. int read_sensor(void)
  2. {
  3.   char byte_alto, byte_bajo;
  4.  
  5.   byte_alto = read_spi();
  6.   byte_bajo = read_spi();
  7.   return ((byte_alto >> 8) + byte_bajo);
  8. }

De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #34 en: 07 de Diciembre de 2010, 13:49:28 »
Sigue sin funcionarme... no se el porque la verdad. He hecho lo que me has dicho.. he probado tambien de enviar los datos por separado al puerto serie y ver los valores. He enviado "byte_sensor_high" y "byte_sensor_low" y he visto : 00. Por lo que no se si leemos bien los datos.. Adjunto codigo y un imp pantalla d la simulacion.

Gracias.

Código: [Seleccionar]
#include <htc.h>
#include <stdlib.h> // Para usar la funcion itoa

/* =================================================================================
Definitions
    ================================================================================= */
#define PORTBIT(adr, bit) ( (unsigned)(&adr)*8 + (bit) )

#define Idle_Low 1 // No envia datos
#define Idle_High 2 // Envia datos

#define true 1
#define false 0

#define BAUD  9600 // Configuramos la velocidad, tanto puede ser 19200 o de 9600 kbaud/s pero hay q cambiarlo tb en la simulacion de proteus
#define PIC_CLK 4000000 // Clock de 4MHz (Cristal)

/* =================================================================================
Function prototypes
    ================================================================================= */
static void interrupt service_routine (void); // This is the interrupt service routine

void init_system (void);
void time_delay (unsigned int );
char output_logic(void);
char future_state_logic(void);

void setup_sensor(void);
void setup_adc(void);
void serial_setup(void);

void putst(register const char *str);
void putch(unsigned char c);

unsigned char getch(void);
unsigned char UsartReadChar_nonstop(void);
unsigned char getch_available(void);
void clear_usart_errors(void);

unsigned char read_spi (void);
unsigned char read_adc(void);
int read_sensor(void);



/* =================================================================================
Global variables 
  ================================================================================= */
static bit potenciometro @ PORTBIT(PORTA, 0); // Declaración del potenciometro
static bit serial_data_in @ PORTBIT(PORTB, 0);
// Serial Data 0utput disabled in master mode (configuración como entrada)
static bit serial_clock @ PORTBIT(PORTB, 1);
static bit LED @ PORTBIT(PORTB, 2);
static bit CS @ PORTBIT(PORTB, 3);

static char present_state = Idle_Low; // state variable
static char future_state = Idle_Low; // state variable

unsigned char valor_potenciometro;
unsigned char valor_sensor_temperatura;



unsigned char buf_pot[6];
unsigned char buf_sensor[10];

char * valor_pote_en_texto;
char * valor_sensor_en_texto;

static unsigned char caracter_recibido;

unsigned char dummy;


/* =================================================================================
Main function
  ================================================================================= */
void main(void){

valor_potenciometro=0;
valor_sensor_temperatura=0;
LED = 0;
init_system ();
setup_sensor();
setup_adc();
serial_setup();


while(1) {

CS = 0;
  valor_sensor_temperatura = read_sensor(); // Lectura datos del sensor (2bytes)
CS = 1;

valor_potenciometro=read_adc(); //Lectura de datos del conversor (1byte)

valor_pote_en_texto= itoa(buf_pot,valor_potenciometro,10);
valor_sensor_en_texto=itoa(buf_sensor,valor_sensor_temperatura,10);

output_logic();
future_state_logic();
}

}

/* =================================================================================
Function definitions
  ================================================================================= */

//*****************************************************************************
//Future_state_logic routine
//*****************************************************************************
char future_state_logic(void){

char error = 0;

switch (present_state) {
case Idle_Low:

if ((valor_sensor_temperatura<20)||(valor_potenciometro<25)){ // Menor de 20ºC o la resistencia menos a 25Kohms
present_state = Idle_High;
}
else

if (getch_available()==true) // Si hay un caracter disponible recibido por el puerto serie.
{
caracter_recibido=getch();
if(caracter_recibido=='a')
{

present_state = Idle_High;
LED=1;
error=0;

}
else{
present_state=Idle_Low;
LED=0;
error=1;
}
}
else
error=1;
break;

case Idle_High:
if (TXIF==0){ // Buffer de transmision vacio
present_state = Idle_Low;
}
else{
error=1;
}
break;


default:
error = 1;

}
return (error);
}

//*****************************************************************************
//Output logic routine
//*****************************************************************************
char output_logic(void){
unsigned char error = 1;


switch (present_state) {

case Idle_Low:
LED = 0;
error = 0;
break;

case Idle_High:

putst("\n");   // Cambio de linea
putst("Valor del potenciometre: ");
putst(valor_pote_en_texto);
putst("\n");   // Cambio de linea
putst("Valor del sensor: ");
putst(valor_sensor_en_texto);

//putst("Suponemos un valor de 25 grados");
putst("\n");

LED=1;
error=0;
break;


default:
error = 1;
LED=0;
break;
}

return (error);
}

//*****************************************************************************
//Init operations 
//*****************************************************************************
void init_system (void)
{
// Declaración del potenciometro
TRISA = 255;

//Declaracion del sensor
//Serial Data Input is automatically controlled by the SPI module

TRISB = 4; // SCK. En master mode TRISB<1> bit cleared && El led como entrada en TRISB<2>. CS como salida ( a 0)

// Declaración del terminal (como entradas)
TRISC = 192; // tx/rx

}


//*****************************************************************************
//Time delay routine.   
//*****************************************************************************
void time_delay(unsigned int delay){

unsigned int i;
for(i = 0; i <= delay ;i++){
NOP();
}
}

//*****************************************************************************
// SERIAL SETUP 
//*****************************************************************************
void serial_setup(void){
#define SPBRG_VALUE ((PIC_CLK/(16UL*BAUD)) -1)


BRGH = 1;
BRG16 = 0;
SPBRG = SPBRG_VALUE;

SPEN=1; // Enable serial port
SYNC=0; // Asincrono

TXIE=0; // Desactivar interrupciones en tx
TXEN=1; // Enable the transmitter
TX9=0; // 8 bits transmission

RCIE=1; // Activar interrupciones en rx
RX9=0; // 8 bits reception
CREN=1; //Enable reception


#define clear_usart_errors_inline \
if (OERR)
{
TXEN=0; \
TXEN=1; \
CREN=0; \
CREN=1; \
}
if (FERR) \
{
dummy=RCREG; \
TXEN=0; \
TXEN=1; \
}

}


//*****************************************************************************
// Enviar datos ( un caracter)
//*****************************************************************************

void putch(unsigned char c)
{
while(!TXIF){
clear_usart_errors_inline;
CLRWDT();
}
TXREG=c;

}
//*****************************************************************************
// Enviar datos (un buffer)
//*****************************************************************************
//Los if están para detectar el "salto de línea" y al "retroceso de carro".Como si fuera un "Enter"

void putst(register const char *str)
{
while((*str)!=0)
{
putch(*str);
if(*str==13)
putch(10);

if(*str==10)
putch(13);
str++;
}

}


//*****************************************************************************
//Leer datos ( un caracter)
//*****************************************************************************

unsigned char getch(void)
{
while(RCIF!=1){ //1 = The EUSART receive buffer, RCREG, is full
CLRWDT();
clear_usart_errors_inline;
}
return RCREG;
}

//*****************************************************************************
//Leer datos (un buffer)
//*****************************************************************************
unsigned char UsartReadChar_nonstop(void) {

if(!PIR1bits.RCIF) // TRMT1 is set when TSR is empty
      return 0;   

    return RCREG;
}


//*****************************************************************************
//Comprueba si aun faltan datos o no
//*****************************************************************************
unsigned char getch_available(void)
{
if(RCIF)
return true;
else
return false;
}


//*****************************************************************************
//Errores USART
//*****************************************************************************
void clear_usart_errors(void)
{
clear_usart_errors_inline;
}


//*****************************************************************************
//Leer entradas.
//*****************************************************************************

//*****************************************************************************
//Leer bytes recibidos del bus del modulo SPI
//*****************************************************************************

void setup_sensor(void)  // SPI Master mode:
{

SSPEN=1;    //Enables serial port and configures SCK, SDO, SDI and SS as serial port pins
BF=0;        //Receive not complete, SSPBUF is empty

//SCK is the clock output (Master Mode)
//Clock Polarity(Idle state of SCK)

SMP=1;      //Input data sampled at end of data output time
CKE=0;      //Transmit occurs on transition from Idle to active clock state

SSPM3=0;
SSPM2=0; //SPI Master mode, clock = FOSC/4
SSPM1=0;
SSPM0=0;

CKP=0; //Idle state for clock is a low level

SSPIF=0;   

}


void setup_adc(void)
{

ADCON1=14; // PCFG3=1,PCFG2=1,PCFG1=1,PCFG0=0. Todas las entradas digitales


CHS3=0;
CHS2=0; // Seleccionamos el canal 0 (AN0) que es donde esta conectado el potenciometro
CHS1=0;
CHS0=0;

//Tiempo de adquisicion
ACQT2=0;
ACQT1=0;  // 2Tad (Tad=1us) Por tanto 2x1us =2us >= 1.65us( Tacq calculado teoricamente)
ACQT0=1;

ADCS2=1;
ADCS1=0;       // Idem a 4Tosc. 4*Tosc(1us) es el primer valor que hace que sea superior a 0.7us( el minimo)
ADCS0=0;


ADON=1; // A/D converter module is enabled

/* Configure A/D interrupt*/
ADIF=0;
//ADIE=1;

ADFM = 1; // justificada a la derecha


}

//*****************************************************************************
//Leer entradas.
//*****************************************************************************

//*****************************************************************************
//LEER DATOS SENSOR
//*****************************************************************************

unsigned char read_spi (void)
{
if((BF==1)&&(SSPIF==1)){ //Receive complete, SSPBUF is full && The transmission/reception is complete  (must be cleared in software)
SSPIF=0; ////Waiting to transmit/receive6.   
 BF=0;   
return SSPBUF;
}
  return 0;         
}

int read_sensor(void)
{
  char byte_alto, byte_bajo;
 
  byte_alto = read_spi();
  byte_bajo = read_spi();
  return ((byte_alto >> 8) + byte_bajo);
}


//*****************************************************************************
//LEER DATOS POTENCIOMETRO
//*****************************************************************************



unsigned char read_adc(void)
{
//Empezamos a leer
GODONE=1; //A/D conversion in progress

while(ADIF==0); //An A/D conversion completed (must be cleared in software)
ADIF=0;
return((ADRESH << 8)+(ADRESL));
}
 
 

 


Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #35 en: 07 de Diciembre de 2010, 14:26:51 »
 Hay un error en el ejemplo que te mostré para la función read_sensor; tiene que ser "return ((byte_alto << 8) + byte_bajo) (el byte alto rotarlo a la izquierda 8 veces, que es lo mismo que multiplicar por 256, o lo mismo que decir el byte alto de una variable de 16 bits).

  Otro cosa que veo es que tenés definida como unsigned char a la variable que almacena el dato leido del sensor; la tanés que definir como int.

  El pin que usas para el led lo tenés como entrada, tiene que ir como salida.

  En cuanto a que no funcione la lectura, ya ahí habría que usar el spi debugger del proteus para ver si hay aunque sea alguna transmisión de datos. Puede ser que tengas configurado la interface SPI en un modo que no es soportado por el TC77 o que falle la simulación de éste último.... ahí que probar
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #36 en: 07 de Diciembre de 2010, 15:25:07 »
Las dos primeras cosas arregladas, muchas gracias. La simulacion sigue sin ir...en teoria el sensor tiene que soportar todos los modos.. si esta en la misma placa no? No se porque me parece que no estoy conectando bien las cosas..

El clock, lo conecto directamente a un pin pero no hago nada.. ( aunque lo tenga configurado en el setup_sensor).

Por otra parte leyendo un poco, he ido a parar aqui Aquí
Habla de como conectar el chip select (CS).

Voy a seguir mirando...

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #37 en: 07 de Diciembre de 2010, 16:14:39 »
Encontré un problema en tu código de la rutina read_spi() y es que no llenás el SSPBUF.
Para que comience la transmisión tiene que estar lleno el SSPBUF y ahí el PIC empieza a generar los pulsos de clock y a su vez va haciendo la lectura y va llenando el SSPBUF con el valor de entrada.

Por eso en mi rutina read_spi() pongo en alta impedancia (puero como entrada) SDO y a su vez pongo el dato 16 (podría ser cualquier otro) en SSPBUf. Al poner en alta impedancia dicho pin logro que el PIC no transmita datos hacia el periférico.

Código: C
  1. unsigned char read_spi()
  2. {
  3.   ....  // tris del SDO = 1
  4.   SSPBUF = 16; // puede ir cualquier cosa
  5.   while (SSPIF == 0);
  6.   SSPIF = 0;
  7.   return SSPBUF;
  8. }
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #38 en: 07 de Diciembre de 2010, 20:42:21 »
Gracias de nuevo. He cambiado la funcion pero... para declarar SDO tendria que declararlo en RC7 ( que es donde tengo el terminal).
En el proteus me sale un warning despues de hacer este cambio en la funcion:

Logic contention(s) detected on net #00008

El problema tambien es que el sensor TC77 en proteus tiene 3 pines: cs,sck y una misma entrada para sdi y sdo ( data input y data output..). Como lo conecto entonces?

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #39 en: 07 de Diciembre de 2010, 23:09:34 »
Gracias de nuevo. He cambiado la funcion pero... para declarar SDO tendria que declararlo en RC7 ( que es donde tengo el terminal).
En el proteus me sale un warning despues de hacer este cambio en la funcion:

Logic contention(s) detected on net #00008


  Pero ese error te sale porque seguramente no estás configurando el pin como entrada, sino como salida. Fijate que para que funcione como RX del UART ya queda en alta impedancia (puerto como entrada) entonces si yo lo vuelvo a configurar como entrada no tiene porque haber conflicto, de hecho ni siquiera es necesario volver a configurarlo como entrada. Simplemente te dije que lo configuraras como entrada así te hacés una rutina de lectura de spi genérica y la podes reutilizar en distintos proyectos.

  Te subo una captura donde se puede ver el circuito, la pantalla del "virtual terminal" con la información del potenciómetro y la información del TC77. También se ve la ventana del "SPI debugger" con la actividad del bus SPI;

  Este es el programa que estoy usando, hay que hacer correcciones para poder trabajar con los decimales y también con los números negativos. Fijate que en la rutina "read_spi();" sí pongo a 1 el tris de SDO y no me tira ningún error. También tuve que modificar la rutina de "setup_sensor" poniendo SMP = 0 en lugar de SMP = 1 porque sino el paquete recibido por el PIC no era correcto.

Código: C
  1. #include <htc.h>
  2. #include <stdlib.h>  // para poder usar la funcion itoa
  3.  
  4.  
  5. /*      =================================================================================
  6.         Definitions
  7.         ================================================================================= */
  8. #define         PORTBIT(adr, bit) ( (unsigned)(&adr)*8 + (bit) )
  9.  
  10. #define         Idle_Low 1      // No envia datos
  11. #define         Idle_High 2 // Envia datos
  12.  
  13. #define true 1
  14. #define false 0
  15.  
  16. #define BAUD  9600                      // Configuramos la velocidad, tanto puede ser 19200 o de 9600 kbaud/s pero hay q cambiarlo tb en la simulacion de proteus      
  17. #define PIC_CLK 4000000         // Clock de 4MHz (Cristal)
  18.  
  19. #define CS RB3
  20.  
  21. /*      =================================================================================
  22.         Global variables  
  23.         ================================================================================= */
  24. //static bit potenciometro @ PORTBIT(PORTA, 0);         // Declaración del potenciometro
  25. //static bit sensor_temperatura @ PORTBIT(PORTB, 0);
  26. //static bit sensor_datos_salida @ PORTBIT(PORTC, 7);  // SD0 disabled in master mode (configuración como entrada)
  27.  
  28.  
  29. static bit LED @ PORTBIT(PORTB, 2);    
  30. char present_state = Idle_Low;          // state variable
  31. char future_state = Idle_Low;           // state variable
  32. unsigned int  valor_potenciometro;
  33. unsigned int  valor_sensor_temperatura;
  34. unsigned char pote_buf[6];
  35. unsigned char sensor_buf[10];
  36. char * valor_pote_en_texto;           // un puntero para almacenar el numero en texto
  37. char * valor_sensor_en_texto;         // un puntero para almacenar el numero en texto
  38. char byte_alto, byte_bajo;
  39. //unsigned char high_result;
  40. //unsigned char low_result;
  41. unsigned char caracter_recibido;       
  42. unsigned char dummy;
  43.  
  44.  
  45. /*      =================================================================================
  46.         Function prototypes
  47.         ================================================================================= */
  48. //static void interrupt service_routine (void); // This is the interrupt service routine
  49.  
  50. void init_system (void);
  51. void time_delay (unsigned int );
  52. char output_logic(void);
  53. char future_state_logic(void);
  54.  
  55. void setup_sensor(void);
  56. void setup_adc(void);
  57. void serial_setup(void);
  58.  
  59. void putst(const char *str);
  60. void putch(unsigned char c);
  61.  
  62. unsigned char getch(void);
  63. unsigned char UsartReadChar_nonstop(void);
  64. unsigned char getch_available(void);
  65. void clear_usart_errors(void);
  66.  
  67. unsigned char read_spi (void);
  68. unsigned int read_adc(void);
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76. /*      =================================================================================
  77.         Main function
  78.         ================================================================================= */
  79. void main(void)
  80. {
  81.   valor_potenciometro = 0;
  82.   valor_sensor_temperatura = 0;
  83.   LED = 0;     
  84.   init_system();
  85.   setup_sensor();
  86.   setup_adc();
  87.   serial_setup();      
  88.   while(1)
  89.   {
  90.     CS = 0;
  91.     byte_alto = read_spi();
  92.     byte_bajo = read_spi();
  93.     CS = 1;
  94.     valor_sensor_temperatura = (byte_alto << 8) + byte_bajo;
  95.     valor_sensor_temperatura = valor_sensor_temperatura >> 7;
  96.     //valor_sensor_temperatura = read_spi();  // Las pongo aqui porque es donde hago la lectura de los datos.
  97.     valor_potenciometro = read_adc();
  98.    
  99.     valor_pote_en_texto = itoa (pote_buf, valor_potenciometro, 10);
  100.     valor_sensor_en_texto = itoa (sensor_buf, valor_sensor_temperatura, 10);
  101.     output_logic();
  102.     future_state_logic();
  103.   }            
  104. }      
  105.  
  106. /*      =================================================================================
  107.         Function definitions
  108.         ================================================================================= */
  109.  
  110. //*****************************************************************************
  111. //Future_state_logic routine
  112. //*****************************************************************************
  113. char future_state_logic(void)
  114. {
  115.   char error = 0;
  116.   switch (present_state)
  117.   {
  118.     case Idle_Low:
  119.                  /*                            
  120.                   if ((valor_sensor_temperatura < 20) || (valor_potenciometro < 25))
  121.                   { // Menor de 20ºC o la resistencia menos a 25Kohms
  122.                     //future_state = Idle_High;
  123.                     present_state = Idle_High;
  124.                   }
  125.                   else */
  126.                   if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
  127.                   {
  128.                     caracter_recibido = getch();
  129.                     if (caracter_recibido == 'a')
  130.                     {
  131.                       //future_state = Idle_High;
  132.                       present_state = Idle_High;
  133.                       LED = 1;
  134.                       error = 0;
  135.                     }
  136.                     else
  137.                     {
  138.                       //future_state = Idle_Low;
  139.                       present_state = Idle_Low;
  140.                       LED = 0;
  141.                       error = 1;
  142.                     }
  143.                   }
  144.                   break;
  145.     case Idle_High:                                            
  146.                    if (TXIF == 0)
  147.                    { // Buffer de transmision vacio
  148.                      //future_state = Idle_Low;
  149.                      present_state = Idle_Low;
  150.                    }
  151.                    else
  152.                    {
  153.                      error = 1;
  154.                    }
  155.                    break;
  156.     default:
  157.                           error = 1;
  158.   }    
  159.   return (error);
  160. }
  161.  
  162. //*****************************************************************************
  163. //Output logic routine
  164. //*****************************************************************************
  165. char output_logic(void)
  166. {
  167.   unsigned char error = 1;
  168.   switch (present_state)
  169.   {
  170.     case Idle_Low:                             
  171.                    LED = 0;
  172.                    error = 0;
  173.                    break;
  174.     case Idle_High:                    
  175.                    putst ("Valor del pote: ");
  176.                    putst (valor_pote_en_texto);
  177.                    putst ("\n");  //cambio de linea
  178.                    putst ("Valor del sensor: ");
  179.                    putst (valor_sensor_en_texto);
  180.                    //putst ("Suponemos un valor de 25 grados");
  181.                    putst ("\n");
  182.                    LED = 1;
  183.                    error = 0;
  184.                    break;
  185.     default:
  186.                    error = 1;
  187.                    LED = 0;
  188.                    break;              
  189.   }
  190.   return (error);
  191. }
  192.  
  193. //*****************************************************************************
  194. //Init operations  
  195. //*****************************************************************************
  196. void init_system (void)
  197. {
  198.   //TRISB = 1; //LED. Todos los pines se comportaran como salidas menos RB0 2^0=1
  199.   //TRISA = 32; // SS( Select Slave) must have TRISA<5> bit set
  200.   TRISA = 255;
  201.   CS = 1;
  202.   TRISB = 1; // SDI. El bit 0 a 1.Configurado en master mode (bit 1 cleared, en mode slave bit 1 set)
  203.   TRISC = 192; // SDO. Tots els bits a 1 menys la sortida 7
  204. }
  205.  
  206.  
  207. //*****************************************************************************
  208. //Time delay routine.  
  209. //*****************************************************************************
  210. void time_delay(unsigned int delay)
  211. {
  212.   unsigned int i;
  213.        
  214.   for (i = 0; i <= delay; i++)
  215.   {    
  216.     NOP();
  217.   }
  218. }
  219.  
  220. //*****************************************************************************
  221. // SERIAL SETUP  
  222. //*****************************************************************************
  223. void serial_setup(void)
  224. {
  225.   #define SPBRG_VALUE ((PIC_CLK/(16UL*BAUD)) -1)
  226.   BRGH = 1;
  227.   BRG16 = 0;
  228.   SPBRG = SPBRG_VALUE;
  229.   SPEN = 1; // Enable serial port
  230.   SYNC = 0; // Asincrono
  231.   TXIE = 0; // Desactivar interrupciones en tx
  232.   TXEN = 1; // Enable the transmitter
  233.   TX9 = 0; // 8 bits transmission
  234.   RCIE = 1; // Activar interrupciones en rx
  235.   RX9 = 0; // 8 bits reception
  236.   CREN = 1; //Enable reception
  237.   #define clear_usart_errors_inline     if (OERR)\
  238.                                     {\
  239.                                       TXEN = 0;\
  240.                                       TXEN = 1;\
  241.                                       CREN = 0;\
  242.                                       CREN = 1;\
  243.                                     }\
  244.                                     if (FERR)\
  245.                                     {\
  246.                                       dummy = RCREG;\
  247.                                       TXEN = 0;\
  248.                                       TXEN = 1;\
  249.                                     }
  250. }
  251.  
  252.  
  253. //*****************************************************************************
  254. // Enviar datos ( un caracter)
  255. //*****************************************************************************
  256.  
  257. void putch(unsigned char c)
  258. {
  259.   while (!TXIF)
  260.   {
  261.     clear_usart_errors_inline;
  262.     CLRWDT();
  263.   }
  264.   TXREG = c;
  265. }
  266. //*****************************************************************************
  267. // Enviar datos (un buffer)
  268. //*****************************************************************************
  269. void putst(register const char *str)
  270. {
  271.   while ((*str) != 0)
  272.   {
  273.     putch (*str);
  274.     if (*str == 13) putch (10);
  275.     if (*str == 10) putch (13);
  276.     str++;
  277.   }
  278. }
  279.  
  280. //*****************************************************************************
  281. //Leer datos ( un caracter)
  282. //*****************************************************************************
  283.  
  284. unsigned char getch(void)
  285. {
  286.   while (RCIF != 1)
  287.   {                             //1 = The EUSART receive buffer, RCREG, is full
  288.     CLRWDT();
  289.     clear_usart_errors_inline;
  290.   }
  291.   return RCREG;
  292. }
  293.  
  294. //*****************************************************************************
  295. //Leer datos (un buffer)
  296. //*****************************************************************************
  297. unsigned char UsartReadChar_nonstop(void)
  298. {
  299.   if (!RCIF)    // TRMT1 is set when TSR is empty
  300.     return 0;  
  301.   return RCREG;
  302. }
  303.  
  304.  
  305. //*****************************************************************************
  306. //Comprueba si aun faltan datos o no
  307. //*****************************************************************************
  308. unsigned char getch_available(void)
  309. {
  310.   if (RCIF)
  311.     return true;
  312.   else
  313.     return false;
  314. }
  315.  
  316.  
  317. //*****************************************************************************
  318. //Errores USART
  319. //*****************************************************************************
  320. void clear_usart_errors(void)
  321. {
  322.   clear_usart_errors_inline;
  323. }
  324.  
  325.  
  326. //*****************************************************************************
  327. //Leer entradas.
  328. //*****************************************************************************
  329.  
  330. //*****************************************************************************
  331. //Leer bytes recibidos del bus del modulo SPI
  332. //*****************************************************************************
  333.  
  334. void setup_sensor(void)  // SPI Master mode:
  335. {
  336.   SSPEN = 1;            //Enables serial port and configures SCK, SDO, SDI and SS as serial port pins
  337.   BF = 0;                                                               //Receive not complete, SSPBUF is empty
  338.   //SCK is the clock output (Master Mode)
  339.   //Clock Polarity(Idle state of SCK)
  340.   SMP = 0;                                                       //Input data sampled at end of data output time
  341.   CKE = 0;                                                        //Transmit occurs on transition from Idle to active clock state
  342.   SSPM3 = 0;
  343.   SSPM2 = 0;                                                    //SPI Master mode, clock = FOSC/4      
  344.   SSPM1 = 0;
  345.   SSPM0 = 0;
  346.   CKP = 0;                                                              //Idle state for clock is a low level
  347.   SSPIF = 0;                                                   
  348. }
  349.  
  350. void setup_adc(void)
  351. {
  352.   ADFM = 1;
  353.   ADCON1 = 14;          // PCFG3=1,PCFG2=1,PCFG1=1,PCFG0=0. Todas las entradas digitales
  354.   CHS3 = 0;
  355.   CHS2 = 0;                     // Seleccionamos el canal 0 (AN0) que es donde esta conectado el potenciometro
  356.   CHS1 = 0;
  357.   CHS0 = 0;
  358.   //Tiempo de adquisicion
  359.   ACQT2 = 0;
  360.   ACQT1 = 0;            // 2Tad (Tad=1us) Por tanto 2x1us =2us >= 1.65us( Tacq calculado teoricamente)
  361.   ACQT0 = 1;
  362.   ADCS2 = 1;
  363.   ADCS1 = 0;    // Idem a 4Tosc. 4*Tosc(1us) es el primer valor que hace que sea superior a 0.7us( el minimo)
  364.   ADCS0 = 0;   
  365.   ADON = 1;             // A/D converter module is enabled
  366.   /* Configure A/D interrupt*/
  367.   ADIF = 0;
  368.   //ADIE = 1;
  369. }
  370.  
  371. //*****************************************************************************
  372. //Leer entradas.
  373. //*****************************************************************************
  374.  
  375. //*****************************************************************************
  376. //LEER DATOS SENSOR
  377. //*****************************************************************************
  378. unsigned char read_spi (void)
  379. {
  380. /*
  381.   if ((BF == 1) && (SSPIF == 1))
  382.   {     //Receive complete, SSPBUF is full && The transmission/reception is complete (must be cleared in software)
  383.     SSPIF = 0; ////Waiting to transmit/receive
  384.     BF = 0;
  385.     return SSPBUF;
  386.   }
  387. */
  388.   TRISC7 = 1; // así pongo en alta impedancia el pin SDO
  389.   SSPBUF = 16;
  390.   while (SSPIF == 0);
  391.   SSPIF = 0;
  392.   return SSPBUF;
  393. }
  394.  
  395. //*****************************************************************************
  396. //LEER DATOS POTENCIOMETRO
  397. //*****************************************************************************
  398. unsigned int read_adc(void)
  399. {
  400.   //Empezar a leer
  401.   GODONE = 1; // A/D conversion in progress
  402.   while (GODONE == 1);
  403.   ADIF = 0;
  404.   return ((ADRESH << 8) + (ADRESL));
  405. }


El problema tambien es que el sensor TC77 en proteus tiene 3 pines: cs,sck y una misma entrada para sdi y sdo ( data input y data output..). Como lo conecto entonces?


  A vos no te interesa mandarle datos al TC77, así que simplemente conectás el pin SDI del PIC al pin SI/O del TC77

De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #40 en: 09 de Diciembre de 2010, 08:55:13 »
Muchas gracias otra vez por la ayuda. El programa funciona perfecto menos cuando arranca. Cuando arranca siempre se envian los datos aunque no se tengan que enviar. Es como si se tardara un tiempo en saber que temperatura es la correcta. Creo que se envian porque al principio el valor del sensor es 0 y tarda un poco en actualizar el valor...pero no se si es exactamente esto porque he probado de inicializar valor_sensor_temperatura con algun valor distinto a 0 y sigue fallando...

A ver si puedes ayudarme...

Gracias de antemano.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #41 en: 09 de Diciembre de 2010, 09:10:46 »
Muchas gracias otra vez por la ayuda. El programa funciona perfecto menos cuando arranca. Cuando arranca siempre se envian los datos aunque no se tengan que enviar. Es como si se tardara un tiempo en saber que temperatura es la correcta. Creo que se envian porque al principio el valor del sensor es 0 y tarda un poco en actualizar el valor...pero no se si es exactamente esto porque he probado de inicializar valor_sensor_temperatura con algun valor distinto a 0 y sigue fallando...

A ver si puedes ayudarme...

Gracias de antemano.

  Lo que pasa es que más allá que vos inicialices el valor, cuando haya una lectura ya va valer 0. Según el SPI debugger eran cerca de 240 ms que transmitía 0 y luego de ese tiempo ya empezaba a envíar los datos correctos el TC77.

  Probá de hacer algún delay de 300ms antes del while y con eso ya le darías tiempo al sensor a que tome el valor correcto.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS2
« Respuesta #42 en: 12 de Diciembre de 2010, 14:15:35 »
Funciona perfectamente! Perdona por contestar tan tarde... he tenido problemas con el Internet..
Mas tarde subo el proyecto entero.

Muchas gracias amigo.

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #43 en: 13 de Diciembre de 2010, 17:27:59 »
Hola de nuevo! mañana es un dia clave, voy a probar el programita en el PIC a ver como va.. esperemos que bien! Esperare a tenerlo funcionando en el PIC para subir todo el proyecto entero.
Ahora estoy añadiendo los fuses para que funcione el proyecto. Las lineas de codigo que he añadido han sido estas:
Código: [Seleccionar]
/*
;******** Configuracion del Oscilador **********
CONFIG FOSC = XT_XT         ;Osc XT, XT usado para el USB

;******** Otros bits de configuracion **********
CONFIG PWRT = ON ;PWRT habilitado
CONFIG BOR  = OFF ;Brown out resete deshabilitado
CONFIG WDT = OFF ;Watch dog deshabilitado
CONFIG  MCLRE = OFF ;MCLR como entrada
[b]CONFIG PBADEN = ON [/b];Todos los pines como entradas analogicas
CONFIG LVP = OFF ;programacion en bajo voltaje deshabilitado

;********* Bits de proteccion ******************
CONFIG CP0 = OFF ;los bloques del codigo de programa
CONFIG CP1 = OFF ;no estan protegidos
CONFIG CP2 = OFF
CONFIG CP3 = OFF
CONFIG CPB = OFF ;Sector Boot no esta protegido
CONFIG CPD = OFF ;La EEPROM no esta protegida
*/

Esta todo correcto? Lo que he puesto en negrita es porque no se si esta bien. Por otra parte tengo que configurarlo para que el reloj sea de 4 Mhz no?
Otra cosa.. una gran duda que tengo. Como se hace el cambio de los dispositivos en el proteus a los dispositivos en la placa? me explico, yo tengo programado que un led se vaya encendiendo pero que LED sera de mi placa? igual que el potenciometro.. el sensor.. como asigno cual es cada uno?

Muchas gracias de antemano como siempre :)

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #44 en: 13 de Diciembre de 2010, 18:51:24 »
Hola de nuevo! mañana es un dia clave, voy a probar el programita en el PIC a ver como va.. esperemos que bien! Esperare a tenerlo funcionando en el PIC para subir todo el proyecto entero.
Ahora estoy añadiendo los fuses para que funcione el proyecto. Las lineas de codigo que he añadido han sido estas:
Código: [Seleccionar]
/*
;******** Configuracion del Oscilador **********
CONFIG FOSC = XT_XT         ;Osc XT, XT usado para el USB

;******** Otros bits de configuracion **********
CONFIG PWRT = ON ;PWRT habilitado
CONFIG BOR  = OFF ;Brown out resete deshabilitado
CONFIG WDT = OFF ;Watch dog deshabilitado
CONFIG  MCLRE = OFF ;MCLR como entrada
[b]CONFIG PBADEN = ON [/b];Todos los pines como entradas analogicas
CONFIG LVP = OFF ;programacion en bajo voltaje deshabilitado

;********* Bits de proteccion ******************
CONFIG CP0 = OFF ;los bloques del codigo de programa
CONFIG CP1 = OFF ;no estan protegidos
CONFIG CP2 = OFF
CONFIG CP3 = OFF
CONFIG CPB = OFF ;Sector Boot no esta protegido
CONFIG CPD = OFF ;La EEPROM no esta protegida
*/

Esta todo correcto? Lo que he puesto en negrita es porque no se si esta bien. Por otra parte tengo que configurarlo para que el reloj sea de 4 Mhz no?
Otra cosa.. una gran duda que tengo. Como se hace el cambio de los dispositivos en el proteus a los dispositivos en la placa? me explico, yo tengo programado que un led se vaya encendiendo pero que LED sera de mi placa? igual que el potenciometro.. el sensor.. como asigno cual es cada uno?

Muchas gracias de antemano como siempre :)

  Por lo que estuve leyendo en el datasheet PBADEN sólo afecta respecto a como quedan los pines inmediatamente después de un RESET. Pero si vos lo configurás después (que es lo que hacés en la rutina de inicialización del AD), los pines se van a comportar de acuerdo a la nueva configuración.

  Si el reloj hay que configurarlo para que sea 4MHz. Vos ya estás poniendo que sea XT (porque supongo vas a usar un cristal de 4MHz) entonces tendrías que configurar los bits CPUDIV (tendrían que quedar en 0 para que pase la señal de 4MHz sin ninguna división), también los bits FOSC (que también tendrían que quedar en 0 para se use el oscilador externo XT). Fijate a partir de la página 286 que tiene la descripción de los bytes de configuración.

  No entiendo a lo que te referís con "el cambio de los dispositivos en el proteus".

  ¿Vos vas a probar el PIC en una placa entrenadora?

  Supongamos que tu placa tiene un led que va al puerto RB6, entonces habría que modificar el programa para que active dicha salida cuando vos quieras prender el led.
  También hay que ver a que puerto va el pote que tenga tu placa. Si va a AN5, habrá que setear dicho canal desde el programa del pic para que haga las lecturas analógicas.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas


 

anything