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

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

Desconectado umalrovi

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 158
    • Aplicaciones Electrónicas
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #75 en: 22 de Diciembre de 2010, 09:24:02 »
Buenas, has comprobado que las velocidades son idénticas tanto en el PC como en el pIC??? Estás transmitiendo datos de manera asíncrona y es fundamental que la configuración del puerto szerie sea la misma en el PC como en el PIC. No se si será ese tu problema, espero ayudarte en algo.

un saludo
Aplicaciones Electrónicas
http://www.neoingenia.com/

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS2
« Respuesta #76 en: 22 de Diciembre de 2010, 10:13:09 »
Edito: Gracias por el comentario. Pensandolo bien creo que tienes razon. Antes te he dicho que habia hecho esta misma prueba con el compim pero esta herramienta te permite configurar bien el puerto. El puerto lo estoy configurando de esta forma:

Velocidad= 9600bits/s
Bits de datos = 8
Paridad= Ninguno
Bits de parada=1
Control de flujo= Ninguno

Adjunto el codigo ya que estoy seguro que es una mala configuracion como dices. Lo que me sorprende es que este caracter extraño me salga con el cable normal y que con el cable cruzado no salga nada...

Código: [Seleccionar]

#include <stdlib.h>  // para poder usar la funcion itoa
#include <htc.h>
__CONFIG(1, 0x0000);
__CONFIG(2, 0x0039);
__CONFIG(3, 0x01FF );
__CONFIG(4, 0x29FF);
__CONFIG(5, 0xC00F);
__CONFIG(6, 0xE00F);
__CONFIG(7, 0x000F);

 
/* =================================================================================
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)
 
#define CS RB2
 


/* =================================================================================
Global variables 
  ================================================================================= */
//static bit potenciometro @ PORTBIT(PORTA, 0); // Declaración del potenciometro
//static bit sensor_temperatura @ PORTBIT(PORTB, 0);
//static bit sensor_datos_salida @ PORTBIT(PORTC, 7);  // SD0 disabled in master mode (configuración como entrada)
 
static bit LED @ PORTBIT(PORTD, 0);
char present_state = Idle_Low; // state variable
char future_state = Idle_Low; // state variable
unsigned int  valor_potenciometro;
unsigned int  valor_sensor_temperatura;
unsigned char pote_buf[6];
unsigned char sensor_buf[10];
char * valor_pote_en_texto;           // un puntero para almacenar el numero en texto
char * valor_sensor_en_texto;         // un puntero para almacenar el numero en texto
char byte_alto, byte_bajo;

unsigned char caracter_recibido;
unsigned char dummy;
 



/* =================================================================================
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(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 int read_adc(void);

 
 
/* =================================================================================
Main function
  ================================================================================= */
void main(void)
{
  valor_potenciometro = 0;
  valor_sensor_temperatura = 0;
  LED = 0;
  init_system();
  setup_sensor();
  setup_adc();
  serial_setup();
 
time_delay(30000);
while(1)
  {
    CS = 0;
    byte_alto = read_spi();
    byte_bajo = read_spi();
    CS = 1;
    valor_sensor_temperatura = (byte_alto << 8) + byte_bajo;
    valor_sensor_temperatura = valor_sensor_temperatura >> 7;
    //valor_sensor_temperatura = read_spi();  // Las pongo aqui porque es donde hago la lectura de los datos.
    valor_potenciometro = read_adc();
   
    valor_pote_en_texto = itoa (pote_buf, valor_potenciometro, 10);
    valor_sensor_en_texto = itoa (sensor_buf, 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 < 15) || (valor_potenciometro < 25))
                 { // Menor de 20ºC o la resistencia menos a 25Kohms
                    //future_state = Idle_High;
                    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;
                    }
                    else
                    {
                     
                      present_state = Idle_Low;
                      error = 1;
                    }
                 }
                  break;
    case Idle_High:
                   if (TXIF == 0)
                   { // Buffer de transmision vacio
                     //future_state = Idle_Low;
                     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");
   putst ("Valor del pote: ");
                   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)
{
 

 
  TRISA = 255;
  CS = 1;
  TRISB = 1; // SDI. El bit 0 a 1.Configurado en master mode (bit 1 cleared, en mode slave bit 1 set)
  TRISC = 192; // RC7 i RC6 a 1
  TRISD=0;
}

 
//*****************************************************************************
//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)
//*****************************************************************************
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 (!RCIF)
    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 = 0;      //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)
{
  ADFM = 1;
  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;
}
 
//*****************************************************************************
//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/receive
    BF = 0;
    return SSPBUF;
 }
*/
  TRISC7 = 1; // así pongo en alta impedancia el pin SDO
  SSPBUF = 16;
  while (SSPIF == 0);
  SSPIF = 0;
  return SSPBUF;
}
 
