Autor Tema: Error con uso de interrupciones  (Leído 2778 veces)

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

Desconectado Pchuqui_1

  • PIC16
  • ***
  • Mensajes: 187
Error con uso de interrupciones
« en: 26 de Abril de 2010, 21:00:11 »
Hola a todos. Estoy tratando de utilizar las interrupciones por cambio de estado en la pata RB0 y por recepción en el bus rs232, pero al compilar me da un error que no puedo entender de que se trata. Estoy definiendo mal las interrupciones? Adjunto el error. Muchas gracias.

#include <16F887.h>
#device adc=10
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7)
#use i2c(Master,sda=PIN_C4,scl=PIN_C3)


//Definiciones pines LCD

#define _FLEX_LCD
#define LCD_DB4   PIN_B3
#define LCD_DB5   PIN_B4
#define LCD_DB6   PIN_B5
#define LCD_DB7   PIN_B6

#define LCD_RS    PIN_C0
#define LCD_RW    PIN_C1
#define LCD_E     PIN_B2

///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////


#include <flex_lcd.c>   
#include <EEPROM_24512.c>                          //Ficheros driver de los periféricos
#include <eeprom_interna_16bits.c>
#include <floatee.c>

int dat_in;
int16 address=0,address1,address2; 
float dato,dato1,dato2;

void  up (void);                         // Lectura de EEprom
void  down (void);                         // Escritura de EEprom
//void  write_eeprom_16bits(void);
//void read_eeprom_16bits(void);

#int_ext
ext_isr()
{
lcd_putc("\f RB0");
}


#int_rda                                      //Interrupción para el puerto serie
rda_isr()
{
dat_in=getc();                           //Lee el puerto serie
if (dat_in=='2')                          //Si es "2" se visualizan los primeros datos de la eeprom
  {
 printf("%lu",555);
     }
  return(dat_in);
}




//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void main() {

lcd_init();
      enable_interrupts(int_rda);
   enable_interrupts(int_ext);               //Habilita la interrupción RBO...
   ext_int_edge(L_TO_H);                  //Por flanco de subida
      enable_interrupts(global);
      address=0;
 

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Error con uso de interrupciones
« Respuesta #1 en: 26 de Abril de 2010, 22:11:48 »
Hola.

El error es porque el programa es muy grande para ese micro y no alcanza la ROM.

Saludos
El papel lo aguanta todo

Desconectado Pchuqui_1

  • PIC16
  • ***
  • Mensajes: 187
Re: Error con uso de interrupciones
« Respuesta #2 en: 26 de Abril de 2010, 22:24:04 »
No puede ser.. le quite una de las interrupciones, lo compile,  y me da que estoy usando un 31 % de la rom...  :?

Desconectado bmfranky

  • PIC16
  • ***
  • Mensajes: 165
    • La Tienda De Fran
Re: Error con uso de interrupciones
« Respuesta #3 en: 27 de Abril de 2010, 04:46:38 »
Hola Pchuqui_1.
Lo que te esta indicando es que la rutina MAIN, es demasiado grande para el banco de memoria, probablemente el CCS no gestione correctamente el cambio de banco, prueba a reducir el tamaño de la función  MAIN, usando llamadas a funciones en vez de crearlo todo en su interior, de todas formas postea el resto del código del MAIN e intentare revisarlo a ver que se puede hacer.
Visiten La Tienda De Fran ;-) Aqui. y mi nueva Web Aqui.

Desconectado Pchuqui_1

  • PIC16
  • ***
  • Mensajes: 187
Re: Error con uso de interrupciones
« Respuesta #4 en: 28 de Abril de 2010, 14:07:14 »
Hola bmfranky. Gracias por contestar. Este es el programa y no creo que se haya llenado la ROM, porque cuando le quito algunas intrucciónes lo compila perfectametne y me dice que estoy usando un 30 % de ROM. Gracias.

#include <16f887.h>
#device adc=10
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7,disable_ints)
#use i2c(Master,sda=PIN_C4,scl=PIN_C3)


//Definiciones pines LCD

#define _FLEX_LCD
#define LCD_DB4   PIN_B3
#define LCD_DB5   PIN_B4
#define LCD_DB6   PIN_B5
#define LCD_DB7   PIN_B6

#define LCD_RS    PIN_C0
#define LCD_RW    PIN_C1
#define LCD_E     PIN_B2

///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////


#include <flex_lcd.c>   
#include <EEPROM_24512.c>                    //Ficheros driver de los periféricos
#include <eeprom_interna_16bits.c>
#include <floatee.c>

int dat_in;
int16 address=0,address1,address2; 
float dato,dato1,dato2;

