TODOPIC

Microcontroladores PIC => Primeros pasos - Iniciación a los microcontroladores => Mensaje iniciado por: edu1989 en 28 de Diciembre de 2010, 13:10:38

Título: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 28 de Diciembre de 2010, 13:10:38
Hola amigos,

Como muchos sabeis estoy haciendo un programa que envia datos de un sensor de temperatura y el valor del potenciometro de la placa PICDEM FS USB que incorpora el PIC18f4550.

He hecho pruebas con la herramienta COMPIM de proteus haciendo una connexion entre dos PCs y los datos los recibo perfectamente. Ahora he grabado ese programa al PIC y en el terminal de mi PC recibo caracteres raros.

Que puede estar succediendo?

Adjunto el codigo a continuacion ( trabajo con un cristal de 5MHz seleccionado a partir de las palabras de configuracion y del registro OSCCON  
Código: [Seleccionar]

#include <stdlib.h>  // para poder usar la funcion itoa
#include <htc.h>


__CONFIG(1, 0x0018);
__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  4800 // 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 5000000 // Clock de 5MHz (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 < 5) || (valor_potenciometro <=0))
                 { // 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)
{
//Primary oscillator
SCS1=0;
SCS0=0;
  
  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
  // Seleccionamos el canal 0 (AN0) que es donde esta conectado el potenciometro
  CHS3 = 0;
  CHS2 = 0;
  CHS1 = 0;
  CHS0 = 0;
  //Tiempo de adquisicion
  ACQT2 = 0;
  ACQT1 = 1;  
  ACQT0 = 0;
  // Tiempo de conversion
  ADCS2 = 1;
  ADCS1 = 0;    //                         Idem a 4Tosc. 4*Tosc(1/5Mhz = 0.2us) es el primer valor que hace que sea superior a 0.7us( el minimo) (100)
  ADCS0 = 0;
  
  ADON = 1; // A/D converter module is enabled
  /* Configure A/D interrupt*/
  ADIF = 0;
}
 
//*****************************************************************************
//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));
}
Gracias de antemano. Cualquier pequeña idea es bienvenida!
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 28 de Diciembre de 2010, 14:25:13
  No entiendo porque ponés la configuración de la palabra 1 en 0x0018.
  Basado en éso me da la siguiente configuración....

  00 El byte alto --> quiere decir que está en modo XT
  18 El byte bajo --> oscilador primario dividido 4 y el PLLDIV queda en 0, como está en 0 el bit 5 --> el clock para USB es directo del cristal.

  Pero el modo XT sólo permite como máximo una frecuencia de 4MHz, y en tu placa PICDEM hay un cristal de 20MHz así que abría que cambiar eso para que el modo sea HS.

  Como en el Datasheet dice que los bits no implementados hay que mantenerlos en "1", yo estaba pensando en la siguiente configuración...  0x3CFC

  Explayo el porque: byte alto bits 7 y 6 en 0, bits 5 y 4 en 1 bits 3..0 1100 para que quede en modo HS. Por lo tanto el byte alto queda 0011 1100 --> 3C

  byte bajo: bits 7 y 6 en 1, bit 5 en 1, bits 4 y 3 en 1 para que el clock del sistema sea el oscilador dividido 4 (que serían los 20MHz/4) bits 2..0 en 100 para que el ingreso al PLL del USB sea el oscilador primario dividido 5 (20MHz/5 = 4MHz, que sería la entrada que acepta el bloque PLL del usb). Por lo tanto el byte bajo quedaría 1111 1100 --> FC

  Pero eso es todo en teoría, ya que como nunca use este PIC, todavía no termino de entender bien porque se producen los fallos en tu programa.
 
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 28 de Diciembre de 2010, 19:54:56
Gracias! He probado de cambiar la palabra de configuracion 1 tal y como has dicho y sigue sin funcionar. Ahora en el proteus cuando le pongo el .hex con las palabras de configuracion, ya no se queja pero siguen saliendo los errores del adc:

ADC conversion clock period(2,0832e-08) violates the minimum required TAD time
ADC conversion clock period(2e-07) violates the minimum required TAD time
Simulation is not running in real time due to excessive CPU load

Eso es lo que sale...

Gracias de antemano, a ver si encontramos la solucion.. yo seguire probando cosas.
P.D: Adjunto el archivo del hyperterminal.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 28 de Diciembre de 2010, 22:14:13
Gracias! He probado de cambiar la palabra de configuracion 1 tal y como has dicho y sigue sin funcionar. Ahora en el proteus cuando le pongo el .hex con las palabras de configuracion, ya no se queja pero siguen saliendo los errores del adc:

ADC conversion clock period(2,0832e-08) violates the minimum required TAD time
ADC conversion clock period(2e-07) violates the minimum required TAD time
Simulation is not running in real time due to excessive CPU load

Eso es lo que sale...

Gracias de antemano, a ver si encontramos la solucion.. yo seguire probando cosas.
P.D: Adjunto el archivo del hyperterminal.

  Con respecto al que dice "ADC conversion clock period(2e-07) violates the minimum required TAD time", ese número es 200ns. Si suponemos que ese tiempo sería (en teoría 4/FOSC), hago 200ns/4 y me da 50ns, ahora hago 1/50ns y me da una frecuencia de 20MHz.
  No se porque, pero parecería que el proteus multiplica la frecuencia que uno le pone por el valor de CPUDIV, recorda que CPUDIV está en 4. Entonces si hacemos 5MHZ * 4 me da los 20MHz que despejé en el párrafo anterior.

  Con respecto al error "Simulation is not running in real time due to excessive CPU load", eso es porque la PC se está sobrecargando para la simulación. Sí se simula cualquier circuito demasiado complejo o con muchas operaciones salta ese mensaje.

  Respecto a los caracteres raros también me pasaba en la simulación de proteus cuando me tiraba ese error del TAD porque aparentemente leia mal el ADC y generaba despelotes.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 29 de Diciembre de 2010, 06:15:29
Creo que tienes razon en lo que dices.. entonces.. hago los calculos de los tiempos del adc para 20MHz? o que hago?

Muchas gracias, a ver si funciona pronto :)
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 29 de Diciembre de 2010, 09:55:53
  Y sí, sería cuestión de probar a ver si haciendo los cálculos del ADC para 20MHz empieza a trabajar bien.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 29 de Diciembre de 2010, 12:18:14
 ¿Qué pasa si grabás el programa como lo tenés pero con la configuración que yo te puse, en el PIC real?
 Porque yo acabo de simularlo en el Proteus dejando los 20MHz como directo y haciendo el cálculo para el TAD basado en los 20MHz pero sigue tirando el error que se viola el tiempo mínimo de TAD. Con lo cual me imagino que hay algún problema en la simulación respecto a como interpreta los bits de configuración.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 29 de Diciembre de 2010, 12:19:10
