Autor Tema: Problema implementación de lcd(flex_lcd.c) e interrupción por INT0  (Leído 5041 veces)

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

Desconectado _LAB_

  • PIC10
  • *
  • Mensajes: 36
Hola!!! Saludos a todos...
Este es mi primer post por acá y bueno... espero puedan ayudarme.

El problema es el siguiente:
Estoy usando la libreria flex_lcd.c, usando los siguientes pines:

#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7

#define LCD_E     PIN_A1
#define LCD_RS    PIN_A3
#define LCD_RW    PIN_A2

Aquí todo funciona perfect. Sucede que al agregar los siguientes comandos:

enable_interrupts(ext_int);
ext_int_edge(H_TO_L);
enable_interrupts(global);

bueno al compilar cero problema solo 4 advertencias 2 relacionadas con condiciones siempre verdaderas que sé cuales son y no es el problema.
Las otras 2 me llaman más la atención...
function not void and does not return a value Rb0_int(así llame la interrupción) ----- creo k se refiere a que no uso return al final para devolver valor, solo incremento una variable, pero bueno siempre lo hago así y funka...
La 2da:
Interrupts disable during call....---- creo k es conocida y si no me equivoco hecho por el compilador (no estoy seguro xD)
bueno compila bien (creo)
y simulo en proteus bien, solo hay unas advertencias "logic contention detected in net"
pero al parecer es algo de la libreria porque cuando la probé sin las interrupciones sucede lo mismo...
Bueno lo grabo al pic y aquí esta como diriamos "la madre del cordero"
Pues el programa funciona, pero solo se queda mostrando la pantalla inicial y los switch no funcionan....
Si alguien me puede ayudar con esto...
Aaaa no estoy ocupando el 18f2550...
NOTA: al revisar los registros se me borra (se pone a 0) el GIE cada vez que entra a la rutina de imprimir en el lcd...
Nose si eso será el problema... bueno si es necesaria la libreria flex_lcd.c ahí va!!!
//--------------------------------------------------------------------------------------------------------
// flex_lcd.c

// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver.  Change these
// pins to fit your own board.

#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7

#define LCD_E     PIN_A1
#define LCD_RS    PIN_A3
#define LCD_RW    PIN_A2

// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

#define USE_LCD_RW   1     

//========================================

#define lcd_type 2        // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line


int8 const LCD_INIT_STRING[4] =
{
 0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
 0xc,                    // Display on
 1,                      // Clear display
 6                       // Increment cursor
 };
                             

//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note:  !! converts an integer expression
// to a boolean (1 or 0).
 output_bit(LCD_DB4, !!(nibble & 1));
 output_bit(LCD_DB5, !!(nibble & 2));
 output_bit(LCD_DB6, !!(nibble & 4));   
 output_bit(LCD_DB7, !!(nibble & 8));   

 delay_cycles(1);
 output_high(LCD_E);
 delay_us(2);
 output_low(LCD_E);
}

//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine.  For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.     

#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3

retval = 0;
   
output_high(LCD_E);
delay_cycles(1);

retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);
 
output_low(LCD_E);
   
return(retval);   
}   
#endif

//---------------------------------------
// Read a byte from the LCD and return it.

#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;

output_high(LCD_RW);
delay_cycles(1);

high = lcd_read_nibble();

low = lcd_read_nibble();

return( (high<<4) | low);
}
#endif

//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);

#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif

if(address)
   output_high(LCD_RS);
else
   output_low(LCD_RS);
     
 delay_cycles(1);

#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E);

lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}

//----------------------------
void lcd_init(void)
{
int8 i;

output_low(LCD_RS);

#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif

output_low(LCD_E);

delay_ms(15);

for(i=0 ;i < 3; i++)
   {
    lcd_send_nibble(0x03);
    delay_ms(5);
   }

lcd_send_nibble(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
    lcd_send_byte(0, LCD_INIT_STRING);
   
    // If the R/W signal is not used, then
    // the busy bit can't be polled.  One of
    // the init commands takes longer than
    // the hard-coded delay of 60 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
    #ifndef USE_LCD_RW
    delay_ms(5);
    #endif
   }

}

