Autor Tema: Ayuda con inerrupcion ccp1 en 18f2550  (Leído 2076 veces)

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

Desconectado rabanisa

  • PIC10
  • *
  • Mensajes: 12
Ayuda con inerrupcion ccp1 en 18f2550
« en: 06 de Diciembre de 2010, 10:15:12 »
Buenos dias:

Mi duda(una de tantas) es la siguiente, estoy realizando un marcador para una mini-moto con 16f876 pero me he quedado corto de memoria y me he psasdo al 18f2550, pero ya no funciona el programa. El tema es que todo el programa gira en torno a una interrupcion.Basicamente esta interrupcion cuenta decimas de segundo y las visualiza. Lo que no consigo pasar del 16f876 al 18f2550, no se si me explico. Aqui posteo el codigo que tengo en el 16f876 :
Código: [Seleccionar]
#include <16F876.h>
#device ADC=10
#use delay(clock=4000000)
#fuses XT,NOWDT
//#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7)

#byte PORTA=0x05
#byte PORTB=0x06
#byte PORTC=0x07
//#include "Crono_LCD.h"
#include <LCDindif.c>
//#include <cgram.c>
#byte T1CON=0x10   //Registro de control de TMR1
#bit TMR1ON=0x10.0   //Bit de puesta en marcha y parada de TMR1
char   decimas, segundos, minutos, horas, ANTES_PORTB,item,SALIR,funcioncrono,numero_vuelta;

//Tratamiento de la interrupción generada por CCP1, cada décima de segundo si está en marcha TMR1
#int_CCP1
CCP1_comparacion_isr()
{
 
   decimas++;         //Incrementamos el contador de décimas
 
   

   if (decimas==10)   //Si llegamos a 10, debemos seguir incrementando
   {
     
      decimas=0;      //Decimas a 0
      segundos++;      //Incrementamos segundos
      // asi es para que cuente  de 100 en 100
     
   
     
   
      if (segundos==60)   //Si llegamos a 60s, seguimos incrementando
      {
         segundos=0;      //Segundos a 0
         minutos++;      //Incrementamos minutos
         if (minutos==60)   //Si llegamos a a 60 minutos, seguimos...
         {   
            minutos=0;   //Minutos a 0
            horas++;   //Incrementamos horas
            if(horas==24)   //Si llegamos a 24 horas, hay que parar
            {
               horas=0;   //Reseteamos horas
               TMR1ON=0;   //Paramos TMR1
               //Mostramos en la linea superior el tiempo
               lcd_putc('\f');   
               lcd_gotoxy(1,1);
               printf(lcd_putc,"MAXIMO ALCANZADO") ;
               //printf(lcd_putc,"%02u:%02u:%02u.%1u \n",horas,minutos,segundos,decimas);
               //Mostramos en la línea inferior el estado
               //lcd_gotoxy(11,1);
               //printf(lcd_putc,"   OFF");
               return;   //Salimos de la función de tratamiento de la interrupción de CCP1
            }
         }
      }
   }
   
   //Si ha cambiado el tiempo, hay que representar el nuevo valor:
   //En la línea superior del LCD, el tiempo actual
   lcd_putc('\f');
   lcd_gotoxy(1,1);
   printf(lcd_putc,"%02U:%02u:%02u.%1u"horas,minutos,segundos,decimas);
   lcd_gotoxy(1,2);
   printf(lcd_putc,"                ");
     
   
     
     
   
   lcd_gotoxy(11,1);
   printf(lcd_putc,"   ON ");
   }//Final de la función para tratamiento de la interrupción de CCP1


   
   void main(){     
   //setup_adc_ports(NO_ANALOGS);
   setup_adc_ports(AN0);   //RA0 entrada analógica
   set_adc_channel(0);      //Selección del canal 0 (RA0)
   delay_us(10);         //Temporiza 10uS
   setup_adc(ADC_CLOCK_DIV_2);
   setup_spi(FALSE);
   //setup_psp(PSP_DISABLED);
   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
   setup_timer_2(T2_DISABLED,0,1);
   setup_ccp2(CCP_OFF);
   
   

   //Configuramos TMR1 como temporizador y con prescaler de 8
   T1CON=0b00110000;   
   set_timer1(0);   //Reseteamos TMR1

   //CCP1 en modo comparación con evento especial de disparo
   setup_ccp1(CCP_COMPARE_RESET_TIMER);   

   //Cargamos registros de CCP1 para alcance de TMR1 cada 0,1s
   // 0.1 s = (4/4MHz)*8*CCP1H_CCP1L -> CCP1H_CCP1L = 12500 = 0x30D4
   CCP_1_LOW = 0xD4;   //Carga de la parte baja
   CCP_1_HIGH = 0x30;   //Carga de la parte alta
   setup_timer_0(RTCC_DIV_1|RTCC_EXT_L_TO_H);   //TMR0 reloj externo 0-1 y preescaler 1:1
   set_timer0 (0);   
   //Se activan las interrupciones del módulo CCP1
   enable_interrupts(INT_CCP1);
   enable_interrupts(global);

   //Reseteamos el LCD por software
   lcd_clear();
   lcd_home();
   //Ahora lo inicializamos
   lcd_init();
   lcd_clear();

   //Inicializamos también la cuenta del tiempo desde cero
   decimas=0;
   segundos=0;
   minutos=0;
   horas=0;
 
           
           
            lcd_init();
            lcd_gotoxy(1,2);
            printf(lcd_putc,"   version 1.0   ");
            lcd_gotoxy(1,1);
            printf(lcd_putc,"  MINI-MARCADOR ");
            delay_ms(3000);
            TMR1ON=1;
           
           while(1) {
           }
           
      }