Sigue sin funcionar pero es que ahora mismo en el proteus tambien me da error ( en el compim se marca la opcion de error). Dejo aqui el programa de nuevo, pruebalo a ver si a ti te funciona. He vuelto a calcular los tiempos tanto el tad como el tacq, y he cambiado el reloj por un 20MHz HS ( quitando todos los postscalers y prescalers). Lo del registro OSCCON lo tengo comentado porque no se si esta bien..

Dejo el codigo y la simulacion. Gracias de antemano, seguire mirando..
Código: [Seleccionar]

#include <stdlib.h>  // para poder usar la funcion itoa
#include <htc.h>


__CONFIG(1, 0x3CE0);  // Cambiar
__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 20000000 // Clock de 20MHz

 
#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 < 10) || (valor_potenciometro < 1))
                 { // 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)
{
//Primary oscillator
// SCS1=0;
// SCS0=0;
  
  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
  // Seleccionamos el canal 0 (AN0) que es donde esta conectado el potenciometro
  CHS3 = 0;
  CHS2 = 0;
  CHS1 = 0;
  CHS0 = 0;
  //Tiempo de adquisicion 010
  ACQT2 = 0;
  ACQT1 = 1;   //4Tad
  ACQT0 = 0;
  // Tiempo de conversion
  ADCS2 = 1;
  ADCS1 = 1;    // 16Tosc                        Idem a 4Tosc. 4*Tosc(1/5Mhz = 0.2us) es el primer valor que hace que sea superior a 0.7us( el minimo) (100)
  ADCS0 = 0;
  
  ADON = 1; // A/D converter module is enabled
  /* Configure A/D interrupt*/
  ADIF = 0;
}
 
//*****************************************************************************
//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));
}
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 29 de Diciembre de 2010, 12:20:46
Sigue fallando... en el "PIC real" siguen saliendo caracteres extraños... y ahora como te he comentado da el error en el compim tambien. Envia datos sin tener que enviarlos..
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 29 de Diciembre de 2010, 12:28:32
  Pro lo que veo en tu programa, lo dejaste como igual al que yo use para probar en el Proteus. Lo único que se me ocurre es comentar la parte de manejo de ADC, tanto la inicialización como la lectura del pote, y probar si al menos se transmiten bien los datos correspondientes al TC77. Como para ir descartando cosas.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 29 de Diciembre de 2010, 12:36:22
No se porque no funciona nada ahora.. he probado lo que dices ( estoy con el sensor solo) y no funciona.
Explico exactamente que es lo que ocurre ( estoy sin palabra de configuracion).

El led se enciende y sale todo el rato como si estuviera tx pero cuando abro el vterm envia una serie de 0 ( imagino que es el tiempo que tarda en coger los datos) y para. Se puede leer bien y cuando tecleo "a" sale el valor correcto y actual del sensor.
El led no para de parpadear.. no se el porque pero esta como enviando cosas...

Edito1: Acabo de volver a poner la parte del adc y no lee bien el dato. Todo el rato sale 0...

Estoy alucinando.. el programa esta tal cual lo teniamos, he quitado la palabra d configuracion y tendria que funcionar. Solo hemos tocado los tiempos del adc y hemos seguido lo que dice en el manual...

Estas seguro que los bits no implementados se asignan como "1" y no es un "0"?
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 29 de Diciembre de 2010, 16:28:33
No se porque no funciona nada ahora.. he probado lo que dices ( estoy con el sensor solo) y no funciona.
Explico exactamente que es lo que ocurre ( estoy sin palabra de configuracion).