//*****************************************************************************
//LEER DATOS POTENCIOMETRO
//*****************************************************************************
unsigned int read_adc(void)
{
  //Empezar a leer
  GODONE = 1; // A/D conversion in progress
  while (GODONE == 1);
  ADIF = 0;
  return ((ADRESH << 8) + (ADRESL));
}
« Última modificación: 22 de Diciembre de 2010, 10:25:08 por edu1989 »

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #77 en: 22 de Diciembre de 2010, 10:39:02 »
  Subí el circuito que estás usando incluyendo el max232, tal vez haya algún error de conexionado o incluso que esté fallando el max232
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 #78 en: 22 de Diciembre de 2010, 10:51:30 »
El PIC que estoy utilitzando pertenece a la  placa y ya incorpora un max232 por lo tanto ese no creo que sea el problema

Por otro lado acabo de probar otra vez el compim y con la configuracion de los fuses no funciona (sin los fuses si, como ya dije antes). El error es el siguiente:
Illegal FOSC bits 0b1010 in CONFIGH. El Pic esta configurado en el proteus esta a 4Mhz.

Subo el proyecto entero, muchas gracias por todo de nuevo.
Edito: Estoy mirando si funciona con el compim puesto y sin la configuracion de los fuses y si, si que funciona bien.

Edito1: Imagino que es por el tema del oscil.lador con el cristal.. que claro, esta implementado en la placa pero no en el proteus.
« Última modificación: 22 de Diciembre de 2010, 11:07:23 por edu1989 »

Desconectado edu1989

  • PIC18
  • ****
  • Mensajes: 275
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #79 en: 23 de Diciembre de 2010, 09:01:23 »
Hola amigos, he seguido probando cosas.. si cambio el oscilador de XT (000x) a Internal oscillator, XT used by USB (INTXT) (1010) ya no me da ese error...
Por lo que creo que debo implementar el oscilador en proteus ya que este es interno y funciona.

Por otro lado ahora me tira un warning:

ADC conversion clock period (8.3332e-8) violates the minimum required TAD time.

Cambiaria el TAD pero creo que este error es fruto a que cambio el oscilador porque esto ya estaba calculado.

A ver si sabeis que es lo que pasa, mas que nada con el primer problema que tengo, muchas 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 #80 en: 23 de Diciembre de 2010, 09:53:30 »
Hola amigos, he seguido probando cosas.. si cambio el oscilador de XT (000x) a Internal oscillator, XT used by USB (INTXT) (1010) ya no me da ese error...
Por lo que creo que debo implementar el oscilador en proteus ya que este es interno y funciona.

Por otro lado ahora me tira un warning:

ADC conversion clock period (8.3332e-8) violates the minimum required TAD time.

Cambiaria el TAD pero creo que este error es fruto a que cambio el oscilador porque esto ya estaba calculado.

A ver si sabeis que es lo que pasa, mas que nada con el primer problema que tengo, muchas gracias!

  Justo estaba pensando en que tal vez ésa es la única configuración que se puede usar con esa placa, me parece raro pero....
  Supuestamente con esa configuración hace uso del oscilador interno que es de 8MHz. Imagino que habrá que configurar el registro OSCCON para lograr una frecuencia de 4MHz

  De todas maneras no entiendo tampoco a que te referís cuando decís "por lo que creo que debo implementar el oscilador en proteus ya que este es interno y funciona"

  Ese error que da respecto del TAD indica que el clock del PIC es mayor al que se uso para calcular el TAD. Por dar un ejemplo sería como si yo configuro un TAD para un clock de 4MHz pero hago trabajar al PIC a 10MHz
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 #81 en: 23 de Diciembre de 2010, 09:59:33 »
Hola, segun la tabla que sale en la pagina 30 del datasheet "TABLE 2-3: OSCILLATOR CONFIGURATION OPTIONS FOR USB OPERATION (CONTINUED)"
Se puede configurar el XT a 4Mhz y de esa tabla he sacado los parametros para configurar bien la palabra de configuracion.

Que solucion propones Angel?

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 #82 en: 23 de Diciembre de 2010, 10:06:33 »
Hola, segun la tabla que sale en la pagina 30 del datasheet "TABLE 2-3: OSCILLATOR CONFIGURATION OPTIONS FOR USB OPERATION (CONTINUED)"
Se puede configurar el XT a 4Mhz y de esa tabla he sacado los parametros para configurar bien la palabra de configuracion.

Que solucion propones Angel?