void  up (void);                         // Lectura de EEprom
void  down (void);                         // Escritura de EEprom



#int_rda                                   //Interrupción para el puerto serie
rda_isr()
{
dat_in=getc();                           //Lee el puerto serie
if (dat_in=='2')                          //Si es "2" se visualizan los primeros datos de la eeprom
  {
// printf("%lu",555);
     }
  return(dat_in);
}


#int_ext
ext_isr()
{
write_eeprom_16bits(0x00,address);
output_low(PIN_D2);
delay_ms(20);
output_high(PIN_C5);                      //led on
do{                                           //bucle...
                                     
} while(1);   

}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void main() {
 
     lcd_init();
      enable_interrupts(int_rda);
   enable_interrupts(int_ext);               //Habilita la interrupción RBO...
   ext_int_edge(L_TO_H);                  //Por flanco de subida
      enable_interrupts(global);
      address=0;
   
 do{                                           //bucle...
   if(!input(PIN_D1))                            //¿switch abierto?
   up();                                         //SI -> Lectura de EEprom
   else
   down();                                     //NO -> Escritura de EEprom
} while(1);             
   }

/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
//MODO LECTURA

void  up (void)
{
// lcd_putc("\up\n");
 output_high(PIN_D2);                   //Leed confirmación

do{
//   if(kbhit())
   if(dat_in=='9'){
   goto sigue;
               }
 }while(1);   
 sigue:

 output_low(PIN_D2);
// lcd_putc("\fpaso");
 address=read_eeprom_16bits(0x00);
 address2=(address/4);
 printf("%lu",address2);
 address1=0;

arriba:
do{

output_high(PIN_D2);
//if(kbhit())
   if(dat_in=='3')                       //Si es "2" se visualizan los primeros datos de la eeprom
  {           
   
//   lcd_putc("\fConfirmo");
   dat_in=0;
   dato=READ_FLOAT_EXT_EEPROM(address1);       //Guarda 4 bytes del FLOAT
   address1=address1+4;   
   delay_ms(50);
   if (address1==address)    {   
      do{
         goto termino;   
         }while(1);
                  }
   dato1=READ_FLOAT_EXT_EEPROM(address1);       //Guarda 4 bytes del FLOAT
   address1=address1+4;   
   delay_ms(50);
   if (address1==address)    {   
      do{
         goto termino;
         }while(1);
                  }               
   dato2=READ_FLOAT_EXT_EEPROM(address1);       //Guarda 4 bytes del FLOAT
   address1=address1+4;   
   delay_ms(50);
   if (address1==address)    {   
      do{
         goto termino;
         }while(1);   
                  }               
termino:
printf("/%4.0f" "/%4.0f" "/%4.0f",dato,dato1,dato2);

if (address1==address)    {   
      
printf("/%c",'1');

do{   
   output_low(PIN_D2);
   delay_ms(20);
   output_high(PIN_C5);          
         }while(1);
               }
goto arriba;
 }
      } while(1);

   }

//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
                                       
void  down (void)                         
{
   address=0;                           //Variables globales
   setup_adc_ports(sAN0|sAN1|sAN3 );           //configuración adc
   setup_adc (adc_clock_internal);             //enciende adc
   setup_adc(ADC_CLOCK_DIV_8 );                //configurando la frecuencia de lectura del ADC a 12Mhz
   delay_us(10);      

   output_high(PIN_D2);                   //Leed confirmación
   lcd_putc("Modo Escritura");              //Visualiza en LCD la hora
   delay_ms(2000);
   lcd_putc('\f'); 

do {

   set_adc_channel(0);                         //elige canal a medir RA1
   dato=read_adc();                       
      WRITE_FLOAT_EXT_EEPROM(address,dato);       //Guarda 4 bytes del FLOAT
      address=address+4;                     //Incrementa 4 posiciones la ADDRESS
   lcd_gotoxy(1,1);
     printf(lcd_putc,"%4.0f",dato);           //Visualiza en LCD   
   delay_ms(100);   

   if (address==32760)    {   
   lcd_putc("\fMEMORIA LLENA\n");
   write_eeprom_16bits(0x00,address);   
      do{
          }while(1);         
                  }                                    


   set_adc_channel(1);                         //elige canal a medir RA1
   dato=read_adc();       
    WRITE_FLOAT_EXT_EEPROM(address,dato);       //Guarda 4 bytes del FLOAT
    address=address+4;                     //Incrementa 4 posiciones la ADDRESS   
   lcd_gotoxy(1,2);
    printf(lcd_putc,"%4.0f",dato);           //Visualiza en LCD
   delay_ms(100);

   if (address==32760)    {                  //32760
   lcd_putc("\fMEMORIA LLENA\n");
   write_eeprom_16bits(0x00,address);         
      do{
         }while(1);      
            }


   set_adc_channel(3);                         //elige canal a medir RA1
   dato=read_adc();       
    WRITE_FLOAT_EXT_EEPROM(address,dato);       //Guarda 4 bytes del FLOAT
    address=address+4;                     //Incrementa 4 posiciones la ADDRESS
   lcd_gotoxy(10,2);
    printf(lcd_putc,"%4.0f",dato);           //Visualiza en LCD f=flotante con truncado
   delay_ms(100);   


   if (address==32760)    {   
   lcd_putc("\fMEMORIA LLENA\n");
   write_eeprom_16bits(0x00,address);         
      do{
         }while(1);      
             }

}while(1);

}

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Error con uso de interrupciones
« Respuesta #5 en: 28 de Abril de 2010, 21:03:00 »
Podés probar con la sentencia "#separete" (creo que era así) eso obliga al compilador a "meter" el código en otra página de la memoria de programa.

