Programació en pic-as del PIC 16F690

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

Exemple T1 - Temporitzador 1

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 1 que és un comptador de 16 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 el registre TMR1 (bytes TMR1L i TMR1H). Quan aquest registre arriba a zero s'activa un bit en un altre registre.

En aquest exemple cada cop que Timer 1 acabi de comptar incrementarem la variable Visualit i en copiarem el resultat sobre els LED. Li hem posat un prescalador de 8, de manera que s'incrementa cada 8 μs i ha de comptar 65536; per tant, fara una rotació cada 0,52 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
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 00110001B  ; Configuració de Timer 1
                   ; 11 - Factor d'escala de 8
                   ; I el posem en marxa
  movwf T1CON  ; Ho guarda al registre de configuració del Timer 1
  bcf TMR1IF  ; 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 TMR1IF  ; Mira si Timer1 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 TMR1IF  ; 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 una velocitat relativament ràpida. Per aconseguir un desplaçament lent dels LED també podem fer servir un comptador de manera que només canviem els LED cada un cert nombre de cicles de Timer1 i així aconseguir una velocitat més precisa. També podem variar el nombre de cicles que fa Timer1 posant-li un valor determinat al registres TMR1L i TMR1H en el moment de començar; entre les dues coses, podríem ajustar el temps com volguéssim.

En el següent programa mantenim el pre-escalat de 8 vol dir que cada increment del comptador són 8 μs. Si volem que el final del temporitzador sigui cada 0,05 s (és a dir cada 50 000 μs) ens caldrà comptar fins a 50 000 / 8 = 6250. Per posar aquest valor, farem:

	TMR1 = 65536 - 6250 = 59286
	TMR1H = 59286 / 256 = 231
	TMR1L = 59286 % 256 = 150

En el programa següent el temporitzador acaba cada 0,05 s, com hem calculat; i la rotació dels LED es fa cada 20 cops, o 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 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 20  ; Canviarem els LED cada 20 cicles de Timer1
  movwf Compta  ; Guarda el valor a Compta
  movlw 231  ; Inicialitza el Timer 1
  movwf TMR1H
  movlw 150
  movwf TMR1L
  movlw 00110001B  ; Configuració de Timer 1
                   ; 11 - Factor d'escala de 8
                   ; I el posem en marxa
  movwf T1CON  ; Ho guarda al registre de configuració del Timer 1
  bcf TMR1IF  ; Desactivem el bit de fi del temporitzador
Bucle:
  btfss TMR1IF  ; Mira si Timer1 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 TMR1ON  ; Atura momentàniament el Timer 1
  movlw 231  ; Inicialitza el Timer1
  movwf TMR1H
  movlw 150
  movwf TMR1L
  bsf TMR1ON  ; Torna a engegar el Timer1
  bcf TMR1IF  ; Si ha arribat, desactivem el bit
  decfsz Compta,f  ; Decrementem Compta
  goto Bucle  ; Si no és zero, torna a esperar el Timer 1
  incf Visualit,f  ; Incrementem Visualit
  movf Visualit,w  ; Copia Visualit a l'acumulador
  movwf PORTC  ; I ho posa als LED
  movlw 20  ; 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.