El led se enciende y sale todo el rato como si estuviera tx pero cuando abro el vterm envia una serie de 0 ( imagino que es el tiempo que tarda en coger los datos) y para. Se puede leer bien y cuando tecleo "a" sale el valor correcto y actual del sensor.
El led no para de parpadear.. no se el porque pero esta como enviando cosas...

Edito1: Acabo de volver a poner la parte del adc y no lee bien el dato. Todo el rato sale 0...

Estoy alucinando.. el programa esta tal cual lo teniamos, he quitado la palabra d configuracion y tendria que funcionar. Solo hemos tocado los tiempos del adc y hemos seguido lo que dice en el manual...

Estas seguro que los bits no implementados se asignan como "1" y no es un "0"?

  Se me ocurre que lo que puede estar pasando es que como no hacés lectura del pote (pero sí la variable "valor_potenciometro" tiene el valor 0 por inicialización) está entrando en los if ya que dicha variable es menor a 25 y por ello ves que te envía siempre 0. Podés probar de inicializarla con un valor superior a 25.

  En cuanto a los bits no implementados, así he visto que están definidos en los .h de HiTech para el 16F876 y funciona bien. También en el datasheet del 18F4550 dice en una de las notas "Unimplemented in PIC18FX455 devices; maintain this bit set.
"
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 29 de Diciembre de 2010, 16:37:14
Sigue sin funcionar, ya habia pensado eso pero como el if tambien depende del sensor, estaba forzando para que entrara y cambiara el valor...
A mi me ha parecido ver en el datasheet que los bits no implementados hay que dejarlos a 0

Mira por ejemplo la TABLE 25-1: CONFIGURATION BITS AND DEVICE IDs (pag 292).

Esta claro que no llega a leer el dato que hay en el pote, la funcion de lectura esta bien y la funcion para pasarlo al valor en texto tambien. Tiene que ser que no guarda bien los datos en el buffer..
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 29 de Diciembre de 2010, 16:48:01
  Dice que los bits no implementados, si yo leo el registro va a aparecer un 0 en dicho lugar, pero en realidad no especifica mucho si es que hay que dejarlos en 0 o en 1.

  Mirando bien el programa, veo que no se está inicializando la variable específicamente, quizá convenga inicializarla en 128, por decir algo. Para evitar que cuando se lo quiera convertir a texto se generen despelotes.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 29 de Diciembre de 2010, 16:49:10
Arriba del todo justo cuando la declaro o donde lo estamos haciendo ahora le pongo 128?

Acabo de probar las dos opciones y nada.. sigue sin funcionar..
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 29 de Diciembre de 2010, 16:51:59
  Dentro del main en lugar de hacer "valor_potenciometro = read_adc();" pone "valor_potenciometro = 128"
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 29 de Diciembre de 2010, 16:54:46
Ahora si...
Osea que el problema como suponiamos es de cuando lee los valores y eso esta directamente relacionado con la frequencia..

Edito: Adjunto codigo actual:
Código: [Seleccionar]

#include <stdlib.h>  // para poder usar la funcion itoa
#include <htc.h>

/*
__CONFIG(1, 0x30E0);  // Cambiar
__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 20000000 // Clock de 20MHz

 
#define CS RB2
 


/* =================================================================================
Global variables 
  ================================================================================= */

 
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 = 30;
  valor_sensor_temperatura = 0;
  LED = 0;
 
init_system();
  setup_sensor();
  setup_adc();
  serial_setup();
 
time_delay(30000000);
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_potenciometro = 128;   
// 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 < 10) || (valor_potenciometro < 25))
                // if (valor_sensor_temperatura < 10)
{ // 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 ("\n");
                   LED = 1;
                   error = 0;
                   break;
    default:
                   error = 1;
                   LED = 0;
                   break;
  }
  return (error);
}

//*****************************************************************************
//Init operations 
//*****************************************************************************
void init_system (void)
{
//Primary oscillator
SCS1=0;
SCS0=0;
 
  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
  // Seleccionamos el canal 0 (AN0) que es donde esta conectado el potenciometro
  CHS3 = 0;
  CHS2 = 0;
  CHS1 = 0;
  CHS0 = 0;
  //Tiempo de adquisicion 010
  ACQT2 = 0;
  ACQT1 = 1;  //4Tad
  ACQT0 = 0;
  // Tiempo de conversion
  ADCS2 = 1;
  ADCS1 = 0;    // 16Tosc                        Idem a 4Tosc. 4*Tosc(1/5Mhz = 0.2us) es el primer valor que hace que sea superior a 0.7us( el minimo) (100)
  ADCS0 = 1;
 
  ADON = 1; // A/D converter module is enabled

 /* Configure A/D interrupt*/
  ADIF = 0;
}
 
//*****************************************************************************
//Leer entradas.
//*****************************************************************************
 
//*****************************************************************************
//LEER DATOS SENSOR
//*****************************************************************************
unsigned char read_spi (void)
{

  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));
}