Probá usándolo antes de la definición y también antes de la implementación de la función down.
Eso obligaría a que toda la función down quede en otro banco.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Pchuqui_1

  • PIC16
  • ***
  • Mensajes: 187
Re: Error con uso de interrupciones
« Respuesta #6 en: 28 de Abril de 2010, 23:18:27 »
Hola, gracias por responder. Pero el ccs c no se encarga solo de cambiar de banco cuando uno ya se ha llenado?? La verdad que no sabia. Voy a intentar probar con esa funcion ("#separete). Tengo que definirla como cualquier otra y nada mas?  Gracias.

Desconectado Pchuqui_1

  • PIC16
  • ***
  • Mensajes: 187
Re: Error con uso de interrupciones
« Respuesta #7 en: 28 de Abril de 2010, 23:29:22 »
Hola otra ves. Busque la instrucción en la ayuda del ccs c y dice que ahora espacion en la ROM pero aumenta el uso del stack...  :?. No se si realmente esta directiva pasa el codigo exedente a otro banco de la ROM. Gracias otra ves.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Error con uso de interrupciones
« Respuesta #8 en: 29 de Abril de 2010, 10:02:47 »
El CCS efectivamente no hace el cambio de banco automáticamente. En cuanto a la pérdida del stack, todo depende de cuanto use tu programa el stack.

Si no llamas a muchas funciones anidadas (una dentro de otra, y luego otra y otra y así...) no vas a tener problemas con el stack.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Pchuqui_1

  • PIC16
  • ***
  • Mensajes: 187
Re: Error con uso de interrupciones
« Respuesta #9 en: 29 de Abril de 2010, 14:10:27 »
No consigo usar esa instrucción, me dá error. Existe otra forma de hacer un cambio de banco?

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Error con uso de interrupciones
« Respuesta #10 en: 29 de Abril de 2010, 14:20:16 »
Te sigue dando el mismo error que antes o ahora es distinto. Yo la había usado en un programa ya funcionó bien. Ahora estoy usando HiTech como compilador.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Pchuqui_1

  • PIC16
  • ***
  • Mensajes: 187
Re: Error con uso de interrupciones
« Respuesta #11 en: 29 de Abril de 2010, 14:50:17 »
Perdon, me ha funcionado. He puesto esa directiva arriba de la función main y no me da más los errores, cuando lo usaba en los otros void me daba un error. Igual no me queda claro, como se si el banco A realmente se lleno y ahora me esta guardando todo en el B u otro? Eso se puede saber? Gracias.
Porque cambiaste a HiTech?

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Error con uso de interrupciones
« Respuesta #12 en: 29 de Abril de 2010, 15:17:03 »
Una forma de saber sería viendo el .asm o .list generado y ver en que direcciones de memoria va quedando todo.
Lo que hace "separete" es forzar la separación aunque el banco no esté lleno del todo.

Cambié a HiTech porque CCS no trabaja exactamente con ANSI C (hay cosas que son únicas de CCS) por lo tanto el código es menos portable.
Además, la versión Lite de HiTech es Free y la puedo usar sin problemas y ahora que estoy usando Linux también hay una versión para dicho OS y la estoy usando con PIKLAB.

Es cierto que CCS tiene funciones cómodas como son la forma de configurar y leer el ADC y la forma de habilitar y deshabilitar las interrupciones.

Para eso me hice mis propias rutinas en Hitech y se manejan de las misma forma así que me fue bastante sencilla la migración.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas


 

anything