Programación Específica > Microcontroladores
Activar Interrupción Pic16f84
xernovil:
Hola, pues bién... estoy "formandome" sobre PIC's, ya que en mi proyecto fin de carrera debo "solapar" dos mandos a radio frecuencia y tengo que programar el resultante. Bien, pues el caso es que tengo un pequeño problema, no se bien bien como se activan las interrupciones, he hecho un programa sencillo en el cual al finalizar una serie de procesos (hacer correr una luz) entra en modo sleep. Mi intención es que al activar una de las interrupciones, se salga del modo sleep y vuelva a reiniciar el programa. Se que no es muy complicado, pero de momento no me sale.
Recursos utilizados:
PROGRAMADOR: Micro PIC trainer v1.1
PIC: 16F84A
software: PicAnt IDE, MPlab, IC-PROG
Se que el vector de interrupciones se situa en la 0x04h, y que para que se activen las interrupciones debe estar a 1 el GIE (a parte de su correspondiente bandera de interrupción), lo que no se es si debo poner yo a 1 el GIE al inicio del programa... en fin, que voy algo perdido en interrupciones.
Código:
--- Código: Text --- #include <system.h> asm {list p=16F84A__config H'3FF1'} main(){ int j,k,i,m; set_bit( STATUS, RP0 ); OPTION_REG= 01010000b;set_tris_b(0);clear_bit( STATUS, RP0 ); while(1){ j=0;PORTB=1; while(j<3){for(k=0;k<8;k++) { for(i=0;i<255;i++) { for(m=0;m<255;m++); } PORTB = PORTB * 2; }j++;PORTB=1;} PORTB=0;asm{sleep}}}
Agradezco vuestra ayuda.
xernovil:
He intentado avanzar, pero no lo consigo, ya que las ideas que voy teniendo solo hacen que incluir errores en la compilación, uno de mis cambios sería:
--- Código: Text --- #include <system.h>asm {list p=16F84A__config H'3FF1'include "p16F84A.inc" ORG 0x00 goto INICIO ORG 0x04 BCF INTCON,GIE ;pongo el GIE a 0 para que no haya otra interrupción hasta ;que no acabe la secuencia goto INICIO ;vuelvo a inicio ya que lo que quiero es reinicializar el ;desplazamiento de las luces INICIO: ;esto no debería dar problema no?? a partir de aquí se mete en el ;main() otra vez directamente, no?} main(){ int j,k,i,m; set_bit( STATUS, RP0 ); OPTION_REG= 01010000b; //al estar el bit 6 a 1 (INTEDG), se activará la //interrupción por flanco de subida, no?set_tris_b(0); clear_bit( STATUS, RP0 ); .. ;hago correr la luz. asm{ BSF INTCON,GIE ;activo el permiso para interrupcionesBSF INTCON,INTE ;activo el permiso para interrupción externa INT/RB0 sleep }
Al poner ese código me pone todo el rato estos errores:
Overwritting previous address contents (0000)
Overwritting previous address contents (0000)
Overwritting previous address contents (0004)
Overwritting previous address contents (0004)
Overwritting previous address contents (0005)
Overwritting previous address contents (0005)
No se como solucionarlos...
Toph:
--- Cita de: "xernovil" ---
Al poner ese código me pone todo el rato estos errores:
Overwritting previous address contents (0000)
Overwritting previous address contents (0000)
Overwritting previous address contents (0004)
Overwritting previous address contents (0004)
Overwritting previous address contents (0005)
Overwritting previous address contents (0005)
No se como solucionarlos...
--- Fin de la cita ---
cambia esto:
--- Citar ---ORG 0x00
goto INICIO
ORG 0x04
BCF INTCON,GIE ;pongo el GIE a 0 para que no haya otra interrupción hasta
;que no acabe la secuencia
goto INICIO ;vuelvo a inicio ya que lo que quiero es reinicializar el
;desplazamiento de las luces
INICIO: ;esto no debería dar problema no?? a partir de aquí se mete en el
;main() otra vez directamente, no?
}
main()
{
--- Fin de la cita ---
por esto
--- Código: Text --- ORG 0x00 goto INICIO ORG 0x04 goto INTERRUPCION ORG 0x05 INICIO: }main(){..
en esta rutina INTERRUPCION debes poner la rutina que necesitas hacer cuando ocurra la interrupcion o sea lo siguiente:
--- Código: Text --- INTERRUPCION:BCF INTCON,GIE goto INICIO retfie; retorno de interrupcion vuelve a donde estaba el programa antes de la interrupcion
el otro problema que veo es aqui:
--- Código: Text --- BSF INTCON,GIE ;activo el permiso para interrupcionesBSF INTCON,INTE;activo el permiso para interrupción externa INT/RB0 sleep} cuando iniciamos se viene para aca activa las interrupciones, hace lo de las luces y entra en modo sleep pero cuando se da la interrupcion se va a la posicion 0x04 de ahi se va a la rutina INTERRUPCION desabilita las interrupciones y luego se viene otra vez a INICIO y cae en sleep el problema es que NUNCA se retorna de la interrrupcion y nunca he visto un programa en que pase esto. :ph34r:
ademas es mejor activar los permisos para las diferente interrupciones y despues activar el permiso global o sea poner la sentencia BSF INTCON,INTE primero y despues la del GIE.
checalo y nos cuentas saludos :hola:
Huguen_aus_Tirol:
Hola!
Me mareo un poco tu programa... programas en asembler o en C? :unsure:
Si lo haces en C, por lo general no deberías preocuparte de que las rutinas de interrupción se inicien en la dirección 0x4; el compilador lo hace automáticamente. Claro, debes indicar de que se trata de una interrupción...
Si lo haces en asembler, si debes indicar la dirección 0x4 (org 0x4). Al entrar a la interrupción (en asm) es importante guardar los registros STATUS y W, y restaurarlos al salir (Encontrarás un buen ejemplo en la hoja de datos del micro!).
Al inicio del programa, no importa que sea C o asm, debes habilitar individualmente las interrupciones y, por último, globalmente (activar GIE)
Para salir de una interrupción (asm) usas RETFIE, que es un RETURN más re-habilitar las interrupciones.
Mi consejo es que practiques un poco en asembler, prueba el clásico "hacer parpadear un led", con y sin interrupciones. Asembler te permitirá conocer un poco más al micro, y después encaras el C.
En lo posible, prueba sobre un PIC real, y no con el simulador; no porque sea más lindo ver parpadear un led, sino por una cuestión de tiempo real ;)
Bueno, sigue probando que ya lo lograrás, y no olvides que aqui estamos para cualquier consulta...
Saludos
Huguen_aus_Tirol:
Hola Tania! Estabamos escribiendo al mismo tiempo!! :D
Un detalle: usas ORG 0x0 para el inicio del programa (vector de reset), luego usas un ORG 0x4 para las interrupciones, con un GOTO a algún lado... luego ORG 0x5.
La instrucción GOTO ocupa más de una posición de memoria, por lo tanto el error de sobreescritura al compilar (overwriting...)
Mi consejo:
ORG 0x0
GOTO main
ORG 0x4
ISR
;salvo STATUS y W (atención!! salvar registros sin modificar STATUS!! solución en microchip.com)
;veo que interrupción es y salto según cual sea con un CALL...
;retorno a la linea que sigue:
ISR_END
;repongo los valores de STATUS y W (sin modificar STATUS!! solución en...)
RETFIE
;y sin poner otro ORG...
main
;programa principal....
El compilador se las arreglará...
Espero haber sido claro..., y si no, siempre podemos hacer un reset y goto main... :P
Saludos :hola:
Navegación
[#] Página Siguiente
Ir a la versión completa