Progetti - PIC

 

1 LED - 5 funzioni


Passare il sorgente ad un altro PIC.

Come detto ampiamente nel Corso Assembly,  se le risorse necessarie al progetto sono presenti in chip diversi da quello che è stato utilizzato in origine, la trasposizione del sorgente è possibile e richiede solamente che si modifichino le parti che riguardano le caratteristiche hardware specifiche del nuovo PIC.

Quindi, occorrerà riconoscere cosa differenzia il chip originale da quello che si desidera utilizzare.

Una nota indispensabile:
Le pagine seguenti sono state scritte esclusivamente a scopo didattico.
Dovrebbe essere chiaro che i Midrange, pur essendo ancora in produzione, non sono per niente competitivi con in  più recenti Enhanced Midrange, sia come prestazioni che come facilità di uso, nè tanto meno per il costo: ad esempio, alla data della stesura di queste pagine, 12F1571-I/P costa 0,58€, pur essendo enormemente superiore al vecchio 12F675-I/P che costa 0,91€.
Quindi, ha senso scrivere nuovo codice per vecchi componenti solamente se li abbiamo nel cassetto e che, se non li usassimo qui, resterebbero inutilizzati.

Proviamo, quindi, a convertire il sorgente per un 12F675. Si tratta di un vecchio Midrange, abbastanza diffuso.

Le differenze tra 10F220/222 e 12F675 sono parecchie, trattandosi di elementi appartenenti a famiglie diverse. Esse riguardano:

  • la struttura della memoria, che è su un banco solo per i 10F e su due per 12F675. Questo richiede di prestare attenzione al cambio di banco.
  • il convertitore AD che è a 10 bit e non a 8 e che presenta una struttura di registri di controllo diversa
  • l'oscillatore del clock, che presenta molte più opzioni
  • la gestione dei WPU
  • la presenza di un comparatore, che, al default, è abilitato

Vediamo il listato del sorgente modificato in cui in rosso sono riportate le righe aggiunte o modificate e in verde le motivazioni. Ci si potrà rendere conto delle differenze comparando il listato con quello visto in precedenza.

Per le connessioni hardware, esse sono chiaramente indicate nel sorgente.
Rispetto all'originale abbiamo:

  • LED verde su GP5
  • LED rosso su GP4
  • Ingresso analogico su GP2
  • GP3 utilizzato come MCLR

