PIC uControllers Tutorial

25

Click here to load reader

Transcript of PIC uControllers Tutorial

Page 1: PIC uControllers Tutorial

PIC uControllers tutorial+ Mikrobasic® programming

Written by: [email protected]

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 2: PIC uControllers Tutorial

Indice:

Argomento trattato• Paragrafo

- Approfondimento

Prima parte: microcontrollers• Architettura dei microcontrollers PIC• Clock• Registri• Porte di comunicazione

Seconda parte: Ambiente di sviluppo mikrobasic• Creazione di progetti• Flag (esempio per il PIC16F88)• Struttura del programma

Terza parte: Fondamenti di programmazione in mikrobasic (dati)• Dati• Dichiarazione ed utilizzo dei tipi statici• Array

- Buffer overflow• Stringhe• Records (strutture)• Dichiarazione ed utilizzo dei tipi dinamici

Quarta parte: Operators & Simple Data Oriented Isntructions• Operatori• Operatori aritmetici• Operatori di precedenza• Operatori di bitwise• Operatori di confronto

- FLAG di ZERO- FLAG di SEGNO

• Lettura e scrittura dei dati da una porta di comunicazione- Interfacciamento

Quinta parte: Strutture di controllo del flusso di un programma• Selezione

- Primo progetto: Hardware key• Case• Iterazione

- secondo progetto: Led blink• Ciclo a conteggio• Funzioni• Ricorsione

- Stack overflowSesta parte: Advenced Data Oriented Instructions and libraries

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 3: PIC uControllers Tutorial

• Serial communication and library- RS232 to TTL- MSCOMM32.ocx e controllo della porta seriale in Delphi- Terzo progetto: Roulette

• Main Math Library functions• Main String Library functions• Main Conversion library functions

Settima parte: interfacciamento, comunicazione• Lettura dei dati analogici

- Interfacciamento (parte analogica)• Scrittura dati verso display a 7 segmenti• Scrittura dati su LCD Hitachi compatibili• ENC28J60: PIC ed Ethernet• Utilizzo di schedine SD ed MMC

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 4: PIC uControllers Tutorial

Microcontrollers…

Un microcontroller è un dispositivo che integra onboard un processore e della memoria contenente il programma (firmware) che il processore deve eseguire.

La miniaturizzaizone dei circuiti integrati ha consentito inoltre di rendere disponibili sullo stesso chip ulteriori dispositivi come ad esmepio convertitori AD, cicruiti integrati per la gestione della comunicazione, ulteriore memoria etc etc..

È quindi possibile fare interagire il firmware con il mondo esterno, controllando dispositivi di svariata natura, led, interruttori, relè, altoparlnti, motori e persino dialogare con altri microcontrollers, PC, display LCD…

I microcontrollers sono impiegati in svariate applicazioni per il loro prezzo conveniente e la loro versatilità (c’è molta differenza tra riprogettare una scheda elettronica e modificare qualche di codice).

Architettura dei microcontrollers PIC:

A differenza dei processori x86 e dei PCn basati dull’architettura di von Neumann, i microcontrollers PIC hanno un’architettura del tipo Harvard che prevede un’unità di

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

I/OMemoria

CPU

Page 5: PIC uControllers Tutorial

elaborazione (CPU) che esegue le istruzioni presenti in una memoria detta memoria di programma.I dati, su cui lavorano le istruzioni, sono presenti in un’ulteriore memoria detta memoria dati.

La suddivisione tra la memoria programma e la memoria dati ha consentito uno sviluppo più agevole poiché in un architettura del tipo di V.N. i dati e le istruzioni che compongono il programma devono essere della stessa dimensione, mentre in un’architettura del tipo di Harvard i dati e le istruzioni possono avere dimensioni differenti e quindi le due memorie sono collegate al processore con bus di dimensione diversa ottimizzando il trasferimentod ei dati.

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 6: PIC uControllers Tutorial

Il Firmware può essere scritto da qualsiasi PC in diversi linguaggi di programmazione sia di basso livello (assembler) che di alto livello (C, Basic, Pascal…).

Una volta scritto il programma dev’essere convertito in linguaggio macchina e cioè compilato in una serie di codici numerici interpretabili dal processore e va scritto nella memoria programma attraverso una scheda ed un software di programmazione.

