TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: _LAB_ en 14 de Agosto de 2011, 22:16:50
-
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!!!!
-
Hola lab.
deberías subir el código donde usas la interrupción, porque es allí donde se genera el problema.
-
Exacto, déjanos ver el código principal. La librería ya está re contra probada.
Saludos!
-
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....
-
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.
-
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:
-
...Si me dijeras donde lo pongo sería genial :D.
...
no te podría decir, porque no se que función cumple ese retardo.
-
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!!!!
-
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!
-
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.
-
Heee! La librería de nuestro amigo Akenafab! Bien conocida ;-)
Saludos!