TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: cedruiz en 17 de Enero de 2011, 12:58:21
-
hola a todo el mundo siento mucho q mi primer post sea para pedir ayuda pero estoy seguro q solo ustedes me pueden sacar de este predicamento.
estoy trabajando en un sistema de seguridad que me pida una contraseña y me este monitoreando unos sensores, estoy trabajando con un 16f877a configurado de la siguiente manera el puerto A y el puerto D se encargan de un lcdX2, el puerto B barre un teclado matricial de 4x3.
El problema consiste con la interrupción externa de flanco que ingresa por el puerto B la cual quiero utilizar para detectar el cambio de estado en los sensores, si bien el teclado matricial esta en el mismo puerto desabilito las resistencias de pull up y cargo la configuracion del teclado y hasta este punto la interrupcion se activa el problema aparece cuando utlizo la instruccion kbd_getc() en este momento la interrupcion pues ya no interrumpe =D.
ahora pues si alguien a tenido este mismo problema podria decirme como puedo solucionarlo =D, si nadie se a topado con esto podrian hecharle un vistaso, solo lo he simulado en proteus puede ser solo problema de simulador?
en fin les agradesco cualquier ayuda que puedan darme =D.
-
vamos gente ideas, preguntas, sugerencias algo jejejeje =)
-
vamos gente ideas, preguntas, sugerencias algo jejejeje =)
por que no mejor pones tambien un esquema del circuito?
asi mejor que mejor comprenderemos lo que haces y como lo haces
-
en hora buena man gracias adjunto en el zip todos los archivos q estoy utilizando incluso el archivo que utilizo para la simulacion en proteus UNTITLED.dsn =D
-
fijate, para poder tener una interrupcion el el pin RB0 lo primero que debes hacer es configurarlo como entrada... mira en el modo debug del proteus el estado del potrb... te pongo una imagen,este esta en 0b11111110 osea que lo tienes como salida no como entrada, tambien te recomendaria poner una resistencia pullup en simulacion ya que a veces falla...
esta imagen es al principio de entrar en el void main
Imagen 1 (http://www.subirimagenes.com/privadas-dibujo1-1339800.html)
y esta otra cuando ya se ha pulsado el keypad
Imagen 2 (http://www.subirimagenes.com/privadas-dibujo2-1339806.html)
el registro de trisb sige igual, no te detectara ninguna interrupcion por cambio de flanco por que ahora mismo tienes habilitado el pin b0 como salida
un saludo
-
gracias man voy hacer las correcciones cualquier adelanto lo comunico =)
-
muchas gracias solucionado el problema con la interrucion, configuro el trisc como me dijiste y se ha solucionado todo =D nuevamente muchas gracias.
-
muchas gracias solucionado el problema con la interrucion, configuro el trisc como me dijiste y se ha solucionado todo =D nuevamente muchas gracias.
de nada me alegro que te funcione un saludo
-
listo como todo esta solucionado y ahora si tengo tiempo aca dejo como solucione este problema por si alguien tiene este inconveniente.
ya q el inconveniente se presentaba con la rutina de manejo del teclado matricial 4x3 (KBD.c) hice una pequeña modificación un poco trivial pero funciona para el caso donde se tenga el teclado matricial en el puerto b y se necesite la interrupcion ext por rb0 adjunto la rutina (KBD1.c)
espero pueda servile a alguien saludos =D
-
muy buen aporte ... facil solucion .. gracias creia que yo era el unico al que le pasaba esto
-
Hola buenas tardes!
Llevo un tiempo siguiendo este foro para aprender lenguaje C pero pocas veces me he animado a escribir en el. Tengo un problema parecido al del creador de este tema pero mi sistema sigue sin funcionar aun utilizando las soluciones que se dijeron en el.
Estoy creando un sistema de alarma tambien. El programa funcionaba perfectamente, pero al añadirle la interrupcion externa no me funciona y la parte de la interrupcion por separado si. Es una cosa un poco rara porque si elimino el cable que une el pin del micro de la interrupcion del interruptor que la crea, el programa funciona correctamente excepto lo que es la interrupcion.
Aquí les dejo el programa para ver si me podeis ayudar. Tambien adjunto los diferentes archivos del programa con la libreria del teclado y el esquema del circuito electrico
#include "C:\Users\acer\Documents\Ruben\UNIVERSIDAD\PFC\Pruebas en C\Pruebas\prueba.h"
#fuses XT //Crystal osc <= 4mhz
#fuses NOWDT //deshabilita el Watch Dog Timer
#fuses NOPROTECT //deshabilita la proteccion del codigo del pic
#fuses PUT //habilita el reseteo de power up timer
#fuses NOLVP //No Low Voltage Programming on B3(PIC16) or B5(PIC18,no habilita la programacion en bajo voltaje)
#fuses NOBROWNOUT //No Reset when brownout detected
#use delay(clock = 4000000)
#use fast_io(A) //con esta instruccion evitamos que
#use fast_io(B) //se este configurando cada vez que usamos
#use fast_io(C) //alguna instruccion de entrada o salida
#BYTE TRISA = 0b10000101 //TRISA = 0x85
#BYTE PORTA = 0b00000101 //PORTA = 0x05
#BYTE TRISB = 0b10000110 //TRISB = 0x86
#BYTE PORTB = 0b00000110 //PORTB = 0x06
#BYTE TRISC = 0b10000111 //TRISC = 0x87
#BYTE PORTC = 0b00000111 //PORTC = 0x07
#include <kbd3x4_2.c> //libreria manejo keypad 3x4
#include <lcd3.c> //libreria manejo lcd 8 bits
#include <string.h> //libreria manejo cadenas
#rom 0x2100={0,0,0,0,0,0,0} //la EEPROM se carga con los valores 00h desde la direccion 00h hasta 06h
////////////////DEFINICION DE FUNCIONES////////////////////////////
void menu_principal(void); //funcion que muestra el menu principal
void escribir_clave(char clave[]); //funcion que escibre la clave tecleada
void cambia_clave_inicial(void); //funcion que cambia clave
void cambiar_clave(void); //funcion que cambia clave
int comparar_claves(int); //función que compara las claves
void nueva_clave_admin(void); //funcion que añade la nueva clave administrativa
void activar_alarma(void); //funcion que activa la alarma
void desactivar_alarma(void); //funcion que desactiva la alarma
void escribir_clave_en_eeprom(int); //función que escribe las claves en la memoria eeprom
void leer_clave_en_eeprom(int); //función que lee las claves y las guarda en su correspondiente variable
void alarma_general(void); //funcion que enciende la sirena
void conteo_intentos(void); //funcion que cuenta el numero de intentos de ingreso de contraseña
////////////////VARIABLES GLOBALES///////////////////////////
char clave_inicial[3]= {'1','2','3'}; //variable usada como clave de inicio
char clave_eeprom_admin[3]; //variable usada para comparar los datos de la eeprom contra los datos ingresados
char clave[3]; //variable usada para recoger la clave tecleada
char k; //variable usada para recoger las teclas pulsadas del teclado
signed char i; //variable usada para movernos por las posiciones de la memoria
char clave_introducida[3]={}; //variable usada para los datos ingresados
int alarm_cont=0; //variable global que cuenta los fallos
int flag;
//////////////////LLAMADA FUNCION INTERRUPCION//////////////
#INT_EXT
void intrb0(void)
{
flag=1;
}
////////////////////PROGRAMA PRINCIPAL//////////////////////
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
flag=0;
set_tris_b(0b11100001);
set_tris_c(0b11100000);
enable_interrupts(int_ext);
ext_int_edge(L_TO_H);
enable_interrupts(GLOBAL);
lcd_init(); //inicializa lcd
delay_ms(1000);
lcd_putc (" Bienvenido ");
delay_ms(1000);
for( ; ; )
{
cambia_clave_inicial();
menu_principal();
if(flag==1)
{
delay_ms(20); //antirrebote
flag=0;
alarma_general ();
}
do
{
cambia_clave_inicial();
menu_principal();
}while(flag==0);
}
}
//////////FUNCION CAMBIAR CLAVE INICIAL
void cambia_clave_inicial(void) //funcion que cambia clave administrativa
{
int p;
clave_introducida=0;
escribir_clave(clave_introducida);
p=strcmp(clave_introducida , clave_inicial);
if (p==0)
{lcd_putc("\fClave Correcta\n");
delay_ms(2000);
nueva_clave_admin();
}
if (p!=0)
{lcd_putc("\fClave Incorrecta\n");
delay_ms(2000);
clave_introducida=0;
//conteo_intentos();
alarma_general ();
}
}
//////////FUNCION ESCRIBIR NUEVA CLAVE
void escribir_clave(char clave[]) //funcion que escibre la clave tecleada
{
int i=0;
lcd_putc("\fEscribir clave:\n"); //presentacion
do{
do{ //espera hasta...
k=kbd_getc();
}while(k==0); //...pulsar una tecla
if(!(k=='*' || k=='#'))
{
lcd_putc("*");
clave=k;
}
i++;
}while( !(k=='*' || k=='#') ); //Si '*' o '#' señalamos que hemos terminado de introducir la contraseña
}
/////FUNCION MENU PRINCIPAL
void menu_principal (void) //funcion que muestra el menu principal
{
for( ; ; )
{
lcd_putc("\f0-Activa Alarma\n1-Cambia Clave");
do{ //espera hasta...
k=kbd_getc();
}while(k==0 || k==1); //...pulsar una tecla
switch (k)
{
case '0': //va a activar la alarma
activar_alarma();
break;
case '1': //va a comprobar clave para despues cambiar la clave
cambiar_clave();
break;
}
}
}
//////////FUNCION CAMBIAR CLAVE
void cambiar_clave(void) //funcion que cambia clave administrativa
{
int p;
escribir_clave(clave_introducida);
leer_clave_en_eeprom(i);
p=comparar_claves(i);
if (p==0)
{lcd_putc("\fClave Correcta\n");
delay_ms(2000);
nueva_clave_admin();
}
if (p!=0)
{lcd_putc("\fClave Incorrecta\n");
delay_ms(2000);
clave_introducida=0;
alarma_general ();
}
}
//////////FUNCION NUEVA CLAVE
void nueva_clave_admin(void) //funcion que añade la nueva clave administrativa
{
int i=0;
lcd_putc("\fNueva clave:\n"); //presentacion
do{
do{ //espera hasta...
k=kbd_getc();
}while(k==0); //...pulsar una tecla
if(k!='*' || k!='#')
{
lcd_putc("*");
clave=k;
}
escribir_clave_en_eeprom(i);
i++;
}while( !(k=='*' || k=='#') ); //Si '*' o '#' señalamos que hemos terminado de introducir la contraseña
}
//////////FUNCION COMPARAR CLAVES
int comparar_claves(int) //funcion que cambia clave administrativa
{
int i=0;
int s=0;
for (i=0;i<3;i++)
{
if (clave_introducida==clave_eeprom_admin)
s++;
else
{s=0;
lcd_putc("\fClave Incorrecta\n");
break;
}
}
if (s==3)
return 0;
}
//////////ACTIVAR ALARMA
void activar_alarma(void)
{
int i=0;
int p=0;
escribir_clave(clave_introducida);
leer_clave_en_eeprom(i);
p=comparar_claves(i);
if (p==0)
{lcd_putc("\fAlarma Activada");
delay_ms(2000);
desactivar_alarma();
}
if (p!=0)
{lcd_putc("\fClave Incorrecta\n");
delay_ms(2000);
clave_introducida=0;
alarma_general ();
}
}
//////////DESACTIVAR ALARMA
void desactivar_alarma(void)
{
int i=0;
int p=0;
lcd_putc("\fDesactivar alarma\n"); //presentacion
escribir_clave(clave_introducida);
leer_clave_en_eeprom(i);
p=comparar_claves(i);
if (p==0)
{lcd_putc("\fAlarma\nDesactivada");
delay_ms(2000);
break;
}
if (p!=0)
{lcd_putc("\fClave Incorrecta\n");
delay_ms(2000);
clave_introducida=0;
alarma_general ();
}
}
//////////ESCRIBIR_CLAVE_EN_EEPROM
void escribir_clave_en_eeprom(int i) //función que escribe las claves en la memoria eeprom
{
write_eeprom (i,k); //guardamos cada valor de la variable global correspondiente
delay_ms(20); //en la direccion i + 0 (para no pisar datos) de la eeprom
i++; //en una palabra escribe de la posicion 0 a la 4 (5 lugares)
}
//////////LEER_CLAVE_EN_EEPROM
void leer_clave_en_eeprom(int i) //función que lee las claves y las guarda en su correspondiente variable
{
for (i=0;i<3;i++)
{
clave_eeprom_admin = read_eeprom(i); //guardamos cada valor de la direccion i + 0 (para no pisar datos)
delay_ms(20); //de la eeprom en la variable global correspondiente
}
}
////////////FUNCION CONTEO INTENTOS
/*void conteo_intentos(void) //funcion que cuenta el numero de intentos de ingreso de contraseña
{
if (alarm_cont==3)
alarma_general();
else
alarm_cont++;
}*/
//////////FUNCION ALARMA GENERAL
void alarma_general (void)
{
set_tris_c(0b11100000); //pines C0 hasta C4 como salida
output_high(pin_C0); //enciende la sirena durante 10 seg y muestra mensaje
//lcd_putc("\fALARMA\n");
delay_ms(2000);
output_low(pin_C0); //apaga la sirena
alarm_cont = 0; //pongo a cero el contador de errores
break;
}
Muchas gracias por todo
-
Buenos dias!
Se me olvido comentar en el anterior post que estoy utilizando un PIC16F876 en lugar del micro citado en el título del tema, que la versión de Proteus que empleo es la 7.7 y que el compilador es CCS