Programació en pic-as del PIC 16F690

Referència Trucs Perifèrics   Recursos CITCEA
Tutorial Exemples Projectes   Inici

Exemple T2 - Temporitzador 2

En els exemples anteriors els LED s'encenien a un ritme que marcaven uns bucles de retard que teníem en el programa. Això volia dir que la major part del temps el processador estava fent bucles. En aquest exemple, en lloc de tenir el microcontrolador ocupat fent bucles per comptar el temps, fem que un temporitzador físic (timer) s'encarregui de comptar el temps. En el nostre cas farem servir el Timer 2 que és un comptador de 8 bits amb comparació. Quan funciona com a temporitzador, agafa la sortida del rellotge del microcontrolador (període d'un microsegon), el divideix per un factor d'escala i el fa servir per incrementar el registre TMR2. Quan aquest registre coincideix amb el valor guardat al registre PR2, TMR2 es posa a zero i es compta una coincidència. Quan el nombre de coincidències és igual al que s'ha definit al postescalador, s'activa un bit en un altre registre.

En aquest exemple cada cop que s'activi TMR2IF incrementarem la variable Visualit i en copiarem el resultat sobre els LED. Li hem posat un prescalador de 16, de manera que s'incrementa cada 16 μs i ha de comptar fins 256; per tant, fara una coincidència cada 4096 μs. Posarem un post-escalat de 16, de manera que el bit TMR2IF s'activarà cada 65,54 ms.

PROCESSOR 16F690
#include <xc.inc>
config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF
config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
Visualit EQU 0x20  ; Una variable on guardem el que mostraran els LED
PSECT code, class=CODE, delta=2, abs  ; A l'inici de la memòria
main:
  bsf RP0  ; Tria el banc 1
  movlw 11110000B  ; Posa els bits de menys pes del port C com a sortida
  movwf TRISC  ; la resta, com a entrades
  bcf RP0  ; Tria el banc 0
  movlw 01111111B  ; Configuració de Timer 2
                   ; 11 - Pre-escala de 16
                   ; 1111 - Post-escala de 16
                   ; I el posem en marxa
  movwf T2CON  ; Ho guarda al registre de configuració del Timer 2
  bcf TMR2IF  ; Desactivem el bit de fi del temporitzador
  clrf Visualit  ; Posa Visualit a 0
  movf Visualit,w  ; Copia Visualit a l'acumulador
  movwf PORTC  ; I ho posa als LED
Bucle:
  btfss TMR2IF  ; Mira si Timer2 ha arribat a zero
                ; Si hi ha arribat, no fa la instrucció següent
  goto Bucle  ; Si no hi ha arribat, repeteix la instrucció
  bcf TMR2IF  ; Si ha arribat, desactivem el bit
  incf Visualit,f  ; Incrementem Visualit
  movf Visualit,w  ; Copia Visualit a l'acumulador
  movwf PORTC  ; I ho posa als LED
  goto Bucle  ; Repetim-ho...
END main

Podem posar una pre-escala i/o una post-escala més petites per aconseguir valors més ràpids però ja no podem posar-les més grans si en volem de més lents. El que sí podem fer és que l'increment es faci només cada, per exemple, 16 finals del temporitzador (que comptem amb la variable Compta); o sigui cada, aproximadament, 1 s (en concret cada 1,05 s):

PROCESSOR 16F690
#include <xc.inc>
config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF
config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
Visualit EQU 0x20  ; Una variable on guardem el que mostraran els LED
Compta EQU 0x21  ; Variable per comptar el nombre de cicles
PSECT code, class=CODE, delta=2, abs  ; A l'inici de la memòria
main:
  bsf RP0  ; Tria el banc 1
  movlw 11110000B  ; Posa els bits de menys pes del port C com a sortida
  movwf TRISC  ; la resta, com a entrades
  bcf RP0  ; Tria el banc 0
  clrf Visualit  ; Posa Visualit a 0
  movf Visualit,w  ; Copia Visualit a l'acumulador
  movwf PORTC  ; I ho posa als LED
  movlw 16  ; Canviarem els LED cada 16 cicles de Timer 2
  movwf Compta  ; Guarda el valor a Compta
  movlw 01111111B  ; Configuració de Timer 2
                   ; 11 - Pre-escala de 16
                   ; 1111 - Post-escala de 16
                   ; I el posem en marxa
  movwf T2CON  ; Ho guarda al registre de configuració del Timer 2
  bcf TMR2IF  ; Desactivem el bit de fi del temporitzador
Bucle:
  btfss TMR2IF  ; Mira si Timer2 ha arribat a zero
                ; Si hi ha arribat, no fa la instrucció següent
  goto Bucle  ; Si no hi ha arribat, repeteix la instrucció
  bcf TMR2IF  ; Si ha arribat, desactivem el bit
  decfsz Compta,f  ; Decrementem Compta
  goto Bucle  ; Si no és zero, torna a esperar el Timer 2
  incf Visualit,f  ; Incrementem Visualit
  movf Visualit,w  ; Copia Visualit a l'acumulador
  movwf PORTC  ; I ho posa als LED
  movlw 16  ; Tornem a posar el nombre de cicles
  movwf Compta  ; Guarda el valor a Compta
  goto Bucle  ; Repetim-ho...
END main

També podem inicialitzar el comptador amb un valor per comptar el temps desitjat. Si mantenim el pre-escalat de 16 vol dir que cada increment del comptador són 16 μs. Si volem que el final del temporitzador sigui cada 2 ms (és a dir cada 2000 μs) ens caldrà comptar fins a 2000 /16 = 125, que és el valor que posarem a PR2.

En el programa següent el temporitzador acaba cada 2 ms, com hem calculat. Hi ha un post-escalador de 10 que fa que el bit TMR2IF sigui cada 20 ms i la rotació dels LED es fa cada 50 cops, o sigui cada segon.

	T2CKPS = 11		1/16
	TOUTPS = 1001		1/10
	T2CON  = 0b01001111

PROCESSOR 16F690
#include <xc.inc>
config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF
config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
Visualit EQU 0x20  ; Una variable on guardem el que mostraran els LED
Compta EQU 0x21  ; Variable per comptar el nombre de cicles
PSECT code, class=CODE, delta=2, abs  ; A l'inici de la memòria
main:
  bsf RP0  ; Tria el banc 1
  movlw 11110000B  ; Posa els bits de menys pes del port C com a sortida
  movwf TRISC  ; la resta, com a entrades
  movlw 125  ; Valor de comparació del Timer 2
  movwf PR2  ; Guarda el valor a PR2
  bcf RP0  ; Tria el banc 0
  clrf Visualit  ; Posa Visualit a 0
  movf Visualit,w  ; Copia Visualit a l'acumulador
  movwf PORTC  ; I ho posa als LED
  movlw 50  ; Canviarem els LED cada 16 cicles de Timer 2
  movwf Compta  ; Guarda el valor a Compta
  movlw 01111111B  ; Configuració de Timer 2
                   ; 11 - Pre-escala de 16
                   ; 1111 - Post-escala de 16
                   ; I el posem en marxa
  movwf T2CON  ; Ho guarda al registre de configuració del Timer 2
  bcf TMR2IF  ; Desactivem el bit de fi del temporitzador
Bucle:
  btfss TMR2IF  ; Mira si Timer2 ha arribat a zero
                ; Si hi ha arribat, no fa la instrucció següent
  goto Bucle  ; Si no hi ha arribat, repeteix la instrucció
  bcf TMR2IF  ; Si ha arribat, desactivem el bit
  decfsz Compta,f  ; Decrementem Compta
  goto Bucle  ; Si no és zero, torna a esperar el Timer2
  incf Visualit,f  ; Incrementem Visualit
  movf Visualit,w  ; Copia Visualit a l'acumulador
  movwf PORTC  ; I ho posa als LED
  movlw 50  ; Tornem a posar el nombre de cicles
  movwf Compta  ; Guarda el valor a Compta
  goto Bucle  ; Repetim-ho...
END main

 

 

Llicència de Creative Commons
Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.