Progetto Di Un Misuratore Di Temperatura

58
5/9/2018 ProgettoDiUnMisuratoreDiTemperatura-slidepdf.com http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 1/58 1 POLITECNICO DI BARI A.A. 2009/2010 Corso di Laurea Specialistica in Ingegneria Elettronica (SEI) Corso di Sistemi Digitali Programmabili Prof. Ing. P. Dello Russo  PROGETTO DI UN MISURATORE DI TEMPERATURA Columbo Lorenzo

Transcript of Progetto Di Un Misuratore Di Temperatura

Page 1: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 1/58

1

POLITECNICO DI BARI

A.A. 2009/2010

Corso di Laurea Specialistica in Ingegneria

Elettronica (SEI)

Corso di Sistemi Digitali Programmabili

Prof. Ing. P. Dello Russo

 PROGETTO DI UN MISURATORE DI 

TEMPERATURA

Columbo Lorenzo

Page 2: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 2/58

2

Introduzione

Obiettivi e caratteristiche generali del progettoIl progetto descritto nella presente relazione ha come prima finalità la comprensione delle

possibilità offerte dall'impiego di un microcontrollore in un sistema rivolto ad una specifica

applicazione, tale che richieda lo sviluppo di una determinata logica ma che non si esaurisca in essa.

Obiettivo successivo ma non secondario è l'apprendimento delle tecniche e l'utilizzo dei tools

disponibili per la programmazione del microcontrollore. Infine, è stato posto l'obiettivo di

sviluppare il flusso di progetto tipico di una scheda PCB, dalla rappresentazione dell'idea mediante

schema a blocchi fino alla generazione del layout.

In generale, un microcontrollore (MCU) è un dispositivo

elettronico integrato su singolo chip, nato comeevoluzione alternativa al microprocessore ed utilizzato

per applicazioni specifiche di controllo digitale. Il primo

processore a 8 bit (lo 8008, in Fig.1) venne proposto sul

mercato da Intel all'inizio degli anni '70, ed era costituito

unicamente da una semplice ALU e da una unità di

controllo in grado di gestire il flusso di dati e indirizzi

tra la ALU e la circuiteria esterna di supporto. Losviluppo tecnologico di questo tipo di dispositivi fu rapidissimo, e caratterizzato naturalmente da

una sempre crescente potenza di calcolo e complessità della struttura interna. Nonostante ciò, i

microprocessori (brevemente, CPU) continuarono nel tempo a richiedere l'utilizzo di unità

periferiche esterne per l'espletamento di funzioni che non

riguardassero strettamente l'elaborazione e il calcolo [1].

Proprio questo tipo di esigenza condusse allora alla

realizzazione dei microcontrollori (il primo dei quali, l'8048

della Intel, rappresentato in Fig.2, fu rilasciato nel 1975): si

trattava di sistemi completi che integravano in uno stesso

chip il processore, la memoria, i canali di I/O ed eventuali

altri blocchi in grado di svolgere funzioni altamente

specifiche. Di conseguenza, a differenza dei microprocessori classici, di fatto sistemi general

purpose, i microcontrollori furono (e sono tutt'ora) progettati per ottenere la massima

autosufficienza funzionale ed ottimizzare il rapporto prezzo-prestazioni in una specifica

applicazione. Il successo commerciale di questo genere di prodotto fu enorme. Tra i fattori che lo

determinarono, figurano sicuramente [2]:

Figura 1: Il primo microprocessore a 8 bit (Intel8008). 

Figura 2: Il primo microcontrollore (Intel8048). 

Page 3: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 3/58

3

  Il basso costo dei sistemi che consentono di realizzare, integrando al loro interno unità

funzionali che dovrebbero altrimenti essere introdotte mediante ulteriori dispositivi;

  Ampia scalabilità di prestazioni, in termini di potenza di calcolo e di complessità funzionale,

nonché elevata varietà di dotazioni in periferiche e moduli specializzati;

  Facilità di programmazione, garantita dall'esistenza di numerosi tools di sviluppo e dalla

larga disponibilità di documentazione, librerie e codici di esempio.

Non di rado, una volta individuato il produttore e il modello del MCU che si intende impiegare, la

scelta dell'ambiente di sviluppo cade sul relativo IDE (Integrated Devolopment Environment)

proprietario: è il caso ad esempio degli affermati PIC della Microchip e del relativo ambiente

MPLAB. Una scelta diversa è stata operata nell'ambito del presente progetto: il microcontrollore

impiegato è infatti il più tradizionale (e meno complesso) 80C32 della Philips, per la

programmazione del quale è stato utilizzato il semplice e potente ambiente di sviluppo Keil-

uVision. Tale IDE si è infatti rivelato in grado di unire ad un efficiente compilatore C utilissimi

tools quali un disassembler chiaro e preciso e un pratico debugger, completo di visuale su memoria

interna e periferiche del micro. Ulteriori dettagli relativi alle caratteristiche tecniche del micro e

dell'IDE impiegati sono riportati nei capitoli successivi.

Per quanto riguarda il flusso di progetto della PCB, il software CAD utilizzato è il popolare

pacchetto Orcad nella sua versione 9.2: in particolare, sono stati impiegati i tools Orcad Capture e

Orcad Layout. Il principale punto di forza di questa soluzione CAD è infatti proprio la funzione di

interfacciamento tra i due tools, che consente di passare rapidamente dal disegno schematico alla

disposizione dei dispositivi e dei componenti sulla scheda, quindi allo sbroglio automatico e alla

stampa su lucido di piste, vias e pad (nonché alla generazione di quei file Gerber impiegati dalle

macchine CNC per la produzione del circuito stampato).

Descrizione generale del sistemaLa specifica applicazione scelta è la rilevazione simultanea di misure di temperatura da un array di

sensori, disposti in linea in modo tale da consentire successive misure derivate di valore medio egradiente termico. Si richiede inoltre che le misure derivate vengano mostrate in tempo reale su un

display LCD, e che invece quelle dirette vengano eventualmente, su richiesta dell'utente, trasmesse

ad un personal computer connesso alla PCB mediante standard RS-232. Il sistema complessivo

includerà allora necessariamente un applicativo in grado di interfacciarsi alle porte seriali ed

effettuare semplici operazioni di elaborazione, rappresentazione e archiviazione delle misure

acquisite. Ulteriori dettagli relativi allo sviluppo di tale applicativo sono riportati in appendice.

Lo schema a blocchi generale del sistema progettato è quindi riportato in Fig.3:

Page 4: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 4/58

4

Figura 3: Schema a blocchi del sistema realizzato.

Già in questa prima rappresentazione si comprende che si avrà a che fare con una parte analogica

estremamente ridotta, costituita essenzialmente dai quattro sensori di temperatura e da un blocco

che implementi il riferimento di tensione necessario (come descritto più avanti, esso sarà ottenuto

semplicemente dall'impiego opportuno di un integrato basato su diodo zener). Come evidenziato, il

micro dovrà fornire all'ADC e al MUX gli opportuni segnali di controllo, oltre che acquisire le

misurazioni di volta in volta prodotte dal convertitore, per il quale si è scelta la dimensione di 8 bit

(adeguata alle porte di I/O del micro). Allo stesso tempo, il micro produrrà in uscita i segnali di dati

e di controllo necessari a rappresentare sul display LCD le misure indirette calcolate e a trasmettere

sulla seriale le misure dirette acquisite.

Presentazione dello schematicoRispetto allo schema a blocchi già mostrato, lo schematico in Fig.4 chiarisce alcuni importanti

dettagli implementativi.

Figura 4: Schematico del circuito realizzato.

Page 5: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 5/58

5

Innanzitutto, in questa versione dello schematico, finalizzata alla sola documentazione, si è preferito

non evidenziare, per comodità di rappresentazione, su tutti gli integrati la presenza dei pin VCC e

GND e delle relative connessioni alle linee di alimentazione (ad esempio, è il caso tra gli altri dei

quattro sensori di temperatura TSENSX).

Nell'implementare lo schema a blocchi descritto in un circuito, si è voluto rendere il riferimento di

tensione fornito all'ADC preciso ed eventualmente regolabile mediante l'impiego di un trimmer da 1

k , tale cioè da garantire che gran parte della corrente erogata dalla alimentazione sul ramo relativo

a R6 (resistenza di limitazione) finisca nel trimmer e non nel carico su cui si vuole realizzare il

riferimento.

Come si evince dallo schematico, inoltre, per la trasmissione dei bit convertiti tra l'ADC e il micro

si è scelto di adottare la tecnica della mappatura in memoria di una periferica: in pratica, la porta

dati dell'ADC è stata posta sulla stessa porta sulla quale il micro legge dalla ROM gli 8 bit relativi

alle istruzioni che deve ad ogni colpo di clock eseguire. I dettagli relativi all'implementazione di

questa tecnica sono riportati nella sezione relativa al codice C sviluppato. Per il momento, si

osserva soltanto come le porte di I/O del micro P0 e P2 siano di fatto speciali, perché preposte dalla

stessa struttura interna del micro a interfacciare quest'ultimo con le porte indirizzo e dati della ROM

contenente il codice macchina da eseguire.

Diversamente dall'ADC, il display LCD è stato posto direttamente su una porta di I/O semplice, che

dedica ad esso 6 dei suoi 8 pin. In particolare, i pin da P1.0 a P1.3 sono destinati a scambiare con il

display i byte di dati: in generale, questi byte potrebbero viaggiare sia dal micro al display,

rappresentando quindi ad esempio i caratteri che il display dovrà mostrare (ma, come si vedrà in

seguito, non solo), sia dal display al micro. La direzionalità di queste linee viene allora istante per

istante ad essere determinata dal valore assunto dal bit R/W (sempre in lettura sul relativo pin del

display): il fatto di mantenere tale bit forzato a 0 implica che il display si porrà sempre in lettura

sulla porta dati. Le altre due linee, En e RS, trasportano segnali di controllo diretti dal micro al

display: la loro funzione sarà chiarita nella sezione relativa al display impiegato.

Una sezione del tutto assente nello schema a blocchi e introdotta a questo livello è invece l'array didiodi LED in basso a destra nello schematico, ciascuno dei quali in serie ad una propria resistenza

di limitazione da 1.2 k  (adatta cioè ad una alimentazione di 5 V e ad una corrente erogata sul

carico dell'ordine di qualche mA). Ciascuno di questi LED (che nel layout finale della scheda

verranno posti accanto al display LCD) è atto a segnalare uno specifico stato del sistema. In

particolare: D1 (verde) indica quando acceso lo stato di ON del sistema, quando spento lo stato di

OFF; D2 (rosso) indica quando acceso che il valore medio di temperatura calcolato supera un certo

livello di soglia superiore prefissato, viceversa quando spento; D3 (blu) indica quando acceso che il

Page 6: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 6/58

6

valore medio di temperatura calcolato si trova al di sotto di un certo livello di soglia inferiore

prefissato, viceversa quando spento.

Il dispositivo D-LATCH svolge la funzione di garantire al micro l'accesso alla memoria programma

esterna ROM (e ad un eventuale memoria dati che però non è prevista nella nostra applicazione).

L'idea implementata è la seguente: quando il micro deve accedere al contenuto di una memoria

esterna, ad un assegnato indirizzo, esso innanzitutto produrrà sulla porta P0 la parte bassa

dell'indirizzo stesso; successivamente, invierà un impulso sull'ingresso di controllo del latch,

ottenendo e produrrà sulla porta P2 la parte alta dell'indirizzo. A questo punto, la porta P0 è in

lettura e l'indirizzo è completo all'ingresso della ROM (oppure, eventualmente, di entrambe le

ROM, nel caso in cui sia prevista anche una memoria dati esterna). L'operazione successiva del

micro è quindi l'invio di un impulso sulla linea di controllo della ROM: tale segnale produce in

uscita alla ROM il byte che era presente all'indirizzo di memoria selezionato, che nel nostro caso è

proprio l'istruzione che il micro dovrà eseguire. Essa viene quindi letta dal micro sulla porta P0.

Facciamo infine qualche considerazione relativa alla componentistica passiva. La cella RC

costituita da R5 e C6 ha unicamente la funzione di consentire all'ADC la generazione di un segnale

di clock di frequenza opportuna (tutto ciò sarà più chiaro nella sezione relativa all'ADC impiegato).

La cella RC costituita da R7 e C2 ha invece la funzione di garantire al microcontrollore il necessario

reset iniziale, a seguito della accensione (per questo motivo, tale blocco non è stato realizzato in

fase di emulazione, quando è il sistema di emulazione stesso che provvede al reset del micro). I due

condensatori C3 e C4, assieme al componente XTAL e all'amplificatore invertente integrato nel

micro tra i due pin indicati, costituiscono un oscillatore Colpitts quarzato che fornisce al micro

stesso il necessario segnale di clock (in questo caso, a 11.0592 MHz: il perché di tale specifico

valore sarà chiaro nella sezione relativa al microcontrollore e al baud-rate della UART). Le quattro

capacità elettrolitiche C5, C6, C7, C8 da 1 F sono semplicemente richieste dal convertitore di

protocollo HIN232 per il suo normale funzionamento (il motivo per il quale esse non sono state

integrate nel dispositivo è probabilmente la difficoltà di realizzare in forma integrata capacità di

dimensioni così elevate). Il componente indicato con la sigla CON9 è semplicemente il tipicoconnettore femmina DE-9 dello standard RS-232, del quale, come evidente, il sistema impiega

unicamente i pin 2, 3 e 5 (ovvero quelli relativi rispettivamente ai segnali in ricezione, in

trasmissione e al riferimento di massa).

Page 7: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 7/58

7

 Analisi dei dispositivi impiegati

PremessaNel presente capitolo verrà fornita una descrizione del principio di funzionamento, delle specifiche

funzionali e della struttura interna di ciascuno dei dispositivi impiegati (naturalmente, verranno

assunti i datasheet come principale riferimento bibliografico), con un grado di dettaglio sufficiente a

comprendere la collocazione del dispositivo nel sistema complessivo e le modalità di interazione

(eventuali segnali di controllo scambiati, timing, componentistica passiva di supporto, ecc.). Non si

è ritenuto opportuno approfondire nel dettaglio il funzionamento della ROM e del D-Latch

impiegati e riportati nello schematico, considerato il fatto che il loro utilizzo non attiene

strettamente alla specifica applicazione sviluppata.

LM35 (Sensore di temperatura)L'integrato LM35 è un sensore di temperatura in grado di riprodurre in maniera precisa e affidabile

una tensione di uscita linearmente proporzionale alla temperatura cui è esposto, misurata

direttamente in gradi centigradi. Per applicazioni che, come quella discussa, richiedono l'utilizzo di

questo tipo di scala, l'LM35 presenta allora un importante vantaggio su analoghi sensori calibrati

però in gradi Kelvin, che costringono, per ottenere la temperatura in °C, a sottrarre dalla loro uscita

una tensione costante di valore piuttosto grande.

Il sensore LM35 offre una accuratezza tipica di ± ¼ °C su un range di temperature che si può

estendere da -55 °C fino a 150°C. Il basso costo associato al suo impiego è assicurato dal fatto che

il dispositivo non richiede la calibrazione dall'esterno. Inoltre, la sua bassa impedenza di uscita e la

sua elevata linearità rendono l'interfacciamento verso il readout e la circuiteria di controllo

particolarmente immediato. Nondimeno, il sensore consente indifferentemente l'impiego di una

alimentazione singola o duale e produce un assorbimento di corrente bassissimo (circa 60 A): da

questo segue un effetto di self-heating molto basso. Il package del dispositivo impiegato è un TO-

92, quindi a 3 pin.

Facciamo infine qualche considerazione sul modo in cui la

tensione di uscita del sensore verrà letta: la Fig.5 (riportata

direttamente dal datasheet del dispositivo) mostra la semplice

configurazione in cui il sensore verrà impiegato. Assumiamo per le

temperature misurate un range esteso tra 0 °C e 128 °C: in questo

modo, per effetto della sensibilità di 10 mV/°C si tratterà di

misurare all'uscita del sensore una tensione compresa tra 0 V e 1.28

V. L'ADC impiegato quantizza a 8 bit, il che vuol dire che sarà possibile distinguere 28 = 256 valori

Figura 5: Configurazione del

sensore LM35.

Page 8: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 8/58

8

di tensione al suo ingresso. Suddividendo il fondo scala ipotizzato in maniera uniforme, saremo in

grado di acquisire tutti i valori di temperatura compresi tra 0 °C e 127.5 °C a passo di 0.5 °C: da

queste considerazioni, come vedremo, seguirà il calcolo del valore opportuno per la tensione di

riferimento da fornire all'ADC. Come si evince dallo schematico rappresentato, ciascuno di questi

sensori sarà associato ad uno specifico indirizzo del multiplexer analogico, pilotato dal

microcontrollore: quest'ultimo sarà allora in grado di distinguere e conservare memoria di quale dei

quattro sensori impiegati ha prodotto uno specifico valore di temperatura acquisito.

LM385 (Riferimento di tensione)L'integrato LM385 è un riferimento di tensione a band-gap, regolabile e a

3 terminali. Alimentato con una tensione singola compresa tra 1.24 V e

5.3 V, esso produce un riferimento di tensione fisso di valore tipico 1.24

V e assorbe una corrente compresa tra 10 A e 20 mA. I principali

features del dispositivo sono un'impedenza di piccolo segnale

eccezionalmente bassa e una buona stabilità termica, oltre che un'elevata

precisione sul riferimento di tensione fornito. Altre caratteristiche

interessanti risultano una bassa rumorosità e una elevata resistenza del

dispositivo nel tempo.

La modalità in cui il riferimento verrà impiegato è descritta dalla Fig.6,

eccezion fatta unicamente per il valore della tensione di alimentazione

(nel nostro caso 5 V) e, di conseguenza, per il valore opportuno della resistenza di limitazione da

impiegare. Subito a valle del riferimento a 1.24 V, la presenza di un trimmer di valore

sufficientemente piccolo (nel nostro caso, 1 k ) consente di produrre su un terzo nodo una tensione

di riferimento del valore desiderato, ovvero 0.64 V (il motivo della necessità di questo riferimento è

chiarito nella sezione relativa all'ADC).

 ADC0804 (Convertitore Analogico/Digitale)L'integrato ADC0804 è un convertitore analogico/digitale CMOS a 8 bit ad approssimazioni

successive, che usa una scala differenziale potenziometrica. Esso viene visto dai microprocessori

come una locazione di memoria o una porta di I/O, ovvero non richiede l'introduzione di ulteriore

logica di interfaccia. L'ingresso analogico a tensione differenziale consente di ottenere una migliore

reiezione di modo comune; inoltre riferimento dell'ADC può essere regolato, agendo su un

opportuno pin, in modo tale da codificare qualunque fondo scala, per quanto piccolo, utilizzando

tutti gli 8 bit di risoluzione (compatibilmente, com'è ovvio, alle specifiche di rumore del

dispositivo). I limiti imposti per il valore della tensione di alimentazione (da 4.5 V a 6.3 V) sono

Figura 6: Configurazioneper la generazione di una

VREF a 1.24 V. 

Page 9: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 9/58

9

perfettamente compatibili con l'alimentazione a 5 V disponibile; l'assorbimento di corrente tipico

dell'integrato è pari a 2.5 mA.

La configurazione con la quale il dispositivo viene impiegato dal sistema è mostrata in Fig.7: sulla

parte sinistra dell'integrato si distinguono gli I/O digitali, di controllo (i primi quattro) e di dati (gli

ultimi otto); sulla parte destra sono stati rappresentati i restanti otto I/O analogici, corrispondenti ai

pin di alimentazione (si osservi che, benché l'integrato offra la possibilità di distinguere massa

analogica e digitale, nella nostra applicazione i due pin saranno posti sullo stesso nodo), i due pin

per la generazione del segnale di clock, i due pin relativi all'ingresso differenziale e il pin destinato

a leggere un eventuale riferimento di tensione esterno, mediante il quale è possibile regolare il

fondo scala dell'ADC.

Prima di tutto, focalizziamo l'attenzione sulle problematiche relative agli ingressi analogici da

fornire al dispositivo. Per la generazione del segnale di clock, si propongono due alternative:

derivarlo direttamente da quello del micro oppure utilizzare la soluzione descritta in Fig.7 (ed

effettivamente implementata), ottenuta mediante un gruppo RC esterno e un trigger di Schmitt

integrato nel dispositivo. Dati i valori di R e C, si può valutare la frequenza del segnale di clock 

ottenuto dalla formula f CLK = 1/(1.1*R*C): in corrispondenza dei valori scelti in Fig.7 si ottiene un

valore di f CLK pari a 606.1 kHz; diversamente, per i valori R = 10 k  e C = 100 pF (ovvero quelli

scelti per la nostra applicazione, come desumibile dallo schematico di Fig.4) si ha f CLK = 909.1 kHz.

Risulta importante osservare che tale comportamento ideale si ottiene a patto di non caricare il pin

CLK R con una capacità parassita troppo grande (nel caso in cui si voglia utilizzare il segnale di

clock così generato anche per altri scopi): sono consentiti valori di capacità di carico fino a 50 pF,

che corrisponderebbe a 7 convertitori A/D di questo tipo pilotati dal clock di uno solo.

Discutiamo ora il riferimento di tensione da porre sul pin VREF /2. L'ADC è stato progettato in modo

tale che, se questo pin viene lasciato floating, il fondo scala si estende da 0 V a VCC. In pratica, la

tensione di riferimento impiegata dall'integrato può essere pari o a metà della VCC oppure alla

Figura 7: Configurazione di utilizzo dell'ADC0804. 

Page 10: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 10/58

10

tensione forzata dall'esterno sul pin VREF  /2 (il guadagno

interno in corrispondenza del pin di ingresso VREF /2 è pari

a 2, così che la tensione di ingresso differenziale

corrispondente al fondo scala risulta pari a due volte la

tensione applicata al pin 9: si veda la Fig.8). Per maggiore

chiarezza, facciamo un esempio numerico. Se i valori

dell'ingresso analogico differenziale (VIN(+) - VIN(-))

cadono nel range compreso tra 0.5 V e 3.5 V, lo span che

si vorrebbe ottenere è pari a 3 V: si potrebbe allora porre

un valore di tensione pari a 0.5 V sul pin VIN(-), in modo

tale da assorbire l'offset, e uno pari a metà di 3 V, ovvero

1.5 V, sul pin VREF /2. In questo modo, si è effettivamente

adattato il fondo scala dell'ADC alla dinamica del segnale

di ingresso, producendo un ovvio miglioramento in termini

di risoluzione ottenuta. Nel nostro sistema, il segnale da convertire sarà di fatto l'uscita prodotta da

ciascuno dei sensori di temperatura utilizzati: la dinamica di ingresso dell'ADC sarà quindi estesa

tra 0 V e, come anticipato, 1.28 V, nelle nostre ipotesi. Si dovrà allora porre sul pin 9 dell'ADC0804

una VREF /2 pari a 0.64 V: nella sezione relativa al LM385 abbiamo già discusso come ciò è stato

ottenuto.

Focalizziamo ora l'attenzione sui segnali di controllo che l'ADC dovrà scambiare con il

microcontrollore affinché il suo corretto funzionamento sia garantito: si tratta dei segnali CS (Chip

Select), RD (Read Strobe), WR (Write Strobe) e INTR (Interrupt), ciascuno con una sua specifica

funzione e tutti attivi bassi. La procedura di dialogo tra micro e ADC si compie in due fasi. La

prima fase è quella di avvio della conversione (il diagramma temporale è riportato in Fig.9). Come

Figura 8: Circuito per la generazione delriferimento nell'ADC0804. 

Figura 9: Diagramma temporale della fase di avvio conversione. 

Page 11: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 11/58

11

si evince dal diagramma, ciò che di fatto avvia la conversione è l'attivazione (transizione alto-basso)

prima del CS, poi del WR, in modo tale che l'impulso di WR sia tutto contenuto all'interno

dell'impulso sulla linea CS. In questa fase, il segnale INTR è a livello logico alto. A questo punto,

l'ADC legge il valore analogico di tensione differenziale ai suoi ingressi e produce in uscita la

parola di conversione: a partire dal ritorno a livello logico alto di WR, si dovrà aspettare un primo

intervallo di tempo di preparazione della conversione stessa, che come evidenziato nel diagramma,

si può estendere tra 1 e 8 volte il periodo di clock dell'ADC, e un secondo intervallo di tempo

associato alla conversione vera e propria e di durata TC (tempo di conversione). Per il valore di TC il

datasheet dichiara un valore minimo di 66 e massimo di 73 cicli di clock: se il valore vero di TC 

fosse 70 cicli di clock, il tempo impiegato dal nostro ADC ad effettuare la conversione sarebbe, per

quanto detto, pari a 70*(1/909.1 kHz) = 77 s. Al termine di questa fase, l'ADC stesso attiva (porta

a livello logico basso) il segnale di INTR: tale segnale, allora, indica che la fase di lettura e

conversione è terminata. Si può procedere quindi alla seconda fase, ovvero quella di lettura della

parola di conversione prodotta (diagramma temporale in Fig.10). Si tratta di ripetere la sequenza di

commutazioni vista per i segnali CS e WR all'inizio della fase precedente semplicemente

sostituendo a WR il segnale RD: si deve cioè produrre un impulso di RD tutto contenuto all'interno

di un impulso di CS. Come si evince dal diagramma, e in perfetta simmetria con quanto descritto

nella fase precedente, già dopo la commutazione alto-basso del RD (e un successivo tempo di attesa

indicato con tACC e pari a 135 ns), i bit di dati iniziano a essere validi e la parola di conversione può

essere letta. Il ritorno a livello logico alto di RD indica all'ADC che la lettura della parola è stata

completata: di conseguenza, il dispositivo riporta i pin relativi alle bit dati di uscita ad alta

impedenza. Risulta immediato allora intuire che il CS agisce come una specie di abilitazione della

comunicazione per l'ADC, mentre l'INTR ha lo scopo di segnalare all'eventuale micro che userà il

Figura 10: Diagramma temporale della fase di lettura della parola di conversione. 

Page 12: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 12/58

12

dispositivo che l'operazione di conversione si è conclusa con successo: queste considerazioni

conducono in maniera diretta alla soluzione che si è scelto di implementare e che verrà descritta in

maniera dettagliata nel capitolo seguente, relativo al microcontrollore e alla sua programmazione. 

L2014 (Display LCD)Il modulo L2014 è un display a cristalli liquidi (LCD) a matrice di punti a basso consumo di

potenza, caratterizzato da un pannello LCD ampio e ad alto contrasto e un controllore CMOS

integrato. Tutte le funzioni del display sono controllate da istruzioni, quindi il modulo è

particolarmente adatto ad essere interfacciato con un microprocessore (o, nel nostro caso, con un

microcontrollore). Questo rende ovviamente il modulo utilizzabile in un'ampia gamma di

applicazioni.

Il display è in grado di mostrare 20 caratteri, ciascuno ottenuto come una matrice di punti 5x7, su 4

linee. Esso include al suo interno una memoria ROM in grado di generare 192 tipi di caratteri (con

la possibilità di generarne altri arbitrari mediante una apposita area RAM), una memoria dati di t ipo

RAM di dimensione 80 bytes, leggibile anche dal MPU, un oscillatore e un circuito di reset

all'avvio integrati (di conseguenza non occorre fornire tali segnali dall'esterno). Risulta inoltre