Tra le diverse schede di programmazione consiglio quelal presente in rete con il nome “minipippo” ed il software winpicpgm che rileva in automatico la scheda utilizzata.

Attraverso winpicpgm si può selezionare il file compilato (.hex) e trasferirlo nel microcontroller.

Una volta programmato, quando si da tensione al microcontroller, inizia l’esecuzione del firmware partendo dalla prima istruzione presente nella prima cella della memoria programma.

All’interno del microcontroller sono presenti altri tipi di memoria di cui alcuni sono fondamentali per l’esecuzione del programma.

Clock

Poiché i microcontrollers PIC sono realizzati in logica RISC, un’istruzione può occupare più colpi di clock per essere eseguita.

Il clock che serve per fare evolvere lo stato della macchina nonche sincronizzare i vari dispositivi, è dato da un oscillatore che può essere esterno (RC o un quarzo) oppure in alcuni microcontrollers è presente all’interno.

Dato che un PIC può lavorare con diverse frequenze (nell’ordine delle decine di Mhz) è possibile selezionare e configurare l’oscillatore utilizzato settando i bit di particolari zone di memoria che prendono il nome di flag.

Tali flag consentono tra l’altro di impostare eventuali protezioni ed altre funzionalità avanzate dei microcontrollers e variano da microcontroller a microcontroller.

Per la loro configurazione si rimanda al datasheet del prorpio microcontroller oppure si veda la parte relativa alla creazione di un nuovo progetto in mikroBasic.

Registri

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 7: PIC uControllers Tutorial

I registri sono aree di memoria molto veloci realizzate in logica latch in grado di lavorare con lastessa frequenza del processore. Tra questi hanno fondamentale importanza il registro program counter e l’instruction register i quali tengono traccia dell’istruzione corrente che si sta eseguendo e sarebbe impensabile che tali registri non fossero ing rado di lavorare alla stessa frequenza del processore..Altri registri servono per configurare i diversi dispositivi presenti sul microcontroller come ad esmepio quello di configurazione del convertitore AD (nei PIC che lo implementano) oppure quelli di configurazione dei timers.

Registri di uso generale sono presenti per memorizzare i dati su cui il processore sta lavorando.

Porte di comunicazione

Coem già acennato nell’introduzioen un pic può interagire con una gran varietà di dispositivi esterni e per questo presenta dei piedini di I/O.

Per una migliroe gestione vengono raggruppati in PORTE ciascuna di 8pin ed associata ad un registro PORTx dove x identifica la porta.

Ogni bit di tale registro corrisponde al valore logico presente sul pin del microcontroller.

Ad esmepio se nel registro PORTA mettiamo 255 (11111111) tutti i pin di PORTA avranno il valore logico 1 e cioè 5V secondo lo standard TTL.

La disposizione dei pin e delle porte cambia a seconda del microcontroller ma rimane all’incirca la stessa per i microcontrollers dello setsso package.

a seocnda della notazione, il pin i della porta x può essere definito come Rxi oppure come PORTx.i

Come si vede dalla figura i pin di una porta sono sia di input che di output, ma non possono essere usati in entrambe le modalità contemporaneamente, si potrebbe infatti verificare un cortocircuito quando in ingresso è presente un valore di tensione basso e si scrive un valore di tensione alto.

Per questo un ulteriore registro di direzione specifica se i pin del dispositivo sono di ingresso oppure di uscita.

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 8: PIC uControllers Tutorial

Nel caso in cui essi siano di ingresso vengono portati nella condizione di alta impedenza in maniera tale da assorbire poca corrente epermettere l’interfacciamento del microcontroller verso dispositivi in grado di erogare corrente ridotta.

Tale registro che nei microcontrollers AVR prende il nome di Data Direction Register, nei microcontrollers PIC prende il nome di TRISx dove x indica sempre la porta a cui si riferisce ed ogni bit indica il singolo pin di tale porta.

I bit settati a 0 indicano che il pin corrispondente è un output mentre i bit settati a 1 indicando che il pin corrispondente è un input.

Nei microcontrollers che integrano dispositivi avanzati come convertitori AD, timers, USARTs il registro TRIS non ha effetto ma ha priorità l’abilitazione di tali dispositivi.

Per questo è possibile che un pin del microcontroller abbia più funzioni, selezionabili impostando i flag di configurazione e cioè andando a scrivere i registri di cui si è parlato prima.

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 9: PIC uControllers Tutorial