Gracias de antemano a todos.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 30 de Diciembre de 2010, 00:23:13
  Se me dio por ver en el proteus si cambiaban los registros ADCON y sí cambian. Noté que proteus permite ver el estado de los bytes de configuración y para sorpresa mía veo que no se corresponden con lo que estamos poniendo. Seguramente de allí vienen todos los problemas. Es como que nunca se graban adecuadamente las palabras de configuración.... voy a seguir investigando al respecto.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 30 de Diciembre de 2010, 10:38:57
  Bueno, lo hice funcionar en Proteus utilizando las definiciones del .h de HiTech para los bits de configuración.  Está trabajando a 20MHz, y así dejé las líneas de configuración...

Código: C
  1. __CONFIG (1, HS & CPUDIV1 & USBPLL & PLLDIV5 & FCMDIS & IESODIS);
  2. __CONFIG (2, BORDIS & WDTDIS & PWRTDIS);
  3. __CONFIG (3, MCLRDIS);  // estoy deshabilitando el pin de MasterClear, tal vez haya que habilitarlo, eso hay que probarlo
  4. __CONFIG (4, LVPDIS);
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 30 de Diciembre de 2010, 10:40:48
A mi sin la palabra de configuracion no me iba bien ayer.. puedes adjuntarme todo el codigo? he cambiado muchas cosas y tengo el codigo un poco revuelto.

Muchas gracias!
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 30 de Diciembre de 2010, 10:49:21
A mi sin la palabra de configuracion no me iba bien ayer.. puedes adjuntarme todo el codigo? he cambiado muchas cosas y tengo el codigo un poco revuelto.

Muchas gracias!

  Como no, ahora lo pongo. Lo único que le falta es el delay del comienzo, el que era para evitar que en los primeros 400ms aproximadamente, el sensor envíe el valor 0.
  Yo creo que todo el problema estuvo dado porque como primero no te anduvo en tu placa (porque teníamos configurado en modo XT pero la placa tiene un cristal de 20MHz), empezamos a sospechar de las definiciones del HiTech. Nos volvimos locos con las palabras de configuración erróneamente.

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

Por otro lado, porque usas las palabras de configuracion si dijimos que el fichero estaba mal..?

Edito: He grabado el programa en el PIC y durante un rato envia caracteres raros, despues empieza a enviar los datos bien ( pote y sensor) a mucha velocidad y envia mal los datos del sensor, pone temp 168

A veces me he fijado que pone una temp de 19 grados que puede ser perfectamente. Pero esto va cambiando y va haciendo burradas 511 160 y pico.. creo que el tiempo que tiene para leer no es suficiente. Es como si fuera mas rapido lo otro y solo diera los valores correctos cada un tiempo.
Gracias!
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 30 de Diciembre de 2010, 12:52:50
Sigue sin funcionarme en el proteus.. a ti te va en el proteus?


  Me va de maravilla, utilizando 20MHz también en el proteus.

Por otro lado, porque usas las palabras de configuracion si dijimos que el fichero estaba mal..?


  Como te comenté en el mensaje anterior. Uso las palabras porque creo que en realidad no estaban mal las definiciones sino que llegamos a esa conclusión errónea porque las primeras veces que hiciste la prueba no sabíamos que el cristal de la placa era de 20MHz.
  De hecho si no uso las palabras y pongo el número manualmente, cuando veo desde PIKLAB (entorno similar a MPLAB) los bytes de configuración noto que no concuerdan con lo que uno quiere. Si uso las palabras sí concuerdan.


Edito: He grabado el programa en el PIC y durante un rato envia caracteres raros, despues empieza a enviar los datos bien ( pote y sensor) a mucha velocidad y envia mal los datos del sensor, pone temp 168

A veces me he fijado que pone una temp de 19 grados que puede ser perfectamente. Pero esto va cambiando y va haciendo burradas 511 160 y pico.. creo que el tiempo que tiene para leer no es suficiente. Es como si fuera mas rapido lo otro y solo diera los valores correctos cada un tiempo.
Gracias!

  Eso puede ser que esté ocurriendo....
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 30 de Diciembre de 2010, 13:00:28
Y a este ultimo problema.. como hay que hacerle frente? porque seria otra vez volver a cambiar la freq...

El proteus te funciona?

Podriamos probar de meterle un delay ( no se exactamente donde) para que tenga tiempo de leer bien. No se si en la misma funcion o en el main.. alguna idea?
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 30 de Diciembre de 2010, 14:08:56
Y a este ultimo problema.. como hay que hacerle frente? porque seria otra vez volver a cambiar la freq...

El proteus te funciona?

Podriamos probar de meterle un delay ( no se exactamente donde) para que tenga tiempo de leer bien. No se si en la misma funcion o en el main.. alguna idea?

  Como te mencioné en el anterior mensaje.... "Me va de maravillas". En Proteus funciona perfectamente.
  Ahora hice un par de cambios para que trabaje a 5MHz y también funcionó. Los cambios fueron:
  Poner CPUDIV4 en la primer palabra de configuración. Cambiar PIC_CLK 20000000 por PIC_CLK 5000000. Recalcular el TAD para una frecuencia de 5MHz (4TOSC). Y en la simulación de proteus poner 5MHz como frecuencia del oscilador.

  Con respecto a poner un delay, se puede poner dentro del while que está en el main, antes de hacer cada lectura del sensor

