Programació en pic-as del PIC 16F690

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

Exemple TM - Temporitzador 0

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 0 que és un comptador de 8 bits. 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 un registre. Quan aquest registre arriba a zero s'activa un bit en un altre registre.

En aquest exemple cada cop que Timer 0 acabi de comptar (és a dir, cada 256 μs) incrementarem la variable Visualit i en copiarem el resultat sobre els LED.

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 10000111B  ; Configuració de Timer0
                   ; Com a temporitzador basat en rellotge
                   ; 111 - Factor d'escala de 256
                   ; I resistències de pull-up desactivades (valor per defecte)
  movwf OPTION_REG  ; Ho guarda al registre de configuració del Timer0
  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
Bucle:
  btfss T0IF  ; Mira si Timer0 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 T0IF  ; 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

Veiem com els LED van comptant de 0 (0000) a 15 (1111) i quan acaben tornen a començar. Però ho fan a velocitat molt ràpida. Si volem un ritme més lent, podem canviar la penúltima instrucció de manera que siguin els bits de l'esquerra els que es copiïn als LED, així anirà 16 cops més lent ja que caldrà que Visualit s'incrementi 16 vegades abans no canviï un bit.

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 10000111B  ; Configuració de Timer0
                   ; Com a temporitzador basat en rellotge
                   ; 111 - Factor d'escala de 256
                   ; I resistències de pull-up desactivades (valor per defecte)
  movwf OPTION_REG  ; Ho guarda al registre de configuració del Timer0
  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
Bucle:
  btfss T0IF  ; Mira si Timer0 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 T0IF  ; Si ha arribat, desactivem el bit
  incf Visualit,f  ; Incrementem Visualit
  swapf Visualit,w  ; Permuta els nibbles i ho posa a l'acumulador
  movwf PORTC  ; I ho posa als LED
  goto Bucle  ; Repetim-ho...
END main

Ara el canvi dels LED serà força lent. Podeu provar de variar el factor d'escala per tenir velocitats diferents. Per exemple amb un factor d'escala de 128 (00000110) sembla una velocitat visualment adequada. Ara serà vuit cops més lent que al primer programa i el doble de ràpid que a l'anterior.

Per aconseguir un canvi lent dels LED també podem fer servir un comptador de manera que només canviem els LED cada un cert nombre de cicles de Timer 0 i així aconseguir una velocitat més precisa. També podem variar el nombre de cicles que fa Timer 0 posant-li un valor determinat al registre TMR0 en el moment de començar; entre les dues coses, podríem ajustar el temps com volguéssim.

En el següent programa el rellotge ens dona un cicle cada 1 μs i el factor d'escala és 16, de manera que el comptador s'incrementa cada 16 μs. Si volem que el bit T0IF s'activi cada 4 ms (0,05 s) el temporitzador ha de comptar

4000 / 16 = 250

Per tant, hem d'inicialitzar TMR0 a

256 - 250 = 6

Si, a més, repetim el cicle 250 cops abans no canviem els LED aconseguirem que el canvi sigui cada segon.

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 10000011B  ; Configuració de Timer0
                   ; Com a temporitzador basat en rellotge
                   ; 011 - Factor d'escala de 16
                   ; I resistències de pull-up desactivades (valor per defecte)
  movwf OPTION_REG  ; Ho guarda al registre de configuració del Timer0
  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 250  ; Canviarem els LED cada 250 cicles de Timer 0
  movwf Compta  ; Guarda el valor a Compta
  movlw 6  ; Inicialització de TMR0
  movwf TMR0  ; Ho posa com a preselecció del temporitzador
Bucle:
  btfss T0IF  ; Mira si Timer0 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 T0IF  ; Si ha arribat, desactivem el bit
  movlw 6  ; Inicialització de TMR0
  movwf TMR0  ; Ho posa com a preselecció del temporitzador
  decfsz Compta,f  ; Decrementem Compta
  goto Bucle  ; Si no és zero, torna a esperar el Timer 0
  incf Visualit,f  ; Incrementem Visualit
  movf Visualit,w  ; Copia Visualit a l'acumulador
  movwf PORTC  ; I ho posa als LED
  movlw 250  ; 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.