L’ambiente di sviluppo mikrobasic:

mikroBasic è un completo IDE che consente di scrivere il firmware per i microcontrollers della famiglia PIC in BASIC, rendendo disponibili strutture della programmazione ad alto livello non che numerose librerie che consentono uno sviluppo più immediato del firmware.

Il compilatore converte il codice scritto in linguaggio macchina cercando tra l’altro di ridurre al minimo gli sprechi di memoria inevitabili quando si programma ad alto livello.

Al termine della compilazione viene prodotto un file .hex conteente il programma in codice macchina che dev’essere trasferito sulla memoria interna del microcontroller tramite uno dei tanti programmatori disponibili (JDM, LUDIPIPO, PICPRO).

Progetti

Prima di iniziare a scrivere il codice è necessario creare un “progetto” dal menu project in maniera tale da specificare per quale microcontroller è destinato il programma che si sta scrivendo, settando quindi le varie opzioni.

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 10: PIC uControllers Tutorial

Il campo “Device” indica per quale microcontroller bisogna compilare il programma e poiché molte routines software sono legate al tempo con cui vengono eseguite è necessario specificare la frequenza di clock del microcontroller.

La sezione Flag rappresenta la word di configurazione del dispositivo che varia a seconda del PIC utilizzato.È possibile abilitare la protezione di Brown out così come selezionare il tipo di oscillatore utilizzato (quarzo, RC….)

Di default viene selezionato un oscillatore esterno con frequenza > 1MHz (FLAG HS=1)

Esempio di altri flag: Il PIC16F88Il PIC16F88 estende il 16F84 che ha solo 4 bit per PORTA poiché gli altri 4 sono occupati per il quarzo, per /RESET e per l’interrupt del Timer.

Selezionando i FLAG è possibile disattivare le funzioni di oscilalote esterno e di /RESET ed aggiungere quei pin a PORTA arrivando ad avere 8bit per PORTA.Come si evde in fgiura, il flag MCLR_ON (e l’opposto MCLR_OFF) abilitano o disabilitano la funzione di MCLR presente su PortA.4.

Una volta creato il progetto viene creato di default un file e visualizzato nell’editor.

Ora è possibile iniziare a scrivere il codice.

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 11: PIC uControllers Tutorial

Struttura del programma

La sezione indica il nome del programma ed eventuali moduli contenenti parti esterne di codice

Il compilatore richeide che la dichiarazione delle costanti, delle variabili globali e delle funzioni sia disposta prima di tutto il resto, attraverso le direttive symbol, const, dim, sub che analizzeremo nel dettaglio in seguito.

Dopodichè con l’etichetta main: ha inizio la routine che viene eseguita all’avvio del programma, cioè quando si da corrente al microcontroller. Per gli amanti del C corrisponde alla main().

Analoga è la struttura dei moduli che al posto della direttiva program riportano la direttiva module, specificando al compilatore che si tratta di un modulo e non del programma principale da caricare sul microcontroller.

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 12: PIC uControllers Tutorial

Fondamenti di programmazione in mikroBasic

mikroBasic segue il paradigma della programmazione strutturata e ne fornisce le strutture fondamentali in maniera ottimizzata per i microcontrollers, che avendo una memoria molto limitata non possono permettersi di eseguire codice con strutture dati di alto livello.

Dati

Il firmware memorizzato nella memoria programma, ha la necessità di lavorare con dei dati che si trovano nella memoria codice.

La memoria del microcontroller è limitata e può essere di diverso tipo a seconda della versione del microcontroller, in ogni modo è organizzata in celle numerate (solitamente da 1 byte ciascuna) il cui numero, detto INDIRIZZO identifica univocamente ogni zona di memoria.

Poiché per un programmatore è scomodo ricordarsi gli indirizzi di memoria a memoria (scusate il gioco di parole) mikrobasic fornisce la possibilità di associare ad ogni cella di memoria (e non solo) un nome che identifica quella cella e un tipo che indica che genere di dato contiene quella cella (numero, carattere…).

Dichiarazione ed utilizzo dei tipi statici

Al fine di ottimizzare la memoria, il compilatore necessita di sapere a priori le variabili con cui dovrà lavorare il rpogramma e quindia ssegnare alle celle di memoria l’identificatore utilizzato come variabile nel programma.

