lunedì 30 dicembre 2013

Pic18f Language Extension Macros :: macro ASM per scrivere meno codice

Chi ha scaricato i progetti SVN degli ultimi post (#4 o #5) della serie "Studio PIC18f" avrà notato la presenza del file 'pic18f-langext-*.inc' e l'utilizzo di una serie di strane istruzioni che non fanno parte del set della famiglia 18f.
In effetti queste istruzioni non sono altro che delle macro realizzate per semplificare alcune operazioni ridondanti e ridurre cosi le linee di codice da scrivere (e di conseguenza gli errori).

Queste macro sono adesso disponibili come progetto indipendente su https://sourceforge.net/p/padnest/svn/HEAD/tree/pic18f/Padnest_PIC18F_langext.X

Col passare del tempo aggiungerò altre macro e quindi qui troverete le nuove versioni della 'raccolta'.
Spero che arrivino numerosi feed back da parte vostra con utili suggerimenti o proposte in merito...

Per conoscere i dettagli su ogni macro aprite il file 'pic18f-langext-*.inc' e troverete ogni comando ben commentato.
Inoltre nel file 'test.asm' trovate tutti i casi di test che fungono anche da validi esempi di utilizzo.

Detto questo, visto che siamo arrivati alla fine dell'anno 2013, approfitto per fare a tutti voi i miei migliori Auguri per uno spumeggiante nuovo Anno 2014 !!!


Stay tuned!
ap

NB: l'autore non risponde di eventuali danni causati da omissioni, inesattezze o errori eventualmente presenti nell'articolo pubblicato.
Prego, segnalare suggerimenti e migliorie commentando questo post o inviando una email a padnest@gmail.com.

domenica 29 dicembre 2013

MPLAB-X #1 :: Subversion per progetti ASM

Se vogliamo utilizzare un repository SVN per i nostri progetti ASM su MPLAB-X possiamo farlo agganciando l'IDE di casa Microchip ad un client SVN installato sulla nostra macchina di sviluppo.
Darò per scontato che chi legge ha già dimestichezza con Subversion...

Seguendo passo passo questo articolo eviterete alcune "trappole" con MPLAB-X; bisogna infatti prestare attenzione a:
  1. installare un client SVN compatibile con MPLAB-X
  2. sapere quali file vanno condivisi e quali assolutamente no


Procediamo quindi con i seguenti passi (testati su MPALAB-X versione 1.95 in inglese):
  1. scaricare e installare un SVN client versione 1.6.x
  2. configurare il path al client SVN su MPLAB-X
  3. importare un progetto ASM sul repository SVN
  4. impostare il progetto per ignorare i file autogenerati nelle future commit

1) scaricare e installare un svn client versione 1.6.x

Consiglio di scaricare e installare questa versione da me testata con successo:
http://sourceforge.net/projects/win32svn/files/1.6.23/Setup-Subversion-1.6.23.msi

(se possibile scegliete come cartella di installazione 'C:\Subversion' evitando path con spazi)

Attenzione: se nel sistema avete già installato una versione di Subversion diversa dalla 1.6 e non vi è possibile effettuare l'upgrade o il downgrade allora scaricate questa distribuzione in formato zip:
http://sourceforge.net/projects/win32svn/files/1.6.23/svn-win32-1.6.23.zip/download

Scompattate lo zip in C:\Subversion1.6.23 e puntate MPLAB-X a questa.


2) configurare il path al client SVN su MPLAB-X

  1. cliccare sul menu Tools > Options > TAB Miscellaneous > TAB Versioning
  2. nella colonna a sinistra 'Versioning Systems' selezionare 'Subversion'
  3. cliccare sul tasto 'Browse' e selezionare la cartella 'bin' presente nella cartella dove avete scelto di installare il client SVN (se avete seguito il mio consiglio il path sarà 'C:\Subversion\bin')
  4. cliccare sul tasto 'OK' 

3) importare un progetto ASM sul repository SVN

  1. assicurarsi di aver selezionato la TAB Projects in modo di avere la vista progetto
  2. cliccare col destro sul nome del progetto e nel menu contestuale scendere in basso e aprire il sotto menu 'Versioning' cliccando poi su 'Import into Subversion Repository'
  3. nella finestra che si apre impostare la URL al vostro repository SVN, la username e la password (vi consiglio di spuntare il salvataggio della password)
  4. cliccare sul tasto 'Next' e nella schermata successiva inserire il commento (es: initial import) lasciando il resto a default
  5. cliccando ancora sul tasto 'Next' nella finestra successiva apparirà la lista dei file da committare sul repository SVN
  6. eliminate la spunta dai file Makefile-* e Package-* in quanto questi non vanno mai condivisi perchè sono autogenerati da MPLAB-X (vedi immagine 3.1) e cambiano da ambiente ad ambiente (conflitti sicuri)
  7. cliccare sul tasto 'Finish'