Gracias.

  Por lo que yo entiendo esa tabla se refiere a los modos XT, HS, EC, ECIO, HSPLL, ECPLL, XTPLL y ECPIO, pero en tu caso no usas ninguno de esos modos. Fijate que en la página 288 donde muestra el registro CONFIG1H muestra claramente que la configuración 1010 de los bits FOSC3...FOSC0 no se corresponde con ninguno de los modos mostrados en la tabla
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 #83 en: 23 de Diciembre de 2010, 10:09:00 »
Si, ya veo que esos bits estan fijos a 1010. Entonces para conseguir un oscilador de 4Mhz con XT..? Si no habria que cambiar los setup de adc y sensor.. ( si cmbiariamos de freq)

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #84 en: 23 de Diciembre de 2010, 10:14:40 »
Si, ya veo que esos bits estan fijos a 1010. Entonces para conseguir un oscilador de 4Mhz con XT..? Si no habria que cambiar los setup de adc y sensor.. ( si cmbiariamos de freq)

  Me parece que sería con lo que te comentaba en el otro mensaje del registro OSCCON. Con dicho registro se modifica el oscilador interno. Fijate en la página 32 del datasheet.

  Y si no, si es que en realidad la señal es tomada desde el bloque PLL habría que configurar los bits CPUDIV para que de dividido 6, eso nos daría 96MHz / 6 que son 16MHz y entonces sí habría que recalcular el TAD para dicha frecuencia.
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 #85 en: 23 de Diciembre de 2010, 13:07:11 »
Entonces utilitzando el registro OOSCON pongo los bits IRCF2:IRCF0 a 110 = 4 MHz y hago SCS1:SCS0: 1x = Internal oscillator en mi funcion init?
El error del proteus decia FOSC3-FOSC0 tenia que ser 1010 y eso si que se corresponde con una opcion ( he entendido que tu has dicho que no).Es la opcion 1010 = Internal oscillator, XT used by USB (INTXT)

Edito: No funciona,sigue saliendo el error pero no entiendo porque, sigue diciendo lo del error en Fosc 1010

Edito1: En el ultimo o penultimo mensaje que has escrito dices que no uso ninguno de los modos ( de los 12 que hay de oscilacion). Queria comentarte que si que uso el modo XT.. a lo mejor estoy entiendo mal lo que me dices pero como modo.. yo entiendo eso


Si te fijas en la FIGURE 2-1: PIC18F2455/2550/4455/4550 CLOCK DIAGRAM ( pag 24) el camino que se sigue para conseguir el XT de 4Mhz es:
Del oscilador primario al oscilador postscaler ( con CPDIV = 00) y despues va directo a los bits FOS3-FOSC0 que tendrian que ser configurados como XT (000X)

La verdad es que he estado probando muchas cosas y sigue tirandome el error. Podrias mirarte a ver como lo harias.. ya no se que probar ni se donde esta el error. Creo que la clave esta en saber seleccionar la "Input frequency " a 4MHz ya que como dice en esa tabla con esa input frequency y esta configuracion se obtienen los 4Mhz
Muchas gracias de nuevo.



« Última modificación: 24 de Diciembre de 2010, 07:03:45 por edu1989 »

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #86 en: 24 de Diciembre de 2010, 09:27:16 »

.........
Edito: No funciona,sigue saliendo el error pero no entiendo porque, sigue diciendo lo del error en Fosc 1010
.........


  ¿Qué software te da ese error? ¿El proteus, cuando intentás colocar esa configuración en el PIC? ¿O el grabador cuando intentás programar al PIC con otra configuración?
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 #87 en: 24 de Diciembre de 2010, 09:30:56 »
Es el proteus. El grabador funciona perfectamente pero como cuando intento comunicarme desde el pic al pc ( con un cable rs232 cruzado) no funciona, pienso que el error del proteus puede que sea la causa real tambien.

Como ya dije con el cable cruzado no recibo nada y con el cable normal recibo caracteres extraños...

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: enviar datos de un sensor de temperatura y de un pot por el puerto serie RS232
« Respuesta #88 en: 24 de Diciembre de 2010, 10:03:05 »
Es el proteus. El grabador funciona perfectamente pero como cuando intento comunicarme desde el pic al pc ( con un cable rs232 cruzado) no funciona, pienso que el error del proteus puede que sea la causa real tambien.

Como ya dije con el cable cruzado no recibo nada y con el cable normal recibo caracteres extraños...


  Yo no tomaría al error del Proteus como posible causa del problema real. Puede ocurrir que Proteus tire dicho error por no ser capaz de simular con esa configuración.

  Volviendo al caso de la vida real. ¿De cuanto es el cristal que tiene tu placa?
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 #89 en: 24 de Diciembre de 2010, 10:16:29 »
Pues en la pag 25  en la tabla TABLE 2-2:CAPACITOR SELECTION FOR CRYSTAL OSCILLATOR pone que el crystal es de 4MHz. Es difícil entenderlo bien porque hay muchos modos y muchas configuraciones distintas.