Código: C
  1. while(1)
  2.   {
  3.     // acá poner un delay, habrá que ir experimentando cual es delay que se adapte
  4.     CS = 0;
  5.     byte_alto = read_spi();
  6.     byte_bajo = read_spi();
  7.     CS = 1;
  8.     ......
  9.     ......
  10.     ......
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 30 de Diciembre de 2010, 15:36:15
Te adjunto mi simulacion de proteus y prueba a ver si te funciona.. porque a mi no.

He grabado el PIC otra vez y el pote funciona perfecto pero el sensor no, muestra todo el rato 168 podria ser que fuessen 16.8ºC?
Lo que falla tambien es que envia los datos siempre, sin seguir ningun criterio.

Por otra parte si ahora cambio a 5MHz para hacerlo mas parecido a cuando lo haciamos con 4MHz y funcionaba.. dices que solo he de cambiar PIC_CLK y los tiempos del conversor pero tambien tendre q cambiar la palabra de configuracion no?
Muchas gracias de antemano
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 30 de Diciembre de 2010, 18:08:47
Te adjunto mi simulacion de proteus y prueba a ver si te funciona.. porque a mi no.


  Ahora la bajo y pruebo.

He grabado el PIC otra vez y el pote funciona perfecto pero el sensor no, muestra todo el rato 168 podria ser que fuessen 16.8ºC?
Lo que falla tambien es que envia los datos siempre, sin seguir ningun criterio.


  Recrodá que según el programa, si la temperatura (o el dato tomado desde el sensor) era inferior a 20, se enviaban constantemente los datos. O sea que estaría bien.

Por otra parte si ahora cambio a 5MHz para hacerlo mas parecido a cuando lo haciamos con 4MHz y funcionaba.. dices que solo he de cambiar PIC_CLK y los tiempos del conversor pero tambien tendre q cambiar la palabra de configuracion no?

  Sí, fijate que en el mensaje anterior te puse que había que poner CPUDIV4 en la primer palabra de configuración.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 30 de Diciembre de 2010, 18:32:46
  Me parece que el diablo ha metido su cola.... Simulé tu circuito y no me funciona. Igualmente encontré una diferencia y es que yo estoy utilizando el PIN RB3 como CS y tu cirtuito estaba hecho con el PIN RB2. Pero de todas formas hice ese cambio e igualmente no funciona. Mi recomendación, empezá esquema nuevo en proteus, ya que a veces genera esas cosas extrañas. Yo estoy usando la versión 7.7 SP2.

  Te adjunto una captura de mi circuito para que veas que está funcionando...
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 31 de Diciembre de 2010, 07:02:17
Ya funciona! volvi a armar el proteus y todo va bien.
Respecto a cuando grabo en el PIC, antes has dicho que ya lo estaba haciendo bien:
Recrodá que según el programa, si la temperatura (o el dato tomado desde el sensor) era inferior a 20, se enviaban constantemente los datos. O sea que estaría bien.[

Eso significa que el valor 168 es 16.8 no? voy a ver si lo arreglo para que pueda verse la ",". Imagino que sera cambiar el tipu de datos a float no?

Edito: He cambiado la variable a float --> float valor_sensor_temperatura;
Y ahora necesito otra funcion ( que no sea itoa) para pasar de float a string. He mirado y la funcion es ftoa. La implementacion de ftoa es segun este ejemplo:
Código: [Seleccionar]
#include <stdlib.h>
#include <stdio.h>
void
main (void)
{
char * buf;
float input = 12.34;
int status;
buf = ftoa(input, &status);
printf("The buffer holds %s\n", buf);
}

Y por tanto la declaracion es char * ftoa (float f, int * status)

Cuando hago el cambio me salen errores en el codigo en las lineas:
Código: [Seleccionar]
    valor_sensor_temperatura = (byte_alto << 8) + byte_bajo;
    valor_sensor_temperatura = valor_sensor_temperatura >> 7;

Y en la linea de la funcion ftoa
Código: [Seleccionar]
valor_sensor_en_texto=ftoa(valor_sensor_temperatura,&status);

He declarado status como int como se dice en el ejemplo pero no entiendo muy bien lo que es. Voy a seguir mirando
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 31 de Diciembre de 2010, 09:19:47
Ya funciona! volvi a armar el proteus y todo va bien.
Respecto a cuando grabo en el PIC, antes has dicho que ya lo estaba haciendo bien:
Recrodá que según el programa, si la temperatura (o el dato tomado desde el sensor) era inferior a 20, se enviaban constantemente los datos. O sea que estaría bien.[

Eso significa que el valor 168 es 16.8 no? voy a ver si lo arreglo para que pueda verse la ",". Imagino que sera cambiar el tipu de datos a float no?


  No, no se si el 168 quiere decir que sean 16.8º.  Mi comentario apuntaba a que, si realmente eran 16.8º, estaba bien que los envíe constantemente. Ahora, habría que estudiar realmente que valor está almacenado en "valor_sensor_temperautra"; porque si el valor almacenado en dicha variable es 168 (tal cual lo que envía por RS232) es un error que entre en el if.

  No creo que baste declarando la variable como float. En realidad lo que hay que hacer es estudiar el formato en el cual envía los datos el TC77, y operar matemáticamente al respecto.

Edito: He cambiado la variable a float --> float valor_sensor_temperatura;
Y ahora necesito otra funcion ( que no sea itoa) para pasar de float a string. He mirado y la funcion es ftoa. La implementacion de ftoa es segun este ejemplo:
Código: [Seleccionar]
#include <stdlib.h>
#include <stdio.h>
void
main (void)
{
char * buf;
float input = 12.34;
int status;
buf = ftoa(input, &status);
printf("The buffer holds %s\n", buf);
}

Y por tanto la declaracion es char * ftoa (float f, int * status)

Cuando hago el cambio me salen errores en el codigo en las lineas:
Código: [Seleccionar]
    valor_sensor_temperatura = (byte_alto << 8) + byte_bajo;
    valor_sensor_temperatura = valor_sensor_temperatura >> 7;

Y en la linea de la funcion ftoa
Código: [Seleccionar]
valor_sensor_en_texto=ftoa(valor_sensor_temperatura,&status);

He declarado status como int como se dice en el ejemplo pero no entiendo muy bien lo que es. Voy a seguir mirando

  Yo también he sufrido varios contratiempos cuando quise usar la función ftoa. Me voy a fijar en los varios programitas que tengo a ver si en alguno hago uso de ftoa exitosamente.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 31 de Diciembre de 2010, 10:53:06
Te explico un poco todo lo que he hecho. He probado el programa con la condicion temp <20 y pote <50 y funciona OK, porque ahora mismo estamos a 18 grados aqui donde estoy y es un valor entero.

La segunda prueba, la he hecho con la condicion temp < 10 y pote < 500 y me pone q la temp es 168, es como si no cogiera bien la temperatura si la primera vez no entra en el if  o no se q pasa..
Lo que si que veo es que cuando es temp=168 el bucle no para y no se q passa.. de eso saco que 168 no es 16.8 ya que la condicion esta por debajo de 10.

Como creo que es eso, ahora mismo estaba enviando los datos ( me salia el 168), he sacado el cable rs232 del pic ( con el puerto abierto) he vuelto a connectarlo y que grata sorpresa! temperatura =18 grados! lo que si que falla es que lo va enviando continuamente...

P.D: No se porque pero me parece que no es un problema de comas ya que si la temperatura fuera de 16.8 mostraria o 16 o 17 pero creo que este no es el problema. A veces aparecen estos 168 por algun que otro motivo.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 31 de Diciembre de 2010, 11:35:51
Ese 168 es problema del tiempo de adquisicion de datos del sensor. Nada mas.

El programa ahora funciona perfecto, lo unico que no muestra bien es cuando le envio el caracter "a" para que me envie los dos datos, el dato del pote esta Ok pero el dato del sensor siempre es 0. Luego si hago cumplir la condicion me dice la temp adequada del sensor..

Creo que en el caso de que se enviase un caracter ( en nuestro caso "a"), tendriamos que leer dentro de esa pequeña parte del codigo el dato que hay del sensor.


Gracias de antemano.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 31 de Diciembre de 2010, 12:21:24
Ese 168 es problema del tiempo de adquisicion de datos del sensor. Nada mas.


  En el datasheet del TC77 me pareció leer que el tiempo de adquisición es de 300ms, pero si se intenta leer el dato antes que termine dicha adquisición el dato que envía el TC77 es el dato que estaba almacenado anteriormente.
Supongamos que el sensor tiene en su registro el valor correspondiente a 17º y yo leo dicho dato. De repente es expuesto a 25º y comienza la adquisición propia del sensor, si yo intento leer en este momento me devolvería 17 si es que todavía no terminó con la adquisición. No debería devolver un valor erróneo.


El programa ahora funciona perfecto, lo unico que no muestra bien es cuando le envio el caracter "a" para que me envie los dos datos, el dato del pote esta Ok pero el dato del sensor siempre es 0. Luego si hago cumplir la condicion me dice la temp adequada del sensor..

Creo que en el caso de que se enviase un caracter ( en nuestro caso "a"), tendriamos que leer dentro de esa pequeña parte del codigo el dato que hay del sensor.


  No debería ser ese el problema, porque lo único que hace el programa es forzar a que se envíen los datos, tanto si la temperatura es menor a 20 como si yo le envío la "a" por el RS232.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 31 de Diciembre de 2010, 12:23:24
El 168 ya no me sale al poner un delay mas grande. El problema ahora es que envia temp=0 cuando pido los datos enviando el caracter "a"
He probado eso de leer el dato justo antes de enviarlo y sigue enviado el 0.

P.d: Yo tambien he leido eso de los 300ms y si q tienes razon.. no se de donde saldra entonces el 168 q salia.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 02 de Enero de 2011, 09:54:58
Hola a todos, aprovecho la ocasion para felicitaros el año y la navidad. Espero que estas fiestas esten hiendo bien

He seguido probando cosas y pasa lo que pasaba hasta ahora.. funciona bien pero cuando envio el caracter a q tiene que devolverme los dos datos, el valor del sensor es 0 no se porque.

Seguire mirando cosas y posteando los resultados.

Muchas gracias.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 03 de Enero de 2011, 06:33:25
Ahora vuelve a salirme el 168. He cambiado a 5MHz y lo he probado y me sale el 168 con la condicion temp < 30ºC ( siempre esta enviando). Por otro lado sigue enviando temp=0 cuando envio el caracter "a"

Ayuda por favor! no se que intentar ya..

ARREGLADO! Era el pin CS! que estaba en rb3 y tenia que estar en rb2.. pequeñas cosas que hacen que todo falle!
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 03 de Enero de 2011, 13:54:48
  Entonces, para clarificar, ¿Cómo quedó el asunto? ¿Está funcionando todo bien ahora?
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 03 de Enero de 2011, 14:00:41
Si, todo OK.
Mirate el post que he abierto hoy para que veas donde estoy ahora mismo. Se por un dia que me dijiste que no dominas mucho los comandos AT pero creo que el problema que tengo no es con los comandos.

Muchas gracias.
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 10 de Enero de 2011, 15:07:44
Hola de nuevo Angel, tengo una pequeña parte mas para ayer.


Tengo que hacer que el dispositivo que va conectado al PIC (via RS232) sea detectable y conectable para otros dispositivos. Eso lo hago con comandos AT ( es igual que no sepas como funcionan). Tengo que enviar por el puerto ser ie los siguientes comandos:
Código: [Seleccionar]
ats0=1<cr>
ats512=4<cr>
ats502=1<cr>
ats536=1<cr>
at+btk="XXXX"<cr>
at&w<cr>
atz<cr>

Cuando recibo cada comando, el modulo Bluetooth me envia un "OK" de vuelta por el puerto serie. Tengo que ir enviado por ejemplo: ats0=1 y esperar a recibir el OK, y cuando lo reciba enviar la siguiente instruccion. Despues de cada instruccion hay que enviar el cambio de linea tambien. Esta parte solo es para hacer el modulo detectable y connectable

Despues tengo que estar a la espera de que el otro modulo se quiera connectar con el del PIC. Hay que estar leyendo el puerto serie para saber cuand envia a peticion de connexion. Despues pondre exactamente el mensaje que envia.

Despues de todo esto hay que iniciar el programa que ya tenemos hecho. Pongo una pequeña parte del codigo que es como yo lo he planteado.
Código: [Seleccionar]
// Establecer connexion con comandos AT

putst ("AT");
putst ("\n");
//Comprovar que reciba  "OK"


putst ("ATS0=1")
putst ("\n");
//Comprovar que reciba  "OK"

putst ("ATS512=4")
putst ("\n");
//Comprovar que reciba  "OK"

putst ("ATS502=1")
putst ("\n");
//Comprovar que reciba  "OK"

putst ("ATS536=1")
putst ("\n");
//Comprovar que reciba  "OK"

putst ("AT+BTK="1234"")
putst ("\n");
//Comprovar que reciba  "OK"

putst ("AT&W")
putst ("\n");
//Comprovar que reciba  "OK"

putst ("ATZ")
putst ("\n");
//Comprovar que reciba  "OK"

 
Si se recibe el mensaje siguiente, empieza el programa:
Código: [Seleccionar]
PAIR 1 008098E6A5F4
PAIR 0 008098E6A5F4
CONNECT 008098E6A5F4,1101 A

Cuando se lea esto, el programa puede empezar con normalidad

Muchas gracias de antemano Angel
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 11 de Enero de 2011, 05:45:34
Hola a todos, he seguido haciendo pruebas y he sacado esto:
Código: [Seleccionar]
Establecer connexion con comandos AT
   ================================================================================= */

//Primer comando AT
putst ("AT");
putst ("\n");
//Comprovar que reciba  "OK"
 if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
 {
   comando_recibido1 = getch();    // Cambiar getch por una funcion que lea mas de 1 caracter
   while (comando_recibido1!="OK"){
      error_comando=0;
}
if(comando_recibido1=="OK")
      error_comando=1;
 }

//Segundo comando AT
if (error_comando==1)
{
error_comando=0;
putst ("ATS0=1");
putst ("\n");
 if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
 {
   comando_recibido2 = getch();    // Cambiar getch por una funcion que lea mas de 1 caracter
   while (comando_recibido2!="OK")
      error_comando=0;
if(comando_recibido2=="OK")
      error_comando=1;
 }
}



//Tercer comando AT
if (error_comando==1)
{
error_comando=0;
putst ("ATS512=4");
putst ("\n");
 if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
 {
   comando_recibido3 = getch();    // Cambiar getch por una funcion que lea mas de 1 caracter
   while (comando_recibido3!="OK")
      error_comando=0;
if(comando_recibido3=="OK")
      error_comando=1;
 }
}


//Quarto comando AT
if (error_comando==1)
{
error_comando=0;
putst ("ATS502=1");
putst ("\n");
 if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
 {
   comando_recibido4 = getch();    // Cambiar getch por una funcion que lea mas de 1 caracter
   while (comando_recibido4!="OK")
      error_comando=0;
if(comando_recibido4=="OK")
      error_comando=1;
 }
}


//Quinto comando AT
if (error_comando==1)
{
error_comando=0;
putst ("ATS536=1");
putst ("\n");
 if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
 {
   comando_recibido5 = getch();    // Cambiar getch por una funcion que lea mas de 1 caracter
   while (comando_recibido5!="OK")
      error_comando=0;
if(comando_recibido5=="OK")
      error_comando=1;
 }
}


//Sexto comando AT
if (error_comando==1)
{
error_comando=0;
putst ("AT+BTK=1234");
putst ("\n");
 if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
 {
   comando_recibido6 = getch();    // Cambiar getch por una funcion que lea mas de 1 caracter
   while (comando_recibido6!="OK")
      error_comando=0;
if(comando_recibido6=="OK")
      error_comando=1;
 }
}

//Septimo comando AT
if (error_comando==1)
{
error_comando=0;
putst ("AT&W");
putst ("\n");
 if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
 {
   comando_recibido7 = getch();    // Cambiar getch por una funcion que lea mas de 1 caracter
   while (comando_recibido7!="OK")
      error_comando=0;
if(comando_recibido7=="OK")
      error_comando=1;
 }
}

//Octavo comando AT
if (error_comando==1)
{
error_comando=0;
putst ("ATZ");
putst ("\n");
 if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
 {
   comando_recibido8 = getch();    // Cambiar getch por una funcion que lea mas de 1 caracter
   while (comando_recibido8!="OK")
      error_comando=0;
if(comando_recibido8=="OK")
      error_comando=1;
 }
}

Hay errores y deberiamos cambiar la funcion getch ya que esta solo lee un caracter y en este caso se envia un "OK" que son dos caracteres

Ayudenme por favor.
Muchas gracias, seguire investigando...
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: AngelGris en 11 de Enero de 2011, 10:25:18
  En estos momentos estoy sin mi PC, porque tengo conectada la de un amigo para probarla; supongo que para el miércoles ya conectaré la mía.
  Podrías fijarte en www.microchipc.com, si en las funciones para RS232 no está ya implementada una función para lectura de cadena a travez del RS232, sino habrá que hacer una rutina propia.

  Creo que cuando envías un comando podés poner directamente "puts ("AT/n");" Con el "/n" ya incluido, tal vez sea más legible así. Es sólo cuestión de gustos.

  En un if hacés "if (comando_recibido1 == "OK") error_comando = 1". Pero no podés comparar cadenas de caracteres de esa manera. Si no me equivoco la función para comparar cadenas de caracteres es STRCMP.

 
  Y como simple detalle, creo que la mayoría de los lenguajes de programación (al menos lo sé de Pascal y Delphi), cuando una función se ejecutó bien el error es 0 (cero). Tal vez para unificar criterios podrías hacer lo mismo, es decir, si el if de comando_recibido es OK entonces poner "error_comando = 0".
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 11 de Enero de 2011, 11:13:11
Muchas gracias! ( Que fallo no usar el strcmp..). Ya he modificado todo lo que dices.

Me sale un error ahora porque creo que debo pasar el puntero de los caracteres. Si te fijas en la declaracion de la función strcmp en la lib string.h:
Código: [Seleccionar]
#include <string.h>

int
strcmp(register const char * s1, register const char * s2)
{
register signed char r;

while(!(r = (unsigned char)*s1 - (unsigned char)*s2++) && *s1++)
continue;
return r;
}


Yo en mi programa lo hago de esta forma: ( Pongo solo una de las palabras porque en todos los casos es lo mismo, lo unico que cambia es el caracter enviado)
Código: [Seleccionar]
//Segundo comando AT
if (error_comando==0)
{
error_comando=1;
putst ("ATS0=1/n");

 if (getch_available() == true) //Si hay un caracter disponible recibido por el puerto serie
 {
   comando_recibido2 = getch();    // Cambiar getch por una funcion que lea mas de 1 caracter
 while (strcmp(comando_recibido2, comando_recibido_ideal)!= 1 ){
      error_comando=1;
}
if(strcmp(comando_recibido2, comando_recibido_ideal) == 1 )
      error_comando=0;
 }


Y la declaracion de estos datos la tengo puesta como:
Código: [Seleccionar]
int error_comando=1;
char comando_recibido_ideal[] = "OK";


char comando_recibido1;
char comando_recibido2;
char comando_recibido3;
char comando_recibido4;
char comando_recibido5;
char comando_recibido6;
char comando_recibido7;
char comando_recibido8;

Creo que es el tema de los punteros...

Gracias de antemano por toda la ayuda prestada
Título: Re: Problema: aparecen caracteres raros PIC18f4550 [Hi-tech PICC-18]
Publicado por: edu1989 en 11 de Enero de 2011, 12:05:53
Hola de nuevo, queria comentarte una cosa que se me paso antes. El salto de linia es /n o \n?

Lo de la función que lee mas de un caracter, tenia una en mi codigo:
Código: [Seleccionar]
unsigned char UsartReadChar_nonstop(void)
{
  if (!RCIF) // TRMT1 is set when TSR is empty
    return 0;   
  return RCREG;
}

Esa parte del if se va haciendo hasta que el bit RCIF es 1 y por tanto el registro TSR esta vacio ( no hay mas para transmitir? ? No entiendo bien ese return 0..
Entra en ese if si el buffer no esta vacio no?

Gracias de antemano.