Proprio perché è un linguaggio ad alto livello consente anche di gestire strutture dati che spaziano su più celle di memoria come array stringhe e persino records, fornendo dei metodi per la gestione di tali organizzaizoni di dati.

Come si vede dalla struttura generale di un programma una variabile si dichiara con la direttiva DIM (dimensiona) la quiale indica al compilatore che si sta dimensionando una variabile, ovvero assegnando un nome ad una zona di memoria che conterrà dati di unc erto tipo. La tipologia dei dati è essenziale al fine di organizzare al meglio la memoria.

I tipi semplici più utilizzati sono i seguenti:

Type Size Rangebyte 8–bit 0 – 255

char 8–bit0 – 255 piochè la codifica ASCII associa ad ognic arattere un numero di 8bit

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 13: PIC uControllers Tutorial

Type Size Rangeword 16–bit 0 – 65535short 8–bit -128 – 127integer 16–bit -32768 – 32767longint 32–bit -2147483648 – 2147483647

float 32–bit ±1.17549435082 * 10-38 .. ±6.80564774407 * 1038

Esempio: dim contatore as byte

Poiché l’utilizzo di indentificatori separati per la gfestione dei dati nons empre è conveniente, può essere utile l’utilizzo di gruppi di variabili che prendono il nome di array.

Array:

Un array è essenzialmente una tabella in cui ogni riga è numerata (ha un determinato indice) e corrisponde ad una variabile.Possono essere dimensionati array di caratteri (stringhe), array di numeri etc etc.

Esempio scorretto:

dim temperatura1 as bytedim temperatura2 as byte…dim temperaturaN as byte

l’utilizzo degli array consente di organizzare le temperature in una struttura migliore

Esempio con array:

dim temperature as byte[N]

dove N indica il numero di celle dell’array.

Per accedere ad una cella basterà porre l’indice tra parentesi [], ad esempio per memorizzare nella prima temperatura il valore 20:

temperature[0]= 20

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 14: PIC uControllers Tutorial

cioè

NomeArray[indice] = ValoreDaMettereNellaCellaIdentificataDallIndice

(il primo indice valido è quello che indica la cella prima cella e vale 0 come in C, l’ultimo disponibile indicherà l’ultima cella e corrisponderà a N-1 poiché inizia da 0)

Nota di approfondimento: overflow

Supponiamo di avere un programma in pseudo-codice di questo tipo:

dim indice as bytedim temperature as byte[20]dim X as byte

….

- leggi l’indice dall’utente- leggi la temperatura dall’utente

temperatura[indice]= (temperatura inserita dall’utente)

se l’utente inserisce un indice che va oltre il numero di celle dell’array -1 (in questo caso 19) si ottiene una condizione di overlow, ovvero il programma accede ad una cella che non fa parte dell’array.

Infatti le varie variabili sono memorizzate in maniera contigua sulla RAM del microcontroller e quindi prima ci sarà una cella che conterrà il valore di indice, poi 20 celle che corrispondono alle 20 celle dell’array temperature, e poi la nostra variabile X che ora scopriamo cos’è.

Se l’utente inserisce 20 come indice, il prgoramma memorizza l’informazione spostandosi di 21 celle dall’inizio dell’array e quindi scriverà il valore di temperatura in X, cosa che non era prevista.

Essendo un architettura Harvardiana non è possibile che i dati vadano a sovrascrivere il codice, ma in un architettura von neumaniana i dati sit rovano prima del codice di un programma, e quindi mandando in overlfow l’array si può andare anche a sovrascrivere il codice di un programma facendogli fare operazioni non previste.

Gli array risultano molto comodi nella loro gestione con i cicli, ma la loro dimensione fissa spreca spesso molta memoria, cosa che viene risolta con le strutture dinamiche.

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 15: PIC uControllers Tutorial

Stringhe:

Poiché i messaggi di testo sono le strutture dati più utilizzate, mikrobasic ha messo a dispositione il tipo string[lunghezza] che consente una getione più agevolata degli array di char, senza andare a dover accedere alle singole celle.

Dim messaggio as string[20]…Messaggio = “Hello World!!”

Come approfondito in seguito sono rpesenti anche delle funzioni per la manipolazione delle stringhe.

Records (strutture):

Supponiamo il caso di voler memorizzare le invormazioni relative ad uno studente, ad esempio in un dispositivo che legge una smart card contenente i dati dello studente (matricola, nome, cognome, classe)

