Esercitazioni ASM - PIC18

 


ESERCITAZIONE # 6


Modifica sull' Esercitazione 5 e programmazione del firmware

 

In questa esercitazione effettuiamo qualche modifica al sorgente dell' Esercitazione precedente:

  • Innanzitutto, utilizziamo un numero maggiore di LED, per avere un effetto ottico migliore.
  • Poi, inseriamo una breve pausa tra ogni ciclo di lampeggio, per evidenziare maggiormente il cambio del clock

Utilizziamo 4 LED collegati ai primi 4 pin di PORTC e li facciamo accendere alternativamente, a coppie.

E modifichiamo il flow chart del ciclo principale per l' aggiunta della pausa.

Sostanzialmente, si tratta di aggiungere semplicemente delle routine di attesa dopo ogni cambio di clock.

Le routine saranno sempre realizzate come per gli altri esempi, onde evitare per ora calcoli sui tempi di ciclo delle istruzioni, utilizziando il calcolatore disponibile in rete per la creazione di ritardi di tempo, il noto Delay Generator di Nicolai Golovchenko.

Nel sorgente il tempo di pausa è di 1 secondo, ma potrà essere variato a piacere modificando le impostazioni della routine di attesa.

Il nostro esercizio prevede di collegare  LED ai bit 3:0 di PORTC , che saranno accesi a coppie.
La gestione relativa è, anche qui, realizzata con macro per semplificare il sorgente.

Per l' esecuzione pratica si dovranno semplicemente collegare i pin PC0:3 ai LED della UniBoard (o del proprio hardware).

Il Pickit è inserito direttamente nella spina ICSP/ICD e permette un debug passo passo delle istruzioni.


Per chi non avesse chiare le connessioni, qui trova di seguito una pagina dedicata.

L' esercizio richiede le seguenti risorse:

  • MPLAB IDE installato
  • Pickit3 (o Pickit2)
  • 28-40pin UniBoard con PIC18F2321 0 4321 (o 2221 o 4221 o altro hardware similare)
  • quattro cavetti jumper da 14-15 cm

Il listato sorgente è una estensione di quello già visto negli altri esercizi e che fa da base per tutti i seguenti, aggiungendo gli elementi necessari al nuovo lavoro.


Vediamo solamente le differenze da quello dell' esercizio 5.

Viene introdotta una selezione per la compilazione in ambiente debug o in release.

Una condizione if/else/endif consente di escludere dalla compilazione uno o l' altro blocco di elementi.

  • Se la variabile DebugOn è uguale a 1, viene compilato il set di CONFIG per il debug.
  • Se DebugOn è uguale a 0, viene compilato il set per la release.

Lo scambio tra le due condizioni si ottiene semplicemente commentando (aggiungendo ; a inizio riga) o de commentando (togliendo il ; iniziale) le linee voluta.
Questa tecnica consente di avere un solo listato per ottenere sia l' oggetto per il debug sia quello per la release finale.

;---------------------------------------------------------------------
; Condizione di compilazione

; Selezionare la modalità richiesta
DebugOn equ 1 ; condizioni di debug
;DebugOn equ 0 ; condizioni di release
;---------------------------------------------------------------------
; Condizioni comuni
; Single-Supply ICSP disabled

 CONFIG LVP = OFF
; Uso dell' oscillatore interno, port su RA7 e FOSC/4 su RA6
 CONFIG OSC = INTIO1
; Funzione del pin MCLR abilitata
 CONFIG MCLRE = ON
; WDT disabilitato
 CONFIG WDT = OFF
; Brown-out in hardware only
 CONFIG BOR = ON

; Condizione di debug
  #if DebugOn == 1
; Background debugger enabled su RB6 e RB7 per il debug con il
; Pickit o altro, attraverso ICSP/ICD

 CONFIG DEBUG = ON
; PWRT disabled per il debug
 CONFIG PWRT = OFF
; Soglia BOR 4.2V
 CONFIG BORV = 1

  #else
; Condizioni di release
; debug disabilitato

 CONFIG DEBUG = OFF
; BORV a 2.7V per alimentazione a batteria
 CONFIG BORV = 2 
; Power On Timer abilitato
 CONFIG PWRT = ON
  #endif

Così come è scritta, quest' area equivale dunque a:

;---------------------------------------------------------------------
; Condizione di compilazione

; Selezionare la modalità richiesta
DebugOn equ 1 ; condizioni di debug
;DebugOn equ 0 ; condizioni di release
;---------------------------------------------------------------------
; Condizioni comuni
; Single-Supply ICSP disabled

  CONFIG LVP = OFF
; Uso dell' oscillatore interno, port su RA7 e FOSC/4 su RA6
  CONFIG OSC = INTIO1
; Funzione del pin MCLR abilitata
  CONFIG MCLRE = ON
; WDT disabilitato
  CONFIG WDT = OFF
; Brown-out in hardware only
  CONFIG BOR = ON

; Condizione di debug
; Background debugger enabled su RB6 e RB7 per il debug con il
; Pickit o altro, attraverso ICSP/ICD

  CONFIG DEBUG = ON
; PWRT disabled per il debug
  CONFIG PWRT = OFF
; Soglia BOR 4.2V
  CONFIG BORV = 1

Nel caso in cui si selezionasse l' altra possibilità, sarebbe equivalente ad avere scritto:.

;---------------------------------------------------------------------
; Condizione di compilazione

