Programació en pic-as del PIC 16F690

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

Exemple RB - Rotació de LED bidireccional

En aquest exemple es combinen coses dels exemples VV i CP.

Com en l'exemple VV, en aquest cas llegirem el potenciòmetre utilitzant una entrada analògica i utilitzarem els vuit bits superiors del valor llegit per variar la velocitat però cada cop que premem el polsador variarem el sentit de gir dels LED.

El programa serà el següent:

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
Polsador EQU 0x20  ; Una variable amb l'estat del polsador (1 = premut)
Previ EQU 0x21  ; I una amb l'estat previ del polsador
Sentit EQU 0x22  ; I una per al sentit de gir
Visualit EQU 0x23  ; Una variable on guardem el que mostraran els LED
Compta EQU 0x24  ; Una variable per comptar iteracions
Retard1 EQU 0x25  ; Variable per al bucle de retard
Retard2 EQU 0x26  ; Variables per al bucle de retard
PSECT code, class=CODE, delta=2, abs  ; A l'inici de la memòria
main:
  bsf RP0  ; Tria el banc 1
  movlw 0xFF  ; Posa l'acumulador a FFh (tot uns)
  movwf TRISA  ; Posa tots els bits del port A com a entrada
  clrf TRISC  ; Posa tots els bits del port C com a sortida
  movlw 00010000B
  movwf ADCON1  ; Posa el conversor a 1/8 de la freqüència
  bcf RP0
  bsf RP1  ; Tria el banc 2
  movlw 0000000B
  movwf ANSEL  ; Posa AN0 com entrada analògica
  bcf RP0
  bcf RP1  ; Tria el banc 0
  movlw 00000001B  ; activa el conversor A/D connectat a AN0
  movwf ADCON0  ; amb el resultat justificat per l'esquerra
  movlw 00001000B  ; Activa el bit 3
  movwf Visualit  ; Ho copia sobre la variable Visualit
  clrf Sentit  ; Inicialment, rotació a la dreta
  clrf Previ  ; L'estat previ del polsador és no premut
Bucle:
  movf Visualit,w  ; Copia la variable Visualit a l'acumulador
  movwf PORTC  ; Copia el resultat sobre els LED
  nop  ; espera un microsegon
  nop  ; espera un microsegon
  nop  ; espera un microsegon
  nop  ; espera un microsegon
  nop  ; espera un microsegon
  bsf GO_DONE  ; Inicia la conversió
  btfsc GO_DONE  ; Quan el bit sigui 0 la conversió haurà acabat
  goto	$-1  ; repetim la línia fins que deixi de ser 0
  movf ADRESH,w  ; Copia els bits superiors a l'acumulador
  addlw 1  ; Li suma 1 i tenim la durada variable del cicle
  movwf Retard2  ; Ho copia a la variable Retard2
RetVar:
  decfsz Retard1,f  ; Decrementa la variable 1
                    ; si dona zero, no es fa la instrucció següent
  goto RetVar  ; Salta, excepte si el resultat ha estat zero
  decfsz Retard2,f  ; Decrementa la variable 2
  goto RetVar  ; Salta, excepte si el resultat ha estat zero
  movlw 13  ; El punt indica que es un valor decimal
  movwf Retard2  ; Comença un altre cicle de durada fixa (10 ms)
Ret10ms:
  decfsz Retard1,f
  goto Ret10ms
  decfsz Retard2,f
  goto Ret10ms
  movlw 00000001B  ; Polsador activat
  movwf Polsador  ; Activem polsador abans de comprovar
  btfsc PORTA,3  ; Mira si està desactivada l'entrada A3
                 ; Si desactivat (premut), no fa la instrucció següent
  clrf Polsador  ; Si no està premut, desactiva polsador
  movf Previ,w  ; Copia Previ a l'acumulador
  xorwf Polsador,w  ; Compara Previ amb Polsador, si són iguals s'activa Z
  btfsc ZERO  ; Si són iguals va a Final
  goto Rotar
  movf Sentit,w  ; Copia Sentit a l'acumulador
  xorlw 00000001B  ; Inverteix el valor
  movwf Sentit  ; I ho guarda a Sentit
Rotar:
  bcf CARRY  ; posa a zero el bit d'arrossegament
             ; Això cal en qualsevol sentit
  btfsc Sentit,0  ; En quin sentit rodem? 
  goto Esquerra  ; 1 = Esquerra
Dreta:  ; Gir a la dreta
  rrf Visualit,f  ; Fa rodar els bits cap a la dreta
                  ; el bit d'arrossegament entra per l'esquerra
                  ; i el bit de la dreta passa a l'arrossegament
  btfsc CARRY  ; Comprova si s'ha activat l'arrossegament
               ; Si no s'ha activat, salta una instrucció
  bsf Visualit,3  ; Si s'ha activat, torna a posar un 1 (0000 1000)
  goto Bucle  ; Repetim-ho...
Esquerra:  ; Gir a l'esquerra
  rlf Visualit,f  ; Fa rodar els bits cap a l'esquerra
  btfss Visualit,4  ; Hem sortit fora dels 4 bits dels LED?
  goto Bucle  ; No, repetim-ho...
  bcf Visualit,4  ; Sí, desactivem el 4
  bsf Visualit,0  ; i tornem a activar el primer
  goto Bucle  ; i repetim-ho...
END main

Si el polsador no funciona, assegureu-vos que heu marcat 3-State on 'Release from Reset' a la finestra de propietats del PICkit 2:

PICkit 2