//----------------------------

void lcd_gotoxy(int8 x, int8 y)
{
int8 address;

if(y != 1)
   address = lcd_line_two;
else
   address=0;

address += x-1;
lcd_send_byte(0, 0x80 | address);
}

//-----------------------------
void lcd_putc(char c)
{
 switch(c)
   {
    case '\f':
      lcd_send_byte(0,1);
      delay_ms(2);
      break;
   
    case '\n':
       lcd_gotoxy(1,2);
       break;
   
    case '\b':
       lcd_send_byte(0,0x10);
       break;
   
    default:
       lcd_send_byte(1,c);
       break;
   }
}

//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;

lcd_gotoxy(x,y);

// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));

output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);

return(value);
}
#endif
//---------------------------------------------------------------------------------
Bueno sin más, espero sus comentarios y ayuda!!!
Gracias!!!! 

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Problema implementación de lcd(flex_lcd.c) e interrupción por INT0
« Respuesta #1 en: 14 de Agosto de 2011, 22:47:48 »
Hola lab.

deberías subir el código donde usas la interrupción, porque es allí donde se genera el problema.

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema implementación de lcd(flex_lcd.c) e interrupción por INT0
« Respuesta #2 en: 14 de Agosto de 2011, 23:07:56 »
Exacto, déjanos ver el código principal. La librería ya está re contra probada.

Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado _LAB_

  • PIC10
  • *
  • Mensajes: 36
Re: Problema implementación de lcd(flex_lcd.c) e interrupción por INT0
« Respuesta #3 en: 15 de Agosto de 2011, 01:43:17 »
Oca, acá dejo el programa...
---------------------------------------------
#include <18f2550.h>
#fuses XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVREGEN,NOPBADEN
#use delay (clock = 48000000)
#include "flex_lcd.c"

//INTCON
//adress 0xFF2
#byte INTCON = 0XFF2  //lo hice pensando que era
#bit GIE = INTCON.7   //problema del compilador
int up=0;
int down=0;
int select;
int rest=0;

//----- funcion interrupcion-------
#int_ext
Rb0_int(){
delay_ms(50);
//GIE = 0;---> con o sin esto es igual
//disable_interrupts(global);
select++;
//enable_interrupts(global);
}
//------------------------------------

void menu(){
   //codigo subrutina....
   //solo hay cambio en los enteros definidos
   // ni un registro
//enable_interrupts(global);--> intento sin resultados xD
//GIE=1;--> lo mismo anterior
}

//--------------------------------------
void main() {

   lcd_init();
       set_tris_b(0x0F);---> 0000 1111
   //set_tris_a(0x00);-->era igual habilitar o desabilitar
     
//---------------------------------- 
   
      
 
   disable_interrupts(int_timer1);   //DISABLE INTERRUPT FOR TIMER1
   disable_interrupts(int_rda);      //DISABLE INTERRUPT FOR ADC     
   disable_interrupts(int_ext1);
   disable_interrupts(int_ext2);
   setup_adc_ports(NO_ANALOGS);      //ALL PORTS 'A' AS DIGITAL
   setup_adc(ADC_OFF);            //NO USE MODULE ADC
   setup_spi(FALSE);            //
   //setup_psp(PSP_DISABLED);
   setup_comparator(NC_NC_NC_NC);   //DISABLE COMPARATOR
   setup_vref(FALSE);            //NO USE THE REFERENCE VOLTAJE FROM PORT
   port_b_pullups(FALSE);         //DISABLE PULLUPS RESISTOR
   
   enable_interrupts(int_ext);
   ext_int_edge(L_to_H);
   enable_interrupts(global);      //DISABLE INTERRUPTS GLOBAL
      
   
   
//--------------------------- 
   printf(lcd_putc,"Hola!!");
   delay_ms(1000);
   //GIE = 1;
//--------------------------------------------
    while(1){
      if(select == 1){
         menu(); // llamamos a funcion
         select = 0;
      }
      switch(rest){
         case 0:
            printf(lcd_putc,"\fselect 1");
            delay_ms(100);
            break;
         case 1:
            printf(lcd_putc,"\fselect 2");
            delay_ms(100);
            break;
         case 2:
            printf(lcd_putc,"\fselect 3");
            delay_ms(100);
            break;
      }
         
   }
}
Bueno ahi tá xD, me dicen si pillan algún problema de sintáxis que ya toy mal con esto jajajaja...
Saludos....

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Problema implementación de lcd(flex_lcd.c) e interrupción por INT0
« Respuesta #4 en: 15 de Agosto de 2011, 10:46:04 »
1.- el switch siempre entrará al case =0, porque rest siempre es 0.
2.- el delay de 50ms dentro de la interrupción, es la causa del "reentrance". el retardo no debería ir ahí sino en el bucle principal.
3.- el "logic contention detected in net" es un aviso que lanza el proteus cuando los pines del micro cambian el tris de entrada a salida o viceversa, no te preocupes tanto por esto.
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado _LAB_

  • PIC10
  • *
  • Mensajes: 36