; Selezionare la modalità richiesta
;DebugOn equ 1 ; condizioni di debug
DebugOn  equ 0 ; condizioni di release
;---------------------------------------------------------------------
; Condizioni comuni
; Single-Supply ICSP disabled

  CONFIG LVP = OFF
; Uso dell' oscillatore interno, port su RA7 e FOSC/4 su RA6
  CONFIG OSC = INTIO1
; Funzione del pin MCLR abilitata
  CONFIG MCLRE = ON
; WDT disabilitato
  CONFIG WDT = OFF
; Brown-out in hardware only
  CONFIG BOR = ON

; Condizioni di release
; debug disabilitato

  CONFIG DEBUG = OFF
; BORV a 2.7V per alimentazione a batteria
  CONFIG BORV = 2 
; Power On Timer abilitato
  CONFIG PWRT = ON

Nell' area degli Equates inseriamo alcune definizioni che ci serviranno durante il programma e possiamo anche creare due macro per il comando dei LED, con la finalità di rendere più leggibile il listato.

;----------------------------------------------------------------------
; Equates 
;
; Numero lampeggi a 1 MHz
nlamp  equ  .5

;----------------------------------------------------------------------
; Macros
;
; Gestione on-off dei LED collegati a PC0 e PC2 contemporaneamente
Led1On   MACRO
     
bsf   LATC,0
     
bsf   LATC,2
       
ENDM
Led1Off
  MACRO
     
bcf   LATC,0
      bcf   LATC,2
       
ENDM 
    
; Gestione on-off dei LED collegati a PC1 e PC3 contemporaneamente
Led2On   MACRO
     
bsf   LATC,1
     
bsf   LATC,3
       
ENDM
Led2Off
  MACRO
     
bcf   LATC,1
     
bcf   LATC,3
       
ENDM  

; spegne tutti i lED azzerando i bit 3:0 di PORTC
LedOff
  MACRO
     
movlw b'11110000'
     
andwf LATC,f
       
ENDM  

 


Per quanto riguarda il "programma" vero e proprio, si tratta solo dell' aggiunta della chiamata alla pausa intermedia.

Va considerato che le routines di tempo usate si basano sul clock per il calcolo della loro durata; nell' eserciz è utilizzata una pausa di 0.5 secondi con un clock di 1MHz.
Però, durante il funzionamento, è proprio il clock a cambiare: per avere una durata costante della pausa anche la sua lunghezza deve variare di conseguenza.

Per semplicità viene usato lo stesso meccanismo impiegato per i cicli di lampeggio, ovvero si ripete un numero di volte crescente una stessa temporizzazione per avere uguale durata con il variare del clock.
Infatti, se la temporizzazione vale 1/2 secondo a 1MHz, occorrerà ripeterla due volte con un clock di 2 MHz per avere sempre 1/2 secondo. Così sarà necessario ripeterla 4 volte a 4 MHZ e 8 volte a 8 MHz.


Va notato che se la pausa base, calcolata a 1MHz, è perfettamente precisa (in funzione della precisione dell' oscillatore, ovviamente), il ripeterla n volte porta ad una lieve imprecisione dovuta all' aggiunta delle istruzioni di ripetizione, la cui durata andrebbe calcolata per ottenere un tempo esatto. 
Però si tratta di pochi micro secondi, che in questa applicazione sono del tutto trascurabili. Quindi non viene effettuata alcuna correzione.

Il numero dei lampeggi per ciclo è fissato in fase di compilazione dalla variabile nlamp.
Il numero delle ripetizioni è fissato a seguito di ogni cambio del clock caricando in WREG un numero proprozionale al clock.

; Ciclo primario
mainloop
       movlw  nlamp        ; numero lampeggi
       call   ciclo        ; lampeggio

       m18SetIntClock 2    ; clock 2 MHz
      
m18IntOscStable     ; attendi stabilizzazione oscillatore
       movlw  nlamp        ; numero lampeggi
       call   ciclo        ; lampeggio
      
movlw  .2           ; numero ripetizioni cicli pausa
      
call   Pausa        ; pausa 1 s

; ecc..

Si potrebbe anche accorpare la pausa nella routine di ciclo lampeggio, ma si è preferito averla come elemento separato che può essere modificato a piacere.
La prima istruzione della routine recupera da WREG il valore da applicare alle ripetizoni, che viene salvato nella locazione di RAM  counter . Sarà questo counter ad essere decrementato per calcolare il numero delle ripetizoni.

; Pausa
; La routine si basa sulla ripetizione di un ciclo base di 
; 1 s a 1MHz di clock
; per cui con clock a 2 MHz il ciclo sarà ripetuto due volte,
; 4 volte con 4 MHz e 8 volte con 8 MHz
; in modo da mantenere sempre una pausa di circa 1 secondo
Pausa  movf   counter      ; numero cicli pausa da eseguire
pas1   call   Attesa       ; da 1 s @ 1 MHz
       decfsz counter      ; fine cicli pausa ?
        bra   pas1         ; no - altro ciclo
      
return              ; si - fine pausa e ritorno

Per semplicità, anche la Pausa si bassa sulla routine Attesa (1/2 s a 1 MHz). Nulla vieta di utilizzare il calcolatore di Golovchenko per determinare altri tempi e inserirli nel programma.


Se si incontrano errori nella compilazione è opportuno verificarli con la lista di descrizione degli errori e correggere dove si è sbagliato.


Il file compresso di questa esercitazione è scaricabile dall'  area di download.

 

 

Copyright © afg. Tutti i diritti riservati.
Aggiornato il 05/04/11.