TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: Enigma en 21 de Septiembre de 2008, 15:05:08
-
Hola muchachos que tal... Aquí recordando mis viejos tiempos en ASM, pues me he puesto a compilar un programa e cual supuestamente me deberia de dar una base de tiempo de 1 segundo con el timer 1, he realizado todas las configuraciones de los registros, pero al parecer el TMR1 nunca me interrumpe, puesto que la bandera TMR1IF nunca se me activa..., pues si alguien me da una manita, a ver que es lo que tengo mal... Aquí les dejo el codigo, es cortiquito, pues to que lo unico que hago es prender y apagar un led durante un segundo... ! segundo apagado y un segundo enecendido!!!!
Estoy trabajando con un 16F877A, el Timer 1 en modo contador, con un cristal de 32768 kHz entre las paticas RC0 y RC1...
LIST P=16F877A
INCLUDE "P16F877A.INC"
ORG 0X00 ;
GOTO PRINCIPAL ;
ORG 0X04 ;
GOTO INTERRUM ;
ORG 0X05 ;
;----------------PROGRAMA PRINCIPAL-----------------------------
PRINCIPAL
CLRF PORTC ; LIMPIO EL PUETO C
CLRF PORTB ; LIMPIA LOS BITS DEL PUERTO B
BSF STATUS,RP0 ; SELECCIONA EL BANCO 1
BSF PIE1,TMR1IE ; HABILITO LA INTERRUPCIÓN POR TIMER1
MOVLW 0X00 ; PARA CONFIGURAR EL PUERTO B
MOVWF TRISB ; CONFIGURA PUERTO B COMO SALIDA
MOVLW 0XFF ; PARA CONFIGURAR LOS PUERTOS COMO ENTRADAS
MOVWF TRISC ; CONFIGURA EL PUERTO C COMO ENTRADA
CLRF STATUS ; REGRESA AL BANCO 0
;-------------------CONFIGURACIÓN DEL TIMER 1---------------------
BSF T1CON,0 ; HABILITAMOS EL TIMER 1 (TMR1ON=1)
BSF T1CON,1 ; SEÑAL DEL RELOJ DEL TIMER 1 EXTERNA (TMR1CS=1)
BSF T1CON,2 ; NO SE SINCRONIZA LA SEÑAL DE RELOJ DEL TMR1 CON LA SEÑAL EXTERNA (T1SYNC=1)
BCF T1CON,3 ; NO HABILITA EL OSCILADOR DEL TIMER 1 (T1OSCEN=0)
BCF T1CON,4 ; PRE DIVISOR DE FRECUENCIA EN 1 (T1CKPS0=0)
BCF T1CON,5 ; PRE DIVISOR DE FRECUENCIA EN 1 (T1CKPS1=0)
;-------------------HABILITACION DE INTERRUPCIONES----------------
BSF INTCON,GIE ; HABILITAMOS TODAS LAS INTERRUPCIONES
SUEÑO NOP ;
GOTO SUEÑO ; A DORMIR!!!!
GOTO SUEÑO ; A DORMIR!!!!
;-------------------RUTINA DE SERVICIO DE INTERRUPCIÓN------------
INTERRUM
BTFSC PORTB,1 ; PREGUNTO COMO ESTÁ EL LED, ENCENDIDO O APAGADO?
GOTO OFF_LED ; ESTA PRENDIDO, VOY A APAGARLO
BSF PORTB,1 ; ESTA APAGADO, VOY Y LO ENCIENDO
BCF PIR1,TMR1IF ; BORRO LA BANDERA DE INTERRUPCIÓNPOR TMR1
RETFIE ; ME RGRESO AL PROGRAMA
OFF_LED
BCF PORTB,1 ; APAGO EL LED
BCF PIR1,TMR1IF ; BORRO LA BANDERA DE INTERRUPCIÓN POR TMR1
RETFIE ; ME REGRESO AL PROGRAMA
END ; FIN DE PROGRAMA
Atte: Enigma... La llanerita de Guayana :-)
-
Holas Enigma!!
Por lo que veo de tu programa, el flag TMR1IF si se está activando, pero no genera la interrupción :(
Para que genere la interrupción falta activar el flag PEIE del registro INTCON.
Sería algo como esto:
LIST P=16F877A
INCLUDE "P16F877A.INC"
ORG 0X00 ;
GOTO PRINCIPAL ;
ORG 0X04 ;
GOTO INTERRUM ;
ORG 0X05 ;
;----------------PROGRAMA PRINCIPAL-----------------------------
PRINCIPAL
CLRF PORTC ; LIMPIO EL PUETO C
CLRF PORTB ; LIMPIA LOS BITS DEL PUERTO B
BSF STATUS,RP0 ; SELECCIONA EL BANCO 1
BSF PIE1,TMR1IE ; HABILITO LA INTERRUPCIÓN POR TIMER1
MOVLW 0X00 ; PARA CONFIGURAR EL PUERTO B
MOVWF TRISB ; CONFIGURA PUERTO B COMO SALIDA
MOVLW 0XFF ; PARA CONFIGURAR LOS PUERTOS COMO ENTRADAS
MOVWF TRISC ; CONFIGURA EL PUERTO C COMO ENTRADA
CLRF STATUS ; REGRESA AL BANCO 0
;-------------------CONFIGURACIÓN DEL TIMER 1---------------------
BSF T1CON,0 ; HABILITAMOS EL TIMER 1 (TMR1ON=1)
BSF T1CON,1 ; SEÑAL DEL RELOJ DEL TIMER 1 EXTERNA (TMR1CS=1)
BSF T1CON,2 ; NO SE SINCRONIZA LA SEÑAL DE RELOJ DEL TMR1 CON LA SEÑAL EXTERNA (T1SYNC=1)
BCF T1CON,3 ; NO HABILITA EL OSCILADOR DEL TIMER 1 (T1OSCEN=0)
BCF T1CON,4 ; PRE DIVISOR DE FRECUENCIA EN 1 (T1CKPS0=0)
BCF T1CON,5 ; PRE DIVISOR DE FRECUENCIA EN 1 (T1CKPS1=0)
;-------------------HABILITACION DE INTERRUPCIONES----------------
BSF INTCON, PEIE ; Habilitamos interrupción por periféricos
BSF INTCON,GIE ; HABILITAMOS TODAS LAS INTERRUPCIONES
SUEÑO NOP ;
GOTO SUEÑO ; A DORMIR!!!!
GOTO SUEÑO ; A DORMIR!!!!
;-------------------RUTINA DE SERVICIO DE INTERRUPCIÓN------------
INTERRUM
BTFSC PORTB,1 ; PREGUNTO COMO ESTÁ EL LED, ENCENDIDO O APAGADO?
GOTO OFF_LED ; ESTA PRENDIDO, VOY A APAGARLO
BSF PORTB,1 ; ESTA APAGADO, VOY Y LO ENCIENDO
BCF PIR1,TMR1IF ; BORRO LA BANDERA DE INTERRUPCIÓNPOR TMR1
RETFIE ; ME RGRESO AL PROGRAMA
OFF_LED
BCF PORTB,1 ; APAGO EL LED
BCF PIR1,TMR1IF ; BORRO LA BANDERA DE INTERRUPCIÓN POR TMR1
RETFIE ; ME REGRESO AL PROGRAMA
END ; FIN DE PROGRAMA
Espero te funcione y me cuentas, ya que me parece muuuuuy util y práctico para proyectos futuros.
Saludos a quienes nos leen.
-
:o Ijole!!! jejeje no me percate de eso!!! Gracias por la corrección sansanoloko... Voy a probar y luego publico los resultados!!!
Atte: Enigma... La llanerita de Guayana :-)
-
; Prueben con este código. Funciona bien.
;*******************************************************************************
; Programa: 1HZ_TMR1.asm
; Versión: 1.0
; Autor: D@rkbytes
; Compañia: Digitek
; Notas:
; Generar una interrupción cada segundo usando el oscilador externo a 32768Hz
;*******************************************************************************
list p=16f628a
include <p16f628a.inc>
__config _INTRC_OSC_NOCLKOUT & _PWRTE_ON & _WDTE_OFF & _LVP_OFF
errorlevel -302
cblock 0x20
cnt1,cnt2 ; Variables para el retardo
endc
w_temp equ 0x7E ; Variables para guardar el contexto de los registros
status_temp equ 0x7F
org 0x00
goto inicio
org 0x04
movwf w_temp ; Guardar el estado actual del registro W
movf STATUS,W ; Mover el el registro STATUS a W
movwf status_temp ; Guardar el estado actual del registro STATUS
goto int_tmr1
inicio
bsf STATUS,RP0 ; Banco 1
movlw b'11111101' ; RA1 salida
movwf TRISA
movlw b'11101111' ; RB4 salida
movwf TRISB
bsf PIE1,TMR1IE ; Habilitar interrupción por desborde de TMR1
movlw b'11000000'
movwf INTCON
bcf STATUS,RP0 ; Banco 0
movlw b'111' ; Comparadores off
movwf CMCON
movlw b'1010' ; Configurar T1CON
movwf T1CON
movlw 0x80 ; Cargar el MSB de 32768 al timer 1
movwf TMR1H
movlw 0x00 ; Cargar el LSB de 32768 al timer 1
movlw TMR1L
bsf T1CON,TMR1ON ; Activar el Timer 1
clrf PORTA ; pines de salida en 0
clrf PORTB
programa:
bsf PORTA,1 ; Encender el LED en RA1
call delay100ms ; Esperar 100Ms
bcf PORTA,1 ; Apagar el LED en RA1
call delay100ms ; Esperar 100Ms
goto programa ; Hacer un bucle infinito
int_tmr1
btfss PORTB,4 ; ¿Está encendido el LED?
goto prende_led ; No, lo enciendo
bcf PORTB,4 ; Si, Apagar el LED
goto salir
prende_led
bsf PORTB,4 ; No, Encender el LED
salir ; Salir de la interrupción
bcf PIR1,TMR1IF ; Limpiar bandera de interrupción por desborde de TMR1
movlw 0x80 ; Cargar el MSB de 32768 al timer 1
movwf TMR1H
movlw 0x00 ; Cargar el LSB de 32768 al timer 1
movlw TMR1L
movf status_temp,w ; Recuperar la copia del registro STATUS
movwf STATUS ; Restaurar el estado anterior a la interrupción del registro STATUS
swapf w_temp,f
swapf w_temp,w ; Restaurar el estado anterior a la interrupción del registro W
retfie ; Retornar de la interrupción
; Subrutina de retardo de 100Ms @ 4 MHz.
delay100ms
; 99993 ciclos
movlw 0x1E
movwf cnt1
movlw 0x4F
movwf cnt2
delay100ms_0
decfsz cnt1, f
goto $+2
decfsz cnt2, f
goto delay100ms_0
; 3 ciclos
goto $+1
nop
; 4 ciclos (incluyendo call)
return
end
; Saludos