possibile interfacciare il display con MPU a 4 e 8 bit. Il dispositivo richiede una alimentazione

singola a 5 V e tipicamente assorbe una corrente di 2.7 mA. Il modulo è in grado di operare in un

range di temperature che si estende da 0 °C a 50 °C.

Il dispositivo presenta 14 pin in linea, il simbolo di ciascuno dei quali è

riportato nella tabella di Fig.11. VSS e VDD sono i pin di alimentazione

(fissati rispettivamente a tensioni di 0 V e 5 V), mentre VLC è un pin su

cui si può agire con un riferimento di tensione in modo da variare il

contrasto dei cristalli liquidi (tale pin viene posto a massa, in modo da

ottenere dal display il massimo contrasto; RS è il pin associato al segnale

di Register Select: quando alto, il display e il micro stanno scambiando

dati, quando basso istruzioni o flag di controllo; R/W è il pin associato alsegnale di Read/Write: quando alto, il display è in scrittura sul bus dati,

quando basso è in lettura (nello schematico, tale pin viene fissato a

massa in quanto la nostra applicazione non richiede che venga scambiata

alcuna informazione dal display verso il micro); E è il pin associato al

segnale di Enable: per effettuare una qualsiasi operazione, un impulso su

questa linea è necessario affinché essa venga avviata; i pin indicati con

DBX sono quelli associati al bus dati: nella nostra specifica applicazione, solo la seconda metà di

questo bus viene utilizzato, e quindi parole di 8 bit verranno scambiate in due fasi successive (di

Figura 11: Simboli associati aipin del modulo L2014. 

Page 13: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 13/58

13

conseguenza, i primi 4 bit di questo bus restano, nello schematico mostrato, privi di connessioni

elettriche).

Il modulo L2014 si presenta piuttosto versatile: risulta d'altra parte opportuno, per ragioni di

brevità, focalizzare l'attenzione unicamente su quelle funzionalità che vengono utilizzate nella

nostra specifica applicazione. L'unica nostra esigenza è quella di scrivere linee di testo predefinite

sul display: si tratterà allora essenzialmente di essere in grado di trasmettere dal micro verso il

display istruzioni e dati. Abbiamo già detto che è il bit RS a indicare di volta in volta se una data

parola trasmessa dal micro al display è una parola di istruzioni o di dati (in questo secondo caso,

nient'altro che un singolo carattere). Restano allora da chiarire due aspetti: quali segnali di controllo

produrre per assicurare che il trasferimento della parola dal micro al display avvenga correttamente

e, in secondo luogo, quale significato associa il display a un dato byte ricevuto (in maniera più

concreta, si dovrà conoscere la lista delle istruzioni e la mappa dei caratteri).

La prima questione è risolta sinteticamente dalla Fig.12, che rappresenta il diagramma temporale

dei segnali di controllo da attivare per effettuare una operazione di scrittura sul modulo L2014 (la

linea "doppia", che indica un livello logico contemporaneamente alto e basso, corrisponde ad una

condizione "don't care").

Come si evince dal diagramma, si tratterà prima di tutto di porre il valore di RS al livello logico che

ci interessa, sulla base di quanto detto relativamente sul suo significato; in secondo luogo, si dovrà

porre a livello logico basso il pin R/W: stiamo effettuando un'operazione di scrittura;successivamente, si porterà il pin E, inizialmente basso, a livello alto. Poco tempo dopo, i bit

Figura 12: Diagramma temporale dei segnali di controllo per un'operazione di scrittura sul modulo L2014. 

Page 14: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 14/58

14

presenti sul bus dati verranno letti: è necessario che in questa fase essi rimangano stabili (per questo

motivo, è più semplice fare in modo che essi vengano stabiliti prima ancora dell'inizio

dell'operazione di scrittura e rimangano costanti per tutta la durata della stessa). Dopo un certo

intervallo di tempo minimo PWEH, è possibile concludere la procedura riportando il pin di E a

livello basso: com'è ovvio, tutti i valori dei tempi riportati sul diagramma sono commentati e

quantificati nel datasheet, ma è immediato osservare come tutti questi tempi, dell'ordine al più di

qualche centinaio di ns, risultino di fatto almeno di un ordine di grandezza inferiori ai tempi con cui

Figura 13: Lista delle istruzioni del modulo L2014. 

Page 15: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 15/58

15

il micro esegue le sue istruzioni. La schematizzazione che segue è allora molto semplice, soprattutto

nell'ipotesi posta per la quale R/W è fisso a livello basso: per effettuare un'operazione di scrittura

sul modulo L2014 sarà sufficiente scrivere il valore di RS, scrivere il valore dei bit sul bus, quindi

produrre un impulso alto sul pin di E (tale impulso viene prodotto dal micro nel modo più semplice

che si possa immaginare, come si evince dal codice C riportato nel capitolo seguente). Nel caso che,

come nella nostra applicazione, si utilizzino soli 4 bit del bus dati disponibile, la procedura resta

identica, con l'unica differenza che si dovranno trasferire separatamente, in due operazioni

successive di scrittura, la parte alta e la parte bassa della parola, dopo aver ovviamente settato il

modulo per lavorare in questa modalità operativa (è questa infatti, come spiegato subito di seguito,

una delle impostazioni che si può richiedere al modulo mediante la scrittura di un'istruzione).

Risolviamo a questo punto la seconda questione aperta, relativa a come il modulo interpreta le

parole che il micro scrive su di esso. La tabella in Fig.13 fornisce la lista completa delle istruzioni

disponibili del modulo L2014: ovviamente, non tutte queste istruzioni sono utili alla nostra

specifica applicazione. Commentiamo allora unicamente le istruzioni che verranno impiegate.

  (1) Display clear: pulisce il display e riporta il cursore alla posizione di partenza. Di default,

tale posizione coincide con l'indirizzo 0, in alto a sinistra, ma può essere cambiata (per la

mappa degli indirizzi associati a ciascuna posizione sul display, si veda la Fig. 14);

  (3) Entry Mode Set: imposta la direzione del movimento del cursore e se il display verrà

shiftato oppure no. L'istruzione prevede due parametri: il bit I/D determina se la posizione

del cursore verrà incrementata (I/D = 1) o decrementata (I/D = 0); il bit S determina se, in

corrispondenza di un'operazione di scrittura di un carattere, si effettuerà uno shift del display

(S = 1) oppure no (S = 0). Nella nostra applicazione, si porrà I/D = 1 e S = 0: il cursore verrà

incrementato e non verrà effettuato alcuno shift del display;

  (4) Display ON/OFF control: determina lo stato di accensione del display complessivo e del

cursore ed, eventualmente, avvia l'effetto di blinking sul cursore (per dettagli sull'effetto di

blinking, nient'altro che l'oscuramento intermittente di tutti i punti di un dato carattere).

L'istruzione prevede tre parametri: il bit D determina se il display vero e proprio è nello

stato ON (D = 1) oppure OFF (D = 0), il che non ha a che fare, ovviamente, con lo stato di

accensione del modulo (anche con il display spento, se l'alimentazione viene mantenuta il

modulo continua ad operare, ad esempio i dati scritti nella RAM del display vengono

conservati); il bit C determina se il cursore è mostrato sul display (C = 1) oppure no (C = 0);

il bit B determina se l'effetto di blinking sul carattere nella posizione del cursore è attivo (B

= 1) oppure no (B = 0). Nella nostra applicazione, si porrà D = 1, C = 1 e B = 0: il display

sarà sempre acceso, con il cursore mostrato e il blinking inattivo.

Page 16: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 16/58

16

  (6) Function Set: imposta alcuni parametri di funzionamento in base al valore assunto dai tre

parametri che contiene: il bit DL (Data Length) determina la lunghezza del bus dati

nell'interfacciamento verso il micro a 4 bit (DL = 0) o 8 bit (DL = 1); il bit N determina il

duty ratio, fissandolo a 1/16 (N = 1) o a 1/8 (N = 0); il bit F determina il carattere

tipografico, rendendolo una matrice di punti 5x10 (F = 1) o 5x7 (F = 0). Nella nostra

applicazione, si porrà DL = 0, N = 1 e F = 0: l'interfacciamento avverrà sempre a 4 bit, il

duty ratio sarà imposto a 1/16 (scelta obbligatoria, come indicato dal datasheet, per lo

specifico dispositivo L2014) e il carattere tipografico sarà inquadrato in una matrice di punti

5x7 (in realtà, per N = 0 il datasheet osserva che tale bit diventa per il modulo una

condizione don't care e il carattere tipografico è necessariamente quello indicato).

Figura 14: Mappa degli indirizzi della DD RAM sul display.

Resta da chiarire in che modo il modulo associa ad una data word ricevuta uno specifico carattere

tipografico e in quale punto del display stampa questo carattere. Come anticipato, il display può

essere visto come una RAM di 80 byte, ovvero 20 caratteri per 4 linee: il nome con cui si fa

riferimento a tale RAM sul datasheet è appunto DD RAM, ovvero Display Data RAM. Ciascuna

locazione di tale memoria è ovviamente associata ad un indirizzo (esprimibile in due cifre

esadecimali) e ad una specifica posizione sul display. In assenza di shift, la mappa delle locazioni

della RAM sulle varie posizioni del display è in Fig. 14.

Semplicemente, gli indirizzi della DD RAM compresi tra 0x00 0x13 sono posti nella linea 1, quelli

compresi tra 0x40 e 0x53 nella linea 2, quelli compresi tra 0x14 e 0x27 nella linea 3, infine quelli

compresi tra 0x54 e 0x67 nella linea 4. Quindi, risultano consecutive le linee 1 e 3 e le linee 2 e 4.

Nel momento in cui viene scritta una stringa di byte nella DD RAM, allora, si parte dalla posizione

corrente del cursore (eventualmente, quella iniziale, o anche posizione "home") e si procede per

indirizzi consecutivi. Sebbene esista la possibilità di spostare il cursore arbitrariamente sul display,

la nostra applicazione non richiede necessariamente questo tipo di azione. La Fig.15 mostra infine il

contenuto della ROM da 192 byte per la scrittura di uno dei caratteri "standard": l'operazione di

scrittura di un carattere sul display, nella sua forma più immediata, consisterà allora semplicemente

nella selezione di uno di questi caratteri attraverso una parola scritta sul bus dati, secondo le

corrispondenze indicate nella stessa Fig.15.

Page 17: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 17/58

17

Figura 15: Mappa dei caratteri standard per il modulo L2014. 

Page 18: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 18/58

18

In ultimo, anticipiamo che la procedura di inizializzazione (dettagliatamente commentata nella

sezione relativa alla descrizione del codice C sviluppato) si tradurrà in una sequenza di istruzioni

dei tipi visti e analizzati, da eseguire sul modulo prima del suo utilizzo vero e proprio.

CD74AC14E (Invertitore CMOS)L'integrato CD74AC14 contiene sei invertitori indipendenti. Questo dispositivo realizza

l'operazione booleana NOT mediante un trigger di Schmitt: gli invertitori hanno quindi differenti

tensioni di ingresso di soglia per le commutazioni basso-alto (VT+) e alto-basso (VT-). Più

precisamente, l'isteresi, definita come la differenza VT+ - VT-, ha un valore tipico di 0.5 V.

La tensione di alimentazione può essere compresa tra 1.5 V e 5.5 V; fissata la VCC, l'ingresso può

collocarsi tra 0 V e la VCC stessa. La corrente erogata dal dispositivo sul pin di uscita è, in

entrambi gli stati, pari a 24 mA.

La modalità, piuttosto tradizionale, in cui il dispositivo verrà impiegato nel sistema non richiede

l'indicazione di ulteriori dettagli. L'unica specifica che è opportuno focalizzare è il valore dei tempi

di commutazione, dell'ordine di qualche nanosecondo: si tratta di tempi del tutto trascurabili rispetto

a quelli con cui il micro svolge le sue operazioni (un clock a 11.0592 MHz equivale a un periodo di

circa 90 ns, senza contare che una singola istruzione richiede svariati cicli di clock per essere

completata: per ulteriori dettagli, si faccia riferimento al capitolo sul microcontrollore): potremo

allora considerare l'operazione di inversione tra IN e OUT istantanea. Si osserva infine che il

sistema utilizzerà una sola delle porte logiche messe a disposizione dall'integrato: come evidenziato

dallo schematico, gli altri ingressi e uscite verranno lasciate floating (in corrispondenza di questi e

altri nodi è stato utilizzato il simbolo Capture di "no connect").

HEF4051 (Multiplexer Analogico a 8 canali)L'integrato HEF4051 è un multiplexer analogico a 8 canali con tre ingressi di indirizzo, un ingresso

di enable attivo basso, otto ingressi indipendenti e un'uscita comune. L'operazione di multiplexing è

ottenuta mediante un array di 8 switch analogici bidirezionali tra gli ingressi e l'uscita. Con il pin di

enable basso, uno degli otto switch viene selezionato (stato di ON, bassa impedenza) in base ai

valori logici presenti sui pin di indirizzo. Viceversa, con enable alto, tutti gli switch si pongono in

alta impedenza, indipendentemente dal valore assunto dai bit di indirizzo.

VDD e VSS sono i pin di alimentazione per gli ingressi di controllo digitali (quelli di indirizzo e

l'enable). La differenza di potenziale tra i due pin deve essere compresa tra 3 V e 15 V. I segnali

presenti sui pin analogici (gli ingressi e l'uscita comune) possono variare tra la stessa VDD (come

limite superiore) e la tensione posta su un terzo pin, indicato con VEE. La differenza VDD-VEE

non può superare il valore di 15 V. Affinché il dispositivo funzioni come un multiplexer digitale, si

deve cortocircuitare VEE a VSS (che tipicamente viene posto a massa).

Page 19: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 19/58

19

Nel nostro specifico caso, solo 4 degli 8 ingressi analogici disponibili verranno utilizzati: si tratterà

allora di porre a massa 1 dei 3 pin di selezione. Ad esempio, come verrà mostrato sia in fase di test

su breadboard sia in fase di realizzazione del layout, si può pensare di porre a massa il pin associato

al bit di indirizzo di peso più alto, quindi di utilizzare gli ingressi analogici indicizzati da 0 a 3.

Un'ultima osservazione da rilevare riguarda i ritardi di propagazione tra la variazione dei bit di

indirizzo e la variazione dell'uscita: tale ritardo corrisponde tipicamente a 150 ns. D'altra parte, a

differenza di quanto detto a proposito dell'inverter, tale delay non va confrontato con la durata del

clock, ma con il tempo impiegato dall'ADC a produrre la codifica (per ulteriori dettagli, si faccia

riferimento alle sezioni relative al timing dell'ADC e al codice sviluppato).

HIN232 (Adattatore di livello RS-232)L'integrato HIN232 è un'interfaccia per la trans/ricezione verso una porta RS-232 particolarmente

adatta a quelle applicazioni in cui la alimentazione a ± 12 V non è disponibile. Esso richiede una

alimentazione singola a 5 V e monta dei convertitori di tensione a pompa di carica che, partendo da

quella, generano una ulteriore tensione di alimentazione a ± 10 V richiesta dal funzionamento del

dispositivo stesso.

Alcuni dei principali features del dispositivo sono:

compatibilità CMOS e TTL all'ingresso, slew-rate

limitato sui segnali di uscita, un rate che può arrivare a

120 kbps, bassa dissipazione di potenza.

In Fig.16 è riportata la modalità in cui i condensatori

esterni da 1 F o da 0.1F (come descritto in NOTE 1,

sul datasheet) devono essere connessi al dispositivo. Il

simbolo circuitale utilizzato indica esplicitamente, se

ce ne fosse bisogno, che si debba trattare di

condensatori elettrolitici.

Il massimo valore consentito per la tensione dialimentazione è 6 V, la corrente assorbita è

tipicamente pari a 5 mA; le tensioni di soglia superiore

(per livello basso) e inferiore (per livello alto)

all'ingresso sono rispettivamente 0.8 V e 2 V. La minima tensione sul pin di enable che abilita il

relativo bit è 2.4 V (nello schematico proposto, tale pin è posto direttamente a massa).

Il datasheet del dispositivo offre ulteriori dettagli strutturali e funzionali del dispositivo; d'altra

parte, un ulteriore approfondimento di questi aspetti non risulta propedeutico alla comprensione del

funzionamento del sistema realizzato, quindi verrà tralasciato.

Figura 16: Pinout e connessione dei condensatori disupporto per l'integrato HIN232. 

Page 20: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 20/58

20

Il microcontrollore 80C32

Descrizione generale del dispositivoL'integrato 80C32, prodotto dalla Philips, è un microcontrollore ad alte prestazioni basato

sull'architettura dell'8051 e fabbricato mediante il processo tecnologico CMOS ad alta densità di

integrazione della Philips stessa.

Il dispositivo, privo di ROM al suo interno, contiene una RAM da 256 byte, 32 linee di I/O

parallelo (in pratica, 4 porte ciascuna da 8 bit), tre contatori (o timer) a 16 bit, una struttura di

interrupt a 4 livelli di priorità, una porta di I/O seriale UART destinata a comunicazioni con altri

microprocessori, un circuito di clock on-chip.

Il dispositivo, pensato per lavorare con una tensione di alimentazione singola compresa tra 2.7 V e

5.5 V, ha anche un consumo di potenza statica particolarmente basso, oltre che due soluzionisoftware per la riduzione del consumo di potenza (poiché tali modalità di utilizzo non verranno

impiegate, esse non verranno discusse).

Il pinout dell'integrato è riportato in Fig.17. Ciascun simbolo associato a ciascun pin richiama

mnemonicamente una funzione. In particolare:

  VSS: riferimento di massa;

  VCC: tensione di alimentazione singola (positiva);

 

P0.0-7: la porta 0 è una porta bidirezionale a 8 bit inconfigurazione open drain. I pin di tale porta che presentano un

valore logico alto scritto su di essi vengono visti come floating,

e possono quindi essere usati come ingressi ad alta impedenza.

La porta 0 ha anche una funzione speciale, durante gli accessi

alla ROM esterna: essa fornisce la parte bassa dell'indirizzo cui

accedere e legge la parola prodotta dalla memoria stessa;

  P1.0-7: la porta 1 è una porta bidirezionale a 8 bit, tirata a VCC

da una rete di pull-up. Poiché i pin di tale porta presentano un

valore logico alto scritto su di essi dall'interno del micro, essi

possono essere usati come ingressi nel momento in cui li si

forzi a massa. Gli ultimi due pin della porta hanno anche una

funzione alternativa, che però non verrà utilizzata;

  P2.0-7: la porta 2 è una porta bidirezionale a 8 bit, tirata a VCC da una rete di pull-up.

Poiché i pin di tale porta presentano un valore logico alto scritto su di essi dall'interno del

micro, essi possono essere usati come ingressi nel momento in cui li si forzi a massa. La

porta 2 ha anche una funzione speciale, durante gli accessi alla ROM esterna: essa fornisce

Figura 17: Pinoutdell'integrato 80C32. 

Page 21: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 21/58

21

la parte alta dell'indirizzo cui accedere alla ROM, sia che si tratti del fetch di una istruzione

sia che si tratti della lettura di un dato;

  P3.0-7: la porta 3 è una porta bidirezionale a 8 bit, tirata a VCC da una rete di pull-up.

Poiché i pin di tale porta presentano un valore logico alto scritto su di essi dall'interno del

micro, essi possono essere usati come ingressi nel momento in cui li si forzi a massa. La

porta 3 assolve anche a numerose delle funzioni speciali associate ai features caratteristici

dei microcontrollori basati sull'architettura dell'8051: RxD e TxD sono rispettivamente

ingresso e uscita per la porta seriale; INT0 e INT1 sono gli ingressi associati all'interrupt

esterno; T0 e T1 sono gli ingressi esterni destinati al controllo dei timer; WR e RD sono

destinati rispettivamente ai segnali di write strobe e read strobe nelle fasi di accesso alla

memoria esterna (per la lettura di un dato);

  RST: è il pin di reset. Un valore alto su questo pin per due cicli macchina (naturalmente,

mentre l'oscillatore è in funzionamento) resetta il dispositivo. Un resistore integrato posto

verso VSS consente un reset all'accensione utilizzando unicamente un condensatore esterno

posto verso VCC (è la soluzione adottata nella nostra applicazione, si veda lo schematico);

  ALE: è il pin di Address Latch Enable, destinato al segnale di controllo per il D-Latch che

conserva memoria della parte bassa dell'indirizzo negli accessi alla memoria esterna.

Durante il normale funzionamento, il segnale di ALE è emesso a un rate costante di 1/6

della frequenza di oscillazione (esso viene saltato, invece, durante ogni istruzione di accesso

alla memoria dati esterna). Tale segnale può essere disabilitato settando un opportuno bit di

un SFR (si veda di seguito per maggiore chiarezza): in questo caso, l'impulso di ALE viene

prodotto unicamente durante un'istruzione di accesso alla memoria dati esterna (MOVX);

  PSEN: è il pin di Program Store Enable, destinato al segnale di controllo per la memoria

ROM esterna nelle fasi di fetch delle istruzioni da eseguire. Quando il microcontrollore sta

eseguendo un codice dalla memoria di programma esterna, PSEN viene attivato due volte ad

ogni ciclo di clock, eccetto quando l'istruzione in corso sia l'accesso alla memoria dati

esterna (in tal caso, l'impulso viene "saltato");

  EA/VPP: è il pin di External Access Enable. Tale pin deve essere mantenuto a valore logico

basso dall'esterno per abilitare il dispositivo a estrarre le istruzioni da eseguire dalla

memoria programmi esterna;

  XTAL1: ingresso dell'amplificatore invertente integrato per ottenere l'oscillatore;

  XTAL2: uscita dell'amplificatore invertente integrato per ottenere l'oscillatore.

Lo schema a blocchi del dispositivo 80C32 è riportato in Fig.18. Come già anticipato, l'architettura

di riferimento è quella dell'8051, con variazioni poco significative: i dettagli relativi al

Page 22: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 22/58

22

funzionamento del micro in uso saranno allora raccolti dall'ampia bibliografia dedicata ad esso (in

particolare, si farà riferimento al tutorial disponibile online al link http://www.8052.com/tut8051).

Per la ragione appena esposta, si rimanda alla sezione successiva di questo capitolo la piena

comprensione del principio di funzionamento che lo schema a blocchi in Fig.18 sottende.

L'architettura di riferimento: il microcontrollore 8051Secondo un approccio già utilizzato nelle sezioni precedenti, dell'architettura generale del micro

verranno focalizzati unicamente quegli aspetti che risultano imprescindibili ai fini della piena

comprensione del progetto realizzato. Verranno in particolare discusse caratteristiche quali: la

memoria e i registri speciali, il tempo di esecuzione di un'istruzione, la porta seriale e i timer, gli

interrupt.

Figura 18: Schema a blocchi del microcontrollore 80C32. 

Page 23: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 23/58

23

La memoria e i registri specialiL'8051 prevede in generale l'utilizzo di tre tipi di memoria: memoria on-chip, memoria di

programma esterna e memoria RAM esterna.

La memoria di programma è quella che contiene le istruzioni che il micro deve eseguire, è limitata a

64 kB (da cui segue che la dimensione degli indirizzi è di 16 bit) e può essere sotto forma di

EPROM interna o, come avviene nella maggior parte delle applicazioni, inclusa la nostra, esterna

(si veda lo schematico): in particolare, solo in quest'ultimo caso essa può raggiungere la dimensione

massima indicata. In realtà, anche se il progetto discusso non ne prevede, esistono espedienti

hardware (che non verranno discussi) per fare in modo che l'8051 sia in grado di indirizzare una

memoria programma più estesa di 64 kB.

L'8051 prevede anche l'utilizzo di una RAM esterna, anch'essa limitata a 64 kB, quindi più ampia,

ma ovviamente più lenta, della memoria interna disponibile on-chip (tale soluzione non verrà

comunque implementata nel presente progetto).Come anticipato, l'8051 include una RAM interna

montata on-chip, che si suddivide a sua volta in due

aree (si faccia riferimento alla Fig.19): RAM interna

e Area Registri Speciali (SFR è appunto l'acronimo

di Special Function Register). La RAM interna ha

un'estensione di 128 byte: è la memoria più veloce e

flessibile in lettura e scrittura (com'è ovvio, si tratta

tuttavia di una memoria volatile). Tale area è

costituita unicamente da:

  4 banchi di registri "R", per ciascun banco numerati da 0 a 7, destinati alla memorizzazione

di dati temporanei necessari ad una data operazione complessiva (ad esempio, un'addizione);

tra questi banchi, di default (all'accensione) è in uso il banco 0, ma si può modificare questa

impostazione agendo opportunamente sul valore di un SFR. Occorre osservare che ciascuna

locazione di questa area di memoria può essere indirizzata sia come un byte generico della

RAM interna sia come un registro (tale considerazione sarà chiara più avanti);

  una sezione di memoria indirizzabile a bit, compresa tra gli indirizzi da 0x20 a 0x2F. Tale

sezione, oltre a poter essere indirizzata a byte come qualsiasi altra locazione della RAM

interna, è anche quella cui fanno riferimento alcune istruzioni che operano appunto "a bit"

quali SETB e CLR, mediante gli indirizzi che richiedono come argomento (da 0x00 a 0x7F);

  una sezione (i restanti 80 byte), compresa tra l'indirizzo 0x30 e 0x7F, che può contenere

variabili utente cui si richiede di accedere in maniera frequente e veloce (tale area viene

utilizzata dal micro anche per le operazioni di stack, e risulta quindi spesso un po' esigua).

Figura 19: Schema della memoria interna dell'8051. 

Page 24: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 24/58

24

L'area SFR è costituita da registri che controllano specifiche funzionalità dell'8051. Per esempio, 4

registri SFR consentono l'accesso alle 32 linee di I/O parallelo, un altro consente di leggere e

scrivere sulla seriale, e così via. I registri di quest'area appaiono ancora come locazioni della RAM

interna, identiche alle altre ai fini dell'indirizzamento: benché non a tutte le locazioni di quest'area

(indirizzi compresi tra 0x80 e 0xFF) corrisponda uno specifico SFR, è altamente sconsigliato

utilizzare tali locazioni di memoria apparentemente "libere" come byte di memoria general purpose.

Di fatto, quindi, agire sui registri SFR vuol dire modificare in qualche modo la modalità operativa

del micro. I registri SFR dell'8051 standard sono 21, e ovviamente a ciascuno di essi è associato,

oltre ad un indirizzo, anche un nome mnemonico, utilizzato ad esempio nella programmazione C

dei microcontrollori (ciascun IDE dispone di librerie di file di intestazione che, fra le altre cose,

contengono queste associazioni tra gli indirizzi di memoria interna e i relativi alias degli SFR);

alcuni di questi, inoltre, sono accessibili a bit (i particolare, quelli associati a indirizzi multipli di 8).

Forniamo a questo punto una rapida panoramica degli SFR utilizzati dalla nostra applicazione:

  P0: è la porta P0 di I/O. Ciascun bit di questo registro corrisponde ad un pin del

microcontrollore. Per esempio, il bit 0 è il pin P0.0, il bit 7 è il pin P0.7. Settare un bit di

questo registro SFR equivale a forzare ad un livello alto il corrispondente pin di I/O, mentre

resettarlo equivale a forzarlo ad un livello basso. Lo stesso discorso può essere ripetuto in

perfetta analogia per gli altri SFR, associati alle porte parallele (P1, P2 e P3);

  SP: è lo stack pointer del microcontrollore, ovvero il registro che punta al prossimo valore

dello stack nella RAM interna. Se ad un certo punto del flusso di programma tale registro ha

valore x: la successiva istruzione di PUSH caricherà il valore indirizzato dall'argomento

nello stack, all'indirizzo x+1 (prima incrementa, poi carica); viceversa la successiva

istruzione di POP caricherà il valore dello stack all'indirizzo x in memoria all'indirizzo in

argomento (prima carica, poi decrementa);

  DPL/DPH: sono i registri di Data Pointer (rispettivamente parte bassa e parte alta). Il

registro corrispondente ai 16 bit complessivi (indicato con DPTR) è un intero compreso tra 0

e 65535 con la funzione di puntare a uno specifico indirizzo di una memoria esterna da, al

più (come anticipato), 64 kB, che sia di codice o di dati;

  TCON: è il registro di Timer Control, usato per configurare il modo di funzionamento dei

timer dell'8051; alcuni dei suoi bit sono invece destinati a configurare o segnalere gli

interrupt esterni (vedi sezioni sui timer e sugli interrupt);

  TMOD: è il registro di Timer Mode, usato per configurare il modo di funzionamento di

ciascuno dei due timer (vedi sezione sui timer);

  TL0/TH0: sono i registri che mantengono traccia dello stato corrente del timer 0,individuando un valore intero attraverso 16 bit; possono solo incrementare, e lo fanno a

Page 25: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 25/58

25

seconda del valore assunto da TMOD. Lo stesso discorso può essere ripetuto per TL1/TH1,

con riferimento al timer 1;

  SCON: è il registro di Serial Control, destinato alla configurazione e alla indicazione dello

stato della porta seriale (vedi sezione sulla porta seriale);

  SBUF: è il registro di Serial Buffer, usato per inviare e ricevere i dati dalla porta seriale

dell'8051. Ogni valore scritto dal micro in questo registro verrà inviato serialmente sul pin

TxD, viceversa ogni valore letto dal pin RxD verrà scritto su questo buffer e reso quindi

disponibile al programma in esecuzione sul micro;

  IE: è il registro di Interrupt Enable, usato per abilitare e disabilitare gli interrupt. I 7 bit

meno significativi di IE sono usati per l'abilitazione di ciascun interrupt individualmente,

mentre il bit più significativo è destinato all'abilitazione di tutti gli interrupt;

  IP: è il registro di Interrupt Priority, usato per cambiare la priorità di ciascun interrupt (essa

può essere alta, se il bit corrispondente a quello specifico interrupt è alto, o, viceversa,

bassa). Un interrupt può interrompere solo un altro interrupt a priorità più bassa;

  PSW: è il registro di Program Status Word, usato per memorizzare alcuni bit importanti che

vengono aggiornati nell'esecuzione delle istruzioni (ad esempio, flag di carry e di overflow);

  ACC: è l'accumulatore del micro, il registro più usato, poiché coinvolto in molte istruzioni;

  B: è un registro di supporto utilizzato solo per effettuare operazioni di moltiplicazione e

divisione. Può anche, all'occorrenza, essere usato per memorizzare valori temporanei.

Oltre ai già descritti SFR, esistono altri registri detti "registri base", che includono i già descritti

registri ACC, B e SP, ma ancora il PC e i registri "R". Il PC (Program Counter) è un indirizzo a 2

byte che punta alla locazione di memoria programma dove l'8051 andrà a prendere la prossima

istruzione da eseguire: di conseguenza, allo start-up varrà PC = 0x0000, nel normale flusso di

programma PC verrà incrementato (a seconda della lunghezza della istruzione corrente), mentre

durante l'esecuzione di istruzioni di controllo del flusso (e.g., istruzioni di salto incondizionato)

potrà essere fissato a qualsiasi valore intero a 16 bit. I registri "R" sono, come anticipato, un set di 8

registri denominati R0, R1 e così via fino a R7, utilizzati come registri ausiliari all'accumulatore in

molte operazioni (attraverso due bit del PSW è possibile impostare il banco di registri in uso).

Il tempo di esecuzione di un'istruzioneL'8051 opera sulla base di un clock fornito da un quarzo esterno, con una frequenza di risonanza

tipicamente (e nella nostra applicazione) pari a 11.059 MHz. Il micro opera allora sulla base dei

cosiddetti "cicli macchina": un singolo ciclo macchina è la minima quantità temporale che

un'istruzione dell'8051 richiede per essere eseguita (minima nel senso che l'esecuzione di alcune

istruzioni richiede più cicli macchina). Da un punto di vista fisico, un ciclo macchina corrisponde a

12 impulsi dell'oscillatore al quarzo: possiamo allora calcolare in maniera semplice quanti cicli

Page 26: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 26/58

26

macchina al secondo possono essere eseguiti dall'8051, ovvero 11.059.000/12 = 921.583. A questo

punto, mediando approssimativamente sul numero medio di cicli macchina per istruzione richiesto

dal set di istruzioni del micro, possiamo concludere con una stima di circa 600.000 istruzioni al

secondo mediamente eseguite dal micro, ovvero un tempo medio di esecuzione per una singola

istruzione di circa 1/600.000 sec-1 = 1.67 sec (tutte queste considerazioni hanno valore solo per

l'8051 standard, in quanto in molti suoi derivati il timing delle istruzioni è di fatto diverso).

La porta seriale e i timerL'8051 classico dispone di due timer, che possono essere configurati, controllati e letti in maniera

indipendente. Ciascuno di questi timer può assolvere a tre funzioni generali: tenere traccia del

tempo trascorso (ad esempio per misurare la distanza temporale tra due eventi), contare il numero di

eventi e generare il baud-rate per la porta seriale. Di queste tre funzioni, la nostra applicazione

impiega solo la terza: per questa ragione, discuteremo i timer unicamente da questo punto di vista.

La porta seriale, o UART integrata, è una delle funzionalità più potenti dell'8051: essa rende

possibile ottenere una comunicazione tra due sistemi a microcontrollore in maniera semplice e

veloce. Una volta configurata la porta, sarà sufficiente leggere o scrivere il registro SBUF già

presentato per ricevere od inviare dei dati in linea: sarà il micro col suo hardware ad "avvertirci"

(manipolando il valore di opportuni flag del registro SCON) quando un dato byte è stato ricevuto

(ed è quindi pronto per la lettura da SBUF) oppure la trasmissione seriale di un dato byte

(precedentemente scritto in SBUF) è stata completata.

L'inizializzazione della porta seriale richiede di agire essenzialmente sul registro SCON, già

presentato e indirizzabile a bit (l'indirizzo "a byte" di tale SFR è 0x98, quindi i suoi bit avranno

indirizzo compreso tra 0x98, bit meno significativo, e 0x9F, bit più significativo). Vediamo nel

dettaglio la funzione di ognuno dei suoi bit, in ordine decrescente di peso:

  SM0 (Serial Mode 0): bit 0 di modo;

  SM1 (Serial Mode 1): bit 1 di modo;

  SM2 (Serial Mode 2): abilitazione della comunicazione multiprocessore;

  REN (Receive Enable): abilitazione della ricezione;

  TB8 (Transmit Bit 8): nono bit da trasmettere nel modo 2 e 3;

  RB8 (Receive Bit 8): nono bit da ricevere nel modo 2 e 3;

  TI (Transmit Flag): flag che viene settato automaticamente quando il byte è stato trasmesso;

  RI (Receive Flag): flag che viene settato automaticamente quando un byte è stato ricevuto;

Innanzitutto, osserviamo che solo i 4 bit più significativi del registro hanno una funzione in fase di

configurazione (degli altri 4, utilizzeremo solo gli ultimi 2, ovvero i flag di trasmissione e ricezione:

le modalità in cui verranno impiegati saranno chiare nella sezione relativa al codice C): di questi,

verranno utilizzati effettivamente i bit SM0, SM1 e REN. L'ultimo è semplicemente il bit che abilita

Page 27: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 27/58

27

il micro a ricevere dati sulla porta seriale: ponendo REN = 0, si impedisce al micro di ricevere byte

dalla porta seriale.

A questo punto, dettagliamo meglio il significato dei bit di modo SM0 e SM1: la loro combinazione

fornisce la modalità operativa della UART, associabile ad un intero compreso fra 0 e 3 (ottenuto

ponendo SM0 a bit più significativo). La modalità 0 consiste nella trasmissione di 8 bit e fissa il

baud-rate della UART a un valore di f osc  /12; la modalità 1 consiste nella trasmissione di 8 bit e

deriva il baud-rate della UART dall'overflow del timer 1; la modalità 2 consiste nella trasmissione

di 9 bit e fissa il baud-rate della UART a un valore di f osc  /64; la modalità 3 consiste nella

trasmissione di 9 bit e deriva il baud-rate della UART dall'overflow del timer 1. Innanzitutto, la

porta seriale verrà utilizzata unicamente a 8 bit, quindi si tratterà di comprendere il funzionamento

delle modalità 0 e 1 e di scegliere quella più opportuna alle nostre esigenze. La differenza consiste,

come anticipato, unicamente nel modo in cui viene calcolato il baud rate, ovvero la frequenza di

simbolo della UART. Nel primo caso, esso risulta fissato unicamente dalla frequenza di clock: nella

modalità 0, il baud rate sarà inevitabilmente pari a 11.059.000/12 bps, ovvero circa 921.583 bps.

Tale valore non si adatta alla nostra applicazione, quindi la scelta della modalità 1 risulta

praticamente obbligata. Si tratta a questo punto di capire come impostare il timer 1 in modo tale che

il baud rate assuma il valore da noi desiderato, per esigenze di compatibilità con l'applicativo

sviluppato, assunto pari a 9600 bps: come anticipato, si dovrà allora mandare il timer 1 in overflow

proprio con questa frequenza.

Analizziamo a questo punto il funzionamento dei timer, con l'obiettivo di comprendere come

ottenere quanto richiesto. I due timer funzionano entrambi nella stessa maniera, e condividono i due

registri TCON e TMOD, destinati al loro controllo; come anticipato, d'altra parte, ciascun timer

dispone di due registri (valutabili come un unico registro da 16 bit) che mantengono traccia del loro

stato: si tratta dei registri TL0 e TH0 per il timer 0, TL1 e TH1 per il timer 1. Ad esempio, parlando

in decimali, quando il timer 0 ha valore 1000, TH0 conterrà il valore 3, TL0 il valore 232: noto il

valore scritto nei due registri, lo stato del timer 0 può essere indicato da un intero calcolabile come

TH0*256 + TL0. Ovviamente, lo stesso discorso può essere ripetuto identico per il timer 1. Segueallora che il valore decimale più grande che ciascun timer può assumere è 65535: quando uno dei

due timer raggiunge tale valore, un ulteriore impulso di clock lo resetterà o, per meglio dire, lo

manderà in overflow.

Prima di avviare ciascuno dei timer, tuttavia, è necessario stabilire la loro modalità operativa, in

analogia a quanto detto a proposito della UART: ciò viene ottenuto mediante il registro TMOD.

Esso è diviso in una parte alta destinata al timer 1 e una parte bassa destinata al timer 0. Ciascuna

parte è costituita da 4 bit, il cui valore stabilisce la modalità operativa di ciascuno dei due timer

Page 28: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 28/58

28

(anche questo registro è indirizzabile a bit). Ad esempio, con riferimento alla metà più significativa

di TCON, si hanno in ordine decrescente di peso i bit:

  GATE1: quando questo bit è settato, il timer 1 è attivo solo quando il pin P3.3 (indicato

anche con il simbolo INT1 nello schematico) è nello stato alto. Se tale bit è resettato, il timer

1 è svincolato dallo stato del pin P3.3;

  C/T1: quando questo bit è settato, il timer 1 conta il numero degli eventi sul pin P3.5

(indicato anche con il simbolo T1 nello schematico). Se tale bit è resettato, il timer 1 viene

incrementato ogni ciclo macchina;

  T1M1: bit 1 di modo del timer 1;

  T1M0: bit 0 di modo del timer 1.

La parte bassa del registro presenta bit di analoghe funzioni per il timer 0. I modi operativi definiti

dai bit T1M1 e T1M0 possono essere associati, analogamente a quanto visto per i bit SM, a interi da

0 a 3. La modalità 0 è detta "timer a 13 bit" ed è presente nell'8051 unicamente per mantenere la

compatibilità col suo predecessore, l'8048 (non è quindi generalmente utilizzata nei nuovi sviluppi);

la modalità 1 è detta "timer a 16 bit", e prevede che TH1 venga incrementato ogni volta che TL1 va

in overflow (è come se si disponesse per lo stato del timer di un unico registro a 16 bit); nella

modalità 2, detta "timer a 8 bit con auto-reload", TH1 contiene il valore che deve essere caricato in

TL1 quando quest'ultimo va in overflow: in pratica, quando TL1 ha valore 255 e viene

ulteriormente incrementato, esso assume il valore caricato in TH1 invece di ripartire da 0; la

modalità 3, infine, detta "timer in splitted mode", consente di splittare in due timer da 8 bit il timer

0, assegnando i bit di controllo di timer 1 al timer TH0: il timer 1, quindi, potrà funzionare in una

qualsiasi delle modalità 0, 1 o 2, ma potrà essere solo incrementato a ogni ciclo macchina.

Per la nostra applicazione si richiede di utilizzare uno dei due timer (che sarà il timer 1) come

generatore di baud rate ad una frequenza prefissata. Poiché non si richiede l'utilizzo del timer 0 per

altri scopi, la modalità che appare più opportuna selezionare è il modo 2: affinché l'evento di

overflow sia generato dal timer 1 con la frequenza desiderata, entro la approssimazione migliore

possibile, si tratterà di calcolare il valore più opportuno da scrivere nel registro TH1. Si imposta

allora la seguente equazione (anch'essa riportata sulla guida, già citata, a cui questa sezione fa

riferimento):

TH1 = 256 - ((Fq/384)/Baud)

essendo Fq la frequenza del quarzo (come noto, 11.059 MHz) e Baud il baud-rate desiderato (pari a,

come già indicato, 9600 bps). Si ottiene in questo modo un valore di TH1 con ottima

approssimazione pari a 253.

Page 29: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 29/58

29

Gli interrupt L'ultimo aspetto dell'architettura dell'8051 standard e del suo utilizzo su cui è il caso di soffermarsi

è la gestione degli interrupt. In termini generali, un interrupt è un evento che interrompe la normale

esecuzione di un programma. Il flusso di un programma è sempre di tipo sequenziale e può essere

alterato da particolari istruzioni che svolgono appositamente questa funzione (le funzioni di salto); a

differenze di queste, gli interrupt forniscono un meccanismo di "congelamento" del flusso di

programma in corso: solo in corrispondenza di un evento prestabilito che, appunto, genera

l'interrupt, viene eseguita una opportuna subroutine, denominata "interrupt handler", ovvero gestore

di interrupt. L'evento generatore può essere, ad esempio, il timer che va in overflow, oppure la

ricezione di un byte dalla seriale, o ancora un evento (transizione logica) su un apposito pin esterno

(come nel caso della nostra applicazione): l'8051 può essere configurato per gestire ciascuno di

questi eventi con un differente interrupt handler.

Ovviamente, tale capacità di interrompere la normale esecuzione di un programma quando unparticolare evento si verifica rende il programma stesso molto più efficiente nel gestire processi

asincroni, la qual cosa risulterebbe molto più onerosa se si dovesse implementare mediante un

codice che effettui, sufficientemente spesso, tutti i dovuti controlli: viceversa, la scrittura di un

interrupt handler in linguaggio C, come sarà possibile osservare, risulta particolarmente immediata.

Anche nel caso degli interrupt, tuttavia, è necessario configurare il microcontrollore in modo

opportuno: il registro SFR su cui si deve in questo caso intervenire è IE, che, come anticipato,

destina un bit per l'abilitazione di ciascun tipo di interrupt, eccetto il più significativo, destinato a

abilitare/disabilitare il sistema complessivo degli interrupt. Nel nostro caso, si dovrà abilitare

l'interrupt relativo all'evento esterno sul pin INT 0 (o anche pin P3.2): questo vuol dire che

dovranno essere portati a valore logico alto il bit più significativo e il bit relativo a tale interrupt,

ovvero il bit 0 del registro IE (per ulteriori dettagli, si consulti il riferimento citato). Poiché non si

richiede la gestione di più di un interrupt, non avrebbe senso porsi il problema di variare il

contenuto del già introdotto registro IP, relativo alle priorità di ciascun interrupt.

Scelte di progetto preliminari: linguaggio e IDEIl primo passo da compiere in questa fase è, ovviamente, la scelta del linguaggio di

programmazione tra le soluzioni alternative assembler e linguaggio C. Ad oggi, il dibattito su quale

sia in generale la scelta migliore è ancora aperto. Essenzialmente, l'assembler presenta il vantaggio

di fornire il completo controllo del microcontrollore ed è potenzialmente più efficiente (tale

potenzialità si concretizza, ovviamente, se il programmatore è in grado di produrre un codice

efficiente); il linguaggio C è teoricamente più portabile (il codice prodotto subisce meno variazioni

cambiando il microcontrollore in uso), quindi in generale più adatto a quei programmatori che non

sono legati ad una specifica architettura (eventualmente, conosciuta in modo approfondito). D'altra

Page 30: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 30/58

30

parte, i moderni compilatori C sono in grado di generare un codice altamente ottimizzato, che

supera spesso in efficienza il codice assembler prodotto da un programmatore medio, specialmente

se questo non ha una particolare qualificazione nell'utilizzo della specifica architettura; un'ultima

considerazione può riguardare il costo dei compilatori C, di frequente molto più cari di quelli

assembler. Considerati questi elementi, appare opportuno orientarsi verso la scelta del linguaggio C.

Come anticipato, verrà utilizzato il software Keil uVision, dotato di tutti gli strumenti necessari a

una programmazione efficace. In fase di avvio del progetto, è possibile scegliere la architettura su

cui si sta sviluppando, nel nostro caso l'80C32 della NXP (fondata dalla Philips): questo ci

consentirà di avere a disposizione un header file (reg51.h) in cui ad ogni alias SFR è associato

l'indirizzo della memoria interna in cui è collocato (questo ci permetterà quindi di riferirci, nel

corpo del codice, ad ogni byte o anche ad ogni bit "speciale" del nostro micro semplicemente

richiamando il suo alias). Una volta scritto il codice su un text editor essenziale e intuitivo, sarà

possibile effettuarne una prima simulazione, con vista sulla memoria interna e su tutte le periferiche

dell'8051. Il tool di debug consente addirittura, attraverso un opportuno prompt di comandi, di

simulare segnali esterni con cui i pin del micro possono interagire. Accedendo alla finestra di

opzioni per il target (si veda il project workspace), è possibile anche impostare il valore della

frequenza di clock del micro, in modo che la successiva simulazione possa anche fornire indicazioni

sul tempo impiegato dal micro ad eseguire il codice sviluppato, step by step (questa possibilità

risulta di una certa importanza per applicazioni in cui il timing è un aspetto critico). Sempre nella

stessa finestra, è possibile specificare anche il tipo di output che il software dovrà produrre al

termine della fase di compilazione: nel nostro caso, si tratterà di produrre il file eseguibile

direttamente in codice macchina (formato HEX-80). Un'ultima funzionalità che appare importante

evidenziare è il disassembly: tale tool rende possibile osservare come ciascuna istruzione C del

sorgente venga tradotta dal compilatore in assembler. In particolare, l'utilità di quest'ultima

funzionalità sarà evidente nella fase successiva alla simulazione del codice nell'IDE, ovvero quella

di emulazione del codice compilato sull'architettura di riferimento e di test del sistema complessivo

(per ulteriori dettagli su questa fase, si faccia riferimento al capitolo successivo).

Il codice C sviluppatoIn questo paragrafo, il codice C sviluppato verrà riportato e descritto sezione per sezione, secondo

l'ordine del sorgente completo. Le sezioni di codice, comprensive delle linee di commento,

verranno riportate sotto forma di una o più screenshot acquisite direttamente dal text editor del Keil

e a ciascuna sezione seguirà la relativa descrizione e analisi.

Il principio generale che ha ispirato la produzione del presente codice (lungo solo 234 linee) è

l'efficacia: non è stato compiuto alcuno sforzo nel tentativo di rendere il codice riutilizzabile in altre

Page 31: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 31/58

31

applicazioni (per questa ragione, non sono stati realizzati file di intestazione per l'area dichiarativa o

file di libreria per le funzioni richiamate, ma tutto il codice prodotto è riportato nell'unico file

programma.c). Tale scelta, seppure poco elegante, ha consentito una certa semplicità in fase di

progetto e non ha impedito di conservare un controllo completo sul codice, stante la sua moderata

complessità concettuale.

Sezione 1: direttive al preprocessore e dichiarazioni generaliLe primissime due linee di codice rappresentano le direttive al preprocessore. Sono semplici

istruzioni di inclusione: si richiede al preprocessore di ricercare eventuali variabili o funzioni

richiamate nel codice, ma non ivi definite, nei due file di intestazione "reg51.h" e "stdio.h". Di

questi due file, il primo è quello che, come anticipato, contiene la definizione degli alias per gli SFR

dell'80C32 (in pratica, quello che ci consente di riferirci ad esempio al SFR relativo alla porta

parallela P1 senza dover indicare il suo indirizzo nella memoria interna). Il secondo file è

l'intestazione di un file di libreria ("stdio.c") che contiene, tre la altre, la funzione "sprintf",

utilizzata nel seguito del programma.

Figura 20: Direttive al preprocessore e dichiarazioni generali.

Le primissime due linee di codice rappresentano le direttive al preprocessore. Sono semplici

istruzioni di inclusione: si richiede al preprocessore di ricercare eventuali variabili o funzioni

richiamate nel codice, ma non ivi definite, nei due file di intestazione "reg51.h" e "stdio.h". Di

questi due file, il primo è quello che, come anticipato, contiene la definizione degli alias per gli SFR

Page 32: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 32/58

32

dell'80C32 (in pratica, quello che ci consente di riferirci ad esempio al SFR relativo alla porta

parallela P1 senza dover indicare il suo indirizzo nella memoria interna). Il secondo file è

l'intestazione di un file di libreria ("stdio.c") che contiene, tre la altre, la funzione "sprintf",

utilizzata nel seguito del programma.

L'area dichiarativa che segue risulta di comprensione particolarmente immediata. Nella sua prima

parte (linee 006-018) si stanno semplicemente ridefinendo con dei nomi mnemonici alcuni singoli

bit a cui il programma dovrà accedere. Il significato di ciascuno di questi bit nel seguito del codice è

illustrato nel seguente elenco puntato (ovviamente, ciascuna di queste ridefinizioni deve risultare

coerente con le connessioni hardware stabilite tra i vari dispositivi a livello di schematico):

  D4-D7: sono i bit associati ai pin della porta parallela sui quali il micro comunicherà con il

display. Ogni comunicazione richiederà l'invio di due semi-byte: questo tipo di approccio si

è preferito alla destinazione di una intera porta parallela di 8 bit per la stessa funzione poiché

si ha la necessità di utilizzare diversamente gli altri 4 bit; inoltre, come si vedrà, la

comunicazione attraverso un bus di 4 linee non costituisce una grave complicazione, ma

presenta l'unica limitazione di risultare un po' più lenta;

  EN: è il bit corrispondente al pin di I/O parallelo destinato al segnale di Enable del display;

  RS: è il bit corrispondente al pin di I/O parallelo destinato al segnale di Register Select del

display;

  HIGH, LOW: sono i bit, normalmente alti, corrispondenti ai pin di I/O parallelo destinati

all'accensione dei due LED rosso e blu (per ulteriori dettagli si veda la sezione relativa alla

presentazione dello schematico);

  STATUS: è il bit, normalmente alto, corrispondente al pin di I/O parallelo destinato

all'accensione del LED verde di stato (ON/OFF);

  sel0, sel1: sono i bit corrispondenti ai pin di I/O parallelo destinati al controllo del

multiplexer analogico che seleziona uno dei quattro sensori;

La seconda parte (linee 019-036), invece, dichiara nuove variabili o costanti. In generale, la

dichiarazione di una variabile o di una costante richiede che vengano specificati, nell'ordine:

1.  il formato di dato, da cui dipenderà ovviamente il peso in byte del dato stesso. I formati

utilizzati nel programma sono solo due, ovvero unsigned char (numeri interi compresi tra 0 e

255, occupano un solo byte di memoria) e float (numeri reali a virgola mobile, con segno, di

modulo approssimativamente compreso tra 1.17E-38 e 3.40E+38, occupano ognuno 4 byte);

2.  il tipo di memoria in cui il dato verrà allocato. Nel programma, alcune variabili sono state

allocate nella memoria RAM interna (idata, di dimensione 256 byte, come visto), altre nella

memoria accessibile in maniera "diretta" (data, di dimensione 128 byte), altre ancora nellamemoria di programma (code, di dimensione fino a 64 kbyte); infine, la sola variabile

Page 33: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 33/58

33

ADC_out, è stata allocata nella memoria dati esterna (xdata, di dimensione fino a 64 kbyte):

il motivo di questa scelta sarà chiaro più avanti;

3.  il nome e la dimensione (in termini vettoriali).

Introduciamo a questo punto il significato di ciascuna delle variabili (o costanti) dichiarate:

  buffer[64]: è il vettore che conterrà i dati letti dal micro sulla porta di uscita dell'ADC,

prima di qualsiasi altra operazione su di essi; la sua dimensione è limitata a 64: poiché i

sensori sono 4, una volta che il vettore sia stato riempito, esso conterrà 16 misure ottenute da

ciascuno dei 4 sensori. Al termine di un ciclo di 64 acquisizioni, allora, prima di procedere

alla sovrascrittura del vettore stesso con le nuove acquisizioni, sarà possibile effettuare su

tali misure le semplici elaborazioni richieste (operazioni di media e gradiente); 

  temp: è una variabile di appoggio ad uso generale, impiegata in diverse sezioni del codice; 

  hex_val[2]: è il vettore che conterrà ciascuno dei due caratteri ASCII trasmessi, per ogni

misura di temperatura ottenuta, sulla porta seriale (si veda la sezione 5 del codice); 

   ADC_out : è la variabile che conterrà il valore letto dalla porta di uscita dell'ADC, dopo ogni

singola acquisizione effettuata. Come si evince, è l'unica variabile di tipo "xdata": si è cioè

effettuata la mappatura in memoria dell'ADC. L'idea è questa: poiché si dispone di una

memoria programma di 216 byte, dei quali verranno utilizzati sicuramente meno della metà

(data la ridotta complessità del codice), si è scelto di fare in modo che il micro veda l'ADC

come una locazione di memoria dati esterna, avente in particolare indirizzo 0xFFFF (a

questo serve la forma sintattica "_at_ 0xFFFF"). A questo punto, ogni volta che il codice

richiederà l'accesso alla variabile  ADC_out , il micro procederà ad una lettura da memoria

dati esterna: tale procedura (implementata a livello hardware nel micro) consiste nell'invio

dell'indirizzo in due parti, in maniera del tutto analoga a quanto descritto per l'accesso a

memoria programma; in questo caso, tuttavia, l'impulso non verrà inviato sulla linea PSEN

(la memoria di programma mantiene quindi le sue uscite in alta impedenza), ma sulla linea

WR (P3.6) in caso di scrittura o sulla linea RD (P3.7) in caso di lettura da memoria dati

esterna. Quindi, il micro si aspetta di leggere il byte prodotto dalla memoria dati esterna

sulla porta P0. Se si confronta questa sequenza di segnali di controllo con quella richiesta

dall'ADC per la produzione della parola di conversione, esse risultano perfettamente

compatibili una volta che si effettuino le assegnazioni riportate nello schematico (in

particolare, si deve dedicare alla selezione dell'ADC il bit di indirizzo più significativo), ,

nel senso che gli impulsi di WR e RD vengono inviati quando CS è attivo. Questo è vero a

meno di una piccola differenza: il segnale di CS che l'ADC si aspetta di ricevere è attivo

basso, mentre quello prodotto dal micro non lo è (in pratica, quando il micro vuoleindirizzare ADC_out , alza tutti i bit dell'indirizzo, per la scelta operata, e il più significativo

Page 34: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 34/58

34

di questi, con riferimento allo schematico, è proprio CS). La soluzione a questo problema è

ovviamente l'inversione logica operata dall'inverter CMOS impiegato e interposto fra l'uscita

P2.7 del micro e l'ingresso CS dell'ADC; 

  i: variabile intera utilizzata come indice per il vettore buffer ; 

   j: variabile intera utilizzata come generica variabile di ciclo; 

  *in_text : si tratta di una costante scritta nella memoria di programma (e associata ad una

stringa) e di cui in_text costituisce il puntatore; 

  hex_offset : è anch'esso una costante e rappresenta l'offset utilizzato per tradurre le misure da

trasmettere (e rappresentativi di ciascuna misura) in una coppia di caratteri ASCII; 

   ROW[20]: è il buffer in cui verrà temporaneamente memorizzata la stringa da stampare sul

display, prima dell'invio dell'istruzione allo stesso; 

  misure[4]: è il vettore in cui verranno memorizzate le misure di temperatura acquisite (alla

fine di una sequenza di 64 acquisizioni) mediate su ciascun sensore; svolge una funzione di

supporto ai successivi calcoli di media e gradiente; 

  mean, grad : variabili in cui verranno memorizzati rispettivamente il valor medio e il

gradiente complessivi calcolati, in termini di codici binari (valore compreso tra 0 e 255); 

  meanT, gradT : variabili in cui verranno memorizzati rispettivamente il valor medio e il

gradiente complessivi calcolati, in termini di gradi centigradi °C; 

  temp_max, temp_min: valori costanti per le soglie superiore e inferiore, con le quali verrà

confrontata la temperatura media misurata (la scelta di tali valori è arbitraria); 

Sezione 2: procedure relative all'utilizzo dell'ADC

Figura 21: Procedure relative all'utilizzo dell'ADC.

Come già indicato, i segnali di controllo CS, WR e RD richiesti dall'ADC sono facilmente ottenuti

attraverso la mappatura dell'ADC in memoria. Esiste però un quarto segnale di controllo, diretto

questa volta dall'ADC al micro, che assolve nel programma una funzione fondamentale: è il segnale

di INTR (interrupt), che rende possibile la gestione asincrona della lettura delle parole prodottedall'ADC. Il dispositivo, infatti, come desumibile dai diagrammi temporali già analizzati, attiva

Page 35: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 35/58

35

questo segnale nel momento in cui una conversione è stata completata e lo conserva in questo stato

fino alla ricezione dell'impulso sulla linea RD (che segnala la lettura della parola prodotta). Perché

tutto ciò possa avvenire occorre che il micro sia in grado di rispondere con la lettura della variabile

 ADC_out in seguito alla ricezione del segnale di INTR: l'idea è allora porre questo segnale su uno

dei due pin disponibili per gli interrupt esterni (in questo caso, il pin INT0), attivare il relativo

interrupt e scrivere una adeguata procedura di interrupt handler. Proprio questa procedura è quella

riportata in questa sezione di codice: si tratta, in generale, della risposta del micro ad un livello

logico basso sul pin INT0.

La prima operazione che la procedura effettua è appunto la lettura della parola prodotta dall'ADC e

la scrittura di questo byte alla i-esima cella del vettore buffer . A questo punto, l'indice i viene

incrementato, e, normalmente, viene avviata una nuova conversione mediante l'accesso in scrittura

alla variabile esterna ADC_out : proprio questo accesso corrisponde infatti all'invio di un impulso di

WR. L'avvio della nuova conversione deve però essere preceduto dalla selezione del sensore di

temperatura successivo: le due operazioni booleane implementate corrispondono all'incremento

unitario dell'indirizzo [sel1 sel0] con cui viene controllato il multiplexer. Procedendo in questo

modo, il vettore buffer  sarà riempito in modo tale che le misure relative al sensore x (per x

compreso tra 0 e 3) saranno collocate, nell'ordine, nelle celle corrispondenti ad indici i di modulo x

in base 4. Facciamo un esempio. Il valore corrente di i è 2, e si assegnano ai bit di selezione i valori

sel1 = 1 e sel0 = 0 (l'ADC sta convertendo la misura prodotta dal sensore 2); l'ADC termina la

conversione, quindi invia il segnale di INTR; il micro, ricevuto tale segnale, avvia l'interrupt

handler, procedendo alla lettura della parola di conversione e all'incremento di i, che passa al valore

3, cioè sel1 = 1 e sel0 = 1; l'impulso di WR avvia una nuova conversione, e tutta la procedura si

ripete; quando i verrà incrementato al valore 4, i bit di selezione verranno nuovamente incrementati

e torneranno quindi ad assumere valore sel1 = 0 e sel0 = 0, ovvero il multiplexer tornerà a

selezionare il sensore 0. Reiterando il discorso, questo vuol dire che sarà possibile trovare tutte le

misure successive acquisite dal sensore 0 nelle celle di buffer pari a 0, 4, 8 ecc., ovvero tutte le celle

da 0 a 63 il cui modulo in base 4 è pari a 0. Lo stesso ragionamento potrà essere ripetuto per gli altritre sensori. In generale, operando in questo modo sarà sempre possibile associare ad ogni elemento

del vettore buffer  il sensore di temperatura da cui quella misura è stata prodotta (specifica

ovviamente fondamentale per ottenere successivamente misure derivate di gradiente).

A questo punto, giustifichiamo la presenza della condizione if: la sequenza di istruzioni commentata

dovrà essere eseguita unicamente nel caso in cui il valore di i non sia 64. Come sarà desumibile dal

seguito del programma, in corrispondenza di tale valore di i, il micro sospenderà la lettura delle

parole prodotte dall'ADC (quindi non consentirà la sovrascrittura del vettore buffer ) per dedicarsi al

calcolo delle misure derivate di media e gradiente e all'aggiornamento del display (nonché,

Page 36: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 36/58

36

eventualmente, alla trasmissione seriale, come sarà chiaro in seguito). Solo dopo che queste altre

operazioni siano state eseguite, il valore di i verrà aggiornato a 0 e tutto si ripeterà con la

sovrascrittura di buffer con altre 64 misure.

Sezione 3: procedure relative all'utilizzo del displayIn questo caso, per la gestione del display sono state scritte e utilizzate quattro procedure distinte.

La prima e più semplice è la procedura delay, che assume come ingresso un intero positivo (a 16

bit, quindi compreso fra 0 e 65535). Tale procedura assolve unicamente alla funzione di fermare il

flusso di programma principale per un ritardo di durata regolabile attraverso l'argomento time. Il

suo principio di funzionamento si basa su un ciclo a decremento: la variabile time, dopo essere stata

opportunamente normalizzata, viene decrementata fino al valore 0, in corrispondenza del quale la

procedura termina e il flusso di programma principale riprende. Il valore di normalizzazione 8.95 è

stato calcolato in modo tale da consentire alla procedura di assumere in ingresso il tempo da

aspettare espresso direttamente in s. Tale procedura risulta di importanza fondamentale per la

gestione del display, che richiede spesso l'attesa di un certo intervallo di tempo tra due istruzioni

consecutive: per questa ragione, le procedure che seguono utilizzano a loro volta tale procedura.

La seconda procedura (lcd_init) è quella di inizializzazione, da eseguire nel main unicamente

all'avvio del programma, prima di eseguire qualsiasi altra operazione sul display. La prima

istruzione che viene eseguita è, appunto, l'attesa da parte del micro di 15 ms, tempo richiesto dal

display tra l'istante di accensione del modulo e l'istante in cui può ricevere la prima istruzione. Le

successive istruzioni realizzano una sequenza di impulsi sul pin di Enable del display, richiesti dallo

stesso in questa fase; in particolare, l'istruzione inviata al display nel segmento di codice (076-079)

gli indica che si intende utilizzare la modalità operativa a quattro bit.

La terza procedura (lcd_write) è quella che verrà utilizzata nel seguito del programma per inviare al

display istruzioni e dati: proprio il primo argomento di ingresso (il bit what ) serve a distinguere

questi due casi (quando pari a 0, si tratta di un'istruzione, quando pari a 1, si tratta di un dato),

mentre il secondo argomento di ingresso (il char word ) rappresenta il dato stesso da inviare. Viene

innanzitutto definita una variabile temporanea temp, che ovviamente, nello scope di questa

procedura, sostituisce la variabile temp globale, quindi si pone sul pin RS del display il valore

logico associato a what . A questo punto, può cominciare la trasmissione del byte, diviso in due

semiword. Viene trasmessa per prima la parte alta di word , e ciò viene ottenuto mediante i seguenti

passi: shift verso destra di 4 posizioni di word e scrittura del risultato in temp; mascheramento della

parte alta di temp (in seguito a questa operazione, solo i 4 bit meno significativi di temp potranno

essere non nulli, ovvero si forza a zero la parte alta di temp); mascheramento della parte bassa di P1

(si forza a zero la parte bassa di P1); operazione di OR logico bit a bit tra temp e P1; impulso di EN .

Page 37: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 37/58

37

Figura 22(a-b): Procedure relative all'utilizzo del display

L'effetto complessivo ottenuto è in pratica la alterazione della sola parte bassa di P1, che viene in

particolare sovrascritta con la parte bassa di temp, ovvero quella che è la parte alta di word . La

sequenza di istruzioni nelle linee (094-099) ripete le stesse operazioni per la parte bassa di word ,

che viene quindi anch'essa trasmessa. Infine, il datasheet del display richiede di attendere 50 s

prima dell'invio di un'altra parola: a questo serve l'istruzione delay della linea (101).

Infine, la procedura lcd_config consente di effettuare la configurazione del display secondo le

impostazioni desiderate: verrà quindi richiamata nel main del programma prima dell'utilizzo del

display e una sola volta, dato che l'applicazione non richiede di variare più volte la modalità

operativa del display stesso. Confrontando le linee di commento di ogni istruzione con la

Page 38: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 38/58

38

descrizione dell'istruction-set del display già riportata, è possibile comprendere l'effetto di ogni

linea di codice. Di fatto, si sta richiedendo complessivamente al display di operare secondo le

impostazioni: comunicazione a 4 bit, duty ratio pari a 1/16, cursore a incremento, assenza di shift,

display acceso, cursore nascosto ed effetto blinking disattivo.

Sezione 4: procedura principale (fase di inizializzazione e avvio)Con questa sezione di codice ha inizio la procedura principale: si tratta della fase di inizializzazione

dei vari dispositivi utilizzati.

Tra questi dispositivi è ovviamente incluso il micro stesso, all'inizializzazione del quale sono

destinate le linee di programma (118-129) con particolare riferimento ai suoi registri SFR. Prima di

tutto, vengono settati i valori iniziali da porre sulle porte di I/O parallelo: il bit STATUS viene

portato a 0, così da accendere il relativo LED, di colore verde; i bit sel0 e sel1 sono inizializzati

entrambi a 0, così che il multiplexer selezioni per primo il sensore di temperatura di indice 0; in

questa fase, viene abilitato l'interrupt esterno 0 (agendo sul bit EX0), associato all'ADC, ma solo

dopo aver disabilitato tutti gli interrupt agendo sul già introdotto bit speciale EA (bit più

significativo del SFR IE) impedendo così all'interrupt handler di assumere il controllo, per il

momento; l'attivazione del bit speciale IT0 imposta il modo di trigger dell'interrupt esterno 0 (con la

scelta operata, l'interrupt si attiva quando il micro vede sul pin INT0 una transizione di livello alto-

basso); le due istruzioni alla linea (124) impostano il già descritto modo 1 per la porta seriale;

analogamente, l'istruzione alla linea (125) imposta per il timer1 la modalità 2, mentre l'istruzione

successiva imposta il valore di auto-reload del timer1 al valore calcolato in precedenza, pari a 253;

quindi, le due istruzioni alle linee (127-128) abilitano il timer1 e la ricezione per la porta seriale.

Figura 23: Procedura principale (fase di inizializzazione e avvio).

Page 39: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 39/58

39

Le linee (130-137) della presente sezione sono invece destinate al primo utilizzo del display, che

sarà ottenuto semplicemente richiamando le procedure già preparate e descritte: si procede quindi

alla inizializzazione, configurazione, puntamento alla prima locazione di memoria associata della

DD-RAM del modulo (che corrisponde a porre il cursore in alto a sinistra sul display), quindi

scrittura della stringa iniziale, puntata dalla variabile in_text . Quest'ultima funzione, in particolare,

si esaurisce, come evidente, nel ciclo for alle linee (135-136).

L'ultima parte della sezione corrisponde all'abilitazione del sistema di interrupt (che resterà attivo da

quel momento in poi fino allo spegnimento del sistema) e all'avvio della prima conversione A/D.

Sezione 5: procedura principale (ciclo principale)Questa sezione rappresenta il ciclo perpetuo in cui si esplicherà di fatto il funzionamento del

circuito: il sistema sarà in grado di effettuare tutte le operazioni richieste, ovvero acquisizione delle

misure, calcolo di media e gradiente, aggiornamento del display ed eventuale trasmissione delle

misure su porta seriale, per un tempo indefinito (in pratica, fino alla interruzione della

alimentazione).

Page 40: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 40/58

40

Figura 24(a-b-c): Procedura principale (ciclo principale).

Le istruzioni corrispondenti alle linee di codice (145-148) hanno una funzione solo in fase di debug,

per questo sono state rimosse in fase di emulazione del sistema completo. In pratica, esse simulano

il riempimento del buffer  che nel sistema funzionante dovrebbe essere scritto dall'ADC, nelle

modalità già discusse. In questo modo, è stato possibile anche in fase di simulazione sull'ambiente

Keil verificare il funzionamento del programma rispetto alle fasi di calcolo di media e gradiente in

gradi centigradi, pilotaggio del modulo LCD e trasmissione su porta seriale, senza dover utilizzare il

complesso strumento, fornito dall'IDE, di simulazione dei segnali esterni. In queste linee di codice,

allora, si può scegliere di riempire il buffer con tutti valori unitari, o ancora un valore intero che sia

pari a i o a 2*i, quindi proporzionale all'indice della rispettiva cella, e così via, in modo da verificare

volta per volta che i valori di media e gradiente calcolati risultino coerenti. Per descrivere il

funzionamento del sistema completo, quindi, ragioniamo in assenza di questo blocco di istruzioni.

Quello che si verifica in questa ipotesi, allora, è possibile dedurlo osservando che subito dopo il

Page 41: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 41/58

41

blocco condizionale if non è presente alcuna istruzione: questo vuol dire che, se i è diverso da 64, il

ciclo verifica continuamente una condizione vera senza mai eseguire nessun'altra istruzione. In

questa condizione il micro è in attesa che il normale flusso di programma venga alterato.

L'unico evento che può generare questo tipo di deviazione è appunto l'interrupt esterno 0, la cui

procedura di gestione è stata descritta precedentemente. Un effetto di tale procedura è, come visto,

l'incremento dell'indice i: quando un ulteriore interrupt incrementerà la variabile i al valore 64,

all'interno della procedura di interrupt handler non verrà avviata alcuna nuova conversione, il

controllo ritornerà immediatamente al ciclo principale, che potrà eseguire le istruzioni contenute nel

blocco condizionale, compreso nelle linee (149-232).

Proprio questo blocco condizionale è quello che esegue tutte le operazioni richieste al micro

(eccetto quella, già realizzata, di acquisire le parole di conversione dall'ADC): la condizione di

partenza è quella di un vettore buffer di 64 acquisizioni completo e ordinato nel modo descritto

nella sezione relativa all'interrupt handler. Evidentemente, la prima operazione da realizzare a

questo punto è il calcolo delle misure indirette (in gradi centigradi) di media e gradiente: è appunto

la fase di elaborazione, inclusa nelle linee (151-169). Le linee (152-153) inizializzano a zero tutte le

celle del vettore misure, destinato a contenere, come anticipato, la media di 16 misure indipendenti

ottenute da ciascuno dei 4 sensori; le linee (154-155) calcolano l'elemento di indice x del vettore

misure come la cumulata delle 16 misure relative al sensore x, per x che va da 0 a 3 (viene scandito

tutto il vettore buffer e ciascun suo elemento viene cumulato all'opportuno elemento di misure); le

linee (156-157) dividono ciascun elemento di misure per 16, in modo da completare il calcolo delle

4 medie. Partendo dal vettore misure risultante, si può procedere quindi al calcolo della media

complessiva e del gradiente spaziale (ovviamente, si tratterà di un gradiente già mediato nel tempo,

poiché tale media temporale si è effettuata, come descritto, sul vettore misure): le linee (158-161)

effettuano il calcolo di mean nel modo più ovvio; le linee (162-166) valutano il gradiente medio su

una retta come la media delle tre differenze tra la misura di ogni sensore e quella del precedente

(ovviamente, perché tale calcolo abbia senso, si richiederà che i tre sensori vengano disposti sulla

PCB finale ordinati in linea retta secondo l'indirizzo con cui ciascuno di essi viene visto dalmultiplexer). A questo punto, le variabili reali mean e grad contengono i valori calcolati per media

e gradiente. Si tratta tuttavia di valori numerici puri: non è ancora stata effettuata l'operazione di

conversione da numeri binari (prodotti dall'ADC) a valori di temperatura in gradi centigradi. Le

linee (167-169) contengono quindi le istruzioni per effettuare questa conversione: avendo scelto per

l'ADC (a 8 bit) un fondo scala di 128 °C, il LSB assumerà valore 128 °C/28

= 0.5 °C. Questo vuol

dire che l'incremento unitario della parola di conversione dell'ADC corrisponde ad un incremento

della temperatura misurata di 0.5 °C: il coefficiente di proporzionalità per cui moltiplicare i valori

binari mean e grad per ottenere le stesse grandezze in °C (meanT e gradT ) è quindi proprio 0.5.

Page 42: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 42/58

42

La prima operazione che viene effettuata sulle due nuove misure indirette calcolate è il confronto di

meanT con le due soglie (superiore e inferiore) predefinite, alle linee (170-180). I due test vengono

effettuati in maniera indipendente: se, ad esempio, meanT  dovesse risultare inferiore alla soglia

minima prefissata, il micro pone a 0 il bit LOW , accendendo così il LED blu che segnala quindi una

temperatura media sotto soglia. Per il bit HIGH vale un discorso analogo.

La parte successiva del ciclo, compresa nelle linee (181-198) controlla l'aggiornamento del display

con entrambe le misure indirette calcolate. Per la preparazione della stringa da inviare al display

(bufferizzata nella variabile stringa  ROW ) viene impiegata l'istruzione C sprintf, presente nella

libreria standard del linguaggio C "stdio.c", richiamata attraverso il relativo file header. La stringa

di formato impiegata per la rappresentazione dei due numeri reali meanT e gradT prevede l'utilizzo

di due cifre per la parte intera e una per la parte decimale (separate tra loro da un punto); il carattere

'C', stampato sul display, indica quindi che si tratta di misure espresse in °C. Il ciclo alle linee (185-

189) utilizza come condizione la fine della stringa: quando il carattere verificato coincide con il

carattere di terminazione della stringa (in linguaggio C, è il carattere '\0'), il ciclo si interrompe,

poiché la stringa  ROW  è stata stampata interamente. Lo stesso discorso può essere ripetuto in

maniera pressoché identica per la stampa della seconda linea del display, con l'unica differenza che

alla linea (191) viene ovviamente indirizzato il byte della DD-RAM relativo all'inizio della riga 2.

Il segmento di codice alle linee (199-229) è destinato all'eventuale svuotamento del vettore buffer 

sulla porta seriale. Come desumibile dalla linea (200), non è detto che la trasmissione seriale delle

misure acquisite debba verificarsi ogni volta che il programma accede al blocco condizionale

associato alla condizione i == 64: la condizione che si deve verificare perché la trasmissione abbia

luogo è che essa venga esplicitamente richiesta dall'interlocutore attraverso l'invio di un qualche

carattere. In particolare, si è scelto di assumere un carattere specifico (nel caso mostrato, la lettera

'a') che, una volta verificato, possa avviare la trasmissione: questo ulteriore controllo, effettuato alla

linea (204), consente di evitare il rischio che un qualsiasi disturbo, magari anche a connettore

staccato, possa attivare questo segmento di codice. Una volta verificata questa condizione, si

procede alla trasmissione delle misure vera e propria, compresa nelle linee (205-228): la primaoperazione che viene effettuata è la disabilitazione della ricezione seriale, quindi si procede in un

ciclo for ad ogni iterazione del quale viene trasmesso un singolo elemento del vettore buffer . Poiché

il protocollo RS-232 è progettato unicamente per la trasmissione di dati alfanumerici, non sarebbe

possibile inviare le parole acquisite dall'ADC così come sono (ovvero dati binari), ma è necessario

sottoporle ad una conversione che le renda adatte al protocollo di comunicazione. Inizialmente si

era pensato di esprimere ognuno dei 256 valori possibili dell'i-esimo byte di buffer attraverso la sua

rappresentazione esadecimale, da cui il nome del vettore hex_val: così facendo, sarebbero state

sufficienti, com'è ovvio, due sole cifre alfanumeriche. Successivamente, si è osservato come questo

Page 43: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 43/58

43

tipo di approccio risultava in una procedura di conversione di inutile complessità; la scelta operata è

stata allora quella di collocarsi in un qualsiasi punto della tavola ASCII mediante un opportuno

valore di offset (hex_offset , appunto) e inviare quindi i caratteri che si ottenevano sommando a

questo offset il valore binario da trasmettere. Per l'offset è stato scelto il valore 0x30 (48 in

rappresentazione decimale), che corrisponde proprio al carattere '0': sulla tavola ASCII seguono i

caratteri '1','2', e così via fino a '9', quindi ':', ';', e altri, fino ad arrivare all'elemento alla riga

hex_offset +15 (si intende questo nella linea di commento in cui si fa riferimento ad un codice

esadecimale "non standard": rispetto all'esadecimale noto, in fondo, si sono solo cambiati i simboli

relativi ai valori maggiori o uguali a 10). Quindi, si effettua separatamente la conversione in questo

formato della parte alta e della parte bassa del byte buffer[i], e si procede infine alla trasmissione

dei due caratteri ASCII dello stesso, alle linee (218-225): come la UART dell'8051 richiede di fare,

si pone a 0 il flag di trasmissione TI, si scrive il valore da trasmettere serialmente nel registro

SBUF, e si rinchiude il flusso di programma in un ciclo while che, per uscire, attende che il flag TI

venga attivato (è il segnale che la trasmissione del byte è conclusa); quindi, si ripete l'operazione

per entrambi i caratteri. La linea (227) contiene l'istruzione che riabilita la ricezione seriale, per le

iterazioni successive sul riempimento di buffer . Le ultime linee di codice (228-234), infine, oltre a

chiudere cicli e blocchi condizionali rimasti aperti, svolgono la sola funzione, alla fine del blocco if 

(quindi ancora solo nel caso di i pari a 64) di azzerare la variabile i e avviare una nuova

conversione: esse consentono quindi la produzione di un successivo riempimento del vettore buffer ,

che viene così sovrascritto con le nuove misure acquisite.

Page 44: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 44/58

44

Conclusioni

Le ultime fasi del flusso di progettoLa procedura di debug del codice C prodotto verrà svolta mediante le seguenti modalità. Una volta

che la simulazione del sorgente su ambiente Keil abbia dato esito positivo, il codice esadecimale

prodotto verrà passato all'emulatore e quindi testato direttamente su PCB. In questa fase, verrà

impiegato lo strumento di emulazione HITOP. Da un punto di vista hardware, è possibile connettere

l'emulatore alla PCB su cui sarà montato il circuito da testare attraverso un opportuno pad, sul quale

a sua volta sarà montato il nostro micro 80C32. Sarà in questo modo possibile già a questo punto

(prima quindi della realizzazione della PCB vera e propria) verificare la funzionalità del circuito in

ogni sua parte, fatta eccezione unicamente per la ROM e per il D-Latch (e relative connessioni),

sostituite nella funzione di fornire il codice da eseguire al micro dall'emulatore stesso.Procedendo in questo modo, sarà possibile individuare quali segmenti del codice assembler

producono errore e quindi, attraverso il disassembly del Keil, su quali istruzioni C del sorgente

intervenire. Tale procedura di test potrà essere ripetuta per ogni unità funzionale del circuito, prima

di essere effettuata sul circuito complessivo; in particolare, verranno testati separatamente il

funzionamento della unità di conversione A/D delle misure di temperatura, del display LCD e infine

della comunicazione su porta seriale con il PC. Relativamente a questo punto, il primo test verrà

effettuato mediante l'utilizzo dell'Hyper Terminal di Windows; da questo test, quindi, sarà possibile

produrre le specifiche di progetto per l'applicativo Visual Basic da sviluppare. Anche questo

applicativo verrà quindi sottoposto a test direttamente nella comunicazione seriale col micro. Infine,

sarà possibile testare il sistema complessivo (con il codice C sviluppato ancora in fase di

emulazione).

Come ovvio, per ragioni di brevità, la descrizione del lungo processo di "trial & error" che ha

portato alla produzione del codice completo e corretto è interamente omessa. Nelle sezioni seguenti

vengono piuttosto forniti alcuni dettagli relativi alla fase di test, le indicazioni principali sulla

realizzazione del layout della PCB e, infine, poche considerazioni su eventuali possibili sviluppi

futuri per un progetto di tipo analogo.

Test su breadboardLa breadboard di test realizzata è rappresentata in Fig.25. Essa è completa di tutte le connessioni,

fatta eccezione per i tre LED (di ridotta criticità rispetto agli obiettivi del test stesso) e per la

componentistica di supporto al micro (circuito di clock, D-LATCH, ROM) resa inutile dai segnali

forniti dall'emulatore stesso. In basso a sinistra è stata montata la sezione relativa al riferimento di

tensione destinato all'ADC (sono riconoscibili il trimmer e l'integrato TO-92, l'LM385); in basso a

Page 45: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 45/58

45

destra è stata collocata la schiera degli LM35, disposti in modo arbitrario solo per la fase di test

(come anticipato, nel disegno del layout finale della scheda si opererà diversamente); il primo

integrato sulla destra a partire dal basso è il multiplexer analogico, la cui uscita è diretta all'ADC (il

terzo integrato a partire dal basso); il secondo integrato dal basso è l'inverter, mentre quello più in

alto è il convertitore di livello (è riconoscibile in questo caso la sezione di condensatori elettrolitici

richiesti dal dispositivo nel suo normale funzionamento); sulla parte sinistra della breadboard è stato

montato il pad, su cui è collocato a sua volta l'80C32 (anche se non visibile, il cavo che si

interrompe sulla sinistra è connesso al modulo HITOP); subito alla sinistra del pad è riconoscibile il

modulo L2014.

Figura 25: Breadboard montata per la fase di test.

Il display LCD è rappresentato nel dettaglio di Fig.26: in questa figura è possibile leggere (sebbene

sfocate) le misure indirette stampate sul display stesso. Si misura un valor medio complessivo di

+15.5 °C e un gradiente medio pari a -0.1 °C (come già indicato, in questa fase di test tale misura

non ha alcun significato, data la disposizione arbitraria dei sensori).

Figura 26: Dettaglio sul display LCD.

Page 46: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 46/58

46

Ancora con riferimento alla Fig.25, è possibile distinguere un cavo che si allontana dalla breadboard

verso destra: si tratta del cavo seriale impiegato per realizzare la connessione verso il PC. In questa

fase di test si sono potute sperimentare anche le funzionalità dell'applicativo su PC destinato alla

raccolta, archiviazione, elaborazione e rappresentazione grafica delle misure acquisite (il sorgente

di tale programma, riportato per completezza in appendice, è stato prodotto in linguaggio Visual

Basic). La screenshot in Fig.27 riproduce la schermata principale dell'applicativo.

Figura 27: Schermata principale dell'applicativo VB.

Innanzitutto, nel menu "File" sono accessibili unicamente le scelte "About" (che produce un

messaggio con le informazioni sul programma) e "Exit" (che chiude il programma). Nel menu

"Opzioni", sono invece accessibili le scelte relative a quale porta seriale (COM1/COM2)

selezionare per la acquisizione delle misure. Come ulteriore alternativa (opzione "Test without

COM"), è possibile testare l'applicativo in assenza di acquisizioni via seriale: in questo caso,

chiaramente, il programma simulerà l'acquisizione di misure che saranno però valori pseudocasuali.

Al momento della acquisizione della screenshot in Fig.27, era selezionata l'opzione COM2 (la porta

COM1 del PC era stata destinata al modulo HITOP, quindi non era disponibile): le misure indirette

di media e gradiente riportate sono allora associate a valori di temperatura realmente acquisiti. La

prima casella di testo (in bianco) è l'unico testo editabile e ammette unicamente numeri interi

positivi: si tratta del numero di acquisizioni ripetute che si richiede al sistema di effettuare. La

casella di testo affianco contiene invece il numero complessivo di acquisizioni effettuate a partire

dall'ultimo reset fino a quel momento (naturalmente, le misure indirette riportate di seguito si

riferiscono a tutte queste acquisizioni). Quindi, le successive caselle di testo contengono i dati

descritti dalle rispettive label, tutti in unità °C: la media per un sensore rappresenta il valore medio

di temperatura calcolato su quel sensore; il gradiente per un sensore rappresenta il valore medio

delle differenze tra ogni coppia di valori di temperatura (si considerano in questo caso coppie di

valori acquisiti in maniera successiva nel tempo, il gradiente in questione è quindi di natura

temporale e non spaziale); la media complessiva rappresenta il valore medio di temperatura

Page 47: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 47/58

47

calcolato su tutti i sensori; il gradiente complessivo rappresenta il valore medio delle differenze tra i

valori medi di temperatura su coppie di sensori adiacenti (questo è allora un gradiente spaziale).

Chiariamo ora la funzione dei button: il pulsante "Acquire" avvia le procedure destinate ad

effettuare il numero indicato di acquisizioni ripetute; il pulsante "Restart" effettua un reset del

programma (le misure precedentemente acquisite verranno quindi, eventualmente, perse); il

pulsante "Save" apre una finestra di dialogo per il salvataggio su file (in formato .txt) delle misure

acquisite fino a quel momento dal micro. A titolo di esempio, si riporta di seguito la prima riga

scritta dalla procedura di salvataggio su file in un file "misure.txt" prodotto durante il test finale:

|016,0-016,0-016,0-015,0-015,5-015,0-015,5-016,0-017,0-

016,0|015,5-015,5-015,5-015,5-016,5-016,0-016,0-015,5-015,5-

015,5|015,0-015,5-015,5-016,0-016,0-015,5-016,0-016,0-016,0-

015,0|014,5-015,5-015,0-016,0-015,0-015,0-015,5-015,5-016,0-

015,5|23/09/2007-18.02.33-COM2

Le misure vengono salvate in formato testuale, espresse in gradi centigradi. Il carattere speciale '|'

ha la funzione di terminazione: indica l'inizio e la fine della stringa di misure; il carattere speciale ','

ha la funzione di separare parte intera e parte decimale di ogni misura. Alla fine della stringa di 64

misure (ovvero di un buffer completo acquisito dal micro), vengono salvate anche ulteriori

informazioni, separate dal carattere '-' e relative alla specifica acquisizione effettuata, quali data e

ora dell'acquisizione da micro e porta seriale di comunicazione.

Infine, i quattro button "View PDF", associato ciascuno ad un sensore, consentono di rappresentareun grafico della densità di probabilità dei valori acquisiti dal relativo sensore. In Fig.28 sono

rappresentati due dei quattro grafici che era possibile ottenere, in particolare quelli relativi ai sensori

0 e 3 (come indicato nei titoli delle finestre).

Page 48: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 48/58

48

Figura 28(a-b): Rappresentazione grafica della densità di probabilità dei valori acquisiti dai sensori 0 e 3.

Realizzazione layout della PCBCome già indicato, per lo sviluppo della documentazione relativa alla PCB è stato utilizzato il

pacchetto software Orcad, in particolare i tool Capture e Layout. Questo secondo tool è proprio

quello necessario a produrre i file gerber necessari alla realizzazione della PCB. Uno dei principali

punti di forza del pacchetto software scelto è probabilmente proprio l'immediatezza con cui è

possibile passare dalla rappresentazione del circuito sottoforma di schematico alla realizzazione del

layout: molte delle operazioni da effettuare (essenzialmente placement dei componenti e routing

delle piste) sono o possono essere rese automatiche, e ciò funziona particolarmente bene se, come

nel nostro caso, il circuito non presenta particolari criticità in termini di accoppiamento

elettromagnetico tra i componenti o tra le piste stesse.

Una volta realizzato lo schematico, Orcad Capture è in grado di produrre autonomamente la netlist,

ovvero un file di estensione .mnl che contiene la descrizione completa del circuito in formato

testuale. All'avvio di Orcad Layout, è possibile chiedere che il software carichi proprio tale netlist,

associandola ad un opportuno file template, contenente nient'altro che informazioni generali dinatura tecnologica sul tipo di scheda che si intende realizzare. L'unica operazione che si richiede

all'utente di effettuare è quella di associazione di un footprint adeguato ad ogni dispositivo (o più in

generale, ad ogni black-box) del circuito, fatta eccezione per i componenti già a livello di

schematico presi dalle librerie di Orcad. I possibili modi di procedere sono due: crearsi una libreria

di footprint adatti ai dispositivi utilizzati e destinata quindi allo specifico progetto; viceversa,

utilizzare i footprint già messi a disposizione dalle librerie di Orcad ma rinominare i pin di ciascun

dispositivo sullo schematico in modo tale che vi sia corrispondenza con il relativo footprint scelto

(nel nostro caso, è stata scelta la seconda opzione). Tutto ciò che segue può essere effettuato in

Page 49: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 49/58

49

maniera automatica: nella nostra applicazione, si è richiesta una particolare disposizione per i

sensori di temperatura, che devono essere disposti in linea retta nell'ordine corretto (secondo quanto

già specificato) nel layout finale; ulteriori preferenze specifiche di collocazione della porta seriale,

del display e dei LED hanno suggerito di effettuare in maniera manuale il piazzamento dei

componenti della scheda. Viceversa, l'operazione di sbroglio delle connessioni è stata eseguita in

modo automatico: si è richiesta in particolare la generazione di uno sbroglio per una scheda a due

livelli (top e bottom).

Figura 29: Rappresentazione del layout complessivo (le piste relative ai due strati sono rappresentate con colori diversi).

Una volta corretti gli errori segnalati dal DRC (Design Rule Check) e ripetuto lo sbroglio, si è prima

di tutto ottenuta la rappresentazione del layout complessivo riportata in Fig.29, quindi le piste e le

vie stampate in distintamente per i due strati in Fig.30 (come spesso accade, lo strato di bottom è

stato specchiato rispetto all'originale).

Figura 30(a-b): Rappresentazione di piste e vie per il top (a sinistra) e per il bottom (a destra) della PCB.  

Page 50: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 50/58

50

Considerazioni finali: possibili sviluppiGli aspetti del sistema progettato che potrebbe risultare opportuno ottimizzare sono numerosi.

Innanzitutto, si potrebbe senza alcuno sforzo pensare di incrementare il numero di sensori di

temperatura impiegati, per esempio arrivando a 16: questo implicherebbe ovviamente anche

l'utilizzo di un multiplexer di dimensione doppia, il che a sua volta comporterebbe il problema di

dover rinunciare magari a qualcuno dei LED di segnalazione per far posto al nuovo bit di selezione

destinato al multiplexer. Tali 16 sensori potrebbero quindi essere disposti in maniera uniforme su

una superficie quadrata: in tal modo, sarebbe possibile ottenere dalle misure acquisite informazioni

sulla distribuzione superficiale di un campo di temperatura (risulterebbe tuttavia a questo punto

necessario calcolare solo il gradiente lungo due direzioni ortogonali). Si potrebbe ancora pensare di

migliorare l'aspetto relativo alla collocazione temporale delle misure acquisite, in modo tale da

consentire misure derivate di variazione della temperatura nel tempo. Ancora nell'ipotesi di riuscire

a fare posto a qualche segnale di controllo sulle porte parallele del micro, potrebbe risultare

possibile ottenere la comunicazione del circuito con un PC remoto attraverso connessione wireless a

corto raggio (ad esempio, in standard Bluetooth), il che renderebbe il sistema adatto ad effettuare

misure in condizioni più estreme (dove, generalmente, un operatore umano non può arrivare).

Infine, nulla esclude che il sistema progettato (inteso come interazione tra micro 8051-like, modulo

LCD, ADC e connessione via seriale con PC) possa essere modificato per adattarsi all'acquisizione

ed elaborazione elementare di dati prelevati da sensori diversi da quelli di temperatura.

Page 51: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 51/58

51

 Appendice: codice sorgente Visual Basic

Per ragioni di completezza, si riporta di seguito il codice sorgente VB dell'applicativo sviluppato

per l'interazione del PC con il micro via seriale. Naturalmente, tale sorgente è da ritenersi completo

solo in associazione alla sua parte visuale, la descrizione della quale è stata omessa nella presente

relazione.

In ogni caso, tutta la documentazione prodotta in ambiente VB durante lo sviluppo di tale

applicativo, così come quella prodotta in ambienti Orcad e Keil, è riportata in formato digitale nel

CD allegato alla presente relazione.

Option Explicit

Dim rs As Recordset

Dim buffer As String

Dim receive_req As Boolean

Dim porta As IntegerDim times As Long

Dim j As Integer

Private Sub About_Click()

MsgBox ("Misuratore di temperatura v1.0" & vbCr & "Authors: Columbo Lorenzo" & vbCr & "

Columbo Gaetano")

End Sub

Private Sub bt_acquire_Click()

'

' Controlla che sia stata operata la scelta "PORTA COM"

'

If COM1.Checked = False And COM2.Checked = False And Test_without_COM.Checked = False Then

MsgBox ("Seleziona porta COM da Opzioni")

Exit Sub

End If

If Test_without_COM.Checked = True Then porta = 0

If COM1.Checked = True Then porta = 1

If COM2.Checked = True Then porta = 2

If porta > 0 Then

If apri_porta = False Then

MsgBox ("Impossibile proseguire.")

Exit Sub

End If

End If

'

' Controlla che frm_acquire sia integer

'

If Not IsNumeric(frm_acquire) Then

MsgBox ("Valore non ammesso.")frm_acquire.SetFocus

Exit Sub

End If

If Not frm_acquire > 0 Then

MsgBox ("Valore non ammesso.")

frm_acquire.SetFocus

Exit Sub

End If

times = 1

'... Sollecita invio e attende ricezione buffer BYTEWISE (se non è test)

Frame1.Enabled = False

buffer = ""

If porta > 0 Then

MSComm1.Output = "a"

Else

For times = 1 To frm_acquire

buffer = genera

Call acquire

Next

Page 52: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 52/58

52

Call elaborate

Frame1.Enabled = True

End If

End Sub

Private Sub acquire()

Dim ora As String

'

' Effettua una volta la scrittura nel rs delle 64 misure

'rs.AddNew

'... Ricevi buffer seriale alla data e ora e da sorgente

rs.Fields("data") = Date

ora = Time

rs.Fields("ora") = ora

Select Case porta

Case 0

rs.Fields("source") = "TEST"

Case 1

rs.Fields("source") = "COM1"

Case 2

rs.Fields("source") = "COM2"

End Select

'... Costruisci campi misure

For j = 1 To 128 Step 8

rs.Fields("misure_0") = rs.Fields("misure_0") & Format((codice(Mid(buffer, j + 0, 2)) *

0.5), "000.0")

rs.Fields("misure_1") = rs.Fields("misure_1") & Format((codice(Mid(buffer, j + 2, 2)) *

0.5), "000.0")

rs.Fields("misure_2") = rs.Fields("misure_2") & Format((codice(Mid(buffer, j + 4, 2)) *

0.5), "000.0")

rs.Fields("misure_3") = rs.Fields("misure_3") & Format((codice(Mid(buffer, j + 6, 2)) *

0.5), "000.0")

Next

bt_save.Visible = True

ridimensiona (1)

End Sub

Private Sub elaborate()Dim i As Integer

Dim w_media As Double

Dim w_media_c As Double

Dim w_grad As Double

Dim w_grad_c As Double

Dim w_num As Double

'

'... Calcola e visualizza le medie

'

w_media_c = 0

'... Calcola e visualizza la media di sensore 0

rs.MoveFirst

w_media = 0

Do While Not rs.EOFFor i = 1 To 80 Step 5

w_num = Mid(rs.Fields("misure_0"), i, 5)

w_media = w_media + w_num

Next

rs.MoveNext

Loop

w_media_c = w_media_c + w_media

w_media = w_media / (rs.RecordCount * 16)

frm_media(0) = Format(Round(w_media, 2), "##0.00")

'... Calcola e visualizza la media di sensore 1

rs.MoveFirst

w_media = 0

Do While Not rs.EOF

For i = 1 To 80 Step 5

w_num = Mid(rs.Fields("misure_1"), i, 5)

w_media = w_media + w_num

Next

rs.MoveNext

Loop

Page 53: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 53/58

53

w_media_c = w_media_c + w_media

w_media = w_media / (rs.RecordCount * 16)

frm_media(1) = Format(Round(w_media, 2), "##0.00")

'... Calcola e visualizza la media di sensore 2

rs.MoveFirst

w_media = 0

Do While Not rs.EOF

For i = 1 To 80 Step 5

w_num = Mid(rs.Fields("misure_2"), i, 5)

w_media = w_media + w_num

Nextrs.MoveNext

Loop

w_media_c = w_media_c + w_media

w_media = w_media / (rs.RecordCount * 16)

frm_media(2) = Format(Round(w_media, 2), "##0.00")

'... Calcola e visualizza la media di sensore 3

rs.MoveFirst

w_media = 0

Do While Not rs.EOF

For i = 1 To 80 Step 5

w_num = Mid(rs.Fields("misure_3"), i, 5)

w_media = w_media + w_num

Next

rs.MoveNext

Loop

w_media_c = w_media_c + w_media

w_media = w_media / (rs.RecordCount * 16)

frm_media(3) = Format(Round(w_media, 2), "##0.00")

'... Calcola e visualizza la media complessiva

w_media_c = w_media_c / (rs.RecordCount * 64)

frm_media_c = Format(Round(w_media_c, 2), "##0.00")

'

'... Calcola e visualizza i gradienti

'

w_grad_c = 0

'... Calcola e visualizza il gradiente di sensore 0

rs.MoveFirst

w_grad = 0

Do While Not rs.EOFFor i = 1 To 71 Step 5

w_num = Mid(rs.Fields("misure_0"), i + 5, 5) - Mid(rs.Fields("misure_0"), i, 5)

w_grad = w_grad + w_num

Next

rs.MoveNext

Loop

w_grad = w_grad / (rs.RecordCount * 16 - 1)

frm_grad(0) = Format(Round(w_grad, 2), "##0.00")

'... Calcola e visualizza il gradiente di sensore 1

rs.MoveFirst

w_grad = 0

Do While Not rs.EOF

For i = 1 To 71 Step 5

w_num = Mid(rs.Fields("misure_1"), i + 5, 5) - Mid(rs.Fields("misure_1"), i, 5)

w_grad = w_grad + w_numNext

rs.MoveNext

Loop

w_grad = w_grad / (rs.RecordCount * 16 - 1)

frm_grad(1) = Format(Round(w_grad, 2), "##0.00")

'... Calcola e visualizza il gradiente di sensore 2

rs.MoveFirst

w_grad = 0

Do While Not rs.EOF

For i = 1 To 71 Step 5

w_num = Mid(rs.Fields("misure_2"), i + 5, 5) - Mid(rs.Fields("misure_2"), i, 5)

w_grad = w_grad + w_num

Next

rs.MoveNext

Loop

w_grad = w_grad / (rs.RecordCount * 16 - 1)

frm_grad(2) = Format(Round(w_grad, 2), "##0.00")

'... Calcola e visualizza il gradiente di sensore 3

Page 54: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 54/58

54

rs.MoveFirst

w_grad = 0

Do While Not rs.EOF

For i = 1 To 71 Step 5

w_num = Mid(rs.Fields("misure_3"), i + 5, 5) - Mid(rs.Fields("misure_3"), i, 5)

w_grad = w_grad + w_num

Next

rs.MoveNext

Loop

w_grad = w_grad / (rs.RecordCount * 16 - 1)

frm_grad(3) = Format(Round(w_grad, 2), "##0.00")

'... Calcola e visualizza il gradiente complessivo

w_grad_c = Val(Replace(frm_media(3), ",", ".")) - Val(Replace(frm_media(0), ",", "."))

w_grad_c = w_grad_c / 3

frm_grad_c = Format(Round(w_grad_c, 2), "##0.00")

'... Visualizza numero totale acquisizioni al momento

frm_acquired = rs.RecordCount

End Sub

Private Function apri_porta() As Boolean

On Error GoTo errore

With MSComm1

If .PortOpen Then .PortOpen = False

.CommPort = porta

.Settings = "9600,N,8,1"

.RThreshold = 1

.SThreshold = 0 'default

.PortOpen = True

End With

apri_porta = True

Exit Function

errore:

MsgBox ("from apri_porta: " & Err.Description & ". Abort")

apri_porta = False

End Function

Private Function genera() As String

Dim i As Integer

Dim valore As Integer

Dim car As String

Dim cifra As IntegerFor i = 1 To 128

valore = Int(16 * Rnd) + 48

car = car & Chr(valore)

Next

' For i = 1 To 64

' valore = 1

' cifra = valore / 16

' car = car & Trim(Str(cifra)) & Trim(Str(valore - cifra * 16))

' Next

genera = car

End Function

Private Sub bt_save_Click()

salva_rsEnd Sub

Private Sub salva_rs()

Dim i As Integer

Dim riga As String

Dim filename As String

'... Verifica se rs esiste e non è vuoto

If rs Is Nothing Then Exit Sub

If rs.RecordCount = 0 Then Exit Sub

'... ottieni nome file

filename = get_filename

'... se "annulla", abbandona

If Len(Trim(filename)) = 0 Then Exit Sub

If SE_FILE_ESISTENTE(filename) Then

If MsgBox("Il file esiste. Sovrascrivo?", vbYesNo) = 7 Then

'... abbandona

Page 55: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 55/58

55

Exit Sub

End If

End If

'... Scrittura del file

rs.MoveFirst

Open CommonDialog1.filename For Output As #1

Do While Not rs.EOF

riga = "|"

'... Rappresentazione misure per sensore

For i = 1 To 48 Step 5riga = riga & Mid(rs.Fields("misure_0"), i, 5) & "-"

Next

riga = Mid(riga, 1, Len(riga) - 1) & "|"

For i = 1 To 48 Step 5

riga = riga & Mid(rs.Fields("misure_1"), i, 5) & "-"

Next

riga = Mid(riga, 1, Len(riga) - 1) & "|"

For i = 1 To 48 Step 5

riga = riga & Mid(rs.Fields("misure_2"), i, 5) & "-"

Next

riga = Mid(riga, 1, Len(riga) - 1) & "|"

For i = 1 To 48 Step 5

riga = riga & Mid(rs.Fields("misure_3"), i, 5) & "-"

Next

riga = Mid(riga, 1, Len(riga) - 1) & "|"

riga = riga & rs.Fields("data") & "-"

riga = riga & rs.Fields("ora") & "-"

riga = riga & rs.Fields("source")

'... Scrittura su file

Print #1, riga

rs.MoveNext

Loop

Close #1

bt_save.Visible = False

End Sub

Private Function get_filename() As StringCommonDialog1.filename = ""

CommonDialog1.Filter = "File di testo (*.txt)|*.txt"

CommonDialog1.FilterIndex = 1

CommonDialog1.ShowOpen

If Len(CommonDialog1.filename) = 0 Then

MsgBox ("Nome file mancante")

Exit Function

End If

get_filename = CommonDialog1.filename

End Function

Private Function SE_FILE_ESISTENTE(File As String) As Boolean

Dim fs

Set fs = CreateObject("Scripting.FileSystemObject")

If fs.fileexists(Trim(File)) ThenSE_FILE_ESISTENTE = True

Else

SE_FILE_ESISTENTE = False

End If

End Function

Private Sub COM1_Click()

COM1.Checked = Not COM1.Checked

COM2.Checked = False

Test_without_COM.Checked = False

End Sub

Private Sub COM2_Click()

COM2.Checked = Not COM2.Checked

COM1.Checked = False

Test_without_COM.Checked = False

End Sub

Private Function codice(esa As String) As Integer

Page 56: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 56/58

56

If Len(esa) <> 2 Then

MsgBox ("From codice: Valore esa errato")

codice = 0

Exit Function

End If

If Mid(esa, 1, 1) >= "0" And Mid(esa, 1, 1) <= "?" Then

Else

MsgBox ("From codice: Primo carattere esa errato della coppia: " & esa & " di indice: " & j)

codice = 0

Exit Function

End If

If Mid(esa, 2, 1) >= "0" And Mid(esa, 2, 1) <= "?" Then

Else

MsgBox ("From codice: Secondo carattere esa errato della coppia: " & esa & " di indice: " &

j)

codice = 0

Exit Function

End If

codice = ((Asc(Mid(esa, 1, 1)) - 48) * 16) + ((Asc(Mid(esa, 2, 1)) - 48) * 1)

End Function

Private Sub Exit_Click()

Unload MDIForm1

End Sub

Private Sub PDF0_Click()

Dim w_misure As String

Dim w_valore As Double

Dim i As Integer

'... Costruzione del vettore delle occorrenze normalizzato per il sensore 0

For v_ind = 0 To 255

rs.MoveFirst

v_occur(v_ind) = 0

Do While Not rs.EOF

w_misure = rs.Fields("misure_0")

For i = 0 To 15

w_valore = Mid(w_misure, (i * 5) + 1, 5)

If w_valore = v_gradi(v_ind) Then v_occur(v_ind) = v_occur(v_ind) + 1

Next

rs.MoveNextLoop

v_occur(v_ind) = v_occur(v_ind) / (rs.RecordCount * 16)

Next

'... Apre il frm_chart0

frm_chr0.Show

End Sub

Private Sub PDF1_Click()

Dim w_misure As String

Dim w_valore As Double

Dim i As Integer

'... Costruzione del vettore delle occorrenze normalizzato per il sensore 1

For v_ind = 0 To 255

rs.MoveFirstv_occur(v_ind) = 0

Do While Not rs.EOF

w_misure = rs.Fields("misure_1")

For i = 0 To 15

w_valore = Mid(w_misure, (i * 5) + 1, 5)

If w_valore = v_gradi(v_ind) Then v_occur(v_ind) = v_occur(v_ind) + 1

Next

rs.MoveNext

Loop

v_occur(v_ind) = v_occur(v_ind) / (rs.RecordCount * 16)

Next

'... Apre il frm_chart1

frm_chr1.Show

End Sub

Private Sub PDF2_Click()

Dim w_misure As String

Dim w_valore As Double

Dim i As Integer

Page 57: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 57/58

57

'... Costruzione del vettore delle occorrenze normalizzato per il sensore 1

For v_ind = 0 To 255

rs.MoveFirst

v_occur(v_ind) = 0

Do While Not rs.EOF

w_misure = rs.Fields("misure_2")

For i = 0 To 15

w_valore = Mid(w_misure, (i * 5) + 1, 5)

If w_valore = v_gradi(v_ind) Then v_occur(v_ind) = v_occur(v_ind) + 1

Next

rs.MoveNextLoop

v_occur(v_ind) = v_occur(v_ind) / (rs.RecordCount * 16)

Next

'... Apre il frm_chart2

frm_chr2.Show

End Sub

Private Sub PDF3_Click()

Dim w_misure As String

Dim w_valore As Double

Dim i As Integer

'... Costruzione del vettore delle occorrenze normalizzato per il sensore 1

For v_ind = 0 To 255

rs.MoveFirst

v_occur(v_ind) = 0

Do While Not rs.EOF

w_misure = rs.Fields("misure_3")

For i = 0 To 15

w_valore = Mid(w_misure, (i * 5) + 1, 5)

If w_valore = v_gradi(v_ind) Then v_occur(v_ind) = v_occur(v_ind) + 1

Next

rs.MoveNext

Loop

v_occur(v_ind) = v_occur(v_ind) / (rs.RecordCount * 16)

Next

'... Apre il frm_chart2

frm_chr3.Show

End Sub

Private Sub bt_restart_Click()'... Riavvia il programma: svuota gli array e ridimensiona main

If Not rs Is Nothing Then

If rs.RecordCount > 0 And bt_save.Visible = True Then

If MsgBox("Salvo elaborazione precedente?", vbYesNo) = 6 Then

salva_rs

Else

bt_save.Visible = False

End If

End If

rs.Close

frm_acquired = ""

ridimensiona (0)

frm_acquire = ""

frm_acquire.SetFocus

apri_rs

End IfEnd Sub

Private Sub Form_Load()

'

'... Inizializza

'

set_v_gradi

ridimensiona (0)

apri_rs

End Sub

Private Sub set_v_gradi()

For v_ind = 0 To 255

v_gradi(v_ind) = v_ind * 0.5

Next

End Sub

Private Sub ridimensiona(aspetto As Integer)

Select Case aspetto

Case 0

Page 58: Progetto Di Un Misuratore Di Temperatura

5/9/2018 Progetto Di Un Misuratore Di Temperatura - slidepdf.com

http://slidepdf.com/reader/full/progetto-di-un-misuratore-di-temperatura 58/58

58

main.Height = 1300

main.ScaleHeight = 720

Case 1

main.Height = 4020

main.ScaleHeight = 3240

End Select

End Sub

Private Sub apri_rs()

'... Verifica che il recordset non sia già aperto

If Not rs Is Nothing Then

Set rs = NothingEnd If

Set rs = New ADODB.Recordset

'... Definisce la struttura del record set

rs.Fields.Append "misure_0", adVarChar, 80

rs.Fields.Append "misure_1", adVarChar, 80

rs.Fields.Append "misure_2", adVarChar, 80

rs.Fields.Append "misure_3", adVarChar, 80

rs.Fields.Append "data", adDate

rs.Fields.Append "ora", adVarChar, 8

rs.Fields.Append "source", adVarChar, 4

rs.CursorLocation = adUseClient

rs.Open , , adOpenStatic, adLockBatchOptimistic

End Sub

Private Sub Test_without_COM_Click()

Test_without_COM.Checked = Not Test_without_COM.Checked

COM1.Checked = False

COM2.Checked = False

End Sub

Private Sub MSComm1_OnComm()

Dim carattere

If MSComm1.CommEvent = comEvReceive Then

carattere = MSComm1.Input

If carattere = vbCr Then Exit Sub

buffer = buffer & carattere

End If

If Len(buffer) = 128 Then

acquire

If times < frm_acquire Then

buffer = ""

MSComm1.Output = "a"times = times + 1

Else

Call elaborate

Frame1.Enabled = True

End If

End If

End Sub