Essi potrebbero essere gestiti da tante variabili sparpagliate, ma torna utile al fine di una scrittura più compatta del codice, dichiarare un nuovo tipo di variabile, il tipo Studente che avrà al suo interno i campi matricola, nome, cognome e classe, ciascuno del tipo corretto.

Come prima cosa occorre dichiarare le generalità di una struttura, in questo caso di uno studente generico (la classe in OOP)

structure Studente dim matricola as integer ... dim classe as string[2]end structure

Una volta dichiarata una struttura possono essere dimensionate delle variabili che rappresentano una o più strutture ralmente esistenti sulla RAM , ad esempio il miglioreStudente

dim migliroeStudente as Studente

oppure tutti gli studenti di una scuola

dim scuola as Studente[100]

quello che noi abbiamo chiamato variabili in questo caso corrispondono all’istanza in OOP.

In sostanza, la struttura rappresenta lo stampo di unc erto tipo di dato, mentre l’istanza è la creazione fisica fatta con quello stampo, che si può toccare con mano, o meglio accedere ed utilizzare.

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 16: PIC uControllers Tutorial

Dichiarazione ed utilizzo delle strutture dinamiche

Dato che la quantità di memoria disponibile sul microcontroller è molto limitata e gli array sprecano molta memoria, mikroBasic fornisce, ma non completamente, al programmatore la possibilità di gestire i puntatori.

Tornando all’esempio dell’array che memorizzava delle temprerature, esso occuperà sempre quei 20 byte di RAM e non potrà andare oltre, ne sprecare di meno.

Le strutture dinamiche risolvono questo problema, andando ad occupare una zona di memoria dati libera quando necessario, e non a priori come le strutture statiche, sarà quindi possibile occupare una cella libera e memorizzarci un dato così come liberare e rendere disponibili la memoria dati inutilizzata.

Gi array vengono quindi sostituiti dalle LISTE che sono una sequenza di strutture formate dal campo che memorizza unc erto valore, e il campo che contiene l’indirizzo in memoria della cella successiva, in gergo informatico il puntatore alla cella successiva.

Al termine della lista, l’ultima cella punterà all’indirizzo NULL che indica che lòa lista è finita.

Oviamente siccome le celle sono prese dove c’è spazio sulla memoria RAM non sono contigue e se si perde un puntatore non si può più ritrovare il resto della lista.

Altre strutture dinamiche come gli Alberi binari cosnentono la ricerca di un elemento utilizzando la ricerca dicotomica che ha una complessità di calcolo logaritmica rispetto alla ricerca sequenziale che fa passare tutte le celle di un array fino a che trova il valore desiderato.

Inoltre la potenza dei puntatori non si ferma qui, infatti un puntatore è un indirizzo di memoria, l’ indirizzo di una cella di memoria, (o la prima di un gruppo), e quindi non fa distinzione tra i vari tipi di dato contenuti in una cella, è quindi possibile accedere ai bit di una cella, ignorandone il tipo se si vuiole, consentendo nella OOP la proprietà del POLIMORFISMO.

Nonostante tuttwe queste belle cose, nelle varie architetture chi si occupa della gestione della memoria è il SISTEMA OPERATIVO, e quindi le strutture dinamiche sono solo parzialmente gestite da mikrobasic, il quale fornisce la possibilità di dichiarare una variabile di tipo puntatore, ma non consente l’allocazione e la deallocazione dinamica sulla memoria.

Per dichiarare un puntatore ad un certo tipo di variabile (o ad una struttura):

dim puntatore as ^tipo

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 17: PIC uControllers Tutorial

il ^ indica che non è una variabile di quel tipo, ma l’indirizzo alle celle che contengono una variabile di quel tipo.

Per accederci

puntatore^ = valore

e si legge “puntatore puntato”.

Operators & Simple Data Oriented Instructions:

La trattazione delle strutture dati è avvenuta ad alto livello, utilizzando negli esempi del codice scritto in uno pseudo-linguaggio (in blu) capibile dal lettore ma non certamente dal mikrobasic ne tantomeno dal mikrocontroller.

”leggi la temperatura dall’utente”

Allo stesso modo però sono state utilizzate espressioni del tipo

Messaggio = “Hello World!!”

Senza analizzare nello specifico cosa fosse per mikrobasic il simbolo “=”

