TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: black_flowers en 06 de Abril de 2007, 18:22:43
-
hola, tengo un problema con el timer0 en un programa q estoy haciendo (en un 16f84a) el codigo es el siguiente, no pongo todo, lo importante es como está configurado el timer0 y cuando se lanza. El programa funciona todo bien excepto en que nada más arrancar ya empieza con las interrupciones del timer0 sin yo lanzarlo. teoricamente se tenía que lanzar en al pulsar el ra3 tal y como está programado en el main, pero ya digo que nada más arrancar ya empieza saltando la interrupción y de ahí ya sigue saltando cada 5 segundos que es el tiempo que tiene que temporizar. Todo estaría bien excepto que no salta cuando yo pulso el botón sino nada más empezar (uy cuantas veces lo he repetido, bueno es pa que quede más claro) veis algún fallo evidente a la hora de configurar el timer0, para que suceda lo que os digo??
main
banksel INTCON
bcf INTCON,GIE
bcf INTCON,T0IE
clrwdt
banksel OPTION_REG
bcf OPTION_REG,T0CS
bcf OPTION_REG,PSA
bsf OPTION_REG,PS0
bsf OPTION_REG,PS1
bcf OPTION_REG,PS2
banksel INTCON
bsf INTCON,GIE
bsf INTCON,T0IE
loop
banksel PORTA
movf PORTA,W
banksel entradas_actuales
movwf entradas_actuales
btfss entradas_actuales,0
goto guardar_entradas
btfsc entradas_anteriores,0
goto guardar_entradas
call DEMORA
banksel PORTA
bsf PORTA,3
banksel contador
movlw 0xfa
movwf contador
movlw 0x05
movwf segundos
banksel TMR0
movlw 0x10
movwf TMR0
guardar_entradas
banksel entradas_actuales
movf entradas_actuales,w
movwf entradas_anteriores
goto loop
end
-
Asi a votepronto estas:
-Seleccionando una señal de Ck externa con bsf OPTION_REG,T0CS
-Asignando el divisor de frecuencia al watchdog en lugar de al timer0 bsf OPTION_REG,PSA mientras al timer0 le aplicas la señal directa
(esquema de bloques datasheet page19)
saludos
-
es que no es bsf sino bcf, si te fijas, quizás la cursiva despiste un poco pero es para diferenciar mejor el código, de todas formas
¿lo veis correcto? a mi me parece que no tendría xq saltar el timer0 ya que se supone que hasta que yo no mueva un valor hacia el no debería saltar.
sl.2
-
Es que el TMR0 no se puede detener, al menos no tiene un bit en ningún resgistro para tal fin.
Si no quieres que interrumpa, como "truco" lo puedes poner en modo "contador" pero para ello ten cuidado con el hardware del pin externo (en modo contador, cuenta pulsos en un pin).
Saludos
-
Quizas pudiera funcionar lo siguiente.
Mientras quieras que no empiece a contar el timer0 mantener bloquedada la interrupción asociada, es decir, mantener a cero al INTCON,T0IE, para ello podemos usar el vector de RESET, fuera del bucle en que se quede la ejecución de trabajo normal, pero garantizando que al "conectar" el equipo se ejecute solo una vez
ORG 0x000
bcf INTCON,T0IE
goto INICIO
Tambien puede hacerse en la parte que se configuran los registros si esa parte solo se ejecuta una vez al inicio de funcionamiento despues de cada reset.
En esas condiciones no tiene efecto la interrupción por timer0. Solo queda habilitarla y preparar la interrupción cuando se detecte que se ha activado RA3 y no antes
btfsc INTCON,T0IE ;Pregunta si no está autorizada la interrupción
goto SALTO ;si es falso, ya está autorizada, se salta el tramo siguiente
btfss PA,RA3 ;pero si no lo está pregunta si se ha activado RA3 (o su equivalente si lo tiene para prevenir rebotes)
goto SALTO ;si es falso se salta el resto del tramo
bcf INTCON,T0IF ;Si se ha activado RA3 hay que preparar el timer0, empezamos con una "limpieza" por si acaso
clf TMR0 ;por lo mismo (en su lugar podría ponerse la carga de un valor inicial si es distinto de 0)
bsf INTCON,T0IE ; y activamos al timer0 que a partir de aqui ya funcionará ininterrumpidamnete
SALTO ;Continúa el resto
Disculpa que ponga el código solo en ASM, recien estoy empezando con los PIC y hasta que no adquiera un mínimo de dominio en ensamblador no me quiero pasar a lenguajes de nivel superior (primero quiero "entender" la maquina).
Saludos.
-
osea q nada más activar la interrupcion del timer0 ya salta el cabrón, probaré eso que me dices, parece ser la única solución.
-
Para comprobarlo he hecho el siguiente programa y funciona
;--------------------------------------------------------------------------------------------------------------------------
;PROGRAMA QUE PARA QUE SE INICIE INT DE TMR0 REQUIERE PERMISO DE RA3
;--------------------------------------------------------------------------------------------------------------------------
LIST P=16F84A
PA EQU 0x05 ;TRISA en banco 1
PB EQU 0x06 ;TRISB en banco1
STATUS EQU 0x03 ;en ambos bancos
TMR0 EQU 0x01 ;OPTION_REG en banco1
INTCON EQU 0x0B ;en ambos bancos
AUXILI EQU 0x0C ;Reg. auxiliar
;--------------------------------------------------------------------------------------------------------------------------
ORG 0x000
goto INICIO
ORG 0x004
goto INTE0
;-------------------------------------------------------------------------------------------------------------------------
INICIO ;Tramo de programación de registros
bsf STATUS,5 ;Paso a banco 1 para programar
clrf PB ;Programo TRISB para PB como salidas
movlw 0x80 ;1000 0000
movwf INTCON ;Programo INTCON activado el GIE pero no el T0IE
movlw 0xC7 ;1100 0111
movwf TMR0 ;Programo el OPTION_REG
bcf STATUS,5 ;Fin de programación de registros de control
movlw 0x04
movwf AUXILI
movlw 0x11
movwf PB ;Estas 4 últimas líneas son para ver el funcionamiento
;---------------------------------------------------------------------------------------------------------------------------
TRABAJO ;Inicio de programa de trabajo
;Activación de las int por timer0 la 1ª vez que RA3 valga 1
btfsc INTCON,5 ;Pregunta si NO está activada la int del timer0
goto SALTO ; *si SI lo esta ir a SALTO
btfss PA,3 ;Pregunta si ya se ha activado RA3
goto SALTO ;si NO lo está ir a SALTO
clrf TMR0 ;si Si lo está, limpia contenido de timer0 y
bcf INTCON,2 ;borra el flag y
bsf INTCON,5 ;activa las int por timer0 Siguiente vuelta de (*) pasa a SALTO
SALTO ;puede continuar el programa de trabajo
goto TRABAJO ;Se cierra el bucle de trabajo
;--------------------------------------------------------------------------------------------------------------------------
INTE0 ;Tratamiento de la int de timer0
decfsz AUXILI,1 ;Con cada interrupción de timer0 decrementa AUXILI y ¿=0?
goto SALIR ;si NO lo es salir de interrupción
rlf PB,1 ;si SI lo es rotar PB y
movlw 0x04
movwf AUXILI ;reinicia AUXILI
SALIR
bcf INTCON,2 ;borra el flag del timer0
retfie
;-------------------------------------------------------------------------------------------------------------------------
END
;-------------------------------------------------------------------------------------------------------------------------
Saludos
-
ok, ya lo he solucionado no exactamente como pones en el codigo pero mas o menos enmascarando/desenmascarando la interrupcion, la verdad es q no sabia que saltase ya automaticamente, pero sí así es, un saludo y muchas gracias