TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: DarkVect en 11 de Diciembre de 2006, 14:15:48
-
Hola,
os explico lo que intento hacer y el problema. Utilizo un PIC16F84A con un reloj de 3,2768Mhz.
Intento hacer un programa que cuando detecta un pulso por RB me activa una salida y la mantiene activa durante 24 horas. Si durante ese tiempo se detecta de nuevo el pulso se reinicia el contador.
A priori es sencillo. Utilizo las resistencias de pull-up del puerto B y he desactivado todos los módulos que no necesito:
disable_interrupts(GLOBAL); //deshabilitar interrupciones
disable_interrupts(INT_EEPROM); //deshabilitar interrupcion EEPROM
disable_interrupts(INT_RB); //deshabilitar interrupcion portb
enable_interrupts(INT_EXT); //interrupcion del reed del anemo
ext_int_edge(H_TO_L); //interrupcion en flanco de bajada
enable_interrupts(INT_TIMER0); //interrupcion del contador
port_b_pullups(TRUE); //pullups portb activadas
set_tris_a(0b00000000); //porta todo como salida
set_tris_b(0b11111111); //portb todo como entrada
setup_TIMER_0(RTCC_INTERNAL | RTCC_DIV_128); //preescaler=128 para 1seg
inicializar_parametros();
enable_interrupts(GLOBAL);
La rutina del timer es muy simple: suma cada clock hasta 25, suma un segundo hasta 60, suma cada minuto hasta 60 y luego cada hora. Sencillo.
En la interrupción de RB0 activo la salida y reinicio las variables de tiempo, segundos, minutos y horas.
En el main lo único que hago es mirar la variable horas hasta que llega a 24 y desactivo la salida.
Lo que ES MUY RARO es que si en vez de mirar la variable horas, en el main, miro la varibale minutos todo funciona pefectamente. Las he declarado como int por lo que que no se desbordan en ningún momento.
Incluso lo he probado esperando 4 horas y todo funciona bien... pero a la que lo dejo 24 horas cuando vuelvo cumplido el tiempo no se ha desactivado la salida.
No cre que sea un problema de interferencias, pués todo está aislado y la alimentación es con una batería de 12V stabilizada a 5V.
Saludos y gacias por su ayuda!!!!
-
Hola DarkVect!
Que te parece si pones el programa y le echamos un vistazo entre todos? Por lo que comentas tiene toda la pinta de ser algún error tonto de programación.
Un saludo desde Alicante.
-
Gracias por responder.
No lo he colgado por no llenar el post con código.
Ahora mismo estoy comprobando que la variable Horas no pasa de un valor. Lo hago con leds y haciendo que Minutos incremente Horas cada minuto en vez de cada 60, para ir más rápido, y encendiendo y apagando un led en cada ciclo. Pero llega un momento en que se queda siempre encendido.
Por otro lado, cuando conecto la alimentación a veces me salta la interrupción de RB0, sin que haya el pulso presente. No lo entiendo, pués tengo las pull-ups internas (con una externa no lo hace) y además dejo un delay de 500ms antes de empezar, programando el flanco y el resto de parámetros con las interrupciones deshabilitadas.
Mañana pondré el código, porqué ahora ya he salido de la universidad y no lo tengo.
De todas formas, una pregunta: el modo de funcionamiento lo controlo con una variable Modo tipo entero, que puede valer 1, 2 o 3 según esté en modo de espera del pulso, contando hasta las 24 o contando 1 hora despuésde las 24. Puede ser problema de eso??
Un saludo y gracias!!
-
Aquí va el trozo de código que tengo en casa:
#include <16f68a.h> //pic a utilizar
#fuses XT,NOWDT,NOPROTECT, NOPUT //ordenes para el programador
#use delay (clock=3,27) //no recuerdo el valor exacto
#use fast_io(b) //En el main hago los correspondientes set_tris_a() y set_tris_b()
#use fast_io(a)
#define Alarma 1
#define Normal 0
int nClks=0;
int segundos=0;
int minutos=0;
int horas=0;
int pulsos=0;
int MaxPulsos=1;
INT_TIMER0
void interrupcion_timer0()
{
nClks++;
if(nClks==25) //1 segundo
{
segundos++;
nClks=0;
if(segundos==60)
{
minutos++;
segundos=0;
if(minutos==60)
{
horas++;
minutos=0;
}
}
}
}
void main()
{
delay_ms(500);
disable_interrups(GLOBAL);
//sigo desactivando todas las interrupciones
set_tris_a(0b00000000);
set_tris_b(0b11111111);
//habilito interrupcion rb0 por flanco de bajada (H_TO_L)
delay_ms(500);
enable_interrupts(GLOBAL);
do
{
if(Modo==Normal)
{
.... //parpadea un led (no uso la función delay, sino una lectura del timer0)
}
if(Modo==Alarma)
{
if(horas<1)
{
output_high(PIN_A0);
}
if(horas==1)
{
otuput_low(PIN_A0);
}
if(horas>1)
{
output_high(PIN_A0); //ESTO NO SE EJECUTA NUNCA ¿? horas no pasa del valor 1!!!!
}
}
}
Por otro lado, a veces cuando le pongo la alimentación me salta la rutina de interrupción de rb0 ¿?
En esa rutina lo único que hago es:
pulsos++;
if(pulsos>MaxPulsos)
{
Modo=Alarma;
}
Lo siento por colgarlo así, mañana editaré el post con el código del CCS todo completo. Modificados los == que faltaban (ha sido fallo al escribirlo).
-
Hola DarkVect!
Así a bote pronto... veo:
if(Modo=Normal)
if(Modo=Alarma)
Pon un par de '==' que se te han escapao jeje :mrgreen:.
Mañana sube la versión más definitiva que tengas. A ver si hay algún problema en la comprobación de las horas (en esta versión no está implementada).
Un saludo desde Alicante.
-
Ya está solcuionado!!!
Era cuestión de una "maldita" asignación al contar las horas: horas++; minutos=0; //NO minutos==0; ARGGGGG!!!!!
Sólo una pregunta más.
Cuál es la mejor forma de configurar los parámetros de un PIC?? Lo que hago siempre es:
void main()
{
delay_ms(500); //esperar a que se estabilice (copiado de los ejemplos de aquí)
disable_interrupts(GLOBAL);
****desactivo todo lo que no voy a usar****
****configuro el timer y el flanco para la interrupción externa****
delay_ms(500)
****habilito todo lo que voy a usar (INT_EXT, TIMER, etc...)****
****hago los set_tris_X para todos los puertos****
enable_interrups(GLOBAL);
PROGRAMA
}
Alguna vez me pasa que al dar la alimentación me salta la iterrupción externa de RB0. Esa pata tene activada la resistencia de pull-up por software y stá al aire, esperando a que le conecte un cable con los pulsos a detectar.
GRACIAS POR LA AYUDA!!!
-
Yo nunca pongo esos delay_ms que colocas tú, me parece una pasada esperar un segundo a que se estabilice el micro.
Lo de la interrupción es extraño, puesto que al encender el micro no la tienes aún configurada.
-
Estoy empezando con el tema de programarlos y en algún ejemplo de la colección he visto que usan... diría que exactamente era de 333ms, aunque no recuerdo quien es el que lo posteó.
De todas formas, los he quitado y todo funciona igual de bien. Hoy he reiniciado el micro multitud de veces y en ninguna me ha saltado la interrupción. No se es porque ayer con tanta prueba por la tontería de las horas toqué algo de configuración y hoy al volverlo a revisar y reordenar lo he dejado bien.
Mañana os cuento qué tal.
Gracias!!
-
Hola!
Yo nunca pongo nigún 'delay_ms' al principio de mis programas. Lo que si que me gusta poner es el 'Power Up Timer'.
Lo de la interrupción que comentas... seguro que entre las 1000 pruebas que hiciste, como muy bien dices, algo tocarías que cambió la configuración.
Cuéntanos y danos una buena noticia diciéndonos que te funciona todo perfectamente :mrgreen:
Un saludo desde Alicante.
-
Amigo Darvect:
Estas diciendo que pones las resistencias del puerto b en pullup , pero no veo la declaracion : PORT_B_PULLUPS( true)
en el manual del ccs:
Syntax:
port_b_pull-ups (value)
Parameters:
value is TRUE or FALSE on most parts, some parts that allow pullups to be specified on individual pins permit a 8 bit int here, one bit for each port pin
Returns:
undefined
Function:
Sets the port B input pullups. TRUE will activate, and a FALSE will deactivate.
Availability:
Only 14 and 16 bit devices (PCM and PCH). (Note: use SETUP_COUNTERS on PCB parts).
Requires
Nothing
Examples:
port_b_pullups(FALSE);
Example Files:
ex_lcdkb.c with kbd.c
Also See:
input(), input_x(), output_float()
Si alguien lo corrobora me gustaria que lo comente
-
pido disculpas . Ahora lo vi en el primer post pero no en los subsiguientes!!
-
Fastyx no lo puse para no llenar el post con código de configuración.
De todas formas gracias por la respuesta. Ya está solucionado y comprobado que ahora si que no salta la interrupción al iniciar. El proyecto funciona bien!!!
Un saludo!!