In questa parte del tutorial vengono analizzati i costrutti resi disponibili da mikrobasic per operare con i dati, quindi per confrontarli, analizzarli, leggerli e fornirli in output.

Operatori:

Un OPERATORE è un costrutto della programmazione ad alto livello che consente di eseguire delle operazioni con e su i dati.

Il più semplice è l’operatore di ASSEGNAZIONE = tanto che per la sua semplicità è stato ignorato nella parte precedente di questo tutorial.

Si analizzi il seguente codice:

program es_assegnazione

dim a as bytedim b as byte

main: … a=b …end.

Il programma dichiatra due variabili di tipo byte, identificate con i nomi a e b.

All’interno della routine principale (main) troviamo il costrutto a=b che, prendendo il nome di assegnazione, assegna ad a, il valore di b, o meglio, copia in a, il contenuto di b.

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 18: PIC uControllers Tutorial

Operatori aritmetici di SOMMA, SOTTRAZIONE, MOLTIPLICAZIONE

Anche questi operatori sono molto semplici:

x+y restituisce la somma del contenuto di x e del contenuto di yx-y “ “ differenza “ “X*y “ “ il prodotto “ “

Ma cosa significa restituisce??

Beh non ha senso scrivere x+y come costrutto da solo.. il risultato (che sia la somma piuttosto che la differenza o la moltiplicazione non ha importanza) dev’essere assegnato a qualcosa, o comunque utilizzato in un contesto

dim x as bytedim y as bytedim risultato as byte…

risultato = x+y

ecco che quì la parola restituisce assume senso; x+y restituisce la somma, cioè il valore da assegnare a risultato.

Negazione aritmetica:

Come caso particolare degli operatori precedentemente visti, n = -a viene interpretato come “n = 0 – a”

Operatori aritmetici di divisione:

la divisione viene trattata separatamente poiché mikrobasic supporta tre diversi operatori:

Operatore Opera su Restituisce Indica Esempio/ Due valori

numerici, sia interi che float

Un valore float (su cui si può fare un typecasting [vedi parte successiva])

La divisione reale tra due numeri il cui risultato appartiene ad R.

Meta = n / 2

div Due valori numerici interi

Il quoziente intero della divisione

La divisione naturale tra due numeri il cui risultato appartiene ad N

Q = n div m

se n=5 e m=2Q=5 div 2 = 2

mod Due valori numerici interi

Il resto della divisione naturale

il resto “ ” Q = n mod m

se n=5 e m=2Q=5 mod 2 = 1

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 19: PIC uControllers Tutorial

Operatori di precedenza

Come nelle espressioni aritmetiche, anche in mikrobasic le parentesi gestiscono le precedenze degli operatori. Per definizione l’operatore = ha la priorità minore, cioè vengono prima eseguiti tutti i conti e poi l’assegnazione.

Esempio:

Risultato=((a+b)*c)-4

Operatori sui bit

Gli operatori di bitwise lavorano invece sui bit dei dati.

L’operatore NOT inverte i bit di un numero.. ad esempio

dim a as bytedim b as byte

a = 0 ‘ in binario a= 00000000b = NOT a ‘ NOT a restituisce Not(00000000) = 111111111 = 255

L’operatore AND opera bit a bit,nel caso di confronto tra bit restituisce 1 se entrambi i bit sono 1.

Nel caso di word composte da n bit, per ogni bit restituisce 1 se il bit iesimo del primo dato è 1 e così anche per l’iesimo bit del secondo dato.

Se a = &b00000011 ‘ &b è la notazione binariae b = &b10000001 a AND b restituisce 00000001

del tutto simili gli operatori

OR (1 se almeno un bit = 1)XOR (0 se i bit sono uguali, 1 se i bit sono diversi)

Gli operatori di bitwise possono essere confcatenati ad altri operatori.

Operatori di confronto

Gli operatori di confronto restituiscono un valore booleano (vero/falso) (1/0)a seconda che la CONDIZIONE che essi verificano sia veritiera o meno.

MA cos’è una condizione??

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 20: PIC uControllers Tutorial

La CONDIZIONE è quel costrutto della programmazione ad alto livello che può assumere solo un valore vero o falso, a seconda dei valori assunti da due dati, legati da un operatore di CONFRONTO.

