;************************************************************
;* Carlos Alberto Henao *
;* Interrupción por desborde del timer0 con el pic 16f877 *
;* Para multiplización de display de doble segmento *
;* Foro técnico de microcontroladores "todopic" *
;* 16 de julio del 2009 Pereira - Colombia *
;************************************************************
;******************** Declaración de registros especiales *********************************
tmr0 equ 01h
status equ 03h
porta equ 05h
portb equ 06h
portc equ 07h
portd equ 08h
porte equ 09h
intcon equ 0bh
option_reg equ 81h
trisa equ 85h
trisb equ 86h
trisc equ 87h
trisd equ 88h
trise equ 89h
adcon1 equ 9fh
;******************* registros de usuario *************************************************
conta equ 20h ; contador
loop equ 21h
loop1 equ 22h ; registro de para la rutina de tiempo
digito1 equ 23h
digito2 equ 24h ; son los digitos del display
list p = 16f877
;***************** va a empezar el programa ***********************************************
org 00
goto inicio
org 04
goto inter
;**************** Rutina de manejo de interrupción ****************************************
inter btfsc intcon,2 ; pregunto si hubo interrupción por timer0
goto timer0
retfie
timer0 movf conta,0 ; paso lo de conta a w
xorlw d'0'
btfss status,2 ; pregunto si conta es cero para saber que display activar
goto display2
goto display1
display1
bsf portc,1
bcf portc,2 ; activo el display 1 por 11.008ms
movf digito1,0 ; paso digito1 a w
movwf portb ; paso el valor a visualizar
bsf portc,1
bcf portc,2 ; activo el display 1 por 11.008ms
movlw d'1'
movwf conta
movlw d'84'
movwf tmr0 ; vuelvo cargar el valor 84d para que el timer se
; desborde de nuevo en 11.008ms
bcf intcon,2 ; borro el flag
retfie ; retorno al pcl+1
display2
bsf portc,2
bcf portc,1 ; activo el display 2 por 11.008ms
movf digito2,0 ; paso digito1 a w
movwf portb ; paso el valor a visualizar
bsf portc,2
bcf portc,1 ; activo el display 2 por 11.008ms
clrf conta ; limpio a conta para que en el otro ciclo refresque al
; display1
movlw d'84'
movwf tmr0 ; vuelvo cargar el valor 84d para que el timer se
; desborde de nuevo en 11.008ms
bcf intcon,2 ; borro el flag
retfie ; retorno al pcl+1
;*************** Rutina de tiempo antirebote **********************************************
retar movlw d'100'
movwf loop
movlw d'100'
movwf loop1
decfsz loop1,1
goto $-1
decfsz loop,1
goto $-5
return
;*************** rutina de principal (main) ***********************************************
inicio bcf status,6
bsf status,5 ; banco 1
movlw b'11111111'
movwf trisa
movwf trisd
movwf trise ; puerto C,D,E como entradas digitales
movlw b'11111001'
movwf trisc ; configuro el pueto A los primeros 2 terminales como salidas
; digitales las otras 4 como entradas digitales
movlw b'11110000'
movwf trisb ; puerto B como salidas digitales
movlw b'11010101'
movwf option_reg ; configuro el timer a un predivisor de frecuancia de 1:64
movlw b'00000110'
movwf adcon1 ; configuro puerto A Y E como entradas digitales
bcf status,5 ; banco 0
clrf porta
clrf portb
clrf portc
clrf portd
clrf porte ; limpio todo los puertos
movlw b'10100000'
movwf intcon ; habilito la interrupcion global y por desborde del timer0
; ya estamos listos solo falta cargar el valor correspondiente
; en el registro tmro
clrf conta ; limpio el contador
clrf digito1 ; pongo el display en ceros
clrf digito2
movlw d'84'
movwf tmr0 ; pongo 84 en el timer para que cuente 11.008 ms y se
; desborde
clrf portb
pulsa btfsc portc,0
goto $-1
call retar
btfss portc,0 ; ha pulsado el botom
goto $-1
incf digito1,1 ; incremento digito1
movf digito1,0
xorlw d'10'
btfss status,2
goto pulsa
clrf digito1 ; si llego a 10 pongo el digito2 en 1 y el otro en 0 para escribir 20
; 30.....99
incf digito2,1
movf digito2,0 ; paso digito2 a w
xorlw d'10'
btfss status,2
goto pulsa ; si no a llegado a 99 sigo incrementado
clrf digito2 ; vuelvo a inicializar el ciclo desde 00 hasta 99
goto pulsa
nada goto nada ; bucle infinito esperando a que ocurra la interrupción
end
;************************************************************
;* Carlos Alberto Henao *
;* Interrupción por desborde del timer0 con el pic 16f877 *
;* Para medir el ciclo útil de un pulso *
;* Foro técnico de microcontroladores "todopic" *
;* 13 de julio del 2009 Pereira - Colombia *
;************************************************************
;******************** Declaración de registros especiales *********************************
tmr0 equ 01h
status equ 03h
porta equ 05h
portb equ 06h
portc equ 07h
portd equ 08h
porte equ 09h
intcon equ 0bh
option_reg equ 81h
trisa equ 85h
trisb equ 86h
trisc equ 87h
trisd equ 88h
trise equ 89h
adcon1 equ 9fh
;******************* registros de usuario *************************************************
cuenta_l equ 20h ; parete baja de pulso
cuenta_h equ 21h ; parte alta del pulso
bandera equ 23h
list p = 16f877
;***************** va a empezar el programa ***********************************************
org 00
goto inicio
org 04
goto inter
;**************** Rutina de manejo de interrupción ****************************************
inter btfsc intcon,2 ; pregunto si hubo interrupción por timer0
goto timer0
retfie
timer0 incf bandera,1 ; incremento el puerto b en 1
clrf tmr0 ; inicializo de nuevo el timer para tiempo máximo
bcf intcon,2 ; borro el flag
retfie ; retorno al pcl+1
;*************** rutina de principal (main) ***********************************************
inicio bcf status,6
bsf status,5 ; banco 1
movlw b'11111111'
movwf trisa
movwf trisd
movwf trise ; puerto A,D y E como entradas digitales
movlw b'00000000'
movwf trisb ; puerto B Y C como salidas digitales
movlw b'11010111'
movwf option_reg ; configuro el timer a un predivisor de frecuancia de 1:256
movlw b'00000110'
movwf adcon1 ; configuro puerto A Y E como entradas digitales
bcf status,5 ; banco 0
clrf porta
clrf portb
clrf portc
clrf portd
clrf porte ; limpio todo los puertos
movlw b'10100000'
movwf intcon ; habilito la interrupcion global y por desborde del timer0
; ya estamos listos solo falta cargar el valor correspondiente
; en el registro tmro
clrf tmr0 ; limpio el timer para que me produsca un máximo valor de
; tiempo
clrf cuenta_l
clrf cuenta_h
clrf bandera
btfsc porta,0 ; pregunto si esta en cero
goto $-1 ; si no está en cero espero a que se ponga en cero
pulso btfss porta,0 ; si está en uno
goto $-1 ; espero a que a que se ponga en uno
clrf tmr0
clrf bandera
btfsc porta,0 ; si se puso de nuevo en cero ya midio el pulso
goto $-1
movf tmr0,0
movwf cuenta_l
movf bandera,0
movwf cuenta_h
goto pulso ; vuelva y inicia el ciclo
end;*******************************************
;* Carlos Alberto Henao Baena *
;* Foro de microcontroladores TODOPIC *
;* Manejo de interrupción extenta RB0/INT *
;* 5 de agosto del 2009 *
;* Pereira - Colombia *
;*******************************************
;******************************* Registro especiales *************************************
status equ 03h
porta equ 05h
portb equ 06h
portc equ 07h
portd equ 08h
porte equ 09h
intcon equ 0bh
option_reg equ 81h
trisa equ 85h
trisb equ 86h
trisc equ 87h
trisd equ 88h
trise equ 89h
adcon1 equ 9fh
;******************************* Registro de usuario *************************************
bandera equ 20h
;******************************* Empieza el programa *************************************
list p = 16f877
org 00
goto inicio
org 04
goto inter
;****************************** Rutina de manejo de interrupciones ***********************
inter btfsc intcon,1
goto flanco_activo1 ; si ha ocurrido la interrupción
; voy a una rutina de atención
retfie ; si no retorno
flanco_activo1 movf bandera,0 ; paso bandera a W
xorlw d'0'
btfss status,2 ; pregunto por la comparación
goto flanco_activo2
bsf portb,1 ; si es el primer flanco activo el led
incf bandera,1 ; incremento bandera para que en el
; otro flanco activo apague el led
bcf intcon,1 ; limpio el señalizador de interrupción
retfie ; salgo de la interrupción
flanco_activo2 movf bandera,0 ; paso bandera a W
xorlw d'1'
btfss status,2 ; pregunto por la comparación
retfie
bcf portb,1 ; si es el segundo flanco desactivo el led
clrf bandera ; limpio bandera para que en el
; otro flanco activo prenda el led
bcf intcon,1 ; limpio el señalizador de interrupción
retfie
;****************************** Rutina principal de programa MAIN() **********************
inicio bcf status,6
bsf status,5 ; banco 1
movlw b'11111111'
movwf trisa
movwf trisc
movwf trisd
movwf trise ; puerto a,c,d y e como entradas
; digitales
movlw b'11111101'
movwf trisb ; configuro tal que RB0 sea entrada
; digital
movlw b'01000000' ; configuro el flanco de interrupción
movwf option_reg ; ascendente
movlw b'00000110'
movwf adcon1 ; configuro el adcon1 para los puertos
; A y E sean entradas o salidas digitales
bcf status,5 ; banco 0
movlw b'10010000' ; habilito la interrupción global
; y la de RB0/INT y desactivo las
movwf intcon ; demás por timer0 etc
clrf portb
clrf porta
clrf portc
clrf portd
clrf porte
clrf bandera ; inicializo todas la variable y los
; puertos
nada goto nada ; bucle infinito para esperar la
end ; la interrupción
;***********************************************************************************
;* Carlos Alberto Henao *
;* Interrupción por desborde del timer0 con el pic 16f877 en modo contador TOCK1 *
;* Foro técnico de microcontroladores "todopic" *
;* 5 de febrero del 2010 Pereira - Colombia *
;***********************************************************************************
;******************** Declaración de registros especiales *********************************
tmr0 equ 01h
status equ 03h
porta equ 05h
portb equ 06h
portc equ 07h
portd equ 08h
porte equ 09h
intcon equ 0bh
option_reg equ 81h
trisa equ 85h
trisb equ 86h
trisc equ 87h
trisd equ 88h
trise equ 89h
adcon1 equ 9fh
;********************* Registro de proposito especial ***************************************
contador equ 20h
list p = 16f877
;***************** va a empezar el programa ***********************************************
org 00
goto inicio
org 04
goto inter
;***************** Manejo de interrupción **************************************************
inter btfsc intcon,2
goto conta ; si hay desborde atiende la interrupción
retfie ; si no retorna
conta incf contador,1 ; incremento contador
movf contador,0 ; paso contador a w
xorlw d'1' ; comparo con 1
btfss status,2 ; pregunta por el resultado lógico
goto apaga ; so no es cero va a apaga
bsf portb,0 ; prende el primer led si el ciclo es impar
movlw d'250'
movwf tmr0 ; cargo otra vez el timer con 250
bcf intcon,2 ; limpio la bandera de interrupción
retfie ; salgo de la interrupción
apaga bcf portb,0 ; apago el led en el ciclo par
movlw d'250'
movwf tmr0 ; cargo otra vez el timer con 250
bcf intcon,2 ; limpio la bandera de interrupción
clrf contador ; vuelve e inicia el ciclo
retfie ; salgo de la interrupción
;************* Inicia el programa **********************************************************
inicio bcf status,6
bsf status,5 ; Banco 1 de memoria
movlw b'11111111'
movwf trisa
movwf trisc
movwf trisd
movwf trise ; configuro puertos A,C,D,E como entrada
movlw b'11111110'
movwf trisb ; configuro el puerto restante
movlw b'11110000'
movwf option_reg ; configuro el timer a un predivisor de frecuancia de 1:2
; y contador cada flanco ascendente por TOCK1
movlw b'00000110'
movwf adcon1 ; configuro puerto A Y E como entradas digitales
bcf status,5 ; me paso al banco 0
movlw b'10100000'
movwf intcon ; configuro el desborde por timer0
clrf contador
clrf porta
clrf portb
clrf portc
clrf portd
clrf porte ; limpio todos los puertos
movlw d'250'
movwf tmr0 ; cargo al timer0 con 250 para que se me desborde cada
; 12 pulsos de reloj
nada goto nada ; bucle infinito esperando desborde
end;*******************************************************************************
;* Carlos Alberto Henao Baena *
;* Foro de microcontroladores TODOPIC *
;* Manejo de interrupción extenta RB0/INT más timero para medir el ciclo útil *
;* 6 de febrero del 2010 *
;* Pereira - Colombia *
;*******************************************************************************
;******************************* Registro especiales *************************************
tmr0 equ 01h
status equ 03h
porta equ 05h
portb equ 06h
portc equ 07h
portd equ 08h
porte equ 09h
intcon equ 0bh
option_reg equ 81h
trisa equ 85h
trisb equ 86h
trisc equ 87h
trisd equ 88h
trise equ 89h
adcon1 equ 9fh
;******************************* Registro de usuario *************************************
bandera equ 20h
contador_l equ 21h
contador_h equ 22h
desbordes equ 23h
;******************************* Empieza el programa *************************************
list p = 16f877
org 00
goto inicio
org 04
goto inter
;****************************** Rutina de manejo de interrupciones ***********************
inter btfsc intcon,1
goto externa_rb0 ; si ha ocurrido la interrupción
; voy a una rutina de atención
btfsc intcon,2 ; pregunto por interrupcción del timer0
goto timer0 ; voy a una rutina de atencción
retfie ; si no retorno
;**************************** Rutina de atención de la interrupción por flanco activo en RB0*******
externa_rb0 incf bandera,1 ; incremento la bandera para saber si
; el flanco es descendente o ascendente
movf bandera,0 ; paso a w bandera
xorlw d'1' ; comparo con 1
btfss status,2 ; pregunto por el bit z
goto flanco_ascendente ; si no voy a flanco ascendente
movlw b'10110000' ; habilito la interrupción global
; y la de RB0/INT y activo la del timer0
movwf intcon
bsf status,5 ; me paso al banco 1
movlw b'10000111'
movwf option_reg ; cuando pasa la interrupción configuro
; el flanco en descendente
bcf status,5 ; me paso al banco 0
bcf intcon,1 ; limpio la bandera
clrf tmr0 ; empiezo a contar
retfie ; salgo de la interrupción
flanco_ascendente
movlw b'10010000' ; habilito la interrupción global
; y la de RB0/INT y activo la del timer0
movwf intcon
movf tmr0,0 ; paso el contenido del timer0 a w
movwf contador_l ; paso el contenido del timer 0 a contador_l
movf desbordes,0 ; paso desbordes al w
movwf contador_h ; paso el valor de desbordes a la parte alta.
clrf bandera
bcf intcon,1 ; limpio la bandera de interrupción
bsf status,5 ; me paso al banco 1
movlw b'11000111'
movwf option_reg ; configuro ahora como flanco ascendente
bcf status,5 ; me paso al banco 0
clrf tmr0 ; limpio el timer por que ya término de
; medir el ciclo útil
clrf desbordes ; inicializo la variable para el otro pulso
retfie
;************************* Atención por desborde del timer0 *********************************
timer0 incf desbordes,1 ; Incremento el contador en 1
bcf intcon,2 ; limpio la bandera de interrupción
retfie ; salgo de la interrupción
;****************************** Rutina principal de programa MAIN() **********************
inicio bcf status,6
bsf status,5 ; banco 1
movlw b'11111111'
movwf trisa
movwf trisc
movwf trisd
movwf trise ; puerto a,c,d y e como entradas
; digitales
movwf trisb ; configuro tal que RB0 sea entrada
; digital
movlw b'11000111' ; configuro el flanco de interrupción
movwf option_reg ; ascendente y prescaler 1:256
movlw b'00000110'
movwf adcon1 ; configuro el adcon1 para los puertos
; A y E sean entradas o salidas digitales
bcf status,5 ; banco 0
movlw b'10010000' ; habilito la interrupción global
; y la de RB0/INT y activo la del timer0
movwf intcon
clrf portb
clrf porta
clrf portc
clrf portd
clrf porte
clrf bandera ; inicializo todas la variable y los
; puertos
clrf tmr0
clrf contador_l
clrf contador_h ; limpio todas las variables
clrf desbordes
nada goto nada ; bucle infinito para esperar la
end ; la interrupción
Nota si alguién sabe cual es el código en html ([xxx] Texto [/xxxx]) para poner el código más organizado ya que mi computador está algo loco por estos días.
;**************************************************************
;* Carlos Alberto Henao *
;* Foro de microcontroladores TODOPIC *
;* Manejo de interupción por fin de escritura de la EEPROM *
;* Febrero 13 del 2010 *
;* Pereira - Colombia *
;**************************************************************
;************************** Registro especiales *******************************************
status equ 03h
porta equ 05h
portb equ 06h
portc equ 07h
portd equ 08h
porte equ 09h
intcon equ 0bh
pir2 equ 0dh
trisa equ 85h
trisb equ 86h
trisc equ 87h
trisd equ 88h
trise equ 89h
pie2 equ 8dh
eedata equ 10ch
eeadr equ 10dh
eecon1 equ 18ch
eecon2 equ 18dh
;************************ Registros de usuario ********************************************
conta equ 20h
loop equ 21h
loop1 equ 22h
respuesta equ 23h
;*********************** Va a empezar el programa *****************************************
list p = 16f877
org 00
goto inicio
org 04
goto inter
;************************* Rutina de atención de interrupciones **************************
inter bcf status,6
bcf status,5 ; banco 0
btfsc pir2,4 ; pregunto si ya hubo interrupción por finalización
; de escritura en la EEPROM
goto guarda_s
bcf status,6
bcf status,5 ; me paso al banco 0
retfie ; de lo contrario retorno al programa
guarda_s
bcf pir2,4 ; limpio la bandera de intterupción
movlw b'1'
movwf respuesta ; cargo
retfie
;************************* Rutina de tiempo antirebote **************************
retar movlw d'180'
movwf loop
movlw d'200'
movwf loop1
decfsz loop1,1
goto $-1
decfsz loop,1
goto $-5
return
;*********************** Rurina de configuración para la escritura en la EEMPROM ***********
guardar bsf status,6 ; me paso al banco de memoria 2
bcf status,5
movlw d'0'
movwf eeadr ; especifico en parte de la memoria voy a guardar
; en este caso en posición 0x00H
bcf status,6
bcf status,5 ; banco 0
movf conta,0 ; paso conta a w ya que conta es el valor a guardar
bsf status,6 ; me paso al banco de memoria 2
bcf status,5
movwf eedata ; paso el dato a eedata
bsf status,5 ; me paso al banco 3
bsf eecon1,2 ; permito la escritura en la eemprom
movlw 55h
movwf eecon2
movlw 0xAA
movwf eecon2 ; mando el comando de escritura
bsf eecon1,1 ; empieza la escritura
bcf status,6
bcf status,5
movf respuesta,1 ; paso el valor de escritura a w
xorlw d'1' ; lo comparo con 1
btfss status,2 ; pregunto por el resultado lógico de la operación
goto $-3 ; vuelvo y repito esperando interrupción
clrf respuesta ; limpio la bandera
return
;********************** Empieza el programa ************************************************
inicio bcf status,6
bsf status,5 ; banco 1
movlw b'11111111'
movwf trisa
movwf trisb
movwf trisd
movwf trise ; puertos A,B,D,E como entradas digitales
movlw b'11110000'
movwf trisc ; configuro el puerto C
movlw b'00010000'
movwf pie2
bcf status,5 ; banco 0
movlw b'11000000'
movwf intcon ; activo la interrupción por escritura de la EEPROM
clrf portb
clrf conta
clrf portc
clrf respuesta
vuelve btfss portb,1
goto pulsa_2
call retar
btfsc portb,1
goto pulsa_2
call retar
btfss portb,1 ; rutina que pregunta por los dos pulsadores
goto $-1
incf conta,1
goto vuelve
pulsa_2
btfss portb,2
goto vuelve
call retar
btfsc portb,2
goto vuelve
call retar
call guardar
goto vuelve
end