Hem emprat tres variables que només emmagatzemen un bit (Polsador, Previ i Sentit). Podríem agrupar dues d'elles (Previ i Sentit) en una sola a base de fer servir bits diferents. En el programa següent hem agafat una variable anomenada Memoria on el bit 0 correspon a Previ i el bit 1 a Sentit. Per fer fàcil la comparació, el bit que correspon al polsador ha d'estar en la mateixa posició que en la variable Polsador. No és convenient agrupar Polsador a la mateixa variable ja que si ho fem no podríem fer les comparacions amb xor. En el programa també declarem només una variable Retard però comptant que ocupa dos bytes, així reduïm el nombre d'etiquetes.

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
Polsador EQU 0x20  ; Una variable amb l'estat del polsador (1 = premut)
Memoria EQU 0x21  ; El bit 0 és l'estat previ del polsador i el bit 1 és el sentit de gir
Visualit EQU 0x23  ; Una variable on guardem el que mostraran els LED
Compta EQU 0x24  ; Una variable per comptar iteracions
Retard EQU 0x25  ; Variable per al bucle de retard (2 bytes)
PSECT code, class=CODE, delta=2, abs  ; A l'inici de la memòria
main:
  bsf RP0  ; Tria el banc 1
  movlw 0xFF  ; Posa l'acumulador a FFh (tot uns)
  movwf TRISA  ; Posa tots els bits del port A com a entrada
  clrf TRISC  ; Posa tots els bits del port C com a sortida
  movlw 00010000B
  movwf ADCON1  ; Posa el conversor a 1/8 de la freqüència
  bcf RP0
  bsf RP1  ; Tria el banc 2
  movlw 0000000B
  movwf ANSEL  ; Posa AN0 com entrada analògica
  bcf RP0
  bcf RP1  ; Tria el banc 0
  movlw 00000001B  ; activa el conversor A/D connectat a AN0
  movwf ADCON0  ; amb el resultat justificat per l'esquerra
  movlw 00001000B  ; Activa el bit 3
  movwf Visualit  ; Ho copia sobre la variable Visualit
  clrf Memoria  ; Inicialment, rotació a la dreta i polsador és no premut
Bucle:
  movf Visualit,w  ; Copia la variable Visualit a l'acumulador
  movwf PORTC  ; Copia el resultat sobre els LED
  nop  ; espera un microsegon
  nop  ; espera un microsegon
  nop  ; espera un microsegon
  nop  ; espera un microsegon
  nop  ; espera un microsegon
  bsf GO_DONE  ; Inicia la conversió
  btfsc GO_DONE  ; Quan el bit sigui 0 la conversió haurà acabat
  goto	$-1  ; repetim la línia fins que deixi de ser 0
  movf ADRESH,w  ; Copia els bits superiors a l'acumulador
  addlw 1  ; Li suma 1 i tenim la durada variable del cicle
  movwf Retard+1  ; Ho copia a la variable Retard+1
RetVar:
  decfsz Retard,f  ; Decrementa la variable 1
                    ; si dona zero, no es fa la instrucció següent
  goto RetVar  ; Salta, excepte si el resultat ha estat zero
  decfsz Retard+1,f  ; Decrementa la variable 2
  goto RetVar  ; Salta, excepte si el resultat ha estat zero
  movlw 13  ; El punt indica que es un valor decimal
  movwf Retard+1  ; Comença un altre cicle de durada fixa (10 ms)
Ret10ms:
  decfsz Retard,f
  goto Ret10ms
  decfsz Retard+1,f
  goto Ret10ms
  movlw 00000001B  ; Polsador activat
  movwf Polsador  ; Activem polsador abans de comprovar
  btfsc PORTA,3  ; Mira si està desactivada l'entrada A3
                 ; Si desactivat (premut), no fa la instrucció següent
  clrf Polsador  ; Si no està premut, desactiva polsador
  movf Memoria,w  ; Copia Memoria a l'acumulador
  andlw 00000001B  ; Conserva només el bit 0 (Previ)
  xorwf Polsador,w  ; Compara Previ amb Polsador, si són iguals s'activa Z
  btfsc ZERO  ; Si són iguals va a Final
  goto Rotar
  movf Memoria,w  ; Copia Memoria a l'acumulador
  xorlw 00000010B  ; Inverteix el valor del bit 1 (Sentit)
  movwf Memoria  ; I ho guarda a Sentit
Rotar:
  bcf CARRY  ; posa a zero el bit d'arrossegament
             ; Això cal en qualsevol sentit
  btfsc Memoria,1  ; En quin sentit rodem?
  goto Esquerra  ; 1 = Esquerra
Dreta:  ; Gir a la dreta
  rrf Visualit,f  ; Fa rodar els bits cap a la dreta
                  ; el bit d'arrossegament entra per l'esquerra
                  ; i el bit de la dreta passa a l'arrossegament
  btfsc CARRY  ; Comprova si s'ha activat l'arrossegament
               ; Si no s'ha activat, salta una instrucció
  bsf Visualit,3  ; Si s'ha activat, torna a posar un 1 (0000 1000)
  goto Bucle  ; Repetim-ho...
Esquerra:  ; Gir a l'esquerra
  rlf Visualit,f  ; Fa rodar els bits cap a l'esquerra
  btfss Visualit,4  ; Hem sortit fora dels 4 bits dels LED?
  goto Bucle  ; No, repetim-ho...
  bcf Visualit,4  ; Sí, desactivem el 4
  bsf Visualit,0  ; i tornem a activar el primer
  goto Bucle  ; i 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.