Essa assume importanza nelle espressioni logiche ma come vedremo successivamente specialmente negli algoritmi e nelle strutture di controllo del flusso di un programma.

Dim vinto as bytedim punteggio_mio as bytedim punteggio_avversario as byte

vinto = punteggio_mio > punteggio_avversario

In questo caso la condizione è punteggio _mio > punteggio_avversario ed è realizzata dall’operatore maggiore che opera su due valori e restituisce 1 se il primo valore è maggiore del secondo, altrimenti restituisce 0.

Del tutto simili sono gli operatori >=, <, <=, = (uguaglianza), <> (diversità)

Nota: l’operatore = in una condizione, e non in un’assegnazione, realizza la funzione di eguaglianza restituendo 1 se i due valori confrontati sono uguali, 0 se sono diversi.

MA no, state tranquilli non è un MA che fa saltare fuori qualche caso particolare, è un MA che vuole sottolineare che questo è un tutorial ai microcontrollers e non alla programmazione strutturata e basta, quindi si cerca ora di capire come il microcontroller riesce a capire se il contenuto di una cella di memoria è maggiore del contenuto di un'altra cella di memoria, oppure se è minore etc etc.

Il microcontroller come detto nella prima parte di questo tutorial, integra al suo interno un microprocessore che è capace di eseguire operazioni basilari su delle locazioni di memoria. Come prima cosa quindi per verificare se una cella di memoria è maggiore di un'altra, occorrerà copiarla in un registro, in amniera tale da poter accederci più velocemente.

Nel set di istruzioni del microprocessore non sono presenti istruzioni di cofnrontoMa solo istruzioni matematiche come ad esempio la sottrazione, ed anche dei FLAG, che si comportano come le spie del quadro della macchina, sia ccendono e si spengono in particolari condizioni. In particolare il flag di Zero (Z) vale 1 quando il contenuto di un registro diventa zero.

Il flag di segno ivnece vale 1 quando un registro contiene un dato negativo.

Beh allora per verificare se un dato è maggiore di un altro, basta fare la sottrazione e vedere il contenuto del flag di segno..

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 21: PIC uControllers Tutorial

Se a=2 b=3

e si vuole verificare la condizione a > b

Allora il processore esegue la sottrazione a-bin questo caso a-b =-1 quindi il flag di segno vale 1

Verrà restituito quindi l’opposto del flag di segno.

Identica cosa per l’operatore < con la differenza che viene restituito il flag di segno non negato.

Due numeri sono uguali se la loro differenza vale 0, viene quindi restituito il flag di Zero.

Gli operatori di confronto possono essere concatenati agli altri operatori

Ad esempio

sonoRiccoDiSoldi = (mio_zio = berlusconi) OR (mio_stipendio > 5000)

Lettura e scrittura dei dati da una porta di comunicazione

Mikrobasic consente di accedere ai registri del microcontroller, quindi questo capitolo è molto breve in quanto descritto in precedenza nella parte sull’architettura PIC.

Per leggere da una pin di I/O impostato come input, si ricordi che basta utilizzare i registri di comunicazione, che in mikrobasic sono accessibili come una qualsiasi variabile.

Esempio:dim v as byte….TRISB = 255 ‘ scrive in TRISB 11111111 (PORTB usata come input)….V=PORTB ‘ legge il contenuto del registro di comunicazione in v

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 22: PIC uControllers Tutorial

Strutture di controllo del flusso di un programma

Fin ora il tutorial è semrpe stato molto astratto, da questo momento sarà possibile avere una visione più concreta di quello che si sta realizzando e per questo il tutorial presenta alcuni progetti da cui trarre spunto, o da realizzare per capire il funzionamento dei microcontrollers PIC.

Come detto nella prima parte del tutorial, un programma è un insieme di istruzioni

che operano su dei dati, ma il flusso di esecuzione di queste istruzioni può VARIARE a seconda dei dati.

La Variazione del flusso di esecuzione delle istruzioni prende il nome di algoritmo e si basa su strutture fondamentali che danno l’attributo “strutturata” alla programmazione.

La prima di queste strutture è la SELEZIONE:

rappresentata con un rombo in cui entra una freccia e ne escono due, la SELEZIONE fa una cosa piuttosto che un'altra in base ad una CONDIZIONE, che come detto nella parte degli operatori assume importanza proprio nelle strutture di controllo.