Re: Problema implementación de lcd(flex_lcd.c) e interrupción por INT0
« Respuesta #5 en: 15 de Agosto de 2011, 15:06:54 »
Gracias por contestar...
Pero no entiendo a poner el retardo de la interrupción en el bucle principal??
Si me dijeras donde lo pongo sería genial  :D.
Saludos!!!! :P

Voy a probar sin usar retardos mientras y vemos si corre, solo faltaría aprender donde poner el retardo correctamente!! :mrgreen:

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Problema implementación de lcd(flex_lcd.c) e interrupción por INT0
« Respuesta #6 en: 15 de Agosto de 2011, 22:24:06 »
...Si me dijeras donde lo pongo sería genial  :D.
...

no te podría decir, porque no se que función cumple ese retardo.
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado _LAB_

  • PIC10
  • *
  • Mensajes: 36
Re: Problema implementación de lcd(flex_lcd.c) e interrupción por INT0
« Respuesta #7 en: 16 de Agosto de 2011, 13:46:26 »
Amigo, probé quitando el retardo pero nada.
Y bueno este ratardo simplemente es para prevenir una reentrada (suena irónico  :D) dada por los switch.
Espero ayuda, que nada me ha funcionado!!!!

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema implementación de lcd(flex_lcd.c) e interrupción por INT0
« Respuesta #8 en: 16 de Agosto de 2011, 14:13:59 »
En este caso el retardo en la interrupción no va afectar, pero lo ideal es no implementarlo. Conviene inicializar select a 0, así cuando presionas estás seguro que se incrementa a 1. Y lo ideal seria colocarlo a 1 y no incrementarlo.

Luego, rest no lo modificas en ningún lado, así que lo único que mostrará en la pantalla será, "select 1"



Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado _LAB_

  • PIC10
  • *
  • Mensajes: 36
Re: Problema implementación de lcd(flex_lcd.c) e interrupción por INT0
« Respuesta #9 en: 16 de Agosto de 2011, 15:53:53 »
Gracias por los comentarios, bueno voy a tomar en cuenta lo del retardo. Sucede que lo uso por problemas que he tenido con otros pic a la hora de presionar el switch, y esos retardillo me habian dado buenos resultados, en fin.
Cambiando de tema logré que funcionara, claro que cambiando la librería, ahora estoy ocupando una que lamentablemente usa un integrado extra 4094, pero reduzco el uso a solo 3 pines, y nada estoy recien en las primeras pruebas con la librería y tiene algunas fallas pero todo solucionable.
Por si les interesa les dejo el enlace. Aunque nose si podemos hacer eso  :D, pero bueno ahí va!!!
http://blog.bricogeek.com/noticias/electronica/libreria-lcd-con-3-pines-para-microcontroladores-pic/
Una vez más gracias PalitroqueZ y Suky por los consejos!!!!
Saludos.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema implementación de lcd(flex_lcd.c) e interrupción por INT0
« Respuesta #10 en: 16 de Agosto de 2011, 16:37:23 »
Heee! La librería de nuestro amigo Akenafab! Bien conocida    ;-)


Saludos!
No contesto mensajes privados, las consultas en el foro