Immagine 3.1: i file autogenerati da MPLAB-X non vanno mai condivisi

4) impostare il progetto per ignorare i file autogenerati nelle future commit

  1. assicurarsi di aver selezionato la TAB Files in modo di avere la vista a file del progetto
  2. cliccare con destro sulla cartella 'nbproject' e nel menu contestuale portarsi in basso su 'Subversion' e nel sotto menu cliccare su 'Svn Properties'
  3. nella finestra 'Svn Properties Editor' che si è aperta fare doppio click in basso sul nome della proprietà 'svn:ignore' in modo da editarla
  4. in alto adesso vediamo che la proprietà 'svn:ignore' ha già assegnato il valore 'private': questo indica che la cartella 'private' è già stata impostata da MPLAB-X come da ignorare
  5. aggiungiamo sotto a 'private':
     Makefile*
    Package*
  6. verificate che il campo 'Property Value' si presenti adesso come sotto (immagine 4.1)
  7. cliccare sul tasto 'Update' e poi sul tasto 'Close'
  8. fare la commit del progetto su SVN


Immagine 4.1: editare la property svn:ignore


Adesso possiamo lavorare con SVN in modo agevole su MPLAB-X.

Stay tuned!
ap

NB: l'autore non risponde di eventuali danni causati da omissioni, inesattezze o errori eventualmente presenti nell'articolo pubblicato.
Prego, segnalare suggerimenti e migliorie commentando questo post o inviando una email a padnest@gmail.com.

sabato 28 dicembre 2013

Studio PIC 18F (18F4431) #5 :: "PWM RGB led: un arcobaleno di colori"


Vai al precedente POST della serie

Come naturale conseguenza del precedente post, che ha introdotto i primi rudimenti sulla generazione di segnali PWM con i pic18f, questo articolo prosegue e estende il concetto applicandolo ad un led di tipo RGB.
I led RGB, come saprete benissimo, sono 3 led in uno ognuno dedicato ad un singolo colore primario della sintesi additiva: rosso, verde e blu.
Unendo quindi la possibilità di variare l'intensità della luce emessa da un led e la disponibilità di un led in grado di generare i tre colori fondamentali possiamo realizzare un simpatico esperimento con il 4431 e similari.
Intendo utilizzare 3 dei 4 generatori PWM del 4431 associando ad ognuno di essi la gestione dell'intensità di un singolo colore per produrre un effetto arcobaleno con una transizione graduale tra tutte le possibili sfumature.

L'algoritmo "arcobalenico"

Giocherellando con la tavolozza dei colori di 'Gimp' ho verificato che l'effetto si ottiene agendo sull'intensità di una singola componente RGB per volta seguendo questo semplice schema dove 255 rappresenta la massima luminosità e 0 quella minima:
  1. partenza: R=255, G=0, B=0
  2. incremento G: R=255, G=255, B=0
  3. decremento R: R=0, G=255, B=0
  4. incremento B: R=0, G=255, B=255
  5. decremento G: R=0, G=0, B=255
  6. incremento R: R=255, G=0, B=255
  7. decremento B: R=255, G=0, B=0
  8. ora mi ritrovo nella stessa condizione di partenza e quindi ripeto il ciclo dal punto 2
Per rappresentare questi passaggi sono sufficienti 4 bit organizzati nel registro Flags in questo modo:
7 6 5 4 3 2 1 0
X X X X R G B Dir

I bit R, G e B indicano su quale colore agire (=1) mentre il bit Dir indica se l'intensità di quel colore va incrementata (=1) o decrementata (=0).
Quindi proviamo a codificare i passaggi elencati sopra in termini binari:
  1. partenza: settiamo il registro R a 255, G e B a 0
  2. incremento G:  Flags = 0000 0101
  3. decremento R: Flags = 0000 1000
  4. incremento B:  Flags = 0000 0011
  5. decremento G: Flags = 0000 0100
  6. incremento R:  Flags = 0000 1001
  7. decremento B: Flags = 0000 0010

Mano al codice