In mikrobasic la selezione si rappresenta tramite il costrutto IF

IF (CONDIZIONE) THEN Istruzioni da compiere se la condizione è veraELSE Istruzioni da compiere se la condizione è falsaEND IF

Dim valore assoluto as byteDim a as byte…If (a>=0) then valoreAssoluto=a

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 23: PIC uControllers Tutorial

else valoreAssoluto = -aend if

Al fine di comprendere meglio la selezione e per introdurre l’iterazione, si propone un semplice esercizio: una chiave hardware che accende un Led solo se la combinazione in ingresso è corretta.

Primo Progetto: Hardware key

Il software ad alto livello è leggibile e semplice, questo esempio come prima cosa dichiara la combianzioneValida (in questo caso 00000000 in binario) ed una zona di memrioa in cui mettere la combinazioneInserita

Come seconda cosa il programma inizializza le porte di comunicazione, sugli 8 pin di PORTB viene inserita dall’utente la chiave in binario, spostando dei micro dip switch, quindi dev’essere una porta di input quindi TRISB = 255

Su PORTA viene collegato il led che si accende in caso di chiave valida.Il programma attende successivamente 3 secondi (il tempo per impostare la chiave

Quindi legge la cimbinazioneInserita e verifica SE è = a combinazioneValida.

Se lo è allora setta ad 1 il bit2 di PORTA, altrimenti non fa nulla e il programma finisce. Per farlo ripartire occorre un RESET.

Dato che il progetto mi sembra utile a livello didattico anche per spiegare l’iterazione ho deciso di descrivere il circuito.

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 24: PIC uControllers Tutorial

Con l’iterazioen infatti è possibile fare ripetere l’inserimento della chiave primaria,o infinite volte, o FINO a CHE si verifica una determinata CONDIZIONE (ad esempio l’utente ha finito i tentativi disponibili)

Prima di passare allo schema elettrico complichiamoci un attimo la vitaSE la chiave è ERRATA allora facciamo accendere un led rosso, oppure al posto del led un cicalino che emette un segnale acustico, e colleghiamolo a PORTA.0

Passiamo ora al circuito elettrico.

Dobbiamo realizzare una board che fornisce sugli o pin di PORTB in ingresso 0 (0v) oppure 1 (5V) in base ad una combinazione inseribile dall’utente.

Per farlo si utilizza un 8-micro DIP SwitchChe integra 8 interruttorini.

Gli interruttorini però possono collegare solamente i pin di PORTB a +5V, MA quando sono aperti cosa succede?? I pin del microcontroller risultano “staccati” e la

condizione staccato non è la condizione di 0V, ma varia a seconda del caso, dell’elettricità statica presente su quei pin. È been quindi collegarli a massa con una resistenza da qualche K.

Quando il deviatore è chiuso Vout è collegato a +5V, a cui è collegata in parallelo anche una resistenza da 4K7 che non influisce sulla tensione di uscita.

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]

Page 25: PIC uControllers Tutorial

Quando il deviatore è aperto, Vout = 0V opiichè viene ricollegato a massa tramite la resistenza da 4K7.

Questa è un’applicazione agli estremi del partitore resistivo, infatti, R e la resistenza da 4K7 risultano essere in serie, quindi sono attraversate dalla stessa corrente I.

Per la prima legge di ohm, I = 5V / Rtot.

Essendo le resistenze in serie, Rtot = somma delle due resistenzeQuindi I = 5V / (4,7K + R)

Vout è la tensione misurata tra il centro del partitore e massa (a massa si trova anche l’estremo della resistenza da 4,7K) e quindi corrisponde alla tensione ai capi della resistenza da 4,7K.

Riapplicando la prima legge di ohm in manier ainversa abbiamo Vout = I * 4,7K = (5V*4,7K) / (4,7K + R).

Ora se R è l’interruttore, quando è chiuso la resistenza è nulla quindi R = 0Quindi Vout(chiuso) = 5V*4,7K / 4,7K = 5V.

Se R è la resistenza corrispondente all’interruttore aperto (resistenza infinita) si ha Vout = 5V*4,7k / (4,7k + qualcosa di infinito)E un numero / qualcosa di infinito da 0

Quindi quando l’interruttore è aperto al pin di PORTB arriva 0.

Il resto del circuito è molto semplice.

Powered by: Hacking Group Como http://www.hgcomo.org [email protected]