Programma per Windows testato in XP con Service Pack3 e in Windows 7 SP1 (è suggerito di spuntare la voce 'Disabilta temi visivi' nella scheda 'Compatibilità')
L'obiettivo del programma è fornire alcuni strumenti di utilità per lo sviluppo di codice assembler per le CPU PIC di Microchip.
Per mia esperienza ci sono almeno 3 situazioni di confusione e difficoltà nello scrivere il codice per i Pic:
Con le nuove perifiche disponibili sui nuovi Pic Midrange, ovvero l'NCO ('numerically controlled oscillator'),
le CLC ('Configurable Logic Cell') e altre, le aree di complessità sono cresciute di parecchio.
Sto lavorando anche su queste aree, ma la complessità di creazione di una GUI in Visual Basic che sia al contempo
più 'friendly' e più integrata dei tools messi a disposizione di Microchip, non è impresa da poco. Queste aree
potrebbero quindi essere inserite in prossime release del programma.
Nella barra superiore sono raggruppati i comandi comuni a tutte le funzioni, ovvero:
Le caselle di input per i valori di ritardo e di frequenza, prevedono l'introduzione di valori
in microsecondi per i ritardi e in Hz per le frequenze.
Si possono utilizzare le abbreviazioni per i moltiplicatori più utilizzati, ovvero:
u = micro, m = milli, s = secondi, k = kilo
l'uso di maiuscole o minuscole è indifferente.
Il separatore decimale può essere indifferentemente il punto o la virgola.
Per generare un Interrupt ogni periodo di tempo prestabilito occorre configurare gli opportuni valori nei registri del
Timer scelto (abbreviato di seguito in TMR), operazione non difficile, ma noiosa e fonte spesso di errori.
Il primo passo è convertire il periodo voluto (o la frequenza, come inverso del periodo) in
microsecondi in funzione del clock della CPU.
Quindi bisogna studiare il datasheet per scegliere il giusto Timer, in termini di numero di bit e di dotazione e valori
del pre-scaler, se disponibile.
A questo punto, se il ritardo è superiore alla capacità di TMR, si deve scegliere il valore
di prescaler che riporta il ritardo in ambito del registro TMR.
Finalmente il valore ottenuto, meno 2 (valore richiesto dal datasheet) e corretto sottraendo il numero dei cicli spesi nella ISR ('Interrupt Service Routine')
va sottratto alla massima capacità del registro TMR.
Questa finestra del programma svolge tutte queste funzioni: è sufficiente selezionare la CPU, il Clock di sistema e il Timer disponibile e
quindi inserire il valore del periodo. Premendo il tasto Calcola vengono visualizzati i valori ottenuti per TMR e per il prescaler, se utilizzato, e creato il codice
completo da copiare negli Appunti per incollarlo nel proprio codice.
Per generare dei ritardi fissi medio-lunghi (da alcune centinaia di microsecondi a ore!) in assembler si devono scrivere
dei loop di ritardo nidificati.
Considerando che il ritardo è funzione del clock della CPU, può essere
un incubo trovare i valori da assegnare ai diversi stadi di loop per velocità di clock alternative.
Questa sezione risolve il pasticcio!
Basta selezionare il clock e fornire il periodo voluto (da microsecondi ad ore) ed esso calcola questi parametri e
scrive il codice corrispondente.
Inoltre, esso comunica il ritardo effettivo realizzato, lo scostamento e l'errore percentuale, che è tipicamente inferiore
allo 0.1 %.
Per scelta (e per il limite imposto dalla grandezza delle variabili di calcolo utilizzate) il numero massimo di loop
è stabilito in 5, con i quali si può ottenere un ritardo massimo di 3,380,982,724,376 cicli.
Con un clock a 4Mhz questi sono pari a 939 ore (ovvero più di 39 giorni)!
Credo siano sufficienti.
Calcolare il ritardo ottenuto impostando il valore dei contatori è facile; l'inverso, ovvero
dato un ritardo trovare i valori dei vari contatori è complesso. Personalmente non sono
riuscito a trovare su Internet un algoritmo che fornisca queste risposte.
Il motivo è chiaro: con N cicli di loop abbiamo da risolvere 1 equazione
in N< incognite, ovvero non risolvibile con metodi algebrici.
Una soluzione teorica sarebbe di calcolare il ritardo assegnando via via tutti
i possibili valori (da 0 a 255) a tutte le incognite.
Con i PC
attuali questo è fattibile solo fino al massimo di 3 incognite, e già così
occorre reiterare il calcolo 16,777,216 volte!
Con 5 incognite, ritardo massimo ammesso da questo programma, i cicli sarebbero
1,099,511,627,776 !!!..un pò troppi, vero?
La soluzione che ho trovato (non sarà l'unica, non sarà la migliore, ma per me funziona)
è di usare una ricerca ad albero binario del miglior valore per ogni singolo contatore.
Questo riduce il numero di ripetizioni a 8^5 (32,768) nel caso peggiore.
In effetti, il tempo impiegato per il calcolo è trascurabile, tipicamente inferiore a 16msec.
Altro punto importante: i valori calcolati sono approssimati, in quanto non esiste di norma
un set di valori che produce esattamente il ritardo voluto. Considerando però che questo strumento
serve a definire ritardi medio-lunghi (in pratica, da millisecondi a ore!) credo che uno
scarto tipico dello 0.05% sia accettabile.
Ultima nota: si trovano in Internet codici per costuire i loop di ritardo assegnando
un valore iniziale ai contatori utilizzato solo per il primo ciclo; al secondo passaggio
il contatore precedente è diventato 0 per cui il loop diventa ripetuto per 256 volte.
Io ho preferito seguire una strada diversa: i contatori sono 'ricaricati' all'inizo di
ciascun ciclo con lo stesso valore. A scapito dell'uso di 1..5 variabili in più e alcune
istruzioni in più, dalle mie verifiche sembra che questo approccio fornisca risultati migliori.
Come dice la finestra, questa sezione è ancora in LAVORAZIONE
Versione 1.0 di Maggio 2015
Il file eseguibile sarà in linea non appena completata la sezione PWM, spero a giorni
Per mia scelta non pubblico i sorgenti, perchè il programma sicuramente dovrà essere rivisto e, soprattutto,
per il grande impegno che a richiesto e per il quale non vorrei trovare in giro delle 'scopiazzature, come
già successo in altri casi.
Chi fosse comunque interessato può contattarmi direttamente e, se sarà convincente !, vedrò cosa posso fare.