Scaricate il progetto MPLAB-X qui.

Nel file main.asm il codice è organizzato nei seguenti blocchi:


Blocco interrupt

Qui abbiamo tutta la logica di interpretazione del registro Flags cioè il codice deputato ad aggiornare i segnali PWM dei rispettivi colori in base allo stato dei suoi bit.
Quando il comando impostato in Flags è stato completato (cioè quando il relativo registro del colore ha raggiunto il valore massimo o minimo) l'esecuzione passa alla label int_next che provvede ad impostare il registro Flags con la successiva sequenza da eseguire reperita tramite la tabella get_seq con il classico sistema dell'incremento del PCL (che però nel caso dei pic 18f deve essere doppio).

Blocco main

Qui abbiamo l'inizializzazione dei registri LED_R, LED_G, LED_B, Flags e SeqIndex in modo da impostare il punto di partenza della sequenza dei colori.
Si procede poi con inizializzare il modulo PWM impostando una risoluzione di 8 bit e i tempi opportuni per produrre il passaggio tra i singoli colori.
Si abilitano qui i pin da PWM0 a PWM5 come uscita PWM.
Si continua inizializzando gli interrupt ed in particolare quello del modulo PWM.


Schema elettrico

In questo caso la corrente totale richiesta per pilotare il led RGB supera i 25 mA massimi erogabili dal PICkit2 e quindi è ASSOLUTAMENTE NECESSARIO ALIMENTARE IL CIRCUITO ESTERNAMENTE se non si vuole buttare nel secchio il PICkit2.
Inoltre è indispensabile utilizzare dei transistor per evitare di sovra caricare le porte del PIC: nel mio caso avendo un led RGB con anodo in comune utilizzo degli NPN tipo BC337 per adattare anche il segnale al catodo di ogni singolo led.
Nel caso che disponiate di un led RGB con catodo comune basterà semplicemente utilizzare dei PNP tipo BC327 invertendo tutte le polarità.

Nota: il led RGB in mio possesso ha in realtà una Fv (caduta di tensione) pari a 3,2 volt per G e B e di 2,0 volt per R (max 20mA per tutti) quindi per pignoleria avrei dovuto diversificare il valore delle resistenze R2 e R3 rispetto alla R4.






La BB alimentata esternamente e con la sezione 'di potenza' costituita dai tre NPN


Particolare del PICkit2 che non deve alimentare il circuito (filo rosso non connesso alla BB)


Risultato





Stay tuned!
ap

Vai al successivo POST della serie

NB: l'autore non risponde di eventuali danni causati da omissioni, inesattezze o errori eventualmente presenti nell'articolo pubblicato.
Prego, segnalare suggerimenti e migliorie commentando questo post o inviando una email a padnest@gmail.com.

giovedì 26 dicembre 2013

Studio PIC 18F (18F4431) #4 :: "PWM led"


Vai al precedente POST della serie