y aqui pongo lo que tengo con el 18f2550

Código: [Seleccionar]
#include <18f2550.h>
#use delay(clock=4000000)
#fuses XT,NOWDT
//#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7)

#byte PORTA=0xf80 //0x05
#byte PORTB=0xf81 //0x06
#byte PORTC=0xf82 //0x07
//#include "Crono_LCD.h"
#include <LCDindif.c>
//#include <cgram.c>
#byte T1CON=0x10   //Registro de control de TMR1
#bit TMR1ON=0x10.0   //Bit de puesta en marcha y parada de TMR1
char   decimas, segundos, minutos, horas, ANTES_PORTB,item,SALIR,funcioncrono,numero_vuelta;

//Tratamiento de la interrupción generada por CCP1, cada décima de segundo si está en marcha TMR1
#int_CCP1
CCP1_comparacion_isr()
{
 
   decimas++;         //Incrementamos el contador de décimas
 
   

   if (decimas==10)   //Si llegamos a 10, debemos seguir incrementando
   {
     
      decimas=0;      //Decimas a 0
      segundos++;      //Incrementamos segundos
      // asi es para que cuente  de 100 en 100
     
   
     
   
      if (segundos==60)   //Si llegamos a 60s, seguimos incrementando
      {
         segundos=0;      //Segundos a 0
         minutos++;      //Incrementamos minutos
         if (minutos==60)   //Si llegamos a a 60 minutos, seguimos...
         {   
            minutos=0;   //Minutos a 0
            horas++;   //Incrementamos horas
            if(horas==24)   //Si llegamos a 24 horas, hay que parar
            {
               horas=0;   //Reseteamos horas
               TMR1ON=0;   //Paramos TMR1
               //Mostramos en la linea superior el tiempo
               lcd_putc('\f');   
               lcd_gotoxy(1,1);
               printf(lcd_putc,"MAXIMO ALCANZADO") ;
               //printf(lcd_putc,"%02u:%02u:%02u.%1u \n",horas,minutos,segundos,decimas);
               //Mostramos en la línea inferior el estado
               //lcd_gotoxy(11,1);
               //printf(lcd_putc,"   OFF");
               return;   //Salimos de la función de tratamiento de la interrupción de CCP1
            }
         }
      }
   }
   
   //Si ha cambiado el tiempo, hay que representar el nuevo valor:
   //En la línea superior del LCD, el tiempo actual
   lcd_putc('\f');
   lcd_gotoxy(1,1);
   printf(lcd_putc,"%02U:%02u:%02u.%1u"horas,minutos,segundos,decimas);
   lcd_gotoxy(1,2);
   printf(lcd_putc,"                ");
     
   
     
     
   
   lcd_gotoxy(11,1);
   printf(lcd_putc,"   ON ");
   }//Final de la función para tratamiento de la interrupción de CCP1


   
   void main(){     
   setup_adc_ports(NO_ANALOGS);
   //setup_adc_ports(AN0);   //RA0 entrada analógica
   //set_adc_channel(0);      //Selección del canal 0 (RA0)
   //delay_us(10);         //Temporiza 10uS
   setup_adc(ADC_CLOCK_DIV_2);
   //setup_spi(FALSE);
   //setup_psp(PSP_DISABLED);
   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
   setup_timer_2(T2_DISABLED,0,1);
   setup_ccp2(CCP_OFF);
   
   

   //Configuramos TMR1 como temporizador y con prescaler de 8
   T1CON=0b00110000;   
   set_timer1(0);   //Reseteamos TMR1

   //CCP1 en modo comparación con evento especial de disparo
   setup_ccp1(CCP_COMPARE_RESET_TIMER);   

   //Cargamos registros de CCP1 para alcance de TMR1 cada 0,1s
   // 0.1 s = (4/4MHz)*8*CCP1H_CCP1L -> CCP1H_CCP1L = 12500 = 0x30D4
   CCP_1_LOW = 0xD4;   //Carga de la parte baja
   CCP_1_HIGH = 0x30;   //Carga de la parte alta
   
   //Se activan las interrupciones del módulo CCP1
   enable_interrupts(INT_CCP1);
   enable_interrupts(global);

   //Reseteamos el LCD por software
   lcd_clear();
   lcd_home();
   //Ahora lo inicializamos
   lcd_init();
   lcd_clear();

   //Inicializamos también la cuenta del tiempo desde cero
   decimas=0;
   segundos=0;
   minutos=0;
   horas=0;
 
           
           
            lcd_init();
            lcd_gotoxy(1,2);
            printf(lcd_putc,"   version 1.0   ");
            lcd_gotoxy(1,1);
            printf(lcd_putc,"  MINI-MARCADOR ");
            delay_ms(1000);
            lcd_gotoxy(1,1);
            printf(lcd_putc,"                ");
            lcd_gotoxy(1,2);
            printf(lcd_putc,"                ");
            delay_ms(1000);
            lcd_gotoxy(1,2);
            printf(lcd_putc,"   version 1.0   ");
            lcd_gotoxy(1,1);
            printf(lcd_putc,"  MINI-MARCADOR ");
            delay_ms(1000);
            TMR1ON=1;
           
           while(1) {
           }
           
      }
     

