Autor Tema: Problema al pasar codigo de CCS a C18  (Leído 2361 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado omix

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 244
Problema al pasar codigo de CCS a C18
« en: 21 de Mayo de 2005, 15:11:00 »
Hola, he implementado un receptor de mando a distancia RC5 para un proyecto y lo hice en C de CCS, pero al pasarlo a C18 que es el que tengo que usar para el proyecto pues este no funciona como deberia, vamos no me captura ninguna tecla correctamente, yo creo que el problema esta en los delay que uso para capturar la trama, aunque no me explico porque en el CCS si funciona perfectamente y en el C18 no. A ver si alguno me dice donde puede estar el fallo, pq yo llevo dos dias dandole vueltas y no hay manera de encontrarlo.

CODIGO CCS

#include <18F452.h>
#use delay(clock=20000000)

#use fast_io(B)
#use fast_io(D)

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOCPD,NOWRT,NODEBUG

#org 0x7000, 0x7A00 void bootLoader(){}


#byte PORTB = 0xF81
#byte PORTD = 0xF83
#bit MANDO = PORTB.0

/*
 * Rutina que realiza un retraso de 889 microsegundos.
 */
void delay_889us(void){
   int16 tiempo;
   set_timer0(0);
   do{
     tiempo = get_rtcc();
   }while(tiempo < 4445);
}
/*
 * Rutina que realiza un retraso de 444 microsegundos.
 */
void delay_444us(void){
   int16 tiempo;
   set_timer0(0);
   do{
      tiempo = get_rtcc();
   }while(tiempo < 2220);
}
/*
 * Rutina para realizar retrasos de n milisegundos.
 */
void delayms(unsigned int16 miliseconds)
{
   unsigned int16 tiempo;
   unsigned int16 i;
   for(i = 0; i < miliseconds; i++){
      set_timer0(0);
      do{                                 //realiza un retraso de 1ms
         tiempo = get_rtcc();
      }while(tiempo < 5000);
   }
}
/*
 * Rutina para realizar retrasos de n microsegundos.
 */
void delayus(unsigned int16 microseconds){
   unsigned int16 tiempo;
   unsigned int16 i;
   for(i = 0; i < microseconds; i++){
      set_timer0(0);
      do{                                 //realiza un retraso de 1us
         tiempo = get_rtcc();
      }while(tiempo < 5);
   }
}

void procesaTecla(int16 tecla){
   byte comando;
   byte direccion;
   //extraemos comando
   comando = 0;
   direccion = 0;
   comando = tecla & 0x3F;
   //extraemos la direccion de dispositivo al que va dirigido
   direccion = (tecla & 0x07C0);
   switch (comando){
      case 0: PORTD = 0x00; break;
      case 1: PORTD = 0x01; break;
      case 2: PORTD = 0x02; break;
      case 3: PORTD = 0x04; break;
      case 4: PORTD = 0x08; break;
      case 5: PORTD = 0x10; break;
      case 6: PORTD = 0x20; break;
      case 7: PORTD = 0x40; break;
      case 8: PORTD = 0x80; break;
   }
   printf("Tecla leida: ADR = %x, CMD = %x
",direccion,comando);
}

void main()
{

   int i;
   unsigned int16 tecla;
   short int b1,b2;
   short int bit;
   int unos;
   int16 tiempo;

   set_tris_b(0x01);
   set_tris_d(0x00);

   //configuramos timer0 como contador para la base de tiempos de los delays
   //reloj interno = 20000000MHz/4, sin preescaler
   setup_counters(RTCC_INTERNAL,RTCC_DIV_1);//overflow timer 0 cada 13.1ms

   while(1){
      while(MANDO == 1);   //espera el primer bit de start 1->0
      delayus(2);                //retraso para que le de tiempo a la señal a caer a 0
      while(MANDO == 0);   //espera a que la señal pase de nuevo a 1 (segundo bit de start)
      delayus(2);                //retraso para que le de tiempo a la señal a subir a 1
      while(MANDO == 1);   //espera a que la señal caiga a 0 (deteccion segundo bit start)
 
      tecla = 0;
      delay_889us();             //retraso para saltarnos la mitad restante del 2º bit start
      i = 0;
      do{
         tecla = tecla << 1;
         delay_444us();             //posicionamos en el centro del primer bit a leer
         b1 = MANDO;                //tomamos primera muestra
         delay_889us();             //volvemos a posicionarnos en el centro
         b2 = MANDO;                //tomamos la segunda muestra
         if(b1 && !b2){             //si b1 = 1 y b2 = 0 se trata de un 1
            bit = 1;                //RC5 se codifica en bifase y un "1" se representa por una transicion 0->1,
         }else                      //pero el sensor nos da la salida negada asi que un "1" es 1->0 y el "0"
            bit = 0;                //es una trasicion 1->0 y leemos del sensor como 0->1    
         tecla |= bit;              //almacena el bit leido en un buffer
         delay_444us();             //nos posicionamos en el siguiente bit a leer
         i++;
      }while(i < 12);               //repetimos el proceso 12 veces para leer los 12 bits que forman la trama
                                    //1 bit toggle, 5 bits direccion y 6 bits de comando
      procesaTecla(tecla);
      output_bit(PIN_B1, 1);
      delayms(50);
      output_bit(PIN_B1, 0);
      delayms(150);                 //hacemos una pausa para evitar repeticiones
   }

}

CODIGO C18

#pragma config OSC=HS, WDT=OFF, LVP=OFF
#include <p18f452.h>
#include <usart.h>
#include <stdio.h>
#include <timers.h>

#define MANDO PORTBbits.RB0   //Pin en el que se encuentra conectado el receptor IR

/*
 * Rutina que realiza un retraso de 889 microsegundos.  
 */
 void delay_889us(void){
    unsigned int tiempo;
    WriteTimer0(0);
    do{                                
       tiempo = ReadTimer0();
    }while(tiempo < 4445);   
}

/*
 * Rutina que realiza un retraso de 444 microsegundos.  
 */
void delay_444us(void){
   unsigned int tiempo;
    WriteTimer0(0);
    do{                                
       tiempo = ReadTimer0();
    }while(tiempo < 2220);
}
/*
 * Rutina para realizar retrasos de n milisegundos.  
 */
void delayms(unsigned int miliseconds)
{
   unsigned int tiempo;
   unsigned int i;
   for(i = 0; i < miliseconds; i++){
      WriteTimer0(0);
      do{                                 //realiza un retraso de 1ms
         tiempo = ReadTimer0();
      }while(tiempo < 5000);
   }
}
/*
 * Rutina para realizar retrasos de n microsegundos.  
 */
void delayus(unsigned int microseconds){
   unsigned int tiempo;
   unsigned int i;
   for(i = 0; i < microseconds; i++){
      WriteTimer0(0);
      do{                                 //realiza un retraso de 1us
         tiempo = ReadTimer0();
      }while(tiempo < 5);
   }
}

void procesaTecla(unsigned int tecla){
      unsigned char comando;
      unsigned char direccion;
      //extraemos comando
      comando = 0;
      direccion = 0;
      comando = tecla & 0x003F;
      //extraemos la direccion de dispositivo al que va dirigido
      direccion = (tecla & 0x07C0);
   switch (comando){
      case 0: PORTD = 0x00;break;
      case 1: PORTD = 0x01;break;
      case 2: PORTD = 0x02;break;
      case 3: PORTD = 0x04;break;
      case 4: PORTD = 0x08;break;   
      case 5: PORTD = 0x10;break;
      case 6: PORTD = 0x20;break;
      case 7: PORTD = 0x40;break;
      case 8: PORTD = 0x80;break;
   }
      printf("Tecla leida: ADR = %x, CMD = %x
",direccion,comando);
}

void main(){
   int i;
      unsigned int tecla;
      unsigned char b1,b2;

   TRISD = 0x00;
   TRISB = 0x01;
   //configuramos timer0 como contador para la base de tiempos de los delays
      //reloj interno = 20000000MHz/4, sin preescaler
   OpenTimer0(TIMER_INT_OFF & T0_16BIT &
            T0_SOURCE_INT & T0_PS_1_1);//overflow timer 0 cada 13.1ms
   OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF &
            USART_ASYNCH_MODE & USART_EIGHT_BIT &
            USART_CONT_RX & USART_BRGH_HIGH, 129);

   while(1){           
       while(MANDO);               //espera el primer bit de start 1->0
         delayus(2);                    //retraso para que le de tiempo a la señal a caer a 0
         while(!MANDO);               //espera a que la señal pase de nuevo a 1 (segundo bit de start)
         delayus(2);                    //retraso para que le de tiempo a la señal a subir a 1
         while(MANDO);               //espera a que la señal caiga a 0 (deteccion segundo bit start)
        tecla = 0;   
         delay_889us();                  //retraso para saltarnos la mitad restante del 2º bit start
         i = 0;
         do{
         tecla = tecla << 1;
           delay_444us();                //posicionamos en el centro del primer bit a leer
           b1 = MANDO;                 //tomamos primera muestra
           delay_889us();                //volvemos a posicionarnos en el centro
           b2 = MANDO;                 //tomamos la segunda muestra
           if(b1 && !b2)                 //si b1 = 1 y b2 = 0 se trata de un 1
                tecla |= 1;               //RC5 se codifica en bifase y un "1" se representa por una transicion 0->1,
           else                      //pero el sensor nos da la salida negada asi que un "1" es 1->0 y el "0"
              tecla |= 0;            //es una trasicion 1->0 y leemos del sensor como 0->1
                                //almacena el bit leido en un buffer
           delay_444us();                //nos posicionamos en el siguiente bit a leer
           i++;
         }while(i < 12);                 //repetimos el proceso 12 veces para leer los 12 bits que forman la trama
                              //1 bit toggle, 5 bits direccion y 6 bits de comando   
         procesaTecla(tecla);
        PORTBbits.RB1 = 1;               
        delayms(50);
        PORTBbits.RB1 = 0;      
         delayms(150);
     
   }
}

Un saludo.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
RE: Problema al pasar codigo de CCS a C18
« Respuesta #1 en: 21 de Mayo de 2005, 23:34:00 »
Describe cuál es el error que tienes en C18. ¿Qué valor tiene la variable tecla al final del programa?, ¿y en puntos intermedios?

Desconectado omix

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 244
RE: Problema al pasar codigo de CCS a C18
« Respuesta #2 en: 22 de Mayo de 2005, 03:15:00 »
Hola nocturno66, el problema que tengo es que por ejemplo cuando pulso la tecla 1 del mando a distancia en el CCS me captura el valor correcto que es 0x01, pero en cambio en el C18 cuando pulso la tecla 1 me captura el valor 0x1C, lo cual no es correcto y lo mas raro aun es que si pulso la tecla 2 y 3 en el C18 obtengo el mismo valor 0x18, cuando deverian de valer 0x02 y 0x03 respectivamente, y con otras teclas pues pasa mas de lo mismo e incluso salen valores distintos dependiendo de cuando pulses la tecla.

Yo creo que el origen del problema esta en los delays, pq parece ser que no se sincroniza bien con la trama del mando, pero lo que no entiendo si uso el timer 0 en ambos casos para calcular los delays, pq en uno sincroniza bien y en el otro no?

En cuanto a los valores que toma la variable tecla al final del programa es lo que te he dicho anteriormente, en puntos intermedios no puedo imprimir el valor que va tomando pues sino pierdo la sincronizacion total con la trama y salen valores dispares.

Espero que esto aclare algo mas el problema.

Un saludo.

Desconectado omix

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 244
RE: Problema al pasar codigo de CCS a C18
« Respuesta #3 en: 23 de Mayo de 2005, 13:46:00 »
Bueno me respondo a mi mismo, ya encontre el problema, que como bien sospechaba estaba en los delays, al parecer el C18 genera mas instrucciones en ensamblador de las debidas y por eso se iva todo al carajo cuando intentaba usarlas para capturar la trama del receptor de infrarrojos. La solución ha pasado por implementar dichas rutinas en ensamblador pq sino no habia manera quizá haya otra manera de solucionarlo pero no he logrado encontrarla.

Saludos.