Questo consente di avere liberi GP0/GP1 per la programmazione e per un debug on circuit a scopo didattico (dato che questo tipo di chip non dispone di motore ICD integrato, serve l'header AC162050 ).
Per la stessa ragione nella configurazione abbiamo PWRTE=OFF e MCLR=ON.

Va ricordato di aggiungere le resistenze in serie al LED e un pull-up su GP3/MCLR.

;********************************************************************
;--------------------------------------------------------------------
; indicare cambio processore nella documentazione
; Titolo        : Indicatore temperatura per dissipatori
;                 12F675 + sensore MCP9701
; Data          : 19-04-2020
; Modificato il :
; Versione      : V0.0
; Ref. hardware :
; Autore        : afg
;
;--------------------------------------------------------------------
;********************************************************************
; indicare nuovo layout
; Impiego pin :
; ----------------
; 12F675 @ 8 pin DIP
;
;        |¯¯\/¯¯|
;   Vdd -|1    8|- Vss
;   GP5 -|2    7|- GP0
;   GP4 -|3    6|- GP1
;   GP3 -|4    5|- GP2
;        |______|
;
; DIP 
; Vdd             1: ++
; GP5/T1CKI/CLKIN 2: Out LED Verde 
; GP4//CLKOUT/T1G 3: Out LED Rosso
; GP3/MCLR        4: In  RA3
; GP2/T0CKI/COUT  5: AN2 Analog in
; GP1/AN1/ICSPCLK 6: In
; GP0/AN0/ICSPDAT 7: In
; Vss             8: --

;
;********************************************************************
;####################################################################
; risorse processore
; Processor selection
   #include <p12f675.inc>
   radix dec

;####################################################################
;
;====================================================================
; CONFIGURAZIONE =
;====================================================================; ;configurazione nuovo processore
; no MCLR, Osc interno non clockout, Bor On, PWRT on, no WDT, no protezioni

 __config _MCLRE_OFF & _INTRC_OSC_NOCLKOUT & _BOREN_ON & _WDTE_OFF & _PWRTE_ON & _CP_OFF & _CPD_OFF

;####################################################################

;********************************************************************
;* ASSEGNAZIONI LOCALI *
;********************************************************************
; Uscita LMCP9701 19.5 mV/°C + 400mV
; temp Vout ADCdec ADChex
k1 equ .60 ; 40°C -> 1.180V -> 60 -> 3Ch
k2 equ .70 ; 50°C -> 1.375V -> 70 -> 46h
k3 equ .80 ; 60°C -> 1.570V -> 80 -> 50h
k4 equ .90 ; 70°C -> 1.765V -> 90 -> 5Ah
k5 equ .100 ; 80°C -> 1.960V -> 100 -> 64h

;====================================================================
; DEFINIZIONE DI IMPIEGO DEI PORT
;====================================================================
; cambio definizione dei port
;sGPIO map
; | 5   | 4   | 3   | 2   | 1   |  0  |
; |-----|-----|-----|-----|-----|-----|
; | LEDV| LEDR! MCLR| AN2 |     |     |

;
#define LEDR sGPIO,GP4 ; LED Rosso tra pin e Vss
#define LEDV sGPIO,GP5 ; LED Verde

;####################################################################
;====================================================================
;= MEMORIA RAM =
;====================================================================
; cambio indirizzo area ram
; RAM 2 banchi

  CBLOCK 0x20 ; area RAM da 0x20 a 0x5F
    sGPIO     ; shadow I/O
    d1        ; contatori per Delay
    d2
    d3
  ENDC

;====================================================================
;= LOCAL MACROS =
;====================================================================
; local MACRO
; sGPIO->GPIO
EXEC MACRO
    movf sGPIO, W
    movwf GPIO
     ENDM
; accende led Verde
Verde_on MACRO
    bsf LEDV
         ENDM
; accende led Rosso
Rosso_on MACRO
    bsf LEDR
         ENDM
; spegne led Verde
Verde_of MACRO
    bcf LEDV
         ENDM
; spegne led Rosso
Rosso_of MACRO
    bcf LEDR
         ENDM
; toggle rosso
Rosso_tg MACRO
; cambio maschera per gpio
    movlw b'01000' ; toggle rosso
    xorwf sGPIO, f
         ENDM
; toggle verde
Verde_tg MACRO
; cambio maschera per gpio
    movlw b'10000' ; toggle verde
    xorwf sGPIO, f
         ENDM

;####################################################################
;====================================================================
;= RESET ENTRY =
;====================================================================
; Reset Vector
    ORG 0x00

;####################################################################
;====================================================================
;= MAIN PROGRAM =
;====================================================================
MAIN:
; inizializzazioni I/O al reset
; disabilita comparatore
   banksel CMCON
   movlw   0x07
   movwf   CMCON


; Diversa struttura di OPTION_REG
; OPTION default '11111111'
    banksel OPTION_REG
    movlw b'01010111'
          ; 0------- !GPPU abilitato
          ; -1------ INTEDG done
          ; --0----- TMR0 clock interno
          ; ---1---- T0SE done
          ; ----0--- prescaler al Timer0
          ; -----111 1:256
    movlw OPTION_REG

; setup ADC 
    banksel ANSEL
    movlw b'00110010' ; FRC, ANS2
          ; 0------- 
          ; -011---- FRC
          ; ----0100 ANS2
    movwf ANSEL

    banksel ADCON0
    movlw b'00001001' ; left just, ADC on, CH2
          ; 0------- ADFM left
          ; -0------ Vref=Vdd
          ; --00---- 0
          ; ----10-- CH2
          ; ------0- GO
          ; -------1 ADC enabled
    movwf ADCON0

; GPIO
; diversa struttura registri
    banksel GPIO
    clrf    GPIO ; preset GPIO latch a 0
    banksel TRISIO
    movlw   b'11000' ; GP5:4 = out
    movlw   TRISIO ; al registro direzione


;----------------------------------------------------------
;--------------------- mainloop ---------------------------
; tutto eseguito in Banco 0
;
anche ReadAD ha ADCON0 in Banco 0
    banksel GPIO
    Verde_of   ; LED off
    Rosso_of
    EXEC

ml call ReadAD ; read ADC

;range evaluation
   movlw k1    ; < k1?
; ADC a 10 bit 
   subwf ADRESH, w
   skpc
    goto sel1
n1 movlw k2 ; < k2?
   subwf ADRESH, w
   skpc
    goto sel2
n2 movlw k3 ; < k3?
   subwf ADRESH, w
   skpc
    goto sel3
n3 movlw k4 ; < k4?
   subwf ADRESH, w
   skpc
    goto sel4
n4 goto sel5 ; > k4?

; LED driving
sel1:
   Verde_on       ; T<40°C verde fisso
   Rosso_of
   goto selxec
sel2:             ; 40<T<50°C lampeggio verde/giallo
   Verde_on       ; verde fisso +
   Rosso_tg       ; toggle rosso
   goto selxec
sel3: ; 50<T<60°C giallo fisso
   Verde_on       ; verde + rosso
   Rosso_on
   goto selxec
sel4: ; 60<T<70°C lampeggio giallo/rosso
   Rosso_on       ; rosso fisso +
   Verde_tg       ; toggle verde
   goto selxec
sel5:             ; T>70°C rosso fisso
   Verde_of
   Rosso_on

selxec EXEC       ; drive LED

   call Delay025s ; 250ms delay
   call Delay025s ; 250ms delay

   goto ml        ; close loop


;====================================================================
;= SUBROUTINES =
;====================================================================
; Read ADC 
ReadAD: 
; cambio banco
   banksel ADCON0
   bsf     ADCON0, 1 ; start conversion
loopADC
   nop
   btfsc   ADCON0, 1 ; wait for ‘DONE’
    goto   loopADC
   retlw   0

; Delay = 0.25 seconds
; Clock frequency = 4 MHz
; 0.25 seconds = 250000 cycles
Delay025s            ;249993 cycles
   movlw 0x4E
   movwf d1
   movlw 0xC4
   movwf d2
Delay025s_0:
   decfsz d1, f
    goto $+2
   decfsz d2, f
    goto Delay025s_0
   goto $+1          ;3 cycles
   nop
   retlw 0           ;4 cycles (including call)

;********************************************************************
; ===================================================================
; = THE END =
;====================================================================
;********************************************************************
   END

Se avete seguito il Corso Assembly per Baseline e Midrange non dovreste avere alcun  problema a comprendere le varie azioni.

 


Il progetto è stato sviluppato su MPLAB X: anche se MPLAB IDE vecchie versioni è adeguato, non è più in sviluppo e quindi non ha particolare senso continuare ad usarlo. MPLAB X oltre ad essere la versione attuale, presenta molti vantaggi pratici.


Variazione.

Per quanto riguarda la variazione proposta in origine, si procede dello stesso modo per passare il sorgente ad un diverso PIC.

;********************************************************************
;--------------------------------------------------------------------
;
; Titolo        : Indicatore tensione batteria 12V
;                 PIC12F675
; Data          : 20-04-2020
; Modificato il :
; Versione      : V0.0
; Ref. hardware :
; Autore        : afg
;
;--------------------------------------------------------------------
;********************************************************************
;
; Impiego pin :
; ----------------
; 12F675 @ 8 pin DIP
;
;        |¯¯\/¯¯|
;   Vdd -|1    8|- Vss
;   GP5 -|2    7|- GP0
;   GP4 -|3    6|- GP1
;   GP3 -|4    5|- GP2
;        |______|
;
; DIP 
; Vdd             1: ++
; GP5T1CKI/CLKIN  2: Out LED Verde 
; GP4//CLKOUT/T1G 3: Out LED Rosso
; GP3/MCLR        4: In  RA3
; GP2/T0CKI/COUT  5: AN2 Analog in
; GP1/AN1/ICSPCLK 6: In
; GP0/AN0/ICSPDAT 7: In
; Vss             8: --

;
;********************************************************************
;####################################################################
;
; Note :
;
;********************************************************************
;;####################################################################
; Processor selection
; risorse processore

  #include <p12f675.inc>
  radix dec

;####################################################################
;
;====================================================================
; CONFIGURAZIONE =
;====================================================================
;configurazione nuovo processore
; no MCLR, Osc interno non clockout, Bor On, PWRT on, no WDT, no protezioni

  __config _MCLRE_OFF & _INTRC_OSC_NOCLKOUT & _BOREN_ON & _WDTE_OFF & _PWRTE_ON & _CP_OFF & _CPD_OFF

;####################################################################

;********************************************************************
;* ASSEGNAZIONI LOCALI *
;********************************************************************
; Partitore 1:4
; Vin ADCdec ADChex
k1 equ .134 ; 10.5V -> 134 -> 86h
k2 equ .146 ; 11.5V -> 146 -> 92h
k3 equ .153 ; 12V -> 153 -> 99h
k4 equ .184 ; 14,5 -> 184 -> B8h

;====================================================================
; DEFINIZIONE DI IMPIEGO DEI PORT
;====================================================================
; cambio definizione dei port
;sGPIO map
; | 5   | 4   | 3   | 2   | 1   |  0  |
; |-----|-----|-----|-----|-----|-----|
; | LEDV| LEDR! MCLR| AN2 |     |     |

;
#define LEDR sGPIO,GP4 ; LED Rosso tra pin e Vss
#define LEDV sGPIO,GP5 ; LED Verde


;####################################################################
;====================================================================
;= MEMORIA RAM =
;====================================================================
; cambio indirizzo area ram
; RAM 2 banchi
  CBLOCK 0x20 ; area RAM da 0x20 a 0x5F
    sGPIO     ; shadow I/O
    d1        ; contatori per Delay
    d2
    d3
  ENDC

;====================================================================
;= LOCAL MACROS =
;====================================================================
; local MACRO
EXEC MACRO
    movf sGPIO, W
    movwf GPIO
     ENDM
; accende led Verde
Verde_on MACRO
    bsf LEDV
ENDM
; accende led Rosso
Rosso_on MACRO
    bsf LEDR
         ENDM
; spegne led Verde
Verde_of MACRO
    bcf LEDV
         ENDM
; spegne led Rosso
Rosso_of MACRO
    bcf LEDR
         ENDM
; toggle rosso
Rosso_tg MACRO
; cambio maschera per gpio
    movlw b'01000' ; toggle rosso
    xorwf sGPIO, f
         ENDM
; toggle verde
Verde_tg MACRO
; cambio maschera per gpio
    movlw b'10000' ; toggle verde
    xorwf sGPIO, f
         ENDM


;####################################################################
;====================================================================
;= RESET ENTRY =
;====================================================================
; Reset Vector
   ORG 0x00

;####################################################################
;====================================================================
;= MAIN PROGRAM =
;====================================================================
MAIN:
; inizializzazioni I/O al reset
; disabilita comparatore
   banksel CMCON
   movlw   0x07
   movwf   CMCON


; Diversa struttura di OPTION_REG
; OPTION default '11111111'
    banksel OPTION_REG
    movlw b'01010111'
          ; 0------- !GPPU abilitato
          ; -1------ INTEDG done
          ; --0----- TMR0 clock interno
          ; ---1---- T0SE done
          ; ----0--- prescaler al Timer0
          ; -----111 1:256
    movlw OPTION_REG


; setup ADC 
    banksel ANSEL
    movlw b'00110010' ; FRC, ANS2
          ; 0------- 
          ; -011---- FRC
          ; ----0100 ANS2
    movwf ANSEL

    banksel ADCON0
    movlw b'00001001' ; left just, ADC on, CH2
          ; 0------- ADFM left
          ; -0------ Vref=Vdd
          ; --00---- 0
          ; ----10-- CH2
          ; ------0- GO
          ; -------1 ADC enabled
    movwf ADCON0

; GPIO
; diversa struttura registri
    banksel GPIO
    clrf    GPIO ; preset GPIO latch a 0
    banksel TRISIO
    movlw   b'11000' ; GP5:4 = out
    movlw   TRISIO ; al registro direzione



;----------------------------------------------------------
;--------------------- mainloop ---------------------------
;----------------------------------------------------------
; tutto eseguito in Banco 0
;
anche ReadAD ha ADCON0 in Banco 0
    banksel GPIO

    Verde_of ; LED off
    Rosso_of
    EXEC
    movf  sGPIO,w
    movwf d3

ml call ReadAD ; read ADC

;range evaluation
   movlw k1 ; < k1?
   subwf ADRESH, w
   skpc
    goto sel1
n1 movlw k2 ; < k2?
   subwf ADRESH, w
   skpc
    goto sel2
n2 movlw k3 ; < k3?
   subwf ADRESH, w
   skpc
    goto sel3
n3 movlw k4 ; < k4?
   subwf ADRESH, w
   skpc
    goto sel4
n4 goto sel5 ; > k4?

; LED driving
sel1:
   Verde_of ; Vin < 10.5V Rosso
   Rosso_tg ; rosso lampeggiante
   goto  selxec
sel2: ; 10.5 < Vin < 11.5V
   Verde_of ; rosso fisso
   Rosso_on
   goto  selxec
sel3: ; 11.5 < Vin < 12V
   Verde_on ; giallo fisso
   Rosso_on
   goto  selxec
sel4: ; 12 < Vin < 14.5V
   Rosso_of ; verde fisso
   Verde_on
   goto  selxec
sel5: ; Vin > 14.5
   btfss sGPIO,GP1 ; se GP1 e 2 sono uguali, differenzia
    goto a1        ; per usare il ciclo come cadenza per il
   btfss sGPIO,GP2 ; lampeggio
    goto lamp
   goto  adj
a1 btfsc sGPIO, GP2
    goto lamp
adj:               ; GP4=GP5 - differenzia
   Rosso_on
   Verde_of

lamp:
   Verde_tg        ; rosso/verde lampeggiante
   Rosso_tg

selxec:
   EXEC            ; drive LED
   call Delay025s  ; 250ms delay

   goto ml         ; close loop


;********************************************************************
;====================================================================
;= SUBROUTINES =
;====================================================================
;********************************************************************
; Read ADC
ReadAD: 
   banksel ADCON0
   bsf     ADCON0, 1 ; start conversion
loopADC nop
   btfsc ADCON0, 1 ; wait for ‘DONE’
    goto loopADC
   retlw 0

; Delay = 0.25 seconds
; Clock frequency = 4 MHz
; 0.25 seconds = 250000 cycles
Delay025s ;249993 cycles
   movlw  0x4E
   movwf  d1
   movlw  0xC4
   movwf  d2
Delay025s_0
   decfsz d1, f
    goto  $+2
   decfsz d2, f
    goto  Delay025s_0
   goto $+1 ;3 cycles
   nop
   retlw 0  ;4 cycles (including call)

; ===================================================================
; = THE END =
;====================================================================
  END

Come per il programma precedente, si potranno variare sia gli effetti luminosi del LED sia il lampeggio, modificando il sorgente e ricompilando.

 



Un confronto.

Possiamo impiegare qualsiasi altro PIC, ma, restando nell'ambito degli 8bit, la scelta non può cadere che sugli Enhanced Midrange. In particolare possiamo utilizzare 12F1572 (o 12F1571).

Anche qui abbiamo alcune differenze tra il 10F e i nuovi 12F1xxx. Queste riguardano:

  • la disponibilità del registro LATA che evita l'uso della shadow per scrivere gli I/O
     
  • un oscillatore più complesso. Il default all'accensione è 500kHz. Anche se non è necessario per l'esecuzione, lo portiamo a 4MHz per uniformità con l'originale e per utilizzare la stessa routine di ritardo
     
  • la memoria RAM con un'area shared visibile da tutti i banchi; questo evita la necessità di tenere sotto controllo il banking per la RAM.
     
  • un elevato numero di banchi su ci sono disposti i vari SFR; l'uso intensivo di banksel evita qualsiasi errore di banking nella selezione degli SFR.
     
  • il weak pull-up integrato automaticamente attivato su MCLR, cosa che evita la necessità di aggiungere un pull up esterno. Nell'esempio, abbiamo attivato i wpu sui pin lasciati come ingressi e non utilizzati (ma, ovviamente, non su AN2).
     
  • una diversa struttura degli SFR di controllo del modulo ADC che richiede una diversa programmazione
     
  • il risultato della conversione su 10 bit, di cui usiamo solo gli 8 più significativi in ADRESH.

Anche qui abbiamo:

  • LED verde su RA5
  • LED rosso su RA4
  • Ingresso analogico su RA2
  • RA3 utilizzato come MCLR

Questo consente di avere liberi RA0/RA1 per la programmazione e per scopo didattico: questo tipo di chip dispone di motore ICD integrato ed è possibile effettuare un debug on circuit con il semplice PICKIT3.
Per la stessa ragione nella configurazione abbiamo PWRTE=OFF e MCLR=ON.

Va ricordato di :

  • aggiungere le resistenze in serie al LED
  • ma non occorre alcun pull-up su RA3/MCLR perchè è integrato.

Come in precedenza, in rosso le variazioni.

;********************************************************************
;--------------------------------------------------------------------
; Titolo        : Indicatore temperatura per dissipatori
;                 PIC12F1572 + sensore MCP9701
; Data          : 20-04-2020
; Modificato il :
; Versione      : V0.0
; Ref. Hardware : 12F1571/2
; Autore        : afg
;
;--------------------------------------------------------------------
;********************************************************************
; Impiego pin :
; ----------------
; 12F1571/2 @ 8 pin
;
;           |¯¯\/¯¯|
;      Vdd -|1    8|- Vss
;      RA5 -|2    7|- RA0
;      RA4 -|3    6|- RA1
; RA3/MCLR -|4    5|- RA2
;           |______|
;
; Vdd 1: ++
; RA5/OSC1/CLKIN 2: Out LED verde
; RA4/OSC2/CLKOUT 3: Out LED rosso
; RA3/!MCLR/VPP 4: MCLR
; RA2 5: In AN2
; RA1/ICSPCLK 6: In nc
; RA0/ICSPDAT 7: In nc
; Vss 8: --
;
;********************************************************************
;####################################################################
; Processor selection
    #include <p12f1572.inc>
    radix dec

;####################################################################
;
;====================================================================
;                       CONFIGURAZIONE =
;====================================================================
; intosc, no pll, no clockout, no wdt, no pwrt, no bor, mclr, no prot
; no stv, no lvp

 __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF
 __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_LO & _LPBOREN_OFF & _LVP_OFF


;####################################################################

;********************************************************************
;*                        ASSEGNAZIONI LOCALI                       *
;********************************************************************
; Uscita LMCP9701 19.5 mV/°C + 400mV
;             temp      Vout  ADCdec ADChex
k1 equ .60  ; 40°C -> 1.180V -> 60 -> 3Ch
k2 equ .70  ; 50°C -> 1.375V -> 70 -> 46h
k3 equ .80  ; 60°C -> 1.570V -> 80 -> 50h
k4 equ .90  ; 70°C -> 1.765V -> 90 -> 5Ah
k5 equ .100 ; 80°C -> 1.960V -> 100 -> 64h

;====================================================================
; DEFINIZIONE DI IMPIEGO DEI PORT
;====================================================================
;PORTA map
; | 5 | 4 | 3 | 2 | 1 | 0 |
; |-----|-----|-----|-----|-----|-----|
; | LEDV| LEDR| MCLR| AN2 | | |
;
#define LEDR LATA,LATA4 ; LED Rosso tra pin e Vss
#define LEDV LATA,LATA5 ; LED Verde

;####################################################################
;====================================================================
;= MEMORIA RAM =
;====================================================================
; RAM shared
  CBLOCK 0x70 
    d1 ; contatori per Delay
    d2
  ENDC

;====================================================================
;=                      LOCAL MACROS                                =
;====================================================================
; local MACRO
; accende led Verde
Verde_on MACRO
    bsf LEDV
         ENDM
; accende led Rosso
Rosso_on MACRO
    bsf LEDR
         ENDM
; spegne led Verde
Verde_of MACRO
    bcf LEDV
         ENDM
; spegne led Rosso
Rosso_of MACRO
    bcf LEDR
         ENDM
; toggle rosso
Rosso_tg MACRO
   movlw b'00010000' ; toggle rosso
   xorwf LATA, f
         ENDM
; toggle verde
Verde_tg MACRO
   movlw b'00100000' ; toggle verde
   xorwf LATA, f
         ENDM

;####################################################################
;====================================================================
;= RESET ENTRY =
;====================================================================
; Reset Vector
    ORG 0x00

;####################################################################
;====================================================================
;= MAIN PROGRAM =
;====================================================================
MAIN:
; inizializzazioni I/O al reset
; clock 4MHz
   banksel OSCCON
   movlw   b'01101010' ; no pll, 4MHz, intosc
   movwf   OSCCON


; inizializzazione ADC 
; selezione ingressi analogici
banksel ANSELA
   movlw b'00000100' ; ANS2
   movwf ANSELA
; setup ADC
   banksel ADCON0
   movlw b'00001001' ; ADC on, CH2
         ; 0------- -
         ; -00010-- AN2
         ; ------0- GO
         ; -------1 ADC enabled
   movwf ADCON0
   movlw b'01110000' ; Left, FRC, Vdd
         ; 0------- left adj.
         ; -111---- FRC
         ; ----00-- -
         ; ------00 Vdd
   movwf ADCON1

; inizializzazione IO
   banksel LATA
   clrf    LATA        ; led spenti
   banksel TRISA
   movlw   b'00001111' ; RA5:4 = out
   movwf   TRISA       ; al registro direzione
; wpu sugli ingressi non utilizzati RA1:0
   banksel WPUA
   movlw   b'00000011'
   movwf   WPUA
   banksel OPTION_REG
   bcf     OPTION_REG,NOT_WPUEN

;--------------------- mainloop ---------------------------

ml call ReadAD          ; read ADC

;range evaluation
   banksel ADRESH
   movlw   k1           ; < k1?
   subwf   ADRESH, w
   skpc
    goto   sel1
n1 movlw   k2           ; < k2?
   subwf   ADRESH, w
   skpc
    goto   sel2
n2 movlw   k3           ; < k3?
   subwf   ADRESH, w
   skpc
    goto   sel3
n3 movlw   k4           ; < k4?
   subwf   ADRESH, w
   skpc
    goto   sel4
n4 goto    sel5         ; > k4?

; LED driving
sel1:
   banksel LATA 
   Verde_on             ; T<40°C verde fisso
   Rosso_of
   goto selxec
sel2:                   ; 40<T<50°C lampeggio verde/giallo
   banksel LATA 
   Verde_on             ; verde fisso +
   Rosso_tg             ; toggle rosso
   goto selxec
sel3:                   ; 50<T<60°C giallo fisso
   banksel LATA 
   Verde_on             ; verde + rosso
   Rosso_on
   goto    selxec
sel4:                   ; 60<T<70°C lampeggio giallo/rosso
   banksel LATA 
   Rosso_on             ; rosso fisso +
   Verde_tg             ; toggle verde
   goto    selxec
sel5:                   ; T>70°C rosso fisso
   banksel LATA 
   Verde_of
   Rosso_on
selxec:
   call    Delay025s    ; 250ms delay
   call    Delay025s    ; 250ms delay

goto ml                 ; close loop

;====================================================================
;= SUBROUTINES =
;====================================================================
; Read ADC
ReadAD: 
   banksel ADCON0
   bsf     ADCON0, GO  ; start conversion
loopADC nop
   btfsc   ADCON0, GO  ; wait for ‘DONE’
    goto   loopADC
   retlw 0

; Delay = 0.25 seconds @ 4 MHz
; 0.25 seconds = 250000 cycles
Delay025s:             ;249993 cycles
   movlw 0x4E
   movwf d1
   movlw 0xC4
   movwf d2
Delay025s_0
   decfsz d1, f
    goto $+2
   decfsz d2, f
    goto Delay025s_0
   goto $+1           ;3 cycles
   nop
   retlw 0            ;4 cycles (including call)

; ===================================================================
; = THE END =
;====================================================================
   END

Utilizzando lo stesso principio possiamo convertire anche il programma di controllo batteria, che non stiamo a dettagliare, ma che trovate nel relativo progetto.



 

Copyright © afg. Tutti i diritti riservati.
Aggiornato il 22/04/20.