Pero no me hace nada solo visualiza el mensaje en el lcd y de ahi no pasa. Me imagino que es a la hora de definir la interrupcio  pero ahi estoy atascado.

Saludos y gracias por la ayuda.

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: Ayuda con inerrupcion ccp1 en 18f2550
« Respuesta #1 en: 06 de Diciembre de 2010, 11:16:09 »
Hola rabanisa, uno de los problemas que le veo a tu código es que las direcciones de memoria de los puertos del 16F873 y del 18F2550 son diferentes.  Debes buscar en la hoja de datos del 18F2550 y corregir estas direcciones.  Por otro lado te podrían faltar algunos fuses para que el PIC te trabaje bien.  Te recominedo utilizar el wizard del CCS para generar los encabezados y fuses de tu programa y después de estudiar bien la hoja de datos, puedes usar de allí los que te hagan falta o si prefieres todos.

Saludos!

EDITO: por mirar rapidamente, no me había dado cuenta que ya habías cambiado las direcciones de los puertos.  Lo que aún no has cambiado es la dirección de T1CON y por ende la asignación de TMR1ON.  De todos modos puedes tener problemas con los fuses o en el encabezado del main().
« Última modificación: 06 de Diciembre de 2010, 23:43:17 por bmb »

Desconectado rabanisa

  • PIC10
  • *
  • Mensajes: 12
Re: Ayuda con inerrupcion ccp1 en 18f2550
« Respuesta #2 en: 07 de Diciembre de 2010, 11:01:56 »
Buenas tardes:

Gracias compañero por la ayuda, la verdad es que al poner el wizard, me he dado cuenta de la cantidad de fuses opciones y configuraciones distintas que tiene el pic. Efectivamente el tema estaba en lo del T1CON, he cambiado las direcciones y a funcionar. Y como dice un compañero(no recuerdo el nombre , lo siento) todo esta en el datasheet.

De nuevo gracias. Espero tener el proyecto presentable en breve y compartirlo.


Edito:  Todo esta en los datasheet ----> RedPic.
« Última modificación: 07 de Diciembre de 2010, 11:38:37 por rabanisa »


 

anything