Generare un segnale PWM con i pic 18F è estremamente semplice soprattutto se questi dispongono del supporto hardware come nel caso del 4431.
Dando per scontato che si sappia già cosa sia un segnale PWM (eventualmente approfondire in rete l'argomento) vediamo come utilizzarlo per far lampeggiare un led in modo "sfumato" cioè con una progressione da spento fino alla massima luminosità e viceversa.

Iniziamo col dire che il 4431 dispone di 4 generatori PWM indipendenti tra loro in termini di duty cycle ma tutti dipendenti da uno stesso TIMER che ne determina la frequenza/periodo: questo TIMER è dedicato al modulo PWM e si chiama PTMR (non va confuso con gli altri timer del pic).
Associati ad ogni canale PWM abbiamo una coppia di pin di uscita: PWM0 e PWM1 (33-34) per il canale PWM0, PWM2 e PWM3 (35-36) per il canale PWM1, PWM4 e PWM5 (38/28-37) per il canale PWM2, PWM6 e PWM7 (29-30) per il canale PWM3.
NB: dato che i pin di uscita sono condivisi con le porte B e D sarà necessario riservare tali pin al modulo PWM tramite il registro PWMCON0.

In questo esempio utilizziamo un solo canale PWM: il canale 0 e solo il pin di uscita PWM0 (33).
I registri coinvolti sono: PTCON0, PTCON1, PWMCON0, PWMCON1, PTMRL, PTMRH, PTPERL, PTPERH, PDC0L, PDC0H.
I passi per generare il segnale PWM sono:
  1. inizializzare i registri di controllo del timer PTMR: PTCON0 e PTCON1
  2. inizializzare i registri di controllo del modulo PWM: PWMCON0 e PWMCON1
  3. impostare il numero di conteggi del timer PTMR settando i registri PTMRL e PTMRH (12 bit)
  4. impostare il duty cycle del segnale PWM settando i registri PDC0L e PDC0H (14 bit)
  5. avviare il timer PTMR settando a 1 il bit PTEN del registro PTCON1

Determinare la frequenza del segnale

La generazione del segnale PWM è molto semplice: il timer PTMR conta da 0 fino al valore impostato in PTPERL+H incrementando i registri PTMRL+H ad ogni impulso di clock pari a FOSC/4.
Si può ulteriormente scalare il clock attivando il prescaler agendo su PTCKPS<3:2> del registro PTCON0.

Se ad esempio utilizzo un quarzo da 8 MHZ avrò le seguenti possibili combinazioni:

OSC 8 MHZ
PTCKPSprescalerPTMR clockFrequenzaIntervallo incremento PTMR
001:1FOSC/42.000.000 HZ0,5 uSec
011:4FOSC/16500.000 HZ2 uSec
101:16FOSC/64125.000 HZ8 uSec
111:64FOSC/25631.250 HZ32 uSec

Quando il timer PTMR inizia il conteggio da 0 il pin di uscita è posto a livello alto e rimane cosi fino a quando il conteggio non raggiunge il valore impostato in PDCx: a questo punto il pin passa a livello basso.
Il conteggio prosegue fino a quando il valore di PTMRL+H non raggiunge il valore impostato in PTPERL+H: a questo punto PTMRL+H si azzerano, il pin di uscita torna alto e il ciclo ricomincia.
Questo è il funzionamento in modalità free-running: le altre due modalità possibili (single-shot e continuous-up/down) non sono trattate qui.

La frequenza del segnale PWM è quindi determinata da: (FOSC / 4) / ((PTPER+1) * prescaler).
Ad esempio: se il quarzo è da 8Mhz, il prescaler vale 1:4 e PTPER lo imposto a 0xFF avrò: (8.000.000 / 4) / (256 * 4) = 2.000.000 / 1.024 = 1.953,125 Hz.

Registri PDCxL e PDCH

Fino a qui sembra tutto molto semplice ma bisogna fare attenzione ad una particolare insidia che non emerge subito chiaramente dal datasheet: il valore del duty cycle (che determina il passaggio del segnale PWM a livello basso) va inserito nei registri PDCxL+H shiftato di 2 bit verso sinistra in quanto i primi due bit (1:0) di PDCxL determinano il Q-Clock cioè in quale fase di clock deve avvenire il confronto tra PTMRL+H e PDCxL+H.
PTMR e PTPER permettono di impostare al massimo un valore a 12 bit mentre PDCx a 14 bit cioè 12 bit di confronto del duty + 2 bit di impostazione su quando effettuare il confronto (vedi datasheet cap 18.6).

PDCx si presenta quindi in questo modo:
PDCxHPDCxL
XX XX 11 10 09 08 07 06 05 04 03 02 01 00 Q-1 Q-0

Dalla teoria alla pratica

Per far lampeggiare il led dobbiamo variare il duty cycle dallo 0% al 100% e dal 100% allo 0%.
Per fare questo possiamo utilizzare un timer oppure sfruttare un particolare interrupt generato dal modulo PWM ad ogni reset del timer PTMR: questa seconda possibilità è quella che ho scelto in questo caso.
Per semplificare le cose ho scelto di utilizzare solo i registri L e quindi limitare la risoluzione PWM a 8 bit.
Per avere un lampeggio lento ho ridotto il clock impostando il prescaler a 1:16 avendo quindi una frequenza di incremento pari a  FOSC/64.
La frequenza PWM sarà pari a: 2.000.000 / (256 * 16) = 488 Hz circa.
La durata del lampeggio è invece: (256*2) / 488 = 512 / 488 =  1,049 secondi circa.     

Il progetto MPLAB-X relativo a questo articolo è scaricabile qui.

Lo schema elettrico è il seguente:

Il risultato è questo:



Stay tuned!
ap

Vai al successivo POST della serie

NB: l'autore non risponde di eventuali danni causati da omissioni, inesattezze o errori eventualmente presenti nell'articolo pubblicato.
Prego, segnalare suggerimenti e migliorie commentando questo post o inviando una email a padnest@gmail.com.