Istituto Professionale di Stato per l`Industria e l`Artigianato

Transcript

Istituto Professionale di Stato per l`Industria e l`Artigianato
Istituto Professionale di Stato per l'Industria e l'Artigianato
MORETTO
Via Luigi Apollonio, 21 BRESCIA
Progetto finalizzato per
Progettazione e costruzione di schede per interfacciamento
tra PC e circuiti esterni tramite LX833
Realizzazione
Celiento Giuseppe
Chiodoni Fabio
Della classe 5AI a.s. 1998-99
Corso per Tecnici delle Industrie Elettriche ed Elettroniche
1
PROGETTAZIONE E COSTRUZIONE DI SCHEDE PER L’INTERFACCIAMENTO TRA PC E CIRCUITI
ESTERNI TRAMITE LX833 ........................................................................................................................................ 3
SCOPO DEL PROGETTO............................................................................................................................................ 3
PROGETTI DI INTERFACCE .............................................................................................................................. 19
Interfaccia display a sette segmenti decodificati ................................................................................................... 20
Interfaccia Led e Dip Switch .................................................................................................................................. 21
CONTROLLO E SINCRONIZZAZIONE DELLE VARIE INTERFACCE .............................................................................. 22
Assegnazione degli indirizzi ................................................................................................................................... 22
QUARZO 4MHZ .......................................................................................................................................................... 30
Caratteristiche Generali Di Un Convertitore Analogico-Digitale ......................................................................... 32
LA CONVERSIONE DIGITALE-ANALOGICA E ANALOGICA-DIGITALE .................................................. 34
CONVERTITORI ANALOGICI DIGITALI ADC.................................................................................................. 35
ADC AD APPROSSIMAZIONI SUCCESSIVE.................................................................................................... 36
CONVERTITORE ADC 0808..................................................................................................................................... 37
LCD LM018 HITACHI............................................................................................................................................ 38
SOFTWARE DI GESTIONE .................................................................................................................................. 43
2
PROGETTAZIONE E COSTRUZIONE DI SCHEDE PER
L’INTERFACCIAMENTO TRA PC E CIRCUITI ESTERNI
TRAMITE LX833
Scopo del progetto
Lo scopo di questo progetto è quello di poter comandare, attraverso il linguaggio Pascal,
circuiti esterni al computer utilizzando la scheda LX.833, progettata dalla rivista “Nuova
Elettronica”, che abbiamo corredato con il PPI 82C55A costruito dalla Harris
Semiconductor in tecnologia C-MOS.
SCHEMA A BLOCCHI
PC
LX.833
INTERFACCE
LX. 833
La scheda è predisposta per poter essere adattata alle esigenze che il consumatore ha, cioè è
costituita da uno stampato detto “Mille fori” dov’è possibile assemblare altri componenti.
3
LX.833 è una scheda PC/XT, quindi possiede un BUS a 8 BIT per l’entrata e l’uscita dei
dati; con una denominazione che va da: D0 fino a D7.
Lo stampato è predisposto con i seguenti integrati : SN.74LS244, EP.833, e SN.74L245.
L’SN.74LS244 funge da Buffer per i segnali provenienti dal BUS degli indirizzi in modo da
separare le linee del BUS della scheda madre da quelle connesse all’82C55A.
Con questo dispositivo anche se causassimo dei cortocircuiti sulle linee, ad esempio con
collegamenti o saldature errati, questi non si ripercuoterebbero sul BUS principale e,
pertanto, il computer continuerebbe a funzionare senza anomalie.
L’EP.833 è una memoria PROM ( cioè una volta programmata non è più riprogrammabile)
utile per decodificare gli indirizzi.
Sui piedini d’uscita è collocato un piccolo connettore (JUMPER) che permette di
selezionare quattro diversi gruppi di indirizzi da assegnare alla scheda; ognuno di questi
gruppi è composto da otto indirizzi, per cui avremo a disposizione 4 * 8 = 32 indirizzi.
Selezionando il JUMPER la scheda risponde nel campo di indirizzi che vanno da $300 a
$307 (valori in esadecimale); selezionando su B vanno da $308 a $30F, con il C da $310 a
$317 e su D da $318 a $31F.
L’SN.74LS245 è un buffer di dati bidirezionali che viene utilizzato per trasferire gli 8 BIT
dei dati dalla scheda al BUS del computer e viceversa.
Segnali presenti sulla scheda
ED0-ED7 Rappresentano i dati del BUS (D0-D7) bufferizzati a valle dell’integrato
SN.74LS245.
EA0-EA2 Sono la versione bufferizzata degli indirizzi bassi, A0-A2, a valle
dell’integrato SN.74LS244.
ERD E’ la versione bufferizzata del segnale IOR a valle dell’integrato SN.74LS244.
EWR E’ la versione bufferizzata del segnale IOW a valle dell’integrato SN.74LS244.
4
S
L
O
T
NUOVA ELETTRONICA LX833
LOGICA DI
CONTROLLO
P
C
INTERFACCIA SPERIMENTALE PER PC/XT/AT
U1
A30
B14
2
4
6
8
11
13
15
17
A1
IOR
I1
I3
I2
B13
A29
A31
IOW
A2
A0
1
19
1A1
1A2
1A3
1A4
2A1
2A2
2A3
2A4
18
16
14
12
9
7
5
3
1Y1
1Y2
1Y3
1Y4
2Y1
2Y2
2Y3
2Y4
EA1
ERD
U1
U3
U2
EWR
EA2
EA0
1G
2G
ECS
VCC
74LS244
LOGICA DI
SELEZIONE
R3
R2
R1
10K
10K
R4
10K
10K
U3
A28
A27
A26
A25
A24
A23
A22
A11
1
2
3
4
5
6
7
8
9
11
A3
A4
A5
A6
A7
A8
A9
AEN
I0
I1
I2
I3
I4
I5
I6
I7
I8
I9
12
13
14
15
16
17
18
19
F0
F1
F2
F3
F4
F5
F6
F7
CAMPO DI SELEZIONE
JP1-ON $300-$307
JP1
JP2
JP3
JP4
16V8
EP.833/1
JP2-ON $308-$30F
JP3-ON $310-$317
JP4-ON $318-$31F
BUFFER DATI
BIDIREZIONALE
U2
A9
A8
A7
A6
A5
A4
A3
A2
2
3
4
5
6
7
8
9
D0
D1
D2
D3
D4
D5
D6
D7
19
1
A1
A2
A3
A4
A5
A6
A7
A8
18
17
16
15
14
13
12
11
B1
B2
B3
B4
B5
B6
B7
B8
ED0
ED1
ED2
ED3
ED4
ED5
ED6
ED7
G
DIR
74LS245
B1
+5V
B31
C1
B7
-12V
B9
+12V
C2
100nF
10uF
GND
C3
C4
100nF
100nF
C1, C2, C3 vanno connessi sui
pin di alimentazione di U1, U2, U3
B3
+5V
B29
5
8255A
Il circuito integrato INTEL 82C55A è un dispositivo generale di I/O programmabile,
progettato per l'uso con i microprocessori della famiglia INTEL. E’ dotato di 24 linee:
-
8 appartenenti al Port A;
-
8 appartenenti al Port B;
-
8 appartenenti al Port C.
le 8 linee del port A e del Port b possono essere programmate per funzionare o da ingressi
o da uscite in 4 possibili modi:
-
Port A ingresso e Port B uscita;
-
Port A uscita e Port B uscita;
-
Port A ingresso e Port B ingresso;
-
Port A uscita e Port B ingresso.
Le linne del Port C possono essere suddivise in due gruppi da 4 bit ciascuno. Ogni gruppo
può essere programmabile o da ingresso o da uscita nei modi seguenti:
-
da PC0 a PC3 uscita e da PC4 a Pc7 ingresso;
-
da PC0 a PC3 ingresso e da PC4 a Pc7 uscita;
-
da PC0 a PC3 ingresso e da PC4 a Pc7 ingresso;
-
da PC0 a PC3 uscita e da PC4 a Pc7 uscita.
Complessivamente nel Modo 0 si hanno 16 modi diversi di programmazione dell’82C55A.
Descrizione delle funzioni svolte dall'82C55A
6
Generalità
L'82C55A è un'interfaccia per I/O programmabile (PPI = Programmable Peripheral
Interface) atta a collegare una generica periferica al Bus della CPU. La configurazione
operativa dell'82C55A è controllabile da software, in modo da rendere inutile l'uso di
circuiti logici esterni per il normale interfacciamento.
Buffer per il Bus Dati
Viene utilizzato un buffer three-state bidirezionale ad otto bit per interfacciare l'82C55A al
Bus Dati del sistema. I dati sono trasmessi o ricevuti dal buffer sotto il controllo delle
istruzioni di ingresso o di uscita inviate dalla CPU. Anche le parole di controllo e le
informazioni di stato vengono trasferite attraverso questo buffer.
7
Circuiti logici di controllo e di lettura/scrittura
La funzione di questo blocco è di gestire tutti i trasferimenti interni ed esterni sia dei dati
che delle parole di controllo di stato. Riceve comandi dal Bus Indirizzi e da quello di
controllo della CPU e controlla entrambi i gruppi di linee.
(CS )
Chip Select.
La presenza di un livello basso a questo piedino di ingresso abilita le
comunicazioni tra l'interfaccia e la CPU.
(RD)
Read. La presenza di un livello basso a questo piedino di ingresso abilita l'8255A ad inviare
dati o informazioni di stato alla CPU tramite il Bus Dati. In altre parole la CPU è abilitata a
leggere dall'82C55A.
WR
Write. La presenza di un livello basso a questo piedino di ingresso abilita la CPU a scrivere
dati o parole di controllo nell'82C55A.
(A0 e A1)
Port Select 0 e Port Select 1. Questi segnali di ingresso, assieme alle precedenti linee RD
e WR , permettono di selezionare una delle tre porte di accesso ai rispettivi registri di
controllo. Normalmente queste due linee sono connesse ai due bit meno significativi del
Bus degli indirizzi (appunto A0 e A1).
(RESET)
Reset. La presenza di un livello alto a questo piedino azzera il registro di controllo e tutti i
port (A, B e C) vengono settati come ingressi.
Controllo del Gruppo A e del Gruppo B
8
La configurazione operativa di ciascun port è programmabile da software. Per far ciò la
CPU invia una parola di controllo all'82C55A. La parola di controllo contiene appunto le
informazioni atte a definire tale configurazione, quali ad esempio il modo operativo,il set
di bit, etc..
Ciascun blocco di controllo (del Gruppo A e del Gruppo B) riceve comandi dal circuito di
controllo e di lettura/scrittura o direttamente parole di controllo tramite il bus dati interno,
ed emette i segnali di controllo per il port ad esso associato.
Del Gruppo A fanno parte il Port A e la parte alta del Port C (linee da C7 a C4), mentre al
Gruppo B appartengono il Port B e la parte bassa del Port C (linee da C3 a C0).
Il registro di controllo può essere solo scritto. Non sono ammesse operazioni di lettura su
tale registro.
PORT A, B E C
L'integrato 82C55A contiene al suo interno tre port ad otto bit (A, B e C). Tutti e tre
possono essere configurati da programma in vari modi operativi, ma ciascuno ha delle
caratteristiche proprie che lo differenziano dagli altri.
Port A. È un port costituito da un buffer bidirezionale ad 8 bit dotato di memoria (latch) e
di un registro di memorizzazione d'ingresso.
Port B. È un port costituito da un buffer d'uscita ad 8 bit dotato di memoria e da un
registro di memorizzazione d'ingresso bufferizzato ad 8 bit.
Port C. E un port costituito da un buffer d'uscita ad 8 bit dotato di memoria e da un buffer
d'ingresso ad 8 bit (senza memorizzazione). Questo port a sua volta può essere suddiviso
in due port a 4 bit. Ciascuno di questi port di dimensioni contenute contiene un registro di
memorizzazione a 4 bit che può essere utilizzato per i segnali di controllo d'uscita e
d'ingresso assieme ai port A e B.
Operazioni fondamentali dell'8255
A1
A0
RD
WR
CS
9
Operazione d'ingresso (READ)
0
0
1
0
1
0
0
0
0
1
1
1
0
0
0
Port A
Port B
Port C
Data Bus
Data Bus
Data Bus
Operazione d'uscita (WRITE)
0
0
1
1
0
1
0
1
1
1
1
1
0
0
0
0
0
0
0
0
Data Bus
Port A
Data Bus
Port B
Data Bus
Port C
Data Bus
registro di controllo
Funzione di disabilitazione
x
1
x
x
1
x
x
0
1
x
1
1
1
0
0
Data Bus in three-state
Condizione illegittima
Data Bus in three-state
Descrizione delle operazioni svolte dall'8255A
Selezione del modo operativo
Possono essere selezionati da software tre diversi modi operativi:
Modo O - ingresso/uscita normale
Modo 1 - ingresso/uscita controllato da strobe
Modo 2 - bus bidirezionale
Quando il segnale d'ingresso di reset assume un valore alto tutti i Port vengono selezionati
come ingressi (cioè tutte le 24 linee si portano in uno stato di alta impedenza). Quando il
comando di reset termina l'82C55A resta in tale condizione senza che siano richiesti altri
comandi. Durante l'esecuzione del programma possono essere utilizzati tutti i modi
operativi disponibili mediante l'invio dalla CPU di una sola istruzione contenente la parola
10
di controllo appropriata. Ciò permette di utilizzare un solo 82C55A per gestire
contemporaneamente diversi tipi di periferiche.
I modi operativi dei Port A e B possono essere definiti in maniera indipendente l'uno
dall'altro, mentre il Port C viene diviso in due parti in funzione di quanto specificato per
gli altri due port. Tutti i registri d'uscita, inclusi i flip-flop di stato, vengono resettati ogni
volta che viene cambiato modo operativo. Le definizioni di modo dei due port possono
essere combinate tra di loro in modo da adattare l'interfaccia alle varie periferiche. Ad
esempio il Gruppo B può essere programmato in modo Out per controllare la chiusura di
una serie di tasti o visualizzare su display dei risultati, mentre il Gruppo A può essere
programmato in modo In per gestire una tastiera o un lettore di schede o qualsiasi altro
dispositivo gestibile mediante interrupt.
Le definizioni di modo e le loro combinazioni possibili possono sembrare all'inizio
un'inutile complicazione e risultare difficili da comprendere, ma dopo il primo impatto se
ne comprenderà la versatilità d'uso offerta da queste scelte e risulteranno alla fine di facile
apprendimento. La progettazione dell'82C55A ha tenuto conto di vari fattori, quali
l'efficienza della disposizione dei componenti sulla scheda di supporto e la facile
connessione dei segnali di controllo tra CPU e interfaccia, ed ha cercato di offrire la
massima versatilità di funzioni svolte sfruttando tutti i piedini disponibili dell'integrato.
Possibilità di set/reset di un singolo bit
Con una sola istruzione di uscita (OUT) della CPU può essere settato (posto ad 1) o
resettato (posto a O) un singolo bit tra gli 8 disponibili sul Port C. Questa caratteristica
permette di semplificare le subroutine di controllo di trasferimento dei dati.
Quando le linee del Port C vengono usate come linee di controllo dei trasferimenti dei Port
A e B, queste possono essere modificate come se il Port C fosse un normale Port d'uscita.
Controllo dell'interrupt
Quando l'82C55A è programmato per funzionare in modo 1 o modo 2, i segnali di controllo
possono essere utilizzati direttamente per generare richieste di interrupt alla CPU. Quando
11
ciò avviene, i segnali di richiesta di interrupt generati dal Port C possono essere abilitati o
disabilitati ponendo a livello alto o basso il flip-flop INTE associato, utilizzando l'istruzione
set/reset di un singolo bit del Port C.
Con tali istruzioni il programmatore può permettere o negare ad un dispositivo di I/O la
possibilità di lanciare interrupt. Se viene posto ad 1 il contenuto di un dato bit del flip-flop
INTE, l'interrupt del dispositivo relativo viene abilitato, mentre se viene posto a 0 l'interrupt
risulta disabilitato.
NOTA: tutti i flip-flop di mascheramento vengono automaticamente resettati quando viene
selezionato un modo o se il dispositivo viene resettato.
Modi operativi
Modo 0 (ingresso uscita normale). Questa configurazione operativa permette di instaurare
su tutti i 3 Port le normali funzioni di lettura o scrittura di un dato. Non è richiesto alcun
segnale di controllo tipo handshake in quanto i dati vengono semplicementi letti o scritti nel
Port relativo.
Caratteristiche del Modo 0:
- due Port ad 8 bit e due Port a 4 bit;
- qualsiasi Port può essere definito come ingresso o come uscita;
- le uscite sono memorizzate;
- gli ingressi non sono memorizzati;
- sono possibili 16 diverse combinazioni di I/O
CONFIGURAZIONI POSSIBILI IN MODO 0
A
A
B
B
D3
D2
D1
D0
Gruppo Gruppo Gruppo Gruppo
A
A
B
B
Port A Port C Port B Port C
12
0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
0
0
0
0
1
1
1
1
0
0
1
1
0
0
1
1
0
0
1
1
0
0
1
1
0
1
0
1
0
1
0
1
0
1
0
1
0
1
0
1
uscita
uscita
uscita
uscita
uscita
uscita
uscita
uscita
ingresso
ingresso
ingresso
ingresso
ingresso
ingresso
ingresso
ingresso
PC7-PC4
uscita
uscita
uscita
uscita
ingresso
ingresso
ingresso
ingresso
uscita
uscita
uscita
uscita
ingresso
ingresso
ingresso
ingresso
uscita
uscita
ingresso
ingresso
uscita
uscita
ingresso
ingresso
uscita
uscita
ingresso
ingresso
uscita
uscita
ingresso
ingresso
PC3-PC0
uscita
ingresso
uscita
ingresso
uscita
ingresso
uscita
ingresso
uscita
ingresso
uscita
ingresso
uscita
ingresso
uscita
ingresso
Modo 1 (ingresso/uscita mediante strobe). Questo tipo di configurazione permette di
trasferire dati da un Port mediante il controllo di segnali di handshake. Nel modo 1 il Port A
e Port B usano le linee del Port C per generare o acquisire questi controlli.
Caratteristiche del Modo 1:
- due gruppi di trasferimento (Gruppo A e Gruppo B);
- ciascun gruppo contiene un Port di dati ad 8 bit ed un Port di controllo dei dati da 4 bit;
- i due Port di dati ad 8 bit possono essere sia d'ingresso che d'uscita. Sia le uscite che gli
ingressi sono memorizzate;
- i due Port a 4 bit vengono usati per emettere i segnali di controllo e fornire lo stato del
dispositivo alle periferiche collegate ai due Port ad 8 bit.
Definizione dei caratteri di controllo per l'ingresso di un dato.
STB (ingresso di strobe). Se questo ingresso si trova a livello basso i dati in ingresso al
port relativo vengono acquisiti e memorizzati nell'82C55A.
IBF (flip-flop segnalazione buffer di ingresso pieno). Se questa uscita si porta a livello alto
13
vuol dire che dati presenti agli ingressi del Port sono gia stati acquisiti e quindi
memorizzati; in altre parole viene emesso un segnale di “ricevuto” (acknowledge). Il
segnale IBF viene posto ad 1 dal fronte di discesa dell'ingresso di strobe STB, mentre viene
resettato dal fronte d'onda di salita del segnale d'ingresso
RD .
INTR (richiesta di interrupt). La presenza di un livello alto su questa uscita puo' essere
usata per generare un interrupt alla CPU, in quanto indica che il dispositivo d'ingresso sta
richiedendo l'intervento. Il segnale INTR viene posto ad 1 se sia il segnale STB che IBF ed
INTE sono contemporaneamente a livello alto. Viene invece resettato dal fronte d'onda di
discesa del segnale RD . Questo modo di funzionamento permette ad un generica periferica
di ingresso di richiedere alla CPU di acquisirne un dato semplicemente rendendolo
disponibile al Port relativo e generando un segnale di strobe.
Definizione dei segnali di controllo per l'uscita di un dato
OBF flip flop segnalazione buffer d'uscita pieno). Il segnale d'uscita OBF si porta a livello
basso per indicare che la CPU ha emesso (scritto) il dato verso il port specificato. Questo
segnale viene posto a 0 dal fronte d'onda di salita dell'ingresso WR e viene riposizionato ad
1 quando l'ingresso ACK si porta a livello basso.
ACK (dato ricevuto). La presenza di un livello basso a questo ingresso informa 1'82C55A
che il dato emesso dal Port A o dal Port B è stato accettato. In altre parole, con questo
segnale il dispositivo periferico comunica che ha ricevuto il dato emesso dalla CPU.
INTR (richiesta di interrupt). La presenza di un livello alto su questa uscita può essere
usata per generare una segnalizzazione di interrupt alla CPU, in quanto indica che il
dispositivo d'uscita ha ricevuto il dato trasmesso dalla CPU. Il segnale INTR viene posto ad
1 se sia il segnale ACK che OBF ed INTE sono contemporaneamente a livello alto. Viene
invece resettato dal fronte d'onda di discesa del segnale WR.
INTE A. È un segnale che viene controllato mediante la scrittura su singolo bit offerta
dall'82C55A. È collegato al bit 6 del Port C (PC6).
INTE B. È un segnale che viene controllato mediante la scrittura su singolo bit offerta
dall'82C55A. È collegato al bit 2 del Port C (PC2).
14
Configurazioni possibili in Modo 1. Nel Modo 1 sia il Port A che il Port B possono essere
configurati individualmente come ingressi o come uscite.
Modo 2 (ingresso - uscita di dati attraverso bus bidirezionale e segnali di controllo).
Questa configurazione operativa permette all'82C55A di interfacciarsi direttamente ad un
dispositivo avente un bus bidirezionale ad 8 bit. I segnali di controllo (con modalità di
handshake) permettono di regolare il flusso dei dati in maniera analoga a quella vista per il
Modo 1. È possibile inoltre sia generare un segnale di interrupt che di abilitarne e
disabilitarne il funzionamento.
Caratteristiche del Modo 2:
- si può usare solo il Gruppo A;
- un bus bidirezionale ad 8 bit disponibile sul Port A e 5 linee di controllo accessibili sul
Port C;
- sia gli ingressi che le uscite sono memorizzate;
- il port di controllo a 5 bit (Port C) viene usato per controllare e leggere lo stato del bus
bidirezionale ad 8 bit (Port A).
Descrizione dei segnali di controllo del bus bidirezionale
INTR (richiesta di interrupt). La presenza di un livello alto su questa uscita puo' essere
usata per generare un interrupt alla CPU sia per le operazioni di ingresso che per quelle
d'uscita.
15
Operazioni d'uscita
OBF (buffer d'uscita pieno). L'uscita OBF si porta a livello basso per indicare che la CPU
ha scritto il dato sul Port A al fine di emetterlo.
ACK (ricevuto). Quando questo ingresso si porta a livello basso abilita il buffer d'uscita del
Port A, normalmente in condizione three-state, ad emettere il dato sul bus. In caso contrario
il buffer d'uscita rimane in condizione di alta impedenza.
INTE 1(flip-flop INTE associato ad OBF). È un segnale che viene controllato mediante la
scrittura su singolo bit offerta dall'82C55A. È collegato al bit 6 del Port C (PC6).
Operazioni d'ingresso
STB (ingresso di strobe). La presenza di un livello basso a questo ingresso fa caricare il
dato presente sul bus nel latch d'ingresso.
IBF (flip-flop segnalazione buffer di ingresso pieno). Se questa uscita si porta a livello alto
vuol dire che i dati presenti agli ingressi del port sono gia stati acquisiti e quindi
memorizzati.
INTE 2 (flip-flop INTE associato ad IBF). È un segnale che viene controllato mediante la
scrittura su singolo bit offerta dall'82C55A. È collegato al bit 4 del Port C (PC4).
CONSIDERAZIONI SULL'USO DELLE COMBINAZIONI DEI VARI MODI
Vi sono delle combinazioni di programmazione dei vari modi operativi che non utilizzano
interamente i bit disponibili del Port C. Le linee rimanenti possono essere utilizzate nel
seguente modo:
- se programmate come ingressi tutte le linee d'ingresso possono essere lette con una normale
operazione di lettura del Port C;
- se programmate come uscite i bit della parte alta del Port C (PC-PC4) possono essere modificati
16
singolarmente usando la funzione di set/reset di un bit alla volta;
i bit della parte bassa del Port C (PC3-PQ) possono sia essere modificati singolarmente
usando la funzione di set/reset di un bit alla volta che venire scritti regolarmente accedendo
al Port C.
SOMMARIO DEI SIGNIFICATI DELLE LINEE NEI VARI MODI
PA0
PA1
PA2
PA3
PA4
PA5
PA6
PA7
IN
MODO 0
OUT
IN
MODO 1
OUT
IN
IN
IN
IN
IN
IN
IN
IN
OUT
OUT
OUT
OUT
OUT
OUT
OUT
OUT
IN
IN
IN
IN
IN
IN
IN
IN
OUT
OUT
OUT
OUT
OUT
OUT
OUT
OUT
17
MODO 2
solo gruppo
A
IN/OUT
IN/OUT
IN/OUT
IN/OUT
IN/OUT
IN/OUT
IN/OUT
IN/OUT
PB0
PB1
PB2
PB3
PB4
PB5
PB6
PB7
PC0
PC1
PC2
PC3
PC4
PC5
PC6
PC7
IN
IN
IN
IN
IN
IN
IN
IN
IN
IN
IN
IN
IN
IN
IN
IN
OUT
OUT
OUT
OUT
OUT
OUT
OUT
OUT
OUT
OUT
OUT
OUT
OUT
OUT
OUT
OUT
IN
IN
IN
IN
IN
IN
IN
IN
INTRB
IBFB
STBB
INTRA
STBA
IBFA
I/O
I/O
OUT
OUT
OUT
OUT
OUT
OUT
OUT
OUT
INTRB
OBFB
ACKB
INTRA
I/O
I/O
ACKA
OBFA
I/O
I/O
I/O
INTRA
STBA
IBFA
ACKA
OBFA
Caratteristiche d'uscita del Port B e Port C
Qualsiasi bit d'uscita tra quelli disponibili sul Port B o sul Port C possono erogare 2.5 mA a
1.5 Volt. Queste caratteristiche permettono all'82C55A di pilotare direttamente dispositivi
tipo darlington o display a tensione elevata.
Lettura dello stato delle periferiche dal Port C
In Modo 0 il Port C trasferisce dati da o verso le periferiche collegate. Quando invece
l'82C55A è programmato in Modo 1 o 2, il Port C è dedicato alla generazione o alla
rilevazione dei segnali di controllo di handshake delle periferiche. La lettura del Port C
permette al programmatore di sapere lo stato dei dispositivi periferici.
Non sono richieste procedure particolari per acquisire tale valore, è sufficiente
un'operazione di lettura normale.
18
PROGETTI DI INTERFACCE
Il circuito si propone l'obiettivo di realizzare un'interfaccia sperimentale in grado di gestire
e comandare una serie di dispositivi elettronici mediante l'utilizzo di un Personal Computer
IBM compatibile fatto funzionare con un software di gestione redatto in TURBO PASCAL.
I dispositivi prescelti da interfacciare sono:
a) gruppo di 4 relè reed;
b) gruppo di 2 display a sette segmenti decodificati e pilotati da decoder driver 9368;
c) gruppo di 8 diodi led;
d) gruppo di 8 dip-switch;
e) controllo di temperatura ed umidità realizzato con 8 Contraves, 1 display LCD LM018 e
1 display LCM5003.
Data la complessità dell'interfaccia si è deciso di montare su un apposito circuito stampato a
parte (diverso dal circuito LX833) l'hardware relativo ai dispositivi elencati da a) a e).
Esaminiamo uno ad uno i circuiti relativi alle quattro interfacce da realizzare.
Interfaccia relè
VCC
In Fig. 1 è riportato lo
elettrico
R25
dell'interfaccia verso relè
D13
schema
K1
D9
U8A
reed. In essa si nota la
presenza di un registro a
Data Bus
8 bit 74LS374 U4 che
pilota sulle uscite Q0,
Q2, Q4, Q6 quattro
buffer invertenti 7406 che
SEL1
7406
U4
D0
D1
D2
D3
D4
D5
D6
D7
RELAY
VCC
K2
R26
Q0
Q1
Q2
Q3
Q4
Q5
Q6
Q7
OC
CLK
D10
D14
U8B
7406
74LS374
RELAY
VCC
K3
R27
D11
a
loro
volta
pilotano
D15
U8C
altrettanti relè reed a 5V.
7406
RELAY
VCC
K4
Si osservi che ogni relè
R28
D12
19
D16
U8D
7406
RELAY
reed è dotato di diodo volano per i noti problemi esistenti nel pilotaggio dei carichi
induttivi. Si noti che l'attivazione di un relè è pure visualizzata attraverso un diodo led con
relativa resistenza di limitazione posto in parallelo alla bobina di eccitazione. Il circuito
integrato 74LS374 riceve i dati provenienti dal Data Bus della scheda LX833 ED0-ED7 e li
memorizza sul fronte di salita del suo ingresso di clock alimentato dal segnale SEL1.
Per attivare il relè K1 (connesso alla uscita Q0) il PC dovrà inviare al registro U4 il codice
binario
%00000001 ($01), per attivare K2 il PC
dovrà inviare
il codice binario
%00000010 ($02), per attivare contemporaneamente i relè K1, K3 e K4 il PC dovrà inviare
il codice binario %01010001 ($51). Il segnale SEL1 dovrà essere generato da una
operazione WRITE eseguita all'indirizzo attribuito all'interfaccia nell'ambito di quelli
previsti dalla Tab. 1.
Interfaccia display a sette segmenti decodificati
In Fig. 2 è riportato lo schema elettrico dell'interfaccia verso display a 7 segmenti
decodificati. In essa si nota la presenza di un registro a 8 bit 74LS374 U5 che pilota due
decoder TTL 9368 connessi a due display a 7 segmenti catodo comune del tipo FND500. Il
codice binario relativo ai 4 bit D0-D3 attiva il display LSD (cifra meno significativa) il
codice relativo ai 4 bit D4-D7 attiva il display MSD (cifra più significativa). Le due
decodifiche 9368 sono mantenute trasparenti
(LE connesso a 0); la funzione di
memorizzazione è affidata al circuito integrato U5 che come è noto memorizza i dati
presenti sugli ingressi D0-D7 sul fronte di salita dell'ingresso di clock alimentato dal
segnale SEL2.
Fig. 2
20
Per trasferire al gruppo display il dato
binario %01010010 ($52) il PC dovrà
inviare al registro U5 il codice binario
D1
R6
D2
U5
Data Bus
D0
D1
D2
D3
D4
D5
D6
D7
%01010010 o esadecimale $52. Sul display
MSD apparirà la cifra 5 sul display LSD
R5=330
SEL3
D3
Q0
Q1
Q2
Q3
Q4
Q5
Q6
Q7
OC
CLK
apparirà la cifra. Il segnale SEL2 dovrà
74LS374
R8
D4
R9
D5
R10
D6
R11
D7
R12 =330
D8
VCC
VCC
U10
Data Bus
SEL2
1
2
4
8
BI/RBO
RBI
LE
U5
D0
D1
D2
D3
D4
D5
D6
D7
Q0
Q1
Q2
Q3
Q4
Q5
Q6
Q7
DY1
A
B
C
D
E
F
G
9368
VCC
SEL4 U11
OC
CLK
1
2
4
8
BI/RBO
RBI
LE
74LS374
A
B
C
D
E
F
G
9368
essere generato da una operazione WRITE
eseguita
all'indirizzo
LSD
R13 =10K
U6
A1
A2
A3
A4
A5
A6
A7
A8
B1
B2
B3
B4
B5
B6
B7
B8
FND500
MSD
DY2
G
DIR
74LS245
P1
FND500
Fig. 3
attribuito
all'interfaccia nell'ambito di quelli previsti dalla Tab 1.
Interfaccia Led e Dip Switch
In Fig. 3 è riportato lo schema elettrico dell'interfaccia verso 8 led e 8 dip switch. In essa si
nota la presenza di un registro a 8 bit 74LS374 U6 che pilota 8 led corredati della
appropriata resistenza di limitazione della corrente. Nel circuito è pure presente un
transceiver 74LS245 U7 che consente la lettura dello stato logico predisposto dal gruppo di
dip switch P1-P8 alimentati dalle otto resistenze di pull-up. Si osservi che avendo posto
l'ingresso DIR di U7 a livello 0, il trasferimento dati avviene nel transceiver da B verso A.
Il segnale SEL3 (fronte di salita per clock di U6) dovrà essere generato da una operazione
WRITE eseguita all'indirizzo attribuito all'interfaccia Led nell'ambito di quelli previsti dalla
tabella 1. Il segnale SEL4 (livello basso per ingresso G di U7) dovrà essere generato da una
21
R20 =10K
P8
operazione
READ
eseguita
U10A
all'indirizzo
attribuito all'interfaccia Dip-Switch nell'ambito
EA0
EA1
A
B
G
U7A
di quelli previsti dalla tabella 1.
Y0
Y1
Y2
Y3
74LS139
EWR
74LS32
U10B
U7B
A
B
Y0
Y1
Y2
Y3
ERD
G
ECS
Controllo e sincronizzazione delle varie
Y0-RD
Y1-RD
Y2-RD
Y3-RD
74LS139
74LS32
interfacce
Y0-WR
Y1-WR
Y2-WR
Y3-WR
Altro circuito di selezione
Fig. 4
La necessità di interconnettere i circuiti di Fig. 1, 2 e 3 al circuito di Fig. (LX833) impone
di suddividere i circuiti in due gruppi:
1) dispositivi verso i quali il
Interfacci Selezione Indirizzo
a
Relè
SEL1
302
Display
SEL2
303
Led
SEL3
300
DipSEL4
301
Switch
Modo
Connessio
ne
Y2-WR
Y3-WR
Y0-WR
Y1-RD
WR
WR
WR
RD
2) dispositivi verso i quali il PC effettua operazioni di
PC effettua operazioni di tipo
READ (interfaccia dip-switch)
VCC
EA0
EA1
EA2
1
2
3
A
B
C
ERD
ECS
6
4
5
G1
G2A
G2B
tipo WRITE (gruppo relè, gruppo display, gruppo led).
Una soluzione al problema può, in linea di principio
Y0
Y1
Y2
Y3
Y4
Y5
Y6
Y7
15
14
13
12
11
10
9
7
Y0-RD
Y1-RD
Y2-RD
Y3-RD
Y4-RD
Y5-RD
Y6-RD
Y7-RD
74LS138
VCC
U9 (write)
EA0
EA1
EA2
1
2
3
A
B
C
EWR
ECS
6
4
5
G1
G2A
G2B
essere quella di Fig. 4. In essa sono presenti due decoder
74LS139 uno dedicato a gestire fino ad un massimo di
U8 (read)
Y0
Y1
Y2
Y3
Y4
Y5
Y6
Y7
15
14
13
12
11
10
9
7
Y0-WR
Y1-WR
Y2-WR
Y3-WR
Y4-WR
Y5-WR
Y6-WR
Y7-WR
74LS138
Fig. 5
fig. 6 Circuiteria di selezione
otto dispositivi funzionanti in modalità READ e l'altro dedicato a gestire fino ad un
massimo di otto dispositivi funzionanti in modalità WRITE. Ciascun decoder ha l'ingresso
di abilitazione G2B connesso al segnale ECS (abilitazione scheda), l'ingresso di abilitazione
G2A è connesso al segnale ERD nel caso del decoder U8 (gestione interfacce READ) al
segnale EWR nel caso del decoder U9 (gestione interfacce WRITE).
Assegnazione degli indirizzi
22
Ipotizzando ora di assegnare gli indirizzi come presentato in tabella bisognerà da ultimo
rendere la logica di funzionamento dell'interfaccia compatibile con i segnali forniti dal
sistema di decodifiche U8 e U9.
Le uscite dei decoder 74LS138 sono attive a livello basso per cui date le premesse SEL1,
SEL2 e SEL3 dovranno essere ricavati negando con una porta 74LS04 i segnali rispettivi
Y2-WR, Y3-WR e Y0-WR mentre SEL4 dovrà essere collegato direttamente a Y1-RD.
Un altro esempio di circuiteria di assegnazione degli indirizzi viene presentata in Fig. 5 in
tal caso anziché utilizzare due circuiti integrati 74LS139 si utilizza un solo circuito integrato
74LS138 (decodifica doppia) con ovvia conseguente riduzione dei costi.
Interfaccia per il Controllo della Temperatura e dell’ Umidita’
Scopo del progetto
Con questo circuito si vuole simulare un sistema di controllo di temperatura nel quale valori
di soglia di temperatura ed umidità rilevati, saranno confrontati con i valori di soglia
massima impostati. Nel caso che i valori rilevati superino quelli di soglia si attiveranno
degli opportuni segnali di allarme. In Fig. 6 è riportato lo schema a blocchi del circuito.
LX833 A
IMPOSTAZION
E
TEMP. / UMID
LCD 1
LCD 2
LX833 B
ADC
MISURAZIONE
TEMP. / UMID
23
LED
SONDE
ESTERNE
Fig. 6
Componenti utilizzati
-
Contraves;
SN74LS93;
SN74LS04;
SN74LS138;
Trasduttori di temperatura AD590;
Trasduttore di umidità;
Quarzo 4Mhz;
Convertitore Analogico Digitale;
LCD Hitachi LM018;
LCD.
Contraves
Sono dei dispositivi di input logico che servono ad impostare combinazioni BCD o binarie
fisse (Fig. 7).
Tramite un selettore rotante numerato si può
selezionare la combinazione desiderata; sono usati nei
sistemi di controllo di macchine utensili, in unità di
misurazione e di test, nei sistemi di controllo e
regolazione, nei sistemi computerizzati ecc. Le
caratteristiche principali di questi "commutatori
Fig. 7
rotanti" sono l'alta regolarità di funzionamento, di precisione e di durata dei contatti.
I Contraves possono essere accoppiati con displays LED a 7 segmenti o alfanumerici.
• Caratteristiche
1. compattezza;
2. semplice assemblaggio;
24
3. precisa e facile lettura dei valori di set;
4. varia scelta dei limiti di conteggio: 10,11,12 e 16 posizioni di commutazione
5. diversa lunghezza del bordo per l'incorporazione di diodi o resistenze
• Caratteristiche elettriche
1. massimo carico di contatto: 50V, 100mA;
2. resistenza di isolamento 100 MΩ;
3. resistenza di contatto incluso p.c.b. 70-100 mΩ.
SN74LS93
Questo integrato in tecnologia TTL è un 4BIT-BINARY
COUNTER,
cioè
è
un
contatore (modulo 16). E’ costituito da 4 FlipFlop JK, come si vede in Fig.8
Il primo Flip-Flop non è connesso agli altri,
quindi consente la divisione per due del
Fig. 8
numero
di
impulsi
d’ingresso.
Introducendo il segnale
attraverso CK1, dato che
Tab. 2
questo è connesso in
cascata con gli altri due,
si ottiene, sull’uscita Q3,
un segnale di frequenza
1/8 di quella d’ingresso.
25
Per ottenere il conteggio dei 16 impulsi, come indicato in Fig.9, occorre collegare
esternamente l’uscita del primo flip-flop (Q0) con l’ingresso CK1 del secondo
(pin 1 con
pin12).
Fig. 9
SN74LS04
Questo integrato in tecnologia TTL (Fig.10) è un HEX INVERTER ed è costituito da sei
porte NOT .
Queste ultime hanno un solo ingresso, di
conseguenza ci possono essere solo due
configurazioni
di
ingresso: 0 ed 1. Tali
dispositivi
anche
una
hanno
sola
uscita. Dalla tabella
Tab. 4
Fig. 10
di verità Tab.4, che fornisce per ogni livello d’ingresso la corrispondente uscita del circuito,
si comprende che le porte NOT servono a complementare il segnale d’ingresso.
SN74LS138
In Fig.11 sono riportate la piedinatura e la connessione interna
del SN74LS138. Quest’ultimo è un decoder/demultiplexer (3-to8 LINE DECODER), la funzione svolta da questo integrato è
quella di pilotare 8 uscite (Y0...Y7, attive basse) mediante 3
ingressi di selezione (A,B,C). Nel circuito da noi realizzato,
mediante la combinazione binaria che si presenta sugli ingressi,
26
questo integrato seleziona il contraves da cui leggere.
I pin G2A e G2B e G1 sono di enable. I primi due, attivi bassi,
sono stati collegati a massa, mentre il G1 viene gestito tramite il
PC; ciò è necessario per poter realizzare l’attivazione
dell’integrato, come si può apprendere dalla FUNCTION
TABLE (Tab. 5).
Fig. 11
Tab. 5
Trasduttore di temperatura AD590
Sensori di temperatura integrati
La moderna tecnologia dei circuiti integrati ha determinato già da qualche anno
l'immissione sul mercato di trasduttori, finalizzati alla misura delle più diverse grandezze
fisiche, che incorporano, oltre il sensore vero e proprio, circuiterie più o meno consistenti
(circuito di condizionamento del segnale) per l'amplificazione del segnale del sensore, la sua
normalizzazione e la sua linearizzazione. I sensori integrati di temperatura sono tra i più
diffusi di questa relativamente recente generazione di trasduttori.
27
Analog Devices AD590
Funzionalmente è un bipolo che si comporta come un generatore di corrente ad alta impedenza; la corrente generata è proporzionale alla temperatura assoluta:
I=k*T
T in °K (Kelvin)
con la costante di proporzionalità k che ha il valore nominale di 1µA/K: la corrente in µA
coincide numericamente, entro i limiti di errore, con la temperatura in Kelvin.
Il principio fisico utilizzato è sostanzialmente la dipendenza dalla temperatura della Vbe nei
transistor a giunzione; il range utile va da -55 0C (218 K) a +150 0C (423 K), con una
tensione di alimentazione ai capi del bipolo fra 4 e 30 V indifferentemente.
Il funzionamento in corrente presenta il vantaggio di rendere il sistema di misura insensibile
a cadute di tensione; permette pertanto di porre il sensore molto lontano dall'apparato di
misura. Inoltre, sempre per l'intrinseca insensibilità a variazioni di tensione, la reiezione ai
disturbi è molto elevata.
Poiché il sensore ha una massa molto ridotta, la sua velocità di risposta è piuttosto alta: le
versioni in contenitore metallico TO-32
(secondo suffisso H) hanno una costante di tempo termica in aria ferma di
circa 60 s (la costante termica è il
tempo impiegato per adeguarsi al 63%
del salto di temperatura ambientale:
dopo
circa
3
costanti
di
tempo
l'equilibrio termico è praticamente
Fig. 12
raggiunto); questo valore scende di
molto in aria in movimento, e ancor più se il sensore deve misurare la temperatura di un
corpo solido con cui è mantenuto in contatto.
L’AD590 è disponibile in varie versioni, distinte da un primo suffisso I/J/K/L/M, che si
differenziano per precisione (e per prezzo). Le principali cause di imprecisione sono un
errore di scala (il valore di k differisce dal valore nominale 1 µA/K) e un errore di offset (la
caratteristica I/T non passa esattamente per 0 a 0 K). Per esempio, l'AD590K ha un errore
non calibrato di ± 5,5 0C su tutto il range utile; se si compensa l'errore di scala agendo sul
28
guadagno del sistema di condizionamento del segnale l'errore si riduce a ± 2,0 0C. D'altra
parte anche il fuori zero e' compensabile, prevedendo una regolazione di offset; in tal caso
l'unica causa di errore superstite è la non-linearità della caratteristica (±0,8 0C per
l'AD590K).
Per trasformare l'informazione fornita dall'AD590 in tensione il modo più ovvio è far cadere
la corrente su una resistenza.
Tuttavia è più razionale far uso di un convertitore I/V a operazionale (convertitore correntetensione), la cui impedenza di ingresso idealmente nulla dà un ulteriore contributo alla
reiezione delle interferenze e che si presta facilmente alla regolazione di scala e di zero. In
Fig. 12 é riportato il circuito base: la VR serve a produrre la corrente IR che, sottratta alla IS
generata dal sensore, annulla la I e quindi la V0 alla temperatura di inizio scala (per esempio
a 0 °C).
Trasduttore capacitivo di umidità
I
trasduttori
capacitivi
essenzialmente,
in
due
consistono,
superfici
conduttrici, dette armature, separate da
un isolante, detto dielettrico; una delle
armature è mobile e quindi, in seguito ad
una sollecitazione, varia la posizione
reciproca
delle
comportamento
è
armature.
quello
di
Il
un
condensatore con capacità variabile
Fig. 13
a) Trasduttore di livello a capacità: a1 = armatura fissa; a2 =
armatura mobile; d = dielettrico; b) Trasduttore di pressione a
variazione capacitiva.
funzione della grandezza da rilevare.
In un condensatore ad armature piane e parallele, si ha la seguente relazione:
C =∈ S / d
con C: capacità del condensatore; ∈: costante dielettrica del materiale isolante; S: area della
superficie delle armature; d: distanza fra le armature.
Dalla relazione precedente si deduce che per variare la capacità si può o variare la superficie
29
affacciata delle armature o la distanza delle armature stesse. I trasduttori del primo tipo sono
detti ad area variabile e sono impiegati per misure angolari o lineari; quelli del secondo tipo
sono detti a distanza variabile e sono impiegati per misure di piccoli spostamenti.
I trasduttori capacitivi sono caratterizzati da compattezza, stabilità, linearità, buona
precisione e risoluzione. Gli inconvenienti principali sono: l'influenza delle capacità
parassite dei terminali, dato il piccolo valore della capacità del trasduttore; la sensibilità alle
variazioni di temperatura ( che peraltro può essere superata impiegando trasduttori costituiti
da due capacità, una fissa e una di misura, e circuiti di misura opportuni, in cui venga
rilevato il rapporto fra le due capacità); l'elevata impedenza di uscita (che, peraltro, in alcuni
casi può essere un vantaggio, come, ad esempio, quando il traduttore debba essere inserito
in parallelo ad un altro dispositivo).
I trasduttori capacitivi possono essere impiegati, in particolare, per rilevazioni di: posizioni;
spostamenti lineari ed angolari; accelerazioni lineari; forze e pressioni.
Quarzo 4MHz
Il cristallo di quarzo è un componente elettronico molto usato per realizzare generatori di
clock estremamente stabili in frequenza; in tali circuiti la
frequenza di oscillazione coincide con quella di risonanza del
Rs
Cs
quarzo. Si ricorda il largo impiego negli orologi al quarzo,
Ls
Cp
come generatore di clock
x'
y"
nei
x
PC
processore,
y
y'
(clock
del
RTC
real
Ls
Cs
Cp
time clock, clock del
XTAL
x"
x"
circuito di refresh delle
Fig.?
Fig.
14
RAM dinamiche, ecc.). Il
y'
y
circuito equivalente del cristallo è riportato in Fig.15; il
simbolo circuitale in Fig. 14.
x
Fig. 15
y"
x'
Un cristallo di quarzo appartiene alla categoria
materiali “piezoelettrici”; che, in presenza di una sollecitazione di tipo meccanico, si
30
comportano da generatori di f.e.m. proporzionale alla sollecitazione. Questa proprietà è
sfruttata nei microfoni piezoelettrici, negli accendigas piezoelettrici ma più in generale nei
trasduttori piezoelettrici. Il fenomeno della “piezoelettricità” è reversibile ossia applicando
una d.d.p. al cristallo questo si deforma meccanicamente; questa proprietà è sfruttata negli
altoparlanti piezoelettrici nei buzzer (cicalini piezoelettrici). La “piezoelettricità” è comune
a quasi tutti i cristalli privi di un centro di simmetria (per es.: quarzo, tormalina, topazio,
acido tartarico, clorato di sodio).
Per l’utilizzo come oscillatore viene tagliato in lamine a forma parallelepipeda e lo spessore
delle lamine risulta rispettivamente proporzionale alla frequenza di oscillazione. Le
frequenze di oscillazione variano da qualche migliaia di Hz (lamine di spessore maggiore) a
qualche Mega Hz (lamine di spessore inferiore). Se si applica una pressione si manifesta
sulle due facce perpendicolari all’asse elettrico una differenza di potenziale in continua, se
invece si applica una trazione lungo le
Asse ottico
Asse neutro
due facce che scorrono lungo l’asse
neutro si manifesta sulle due facce
normali
(perpendicolari)
all’asse
elettrico una differenza di potenziale di
verso opposto alla precedente; una
Asse elettrico
successione di compressioni e trazioni
applicate lungo l’asse neutro, origina
una differenza di potenziale sulle facce
Fig. 16
Fig.?
perpendicolari all’asse elettrico. Questo
fenomeno è reversibile, cioè applicando sulle due facce perpendicolari all’asse elettrico una
differenza di potenziale alternata il cristallo si mette a vibrare con una sua frequenza di
oscillazione. Le frequenze del quarzo sono due, frequenza di risonanza serie fs e frequenza
di risonanza parallelo fp, codeste assumono dei valori molto prossimi l’una all’altra. Le
formule per trovare la frequenza sono :
1
fp =
2∏
1
fs =
2∏ L1C1
31
1 C1 + C p
(
)
L C1Cp
fs è la frequenza di risonanza serie per X=0 ed fp è la frequenza di oscillazione parallela per
X=infinito. In Fig.16 si possono notare le posizioni che assumono i vari assi rispetto al
cristallo.
ADC0808
Caratteristiche Generali Di Un Convertitore Analogico-Digitale
La funzione dei convertitori A/D è
quella di trasformare un livello di
Vi
A/D
tensione in un numero N espresso in
codice binario ad esso corrispondente
}N
(n bit)
come esplicitato dalla formula:
n= 8,10,12,14,16 bit
V
N = I ⋅ 2n
VREF
dove
Fig. 17
VREF
è la risoluzione del convertitore e n è il numero dei bit del convertitore A/D.
2n
Precisione
E’ definita dallo scarto tra il valore convertito ed il valore vero della grandezza in esame. Le
cause che alterano la precisione del convertitore sono essenzialmente :
• la deriva, intesa come effetto della temperatura, dell’invecchiamento dei componenti e
delle fluttuazioni dell’alimentazione;
• la non linearità del comportamento.
Sensibilità
E’ rappresentata dal più piccolo livello di tensione che può essere convertito. Si definisce
anche il massimo valore dei segnali di ingresso che consentono al convertitore di lavorare
nelle migliori condizioni di funzionamento.
Potere risolutivo
32
E’ la più piccola variazione di tensione cui è sensibile il convertitore, questo non è da
confondere con la sensibilità in quanto il convertitore può non avvertire tensioni prossime
allo zero ma può sentire piccole variazioni in un punto qualsiasi delle sue caratteristiche di
comportamento dinamico.
Tempo di conversione
Rappresenta il tempo impiegato dal circuito per eseguire la conversione da analogico in
digitale. Gli elementi che lo compongono sono:
• tempo di conversione incrementale: è il tempo impiegato a convertire una tensione
corrispondente al potere risolutivo, cioè al minimo incremento cui il circuito è sensibile;
• tempo di conversione sull’intera scala: tempo impiegato dal circuito ad effettuare la
conversione della massima tensione misurabile ( a partire dal livello 0 ).
Se è necessario inserire, all’ingresso del circuito, un filtro per l’eliminazione del rumore il
tempo di conversione si allunga notevolmente.
Nel campo dell’elettronica la conversione viene utilizzata per rendere un segnale
comprensibile, o misurabile, per un qualsiasi strumento di misura o di elaborazione.
I circuiti per convertire i segnali analogici in segnali codificati sotto forma digitale, e
viceversa, sono diventati di grande importanza nei sistemi elettronico-informatici, perchè le
connessioni di varie apparecchiature che comunicano fra loro richiedono mezzi adatti a
tradurre da una forma all’altra.
In generale le uscite dei sensori forniscono segnali di tipo analogico, i quali debbono essere
tradotti in forma numerica per poter essere interfacciati con i sistemi di elaborazione. Una
alternativa a questi sistemi ibridi è quella di sviluppare sistemi tutti digitali. Molti sforzi
sono concentrati per sviluppare nuovi sensori, che abbiano uscite digitali, e nuovi elementi
di controllo e azionamento, che abbiano ingressi digitali.
Tuttavia,
nonostante qualche risultato ottenuto nel campo dei programmi di ricerca
spaziale e militare, questa alternativa rimane, per ora, soprattutto una tendenza di ricerca
e non è ancora di pratica attuazione. I dispositivi, in grado di effettuare la conversione del
segnale sono:
33
• I convertitori digitali analogici o D A C (Digital Analog Converter), oppure D/A;
• I convertitori analogici digitali o A D C (Analog Digital Converter), oppure A/D;
Ma non esistono solo due tipi di conversione nel campo dell’elettronica ci sono anche
conversioni che permettono di ottenere da un segnale di ingresso in corrente un segnale di
uscita proporzionale a quello in ingresso in tensione, e viceversa. Oppure si può anche
convertire una tensione in frequenza, e viceversa.
LA CONVERSIONE DIGITALE-ANALOGICA E ANALOGICA-DIGITALE
Esistono apparecchiature elettroniche che forniscono unicamente segnali di tipo analogico:
tra queste, ad esempio, molti trasduttori, che trasformano grandezze fisiche in elettriche e,
nella maggior parte dei casi, il segnale prodotto è analogico, ovvero subisce variazioni
proporzionali alla grandezza fisica applicata al suo ingresso. Poiché la manipolazione dei
segnali può avvenire attraverso circuiti digitali, è evidente la necessità di convertire la
grandezza analogica in digitale mediante i circuiti definiti convertitori analogici digitali.
Viceversa il risultato dell’elaborazione di una rete logica deve poter comandare attuatori di
tipo analogico. Dato che per attuatore si intende un sistema in grado di trasformare un
segnale elettrico in una grandezza fisica proporzionale al segnale, è necessario che il
risultato dell’elaborazione digitale sia convertito in analogico, per pilotare un attuatore. Un
sistema in grado di trasformare un risultato digitale in un segnale analogico viene definito
convertitore digitale/analogico.
Nella conversione digitale/analogica e analogica/digitale si incontra un problema
fondamentale: una grandezza analogica è costituita da un insieme continuo di valori, una
grandezza digitale,
per la sua natura binaria, è invece costituita da un insieme finito di
valori possibili. Questo condiziona evidentemente la precisione della conversione. Per
aumentare la sensibilità e la precisione si ricorre alla quantizzazione e al campionamento.
Il convertitore è in generale solo uno dei blocchi circuitali che compongono un sistema di
conversione da analogico a digitale e viceversa. Ad esempio un sistema di conversione D/A
è composto tipicamente da un convertitore D/A e da un filtro passa basso in cascata al
34
convertitore con lo scopo di eliminare le discontinuità del segnale di uscita del DAC dovute
alla sua caratteristica di trasferimento . In questo modo è possibile ottenere un segnale privo
di disturbo e di rumore.
Filtro passabasso
D
VO
VO
t
t
Fig. 18
Invece un sistema di conversione analogico-digitale è composto nel caso più semplice da un
filtro passa basso, un circuito di sample and hold e dal convertitore ADC vero e proprio. Il
tutto sarà comprensibile durante la lettura del testo. Comunque la presenza del filtro in
ingresso si può spiegare con la necessità di limitare il contenuto armonico del segnale da
convertire in modo che per la frequenza di campionamento scelta non si verifichi il
fenomeno di aliasing.
B1
VIN
Filtro passabasso
Circuito sample
and hold
ADC
Bn
V di
ingresso
clock
Fig. 19
CONVERTITORI ANALOGICI DIGITALI ADC
I convertitori analogico-digitali trasformano un livello di tensione in un codice binario ad
esso corrispondente.
Questa operazione può avvenire con soluzioni diverse, tuttavia alla base dei criteri di scelta
dei convertitori ADC che vengono presi in esame vi sono tre parametri : la velocità di
conversione, la risoluzione di conversione ed il costo.
Per quanto riguarda la conversione essa può avvenire con diversi metodi:
35
• Ad approssimazioni successive
• Ad integrazione
E relativamente alle particolari strutture interne in:
• Con convertitori paralleli veloci
• Half-flash
ADC AD APPROSSIMAZIONI SUCCESSIVE
Il metodo di conversione ad approssimazioni successive è sicuramente il più diffuso in
quante consente un buon compromesso fra velocità di conversione e risoluzione.
Va
Nel convertitore a 4 bit in
Va'
DAC
MSB
Buffer
di
stato
Fig.
20 il segnale di
ingresso
Va
viene
comparato
con
precisi
LSB
EOC
SAR
Controllo
Temporizz
Fig.Figura
20 14
SOC
livelli di tensione generati
dal
convertitore
DAC.
Dopo l’applicazione del
comando di conversione
SOC
(Start
Of
Convertion), che azzera le uscite e inizializza il sistema, il registro ad approssimazioni
successive SAR (Successive Approssimation Register) si trova nello stato 1000. Questo
dato viene presentato in ingresso al DAC che fornisce il primo livello analogico, pari a metà
della tensione di fondo scala del convertitore, da confrontare con il segnale Va .
Se Va > Va ' l’uscita del comparatore è alta e il bit più significativo del SAR, e quindi anche
quello del dato di uscita, si porta a zero. A questo punto, in sincronismo con il clock, viene
portato ad 1 il secondo bit più significativo del SAR, cosicché il dato presente sugli ingressi
del DAC sarà 1100 oppure 0100 a seconda del risultato del confronto precedente. Il secondo
confronto porta a 0 o mantiene ad uno il secondo bit del SAR e del buffer di uscita, a
36
seconda che Va risulti minore o maggiore di Va ′ . Con procedimento analogo vengono
effettuati il terzo e il quarto confronto. Alla fine della conversione, ovvero dopo quattro
confronti successivi, il dato digitale contenuto nel buffer di uscita è pronto e valido; il
blocco di temporizzazione segnala la fine della conversione EOC (End Of Convertion) e
l’uscita può essere letta.
Utilizzando la tecnica delle approssimazioni successive si richiedono n interazioni, e quindi
n cicli di clock, per convertire una tensione di ingresso in un dato ad n bit,
indipendentemente dal valore della tensione stessa. Questo fatto unitamente alle buone
prestazioni in risoluzione, fa preferire la tecnica ad approssimazioni successive nella
realizzazione di convertitori a media velocità, adatti ad esempio per applicazioni con
microprocessori.
CONVERTITORE ADC 0808
Questi due tipi di convertitori ADC sono i più usati nel mondo dell’acquisizione dati
industriale. Infatti nel nostro caso e stato utilizzato un convertitore analogico-digitale ad
approssimazioni successive. Questo convertitore, l’ADC0808, usa una tecnologia
monolitica a CMOS. A 8 bit di uscita ed 8 ingressi gestiti da un multiplexer, ed è
compatibile con i microprocessori più usati.
37
LCD LM018 HITACHI
Il modulo LCD
è un vecchio modello Hitachi H2572 alimentato a 5V. Esso può
visualizzare
fino ad un
massimo
di
40
caratteri
su
di
unica
una
riga.
L’interfaccia
fra il modulo
LCD
e
Fig. 21
l’esterno è sommariamente descritta nella Tab. 7. Si noti la presenza del bus dei dati
bidirezionale da DB0 a DB7, l’ingresso R/W attraverso cui si specifica la direzione del
flusso dei dati: da PC verso l’LCD se R/W è
Low, dall’LCD verso il PC se R/W è High.
L’Ingresso E (enable) che se posto a livello
alto abilita il Data Bus e con esso il flusso
FIG.
Fig. 22
Tab. 6
38
dei dati, l’ingresso RS che specifica Pin n° Symbol
se in un certo istante la transazione
1
Vss
fra PC e LCD riguarda dati o
2
Vdd
3
Vo
piuttosto comandi inviati al modulo
4
RS
LCD. In Fig. 22 si può notare la
disposizione dei pin di collegamento
dell’LCD. In Tab. 6 sono riportati i
tempi di ritardo da dare all’LCD per
far si che questo possa funzionare
correttamente
rispettando
l’esatta
sequenza delle varie funzioni. In Fig.
21 è riportato il diagramma
temporale di detta sequenza.
Level Function
H/L
5
R/W
H/L
6
7
8
9
10
11
12
13
14
E
DB0
DB1
DB2
DB3
DB4
DB5
DB6
DB7
H/L
H/L
H/L
H/L
H/L
H/L
H/L
H/L
H/L
0V
Power Supply
5V
Power Supply
Power Supply
L=instruction code input;
H=Data input
L=Data read;
H=Data write
Enable Signal
Data bus line
Data bus line
Data bus line
Data bus line
Data bus line
Data bus line
Data bus line
Data bus line
Tab. 7
Principio di funzionamento
Il principio di funzionamento di questo circuito è quello di impostare e effettuare controlli
su delle soglie di temperatura e di umidità che possono variare riaspettivamente da 1 C° a
99C° e dall'1% al 99%. Agendo sui contraves le soglie impostate vengono visualizzate su
un display LCD a 4 righe e, tramite software, dopo confrontate con i valori di temperatura e
di umidità rilevati dai potenziometri, i quali simulano i relativi trasduttori di temperatura e
di umidità. Se le misurazioni lette sui potenziometri sono maggiori di quelle impostate
attraverso i contraves si accenderanno i rispettivi led che segnalano l'eventuale attivazione
di un relè. Oltre alla segnalazione visiva, verrà visualizzato un messaggio di allarme sul
display LM018 (es: SUPERATA SOGLIA T1). Inoltre sempre sul medesimo display
comparirà un messaggio di avvertimento nel caso le soglie impostate siano uguali a zero
(es: IMPOSTARE SOGLIA T1).
39
Modalità di collegamento
Sulle 2 schede LX.833 abbiamo montato il PPI 82C55A. Le schede sono poi state inserite
nel BUS del PC poiché da lì ricevono le relative informazioni mandate dal software di
gestione. Inoltre ogni scheda è stata
corredata di connettore DB37 come
DB37
quello che si può notare in Fig. 23, il
quale attraverso un cavo (costruito da
Fig. 23
noi) rende possibile l’interazione con
circuiti esterni al PC. Sulle schede
LX.833 abbiamo dovuto apportare delle modifiche poiché non vi era la possibilità di
prelevare le e alimentazioni necessarie da mandare alla circuiteria esterna al PC; abbiamo
dunque dovuto attingerle dal BUS a 8 bit del computer seguendo le indicazioni relative al
connettore del BUS di espansione PCXT presente sulla scheda madre (vedi tabella relativa
in allegato).
Gli ingressi dei Contraves (1,2,4,8), sono collegati al catodo dei diodi, questi ultimi a loro
volta hanno l’anodo collegato a +Vcc attraverso 4 resistenze di Pull Up da 10 KΩ come
Fig. 24
si può notare in Fig. 24.
Questi diodi sono così connessi poiché i contraves in questo caso funzionano in logica
negata. Infatti al comune di questi ultimi viene mandato, dal contatore “SN74LS138”, un
40
segnale a livello basso.
Tale segnale manda in conduzione i diodi della combinazione numerica prescelta, portando
così a livello basso i bit del Port B, i quali vengono poi negati attraverso il software di
gestione riportandoli così a livello alto. Una volta fatto questo i bit vengono inviati al
display LCD2 per essere visualizzati come livelli di soglia. Un problema è sorto quando si è
trattato di collegare i displays. Infatti, non avendo a disposizione Port a sufficienza per un
funzionamento indipendente dei due LCD abbiamo dovuto effettuare un collegamento
parallelo tra loro. Per poter far sì
che gli LCD funzionassero correttamente abbiamo
mandato due segnali di attivazione del diplay (ENABLE) distinti. Facendo così è possibile
attivare solamente il display che deve ricevere i dati. I bit D0,D1,…,D6,D7 che vanno ai
display (Pin 7,8,9,10,11,12,13,14) sono collegati ad una resistenza di Pull Up da 10KΩ
mandata a +VCC, per poter evitare l’eventuale presenza di disturbi.
Nella seconda parte del circuito, cioè quella della misurazione delle temperature e delle
umidità, abbiamo montato un convertitore analogico-digitale il quale, convertendo il
segnale analogico proveniente dai potenziometri in un segnale digitale, fa in modo che i
dati rilevati vengano trasferiti al computer per l’elaborazione tramite software e mandati
all’LCD2 .
I valori rilevati oltre ad essere visualizzati sul display
vengono, sempre
attraverso l’elaborazione software, confrontati con quelli impostati tramite i contraves e, a
seconda del risultato, verranno o meno attivate le relative segnalazioni visive, i relativi
messaggi di avvertimento.
Il CK all’ADC0808 è fornito da un oscillatore costituito da un quarzo da 4 MHz, due porte
NOT 74LS04 funzionanti in zona
lineare e due condensatori di
GENERATORE DI CLOCK ADC
R5
compensazione. Le porte TTL
680
U4A
servono da amplificatori invertenti
680
U4B
Y1
1
. Per far questo devono funzionare
R6
3
2
74LS04
C6
22pF
C5
22pF
GND
né in interdizione ). Per ottenere
condizione
14
1
4MHZ
74LS04
in zona lineare (non in saturazione
questa
4
2
3
U5
A
B
QA 12
QB 9
8
QC 11
QD
R0(1)
R0(2)
74LS93
CLKADC
GND
GND
di
Fig. 24
funzionamento dobbiamo fare in modo che la tensione di ingresso VI risulti uguale a quella
di uscita VU . Ciascuna porta NOT introduce uno sfasamento di 180º fra segnale di ingresso
41
e di uscita, e funzionano da amplificatori invertenti per piccole variazioni attorno al punto di
lavoro, perciò lo sfasamento globale è pari a 0º ; la presenza del quarzo assicura che le
condizioni di oscillazione di Barkausen siano verificate in prossimità della frequenza di
risonanza serie del cristallo di quarzo.
Questo tipo di oscillatore e’ semplice da realizzare (come si può notare in Fig. 24) e fornisce
un segnale a frequenza fissa ed e’ discretamente preciso; purtroppo la frequenza e’
influenzata sia pure in minima parte dalla temperatura.
Poiché al nostro integrato occorre una frequenza di 500K Hz abbiamo dovuto inserire anche
un divisore di frequenza per 8 poiché il quarzo è da 4 Mhz. Questo divisore di frequenza è
stato realizzato utilizzando un contatore binario da $0 a $F del tipo 74LS93 prelevando due
segnali dalle uscite QD e QC : la frequenza del segnale proveniente dal quarzo viene divisa
quattro volte se si considera l’uscita QC (1MHz) e otto volte se si considera l’uscita QD
(500KHz).
L’uscita dell’oscillatore l’abbiamo collegata al piedino CLK dell’ADC (come si notare in
Fig. 25).
Il convertitore opera rispettando una serie rigorosa di fasi:
-
Invio degli indirizzi di canale ai piedini A0,A1,A2;
Fig. 25
42
-
invio di un segnale al piedino ALE che permette la memorizzazione dell’indirizzo di
canale selezionato nel latch interno all’ADC;
-
invio di un segnale al piedino di START che permette l’avvio della conversione;
-
attesa del segnale di fine conversione EOC.
Dopodiché i dati letti verranno mandati al display che li visualizzerà. Agli ingressi del
convertitore (IN4,IN5,IN6,IN7) abbiamo collegato dei potenziometri lineari, alimentati a
5V, da 1KΩ in modo da farli funzionare come dei partitori di tensione; in questo modo
forniranno un segnale all’ingresso dell’ADC che varia da 0 a 5 Volt. La lettura ADC varierà
fra 0 e 255.
Quando i valori misurati superano la soglia impostata si accenderanno dei led. Questi sono
stati collegati con il catodo a massa e l’anodo al rispettivo Port come segue.
Temperatura 1 PC4 (Led 1 rosso)
Temperatura 2 PC5 (Led2 rosso)
Umidità 1 PC6 (Led 1 verde)
Umidità 2 PC7 (Led 2 verde)
SOFTWARE DI GESTIONE
43
PASCAL
I linguaggi di programmazione degli elaboratori elettronici
La programmazione degli elaboratori può essere attuata facendo uso del linguaggio
macchina oppure di linguaggi di programmazione detti ad alto livello.
Il linguaggio macchina è un linguaggio specifico di una determinata CPU e quindi
presuppone una buona conoscenza del set di istruzioni del modo di indirizzamento, delle
modalità di esecuzione delle istruzioni da parte della CPU e dell'architettura del sistema
utilizzato.
I linguaggi ad alto livello sono completamente indipendenti dal tipo di CPU su cui operano,
sono molto più aderenti al modo di esprimersi di un essere umano e non richiedono una
conoscenza specifica dell'architettura del sistema su cui viene redatto un determinato
programma.
Generalità sulla stesura di un programma
Il programma scritto dal programmatore ed introdotto nella memoria dell'elaboratore viene
detto programma SORGENTE (SOURCE-PROGRAM); quello materialmente eseguito
dalla CPU, e perciò codificato in linguaggio macchina, viene denominato programma
OGGETTO (OBJECT-PROGRAM). Sarà perciò necessario disporre di un traduttore che,
partendo da istruzioni redatte in linguaggio ad alto livello, le trasformi in equivalenti
istruzioni stese in linguaggio macchina. Ogni linguaggio dispone quindi di un traduttore in
linguaggio macchina.
Un generico linguaggio ad alto livello può essere strutturato per funzionare in modo
INTERPRETE o in modo COMPILATORE.
44
Nel modo INTERPRETE il programma sorgente si trova in memoria RAM e viene
introdotto attraverso una tastiera che di solito opera in codice ASCII (American Standard
Code for Information Interchange); quando viene attivata l’esecuzione del programma
l'interprete per ciascuna riga di programma effettua le seguenti operazioni:
1)- Controllo sintattico sulla riga di programma.
2)- Traduzione della riga di programma in linguaggio macchina.
3)- Esecuzione di quella riga di programma.
La fase 1) di controllo sintattico può dare origine a segnalazioni di errore che appaiono sul
terminale video con indicazione della riga di programma ove si è verificato l'errore e del
tipo di errore riscontrato (codifica numerica) SYNTAX-ERROR. Per correggere l'errore è
necessario riscrivere la riga di programma errata.
La fase 2) di traduzione in linguaggio macchina, può dare origine a segnalazioni di errore di
tipo COMPILATION-ERROR per correggere le quali è necessario sempre riscrivere una o
più righe errate di programma.
La fase 3) di esecuzione del segmento di programma oggetto anch'essa può dare origine a
segnalazioni di errore di tipo RUN-TIME-ERROR per correggere le quali bisogna
analizzare con attenzione qual'è la condizione che ha provocato l'errore.
Nel modo COMPILATORE il programma sorgente si trova di solito su disco sotto forma di
"file" (archivio di informazioni su disco); la preparazione del sorgente su disco avviene
attraverso l'uso di un apposito strumento software" denominato EDITORE.
il compilatore fa una analisi sintattica di tutto il programma sorgente fornendo eventuali
segnalazioni di errore che servono al programmatore per correggere il programma. In caso il
controllo sintattico abbia dato esito positivo, viene effettuata la traduzione in linguaggio
macchina del programma sorgente, traduzione che viene registrata su disco sotto forma di
"file".
Il programma oggetto così prodotto dal compilatore in genere non è ancora eseguibile in
quanto privo delle necessarie informazioni base per eseguire operazioni matematiche più o
meno complesse o operazioni di Input Output. Si rende necessaria un'ultima operazione
denominata operazione di LINK delle librerie che viene attuata per mezzo di un altro
"strumento software" chiamato LINKING-LOADER. Il programma oggetto prodotto dal
compilatore, "linkato" con le routine di libreria è quindi in grado di funzionare
45
autonomamente; anch'esso viene salvato su disco e costituisce il prodotto finale e
conclusivo della compilazione.
Programmi interpretati
L'impiego di un linguaggio interprete presenta pregi e difetti che di seguito vengono
elencati:
- Il programma viene modificato in modo molto semplice (riscrivendo la riga di programma
errata) e in modo altrettanto semplice è possibile verificare la validità della correzione.
- Il programma sorgente è sempre presente in RAM quindi è di solito "listabile" su video o
stampante (manca la segretezza richiesta in taluni casi).
- La velocità di esecuzione del programma è piuttosto bassa in quanto ogni volta che viene
impartito il comando di esecuzione (RUN per il BASIC e PASCAL) vengono sempre e
comunque ripetute le fasi di controllo sintattico e di traduzione in linguaggio macchina del
programma sorgente in quanto a priori non è possibile stabilire se la versione di programma
presente in memoria è quella corretta oppure no.
-
L'area di memoria a disposizione è piuttosto modesta in quanto per consentire
l'esecuzione di un programma interpretato deve essere presente in memoria oltre al
programma sorgente, l'interprete (linguaggio - Interprete) completo corredato di RUNTIME-PACKAGE (biblioteca completa).
Programmi Compilati
L'impiego di un linguaggio compilatore presenta pregi e difetti che di seguito vengono
elencati:
- Il programma sorgente non può essere modificato con rapidità in quanto è necessario
ricorrere all'EDITORE per ricaricare il programma in memoria, correggere la o le righe
46
errate e salvare su disco il programma corretto. La verifica richiede che venga ripetuta la
procedura di compilazione al completo.
- Il programma che viene eseguito dalla CPU è redatto in linguaggio macchina e quindi non
è "listabile" su video o stampante (ciò consente un ottimo grado di segretezza sul codice
sorgente che è stato utilizzato dal programmatore autore del programma) ciò costringe il
cliente a rivolgersi al programmatore per eventuali future modifiche.
- La velocità di esecuzione del programma è più elevata rispetto a quella di un programma
interpretato (il controllo sintattico del programma e la traduzione in linguaggio macchina
sono stati effettuati una volta per tutte dal compilatore prima di produrre il programma
oggetto).
- L'area di memoria a disposizione è la massima possibile in quanto per il suo
funzionamento il programma oggetto non ha bisogno né del compilatore né tantomeno del
programma sorgente che in casi di programmi di una certa lunghezza addirittura non
potrebbe nemmeno stare nell'intera RAM del calcolatore.
Si conclude perciò che, ove un determinato linguaggio abbia la possibilità di configurarsi
nei due modi sopra descritti, sarà opportuno operare in ambiente Interprete nella fase di
stesura, di correzione e di verifica di funzionalità (fase di Debugging) del programma stesso
(sfruttando quindi tutti i vantaggi dell'ambiente Interprete) poi sarà quindi opportuno
trasferirsi in ambiente Compilatore per procedere alla traduzione in linguaggio macchina del
programma predisposto (con tutti i conseguenti vantaggi).
Va comunque ribadito che, programmi di modeste dimensioni consentono di operare
indifferente in modo Interprete e in modo Compilatore mentre programmi di cospicue
dimensioni obbligano ad operare in modo Compilatore.
Struttura di un programma Pascal
Un programma Pascal consiste in una sequenza di istruzioni che realizzano un algoritmo,
cioè una possibile soluzione ad un certo problema. Questo linguaggio è altamente
strutturato, per cui possiede un insieme di regole rigidamente definite, ma nello stesso
tempo flessibili all’uso. Un programma Pascal risulta diviso in più sezioni , ognuna delle
quali ha una precisa collocazione e deve risultare sintatticamente corretta per garantire
47
l’assenza di errori in fase di compilazione. I compilatori Pascal forniscono una ricca
gestione degli errori, che possono venire identificati non solo in fase di compilazione, ma
anche in fase di esecuzione del programma.
Non esistono, nel linguaggio Pascal, regole precise che guidino il programmatore all'uso di
spazi bianchi e linee separatrici, oppure che impongano un particolare tipo di indentazione
delle istruzioni, per cui il programmatore stesso può liberamente adottare per il suo
programma qualunque tipo di formato. Questa libertà presenta vantaggi e svantaggi: se da
un lato la fantasia del programmatore può sbizzarrirsi, dall'altro è bene che questi mantenga
una certa chiarezza e uniformità di stile durante tutto il programma.
Blocchi
I programmi Pascal si compongono di una o più strutture a blocco. La definizione della
struttura di blocco, come altre definizioni sintattiche, è di tipo ricorsivo, in quanto un blocco
può essere annidato in altri blocchi. Questa struttura a blocchi permette di raggruppare
insieme dichiarazioni e istruzioni in relazione tra loro e, in particolare:
1. permette di raggruppare una sequenza di istruzioni in un'unica istruzione composta;
2. fornisce un controllo sull'allocazione di memoria delle variabili (dichiarazione di
variabili) e sulla loro referenziabilità, lecita o meno, nelle diverse parti del programma
(visibilità).
I blocchi possono contenere dichiarazioni, istruzioni e altri blocchi annidati e sono usati per
organizzare un programma Pascal.
Il blocco inizia con la dichiarazione di tutti gli oggetti che sono locali ad esso e, di
conseguenza, referenziabili in ogni eventuale blocco annidato. La sezione dichiarativa, se
esiste, è seguita da una o più istruzioni di programma, delimitate dalle due parole riservate
begin e end.
Gli oggetti locali ad un blocco non possono essere referenziati all'esterno di esso, ma
solamente nel blocco in cui sono dichiarati o nei blocchi annidati in questo. La struttura a
blocchi di un programma Pascal permette di seguire facilmente il flusso di controllo poiché i
blocchi Pascal presentano una sola entrata e una sola uscita.
48
Il Pascal, inoltre, permette l'annidamento di blocchi di procedure e funzioni standard,
appartenenti alla sua libreria.
Programmare in Turbo Pascal
La costruzione di un programma in Turbo Pascal prevede la conoscenza di alcune nozioni
elementari , dato che questo tipo di codifica è soggetto ad una struttura ben precisa.
Esiste una parte fissa, obbligatoria, costituita:
1. dall’intestazione program nome;(ove nome è il nome del programma dato dal
programmatore);
2. dalla parola chiave begin che indica l’inizio della successione delle istruzioni;
3. dalla parola chiave end. Che marca la fine del programma.
Il calcolatore darà una segnalazione di errore nell’analisi di un programma che manchi di
queste tre parti.
Va inoltre ricordato che è obbligatorio, nello scrivere un programma in Turbo Pascal,
segnare la fine di ogni dichiarazione e di ogni istruzione con il punto e virgola (;).
Intestazione del programma
Ogni programma Pascal Standard inizia con un'intestazione del tipo:
program nomeprogramma (input,output)
I parametri, o argomenti, racchiusi tra parentesi, dopo l'indicazione del nome del
programma, indicano i file di ingresso (input) e di uscita (output), tramite i quali il
programma interagisce con l'ambiente esterno. Le variabili predefinite input e output
identificano simbolicamente il file di ingresso, la tastiera, e di uscita, lo schermo.
49
Nel Turbo Pascal, l'intestazione del programma non è obbligatoria, in quanto il compilatore
Turbo la ignora completamente. Si consiglia, comunque, di scrivere sempre l'intestazione,
per garantire la portabilità dei programmi verso altri tipi di compilatori, oltre a migliorare la
leggibilità dei programmi stessi.
Corpo del programma
Il corpo del programma, o blocco principale, contiene dichiarazioni ed istruzioni. La sezione
dichiarativa definisce gli oggetti globali, cioè gli oggetti referenziabili da qualunque parte
del programma, e deve precedere sempre la parte riservata alle istruzioni. Le dichiarazioni
riguardano label, tipi, costanti, variabili e altri blocchi di sottoprogrammi (procedure e
funzioni definite dall'utente). La sezione riservata alle istruzioni specifica, invece, le azioni
che il calcolatore deve eseguire. Delle istruzioni possono fare parte operatori, parole
riservate, chiamate di procedure e di funzioni standard, o definite dall'utente.
I programmi Pascal terminano sempre con un punto, posto dopo l’ultimo delimitatore di
fine blocco (end.).
Visibilità
Nel linguaggio Pascal, gli oggetti dichiarati possiedono una visibilità (scope) che può essere
globale (oggetti noti in ogni parte del programma), oppure locale (oggetti noti solo nel
blocco in cui sono dichiarati). Dal momento che è lecito annidare blocchi in altri blocchi, la
visibilità di un oggetto dichiarato nel blocco più esterno permane anche nei blocchi più
interni. In particolare, gli oggetti dichiarati nel blocco principale hanno una visibilità totale,
cioè esistono per tutti i blocchi del programma.
Nel linguaggio Pascal, ad ogni oggetto dichiarato, cioè label, costanti, tipi, variabili,
procedure e funzioni, è associata una visibilità.
50
Dichiarazioni
Il linguaggio Pascal presuppone che tutti gli oggetti vengano dichiarati prima di essere
referenziati nel corso del programma. Per oggetto si intende ogni cosa che possiede un
nome, dai programmi alle label, dai tipi alle variabili, dalle procedure alle funzioni. La
sezione riservata alle dichiarazioni è collocata tra l'intestazione di blocco e la sezione
istruzioni, per ogni blocco presente nel programma.
Nel Pascal Standard è necessario rispettare un ordine di precedenza prestabilito per i vari
tipi di dichiarazione, ordine che può essere ignorato nel Turbo Pascal. In ogni caso,
comunque, le dichiarazioni devono sempre precedere, all’interno del blocco, le istruzioni.
Le sei parti di cui si compone una sezione dichiarativa sono:
1. label - label (etichette) usate per referenziare linee di programma;
2. const - costanti simboliche il cui valore non è alterabile durante l'esecuzione del
programma;
3. type - strutture e tipi di dati definiti dal programmatore;
4. var - dichiarazioni delle variabili e del loro tipo (ad esempio real, integer ecc);
5. procedure - sottoprogrammi definiti dal programmatore;
6. function - funzioni definite dal programmatore.
Label
Le label sono utilizzate per referenziare particolari punti del programma, a cui il
programmatore intende trasferire il controllo con una istruzione goto. Il Pascal Standard
richiede che le label siano interi senza segno, al massimo quattro cifre, ma il Turbo Pascal
permette di definire label qualunque intero senza segno o, in genere, qualunque
identificatore purché legale.
Costanti
51
Le costanti sono oggetti il cui valore non cambia nel corso dell’esecuzione del programma.
Esse, possono rappresentare qualunque dato ed il loro tipo è implicito nel formato del valore
che rappresentano.
Tipi
Il linguaggio Pascal Standard definisce diversi tipi e strutture dati per variabili e costanti:
real, integer, boolean, char, array, record, set, file . Il Turbo Pascal aggiunge, a questi, altri
due tipi predefiniti: byte e string.
1. real. Le costanti di questo tipo possono assumere un valore positivo o negativo, anche
frazionario, di estensione e precisione limitati dal compilatore e dal calcolatore usato.
Nel Turbo Pascal, il campo dei valori assunti da un numero reale spazia da 1.0E-38 a
1.0E+38, con una mantissa di 11 cifre significative. Le variabili di tipo real, incluso lo
zero, sono scritte con il punto decimale, secondo la seguente forma: 0.0; 1.0; 0.223.
2. integer. Le costanti e le variabil di questo tipo possono assumere valori positivi o
negativi, compresi tra maxint e – (maxint+1), dove maxint è una costante predefinita,
dipendente dal sistema, che indica il massimo valore intero disponibile. Nel Turbo
Pascal, maxint vale 32767 e i valori delle variabili di tipo integer possono oscillare da
32767 a –32768; i tipi integer occupano 2 byte (16 bit) di memoria e le costanti di tipo
integer sono scritte senza punto decimale. Nel Turbo Pascal, inoltre, è lecita la notazione
esadecimale per rappresentare grandezze di tipo integer e di tipo byte. Le costanti
esadecimali iniziano con il carattere $, seguito dalle cifre esadecimali (0...F), come:
$4A1; $A0; $FFCD.
3. boolean. Le variabili di questo tipo assumono il valore true o false. Esse richiedono un
byte di memoria e rappresentano il risultato di espressioni logiche (relazionali), che sono
contenute in istruzioni condizionali e che permettono al programma di prendere delle
decisioni, sulla base del loro valore. Il linguaggio Pascal predefinisce le due costanti true
e false, che il programma utilizza nelle espressioni logiche.
4. char. Nel Pascal Standard il tipo char indica sigoli caratteri, racchiusi tra due apici: ‘A’
‘B’ ‘c’ ‘d’ ‘&’ ‘?’ ‘’ (spazio). La rappresentazione interna dei caratteri è in codifica
52
binaria. Nel confronto fra due caratteri, sono i codici corrispondenti che vengono nella
realtà esaminati. Poiché la codifica dei caratteri dipende dal sistema (ASCII, EBCDIC,
ecc.), il Turbo Pascal non definisce un set standard particolare di caratteri. Nel Turbo
Pascal si può assegnare alle variabili e alle costanti di tipo char un qualunque carattere
appartenente al set esteso dei caratteri ASCII, con valore ordinale compreso tra 0 e 255.
Questo set esteso di caratteri ASCII permette al programmatore di utilizzare speciali
caratteri grafici. Il programmatore può servirsi di valori costanti, racchiusi tra apici,
oppure della funzione chr(), per assegnare valori di tipo char. Un valore di tipo char
occupa un byte di memoria.
5. array. Nel Turbo Pascal, il programmatore può definire un array, i cui elementi siano di
tipo semplice, come integer, real, char, byte, string e boolean. Sebbene tutti gli elementi
di un array debbano essere dello stesso tipo, sono definibili anche array complessi,
costituiti da elementi contenenti più di un singolo tipo di dato, utilizzando il record
come tipo dell'elemento dell'array. Si può pensare ad un array come a un gruppo di celle
numerate, ognuna delle quali contiene un dato. E' sufficiente usare il numero (o indice)
corrispondente a tali celle, per referenziare direttamente il dato contenuto. L'indice che
referenzia le celle dell'array, può essere un qualunque tipo scalare. In fase di
dichiarazione dell'array è necessario indicare il tipo dell'indice oppure il campo di valori
che l'indice stesso può assumere: questi valori possono essere interi positivi o negativi,
oppure valori scalari interni ai limiti di campo dichiarati. Il tipo di indice definisce anche
la massima dimensione degli array. Le versioni commerciali del turbo Pascal permettono
di definire array di qualunque dimensione intera, purché contenuta in un'area di memoria
inferiore a 64 kB. Ciò significa che quattro array di 16 kB di tipo byte (o due di 16 kB di
tipo integer) possono occupare interamente lo spazio di memoria disponibile per
l'allocazione dei dati.
6. byte. Questo tipo è, nel Turbo Pascal, un sottotipo del tipo integer e può, dunque, essere
usato con le stesse modalità e nelle stesse circostanze del tipo integer. Un dato di tipo
byte può assumere un valore intero compreso tra 0 e 255. Le variabili di tipo byte
occupano un byte (8bit) di memoria e le costanti di tipo byte sono sempre scritte senza
punto decimale o con due cifre nella notazione esadecimale.
53
7. string. Nel Turbo Pascal, una variabile del tipo predefinito string rappresenta una
successione di caratteri molto simile ad un array. Il primo elemento (posizione zero) di
questa struttura dati corrisponde al valore di un byte, che memorizza la lunghezza della
stringa (compresa tra 0 e 255). Questo valore cambia se il programmatore assegna alla
stringa oggetti di lunghezza differente. In fase di dichiarazione della variabile di tipo
string, si alloca lo spazio corrispondente in memoria:
var
nome : string[maxlung]
Nel corso di tutto il programma, non è possibile assegnare alla stringa nome un oggetto
la cui lunghezza superi lo spazio di memoria allocato. Il programmatore può definire le
stringhe come array.
Variabili
Le variabili sono oggetti identificati da un nome e il loro valore può cambiare nel corso
dell'esecuzione del programma. Il tipo associato ad ogni variabile deve essere esplicitamente
dichiarato, prima che la variabile venga referenziata nel programma. Le variabili Pascal non
sono inizializzate automaticamente in fase di dichiarazione, ma è necessario assegnar loro
esplicitamente un valore, altrimenti esse rimangono non definite.
Procedure
Le procedure sono gruppi di istruzioni (blocchi) che costituiscono un sottoprogramma in
grado di eseguire determinate azioni. L’attivazione di una procedura avviene tramite una
istruzione di chiamata di procedura , che si compone del nome o identificatore della
procedura, seguito dalla lista di parametri, se esistono, che costituiscono gli argomenti della
procedura. Al termine dell’esecuzione della procedura, il controllo si trasferisce
all’istruzione del programma successiva a quella di chiamata della procedura.
54
Il Turbo Pascal predefinisce un certo numero di procedure, che eseguono operazioni di
ingresso e di uscita, di gestione di stringhe, di visualizzazione sullo schermo, di
manipolazione di file.
Le procedure definite dall'utente sono, invece, dichiarate come gli altri oggetti del
programma. La dichiarazione di procedura inizia con un’intestazione, seguita dal blocco
della procedura. Il blocco della procedura può contenere dichiarazioni di altri oggetti, tra cui
label, costanti, tipi, variabili, funzioni e procedure, che risultano locali al blocco stesso e ai
blocchi annidati.
Funzioni
Anche le funzioni sono sottoprogrammi, ma vengono attivate in fase di valutazione di
espressioni che contengono un riferimento alle funzioni stesse. Diversamente dalle
procedure, le funzioni generalmente restituiscono un valore (risultato) all’espressione che le
attiva e il loro uso riguarda in gran parte l’esecuzione di algoritmi logici o matematici.
Anche per le funzioni è definito un passaggio di parametri simile a quello delle procedure.
Il Turbo Pascal predefinisce un certo numero di funzioni, che eseguono calcoli e
restituiscono un risultato; sono funzioni trigonometriche, di calcolo matematico di
conversione.
Le funzioni sono dichiarate come ogni altro oggetto del programma. Una dichiarazione di
funzione inizia con un'intestazione, seguita dal blocco della funzione. Il blocco della
funzione può contenere dichiarazioni di altri oggetti, tra cui label, costanti, tipi, variabili,
funzioni e procedure, che risultano locali al blocco stesso e ai blocchi annidati. Il risultato
della funzione è ottenuto assegnando , all’interno del blocco della funzione, un valore
all’identificatore di funzione.
Istruzioni
55
Le istruzioni di un programma rappresentano le azioni che il calcolatore deve eseguire e
costituiscono il corpo dei blocchi del programma e dei sotto-programmi. Il Pascal definisce
sia istruzioni semplici che istruzioni composte. Delle istruzioni semplici fanno parte
l'istruzione di assegnamento, l'istruzione vuota, le istruzioni di chiamata di procedure e
l'istruzione goto. Il Turbo Pascal definisce anche l’istruzione inline, che permette di inserire
codice macchina nei programmi Pascal. Delle istruzioni composte fanno parte tutte le
istruzioni
ottenute
disponendo
sequenzialmente
istruzioni
semplici,
l’istruzione
condizionale, l’istruzione ripetitiva e l’istruzione with. Di seguito sono elencate alcune delle
istruzioni più usate.
1. Istruzione di assegnamento. In ambiente Pascal, l’isturzione di assegnamento fa sì che
una variabile assuma un nuovo valore. L’esecuzione di questa istruzione comporta che
l’espressione a destra dell’operatore di assegnamento venga valutata e il valore così ottenuto
sia assegnato alla variabile posta alla sinistra dell’operatore. Nel linguaggio Pascal,
l’operatore di assegnamento è rappresentato dalla coppia di simboli “:=”. Un esempio di
assegnamento è il seguente: totale:=(cost*1.3)+(variabile*0.8)
2. Istruzione di chiamata a procedura. E’ costituita dall’identificatore della procedura da
attivare, seguito da un certo numero di parametri, che sono i valori da fornire in ingresso
alla procedura stessa. Quando il calcolatore esegue questa istruzione, il controllo del
programma passa al blocco della procedura attivata. Al termine dell’esecuzione della
procedura attivata, il controllo ritorna all’istruzione immediatamente successiva a quella di
chiamata.
3. Istruzioni composite. E’ una struttura di controllo che riunisce un gruppo di istruzioni, la
cui escuzione avviene sequenzialmente. Essa si compone di una o più istruzioni,
individualmente corrette, delimitate dalle parole riservate begin e end, e può contenere
annidate al suo interno altre istruzioni composite. La forma generale di un’istruzione
composita è la seguente:
begin
istruzione 1
istruzione 2
.
56
.
.
istruzione n
end.
4. Istruzioni condizionali. L’istruzione condizionale decide, sulla base della valutazione di
una condizione di controllo(true o false), in quale direzione far procedere il flusso escutivo.
Le istruzioni condizionali sono:
Istruzione if. Il costrutto “if a è true then esegui b” definisce uno dei concetti più
semplici ed intuitivi della programmazione. L’istruzione if rappresenta la struttura di
controllo fondamentale di programmazione: permette, infatti, di esguire un’istruzione
(singola o composita ), sulla base della veridicità di una data condizione di controllo. La
forma generale dell’istruzione if è la
seguente:
if condizione then istruzione (se
condizione allora istruzione);
Istruzione if...else. Rappresenta un’estensione dell’istruzione if...then e aggiunge
chiarezza al programma che la usa qualora il programmatore debba decidere tra due flussi
alternativi di istruzioni. La forma generale dell’istruzione if...else è la seguente:
if condizione then istruzione 1 (se condizione allora istruzione 1)
else istruzione 2
(altrimenti istruzione 2)
Istruzione case. Costituisce una versione particolare dell’istruzione if...else, in quanto
permette di selezionare ed eseguire un’istruzione singola all’interno di un gruppo di
istruzioni. Il risultato della valutazione viene confrontato con le costanti elencate nella listacase, con lo scopo di verificarne la congruenza. La forma generale dell’istruzione case è la
seguente:
case espressione of
lista 1 di costanti: istruzione 1;
....
lista n di costanti: istruzione n
57
end;
Istruzione case...else. Risolve esplicitamente il problema di mancata selezione di una
delle alternative-case. La forma generale dell’istruzione case..else è la seguente :
case espressione of
lista 1 di costanti: istruzione 1;
....
lista n di costanti: istruzione n
else
istruzione
end;
5. Strutture iterative. Uno dei requisiti base, per la realizzazione di programmi di una
certa complessità, è la disponibilità di strutture programmative che permettano
l’esecuzione ripetuta di una sequenza di istruzioni, per tutto il tempo in cui
un’espressione logica rimane true. Queste situazioni sono attuabili con le rispettive
strutture iterative che seguono.
Istruzione while. Garantisce, per tutto il tempo in cui la condizione di controllo rimane
true, l’esecuzione ripetuta dell’istruzione-oggetto, singola o composita. Poiché, prima
dell’esecuzione dell’istruzione-oggetto, avviene il test sulla condizione di controllo, il
risultato di questa valutazione regola il numero di volte (zero o più) che la struttura while
sarà eseguita. La forma generale dell’istruzione while è la seguente:
while condizione do
istruzione
58
Istruzione repeat...until. Garantisce l’esecuzione ripetuta di una o più istruzioni, fino a
quando la corrispondente espressione di controllo non diventi true. L’esecuzione delle
istruzioni-oggetto avviene almeno una volta, indipendentemente dal valore iniziale della
condizione di controllo, il cui test, infatti, viene effettuato alla fine dell’esecuzione della
struttura stessa. La forma generale dell’istruzione repeat...until è la seguente:
repeat
istruzione/i
until condizione
(ripeti)
(istruzione)
( fino a che condizione)
Istruzione for. Garantisce l’esecuzione, ripetuta per un certo numero di volte, di
un’istruzione o di un gruppo di istruzioni. Di questa struttura fa parte una variabiledi
controllo che si incrementa (to) o decrementa (downto) automaticamente di una unità ad
ogni esecuzione del ciclo, passando da un valore iniziale ad un valore finale. All’interno
della struttura for non deve esserci alcuna istruzione che modifichi il valore della variabile
di controllo. La forma generale dell’istruzione for è la seguente:
for variabile-controllo:= espressione1 to espressione 2 do istruzione
oppure
for variabile-controllo:= espressione1 downto espressione 2 do istruzione
Formato e stile
Il programmatore che scrive in linguaggio Pascal può definire per il suo programma un
formato qualunque. Gli spazi bianchi o le linee separatrici hanno un preciso significato solo
quando sono usate per isolare gli identificatori e le parole riservate, oppure nelle costanti di
tipo stringa. Le istruzioni possono essere disposte secondo formati diversi per migliorare la
59
leggibilità del programma, ma il compilatore non considera il formato scelto, quando
interpreta il codice sorgente. Il Turbo Pascal permette di scrivere linee di 127 caratteri come
lunghezza massima, e il programmatore può decidere come disporre i caratteri su ogni linea.
Punteggiatura
I programmi in Pascal utilizzano tre caratteri fondamentali di punteggiatura: la virgola (,), il
punto e virgola (;) e il punto (.). La virgola ha il compito di separare gli elementi di una
lista; il punto e virgola separa tra loro le istruzioni e non segue mai l'ultima di esse; il punto,
infine, permette di terminare il programma e segue sempre l'ultimo delimitatore di fine
blocco end. Ciò permette al compilatore di verificare che ogni delimitatore di inizio blocco
begin abbia il corrispondente delimitatore di fine blocco end.
Commenti
Il programmatore può inserire commenti in qualunque punto del programma Pascal, purché
li racchiuda tra i delimitatori "{" e "}" o, indifferentemente, tra i delimitatori "(*" e "*)".
Operatori
Il Turbo Pascal definisce diverse classi di operatori, in corrispondenza di vari tipi di
espressioni, e definisce sei livelli di precedenza, in base alla natura delle operazioni
eseguite. Questi livelli sono, in ordine decrescente:
1. Espressioni racchiuse tra parentesi ( ).
2. Conversione di segno o negazione.
3. Operatore not.
4. Operatori di moltiplicazione aritmetica e logica: * / div mod and shl shr.
60
5. Operatori di somma aritmetica e logica: + - or xor.
6. Operatori relazionali: = < > < > <= >= in.
Operatori aritmetici
Il Pascal definisce sei operatori aritmetici: +, -, *, /, dvi, mod. Questi operatori permettono
di eseguire le usuali operazioni algebriche di addizione, di sottrazione e negazione, di
moltiplicazione, di divisione fra interi e fra reali e di resto della divisione fra interi.
Operatori binari
Il Turbo Pascal definisce un insieme di operatori binari per manipolare singoli bit di valori
integer e byte. Le espressioni che contengono questi operatori realizzano un'interfaccia con
la struttura hardware del calcolatore: il programmatore infatti può modificare direttamente i
singoli bit di una certa variabile. I tipi di operatori binari sono: not, and, or, xor, shr, shl.
Operatori logici
Degli operatori logici fanno parte:
1. Operatori booleani; questo tipo di operatori (not, and, or e xor) consetono di
costruire le
not
epressioni logiche booleane :
complementa il valore booleano dell'espressione logica che lo segue (not true =
false)
and l'espressione logica è vera se sono veri entrambi gli operandi (true and false =
false)
61
or l'espressione logica è vera se è vero uno degli operandi (true or false = true)
xor l'espressione logica è vera se è vero un solo operando (true xor false = true).
2. Operatori relazionali; Gli operatori relazionali si applicano ad operandi di
qualunque tipo scalare standard: real, integer, boolean, char e byte. Il risultato è sempre
di tipo boolean cioè true o false. Gli operatori relazionali disponibili nel Turbo Pascal
sono i seguenti:
=
uguale a
< > diverso da
>
maggiore di
<
minore di
>=
maggiore o uguale a
<=
minore o uguale a.
62
PROGRAMMI DI GESTIONE DELLE INTERFACCE
Interfaccia relè, display 7 segmenti, led, dip-switch
PROGRAM INTERFACCIA(INPUT,OUTPUT);
USES CRT;
VAR
K : INTEGER;
ADDR, LED, DIP, RELE, DISPLAY:WORD;
PROCEDURE PLED; { PROGRAMMA DI GESTIONE DIODI LED }
VAR
N:ARRAY[1..41] OF BYTE; { APERTURA DI UN VETTORE N }
K: INTEGER;
{ DICHIARAZIONE VARIABILE
CONTATORE }
BEGIN
{ I LED SI ACCENDONO CONVERGENDO DAGLI ESTREMI
VERSO IL CENTRO }
N[1]:=$00;
N[2]:=$81;
N[3]:=$42;
N[6]:=$24;
N[7]:=$42;
N[4]:=$24;
N[5]:=$18;
N[8]:=$81;
N[9]:=$00;
{ UN SOLO LED ACCESO PARTENDO DA L8 VERSO L1 }
N[10]:=$80;
N[13]:=$10;
N[11]:=$40;
N[12]:=$20;
N[14]:=$08;
N[15]:=$04;
N[16]:=$02;
63
{ ACCENSIONE PROGRESSIVA DEI LED DA DESTRA VERSO
SINISTRA RIEMPIMENTO PROGRESSIVO DEL REGISTRO }
N[17]:=$01;
N[18]:=$03;
N[19]:=$07;
N[22]:=$3F;
N[23]:=$7F;
N[20]:=$0F;
N[21]:=$1F;
N[24]:=$FF;
{ UN SOLO LED ACCESO ALTERNATIVAMENTE PRIMA L8
QUINDI L1 POI L7 E QUINDI L2 E COSÌ VIA }
N[25]:=$00;
N[26]:=$80;
N[27]:=$01;
N[30]:=$20;
N[31]:=$04;
N[34]:=$10;
N[35]:=$04;
N[38]:=$40;
N[39]:=$01;
N[28]:=$40;
N[29]:=$02;
N[32]:=$10;
N[33]:=$08;
N[36]:=$20;
N[37]:=$02;
N[40]:=$80;
N[41]:=$FF;
PORT[DISPLAY]:=$00;
PORT[RELE]:=$00;
FOR K:=1 TO 41 DO
BEGIN
PORT[LED]:=N[K];
{ OPERAZIONE DI SCRITTURA SUI
LED }
DELAY(200);
GOTOXY(11,19);
{ RITARDO 200MS }
WRITE(K);{ POSIZIONAMENTO DEL CURSORE
COORDINATE 11,19 }
GOTOXY(7,15);
WRITE('QUESTA PROCEDURA È IN GRADO DI FARE ACCENDERE');
GOTOXY(7,16);
WRITE('8 DIODI LED IN VARI TIPI DI SEQUENZA');
END;
64
END;
PROCEDURE PDIP;
{ PROGRAMMA DI GESTIONE DIP-SWITCH
LEGGE IL DATO PRESENTE SUL DIP-SWITCH E POI
LO TRASFERISCE SUL DISPLAY A 7 SEGMENTI }
VAR
J:BYTE;
BEGIN
GOTOXY(7,15);
WRITE('QUESTA PROCEDURA PERMETTE DI
VISUALIZZARE');
GOTOXY(7,16);
WRITE('SUL DISPLAY IL VALORE IMPOSTATO
SUL DIP-SWITCH');
REPEAT
J:=PORT[DIP];
{ INIZIO CICLO RIPETITIVO }
{ OPERAZIONE DI LETTURA DAI DIP-
SWITCH }
J:=255-J;
{ CONVERSIONE DA LOGICA NEGATIVA A
POSITIVA }
PORT[DISPLAY]:=J;
{ OPERAZIONE DI SCRITTURA SUI DISPLAY
GOTOXY(11,19);
WRITE(J:4);
}
UNTIL FALSE;
{ CONDIZIONE DI LOOP INFINITO }
END;
PROCEDURE PRELE;
{ PROGRAMMA DI GESTIONE DEI RELÈ }
VAR
DATO:BYTE;
H:BYTE;
BEGIN
DATO:=0;
PORT[RELE]:=$00;
{ SPEGNIMENTO DEI RELE }
PORT[LED]:=$00;
{ SPEGNIMENTO DEI LED }
K:=PORT[DIP];
{ LETTURA DEL VALORE IMPOSTATO SUL
DIP-SWITCH }
65
K:=255-K;
GOTOXY(11,19);
WRITE(K);
GOTOXY(7,15);
WRITE('QUESTA PROCEDURA PERMETTE DI
AZIONARE I RELE');
GOTOXY(7,16);
WRITE('IN SEQUENZA OGNI 16 CONTEGGI
VISUALIZZATI DAL');
GOTOXY(7,17);
WRITE('DISPLAY PARTENDO DAL VALORE
03');
READLN;
REPEAT
GOTOXY(19,19);WRITE(DATO:4);
PORT[DISPLAY]:=DATO; { SCRITTURA DEL DATO SUL DISPLAY }
IF (DATO MOD 16)=3 THEN BEGIN { QUESTA ISTRUZIONE PERMETTE DI
ATTIVARE } { UN RELE OGNI 16 IMPULSI }
H:=(((DATO DIV 16)+1) MOD 4)+1; { CONVERSIONE DEL RISULTATO
INTERO }
{ DI DATO/16 IN BASE 4 PER ATTIVARE
IL RELE CORRISPONDENTE }
GOTOXY(27,19);WRITE('RELE: ',(((H+2) MOD 4)+1):2);
CASE H OF
1 : PORT[RELE]:=$40; { INDIRIZZO CORRISPONDENTE AL RELE 1 }
2 : PORT[RELE]:=$01;
3 : PORT[RELE]:=$10;
4 : PORT[RELE]:=$04;
END;
END;
DATO:=DATO+1;
DELAY(500);
UNTIL DATO=K+1;
END;
PROCEDURE PDISPLAY;
66
VAR
DATO,K : BYTE;
BEGIN
DATO:=0;
K:=PORT[DIP];
K:=255-K;
GOTOXY(11,19);
WRITE(K);
GOTOXY(7,15);
WRITE(' QUESTA PROCEDURA
PERMETTE DI FARE ');
GOTOXY(7,16);
WRITE(' AVANZARE I DISPLAY
FINO AL NUMERO ');
GOTOXY(7,17);
WRITE(' FISSATO SUI DIP-
SWITCH ');
READLN;
REPEAT
GOTOXY(19,19);WRITE(DATO);
PORT[DISPLAY]:=DATO;
DATO:=DATO +1;
DELAY(500);
UNTIL DATO=K+1;
END;
BEGIN
{ PROGRAMMA PRINCIPALE MAIN }
CLRSCR;
ADDR:=$300; { $300-$307 CAMPO DI INDIRIZZAMENTO DELLA SCHEDA
}
LED:=ADDR;
DIP:=ADDR+$1;
RELE:=ADDR+$2;
DISPLAY:=ADDR+$3;
REPEAT
CLRSCR;
67
GOTOXY(10,3); WRITE(' 1- GESTIONE LED ');
GOTOXY(10,5); WRITE(' 2- GESTIONE DISPLAY');
GOTOXY(10,7); WRITE(' 3- GESTIONE RELE''');
GOTOXY(10,9); WRITE(' 4- GESTIONE DIPSWITCH'); GOTOXY(10,11); WRITE(' 0- FINE');
GOTOXY(11,13); READLN(K);
CASE K OF
1:PLED;
2:PDISPLAY;
3:PRELE;
4:PDIP;
END;
UNTIL K=0;
END.
Interfaccia controllo di temperatura ed umidità
PROGRAM TEMP_UMID;
USES CRT;
TYPE STR80 = STRING[80];
CONST
SCHEDA=$300;
PA=SCHEDA+$0;
68
PB=SCHEDA+$1;
PC=SCHEDA+$2;
CW=SCHEDA+$3;
SCHEDA1=$308;
PA1=SCHEDA1+$0;
PB1=SCHEDA1+$1;
PC1=SCHEDA1+$2;
CW1=SCHEDA1+$3;
VAR
I, C : INTEGER;
NO : STR80;
CHIAVE: CHAR;
PROCEDURE INIT_8255;
BEGIN
PORT[CW]:=$81;{ PORT A USCITA; PORT B USCITA; PC4-PC7 USCITA;
PC0-PC3 INGRESSO }
END;
PROCEDURE INIT_8255A;{PORT A INGRESSO: COLLEGATO ALL'ADC DA D0
A D7
PORT B USCITA: COLLEGATO ALL'ADC, PBO AD A0,
PBI AD A1, PB2 AD A2, PB3 A START
PB4 AD ALE
PORT C INGRESSSO (DA PC0 A PC3): COLLEGATO ALL'ADC
PC0 ALL'EOC
PORT C USCITA (DA PC4 A PC7): COLLEGATO AI LED,
PC4 A T1, PC5 A T2
PC6 A U1, PC7 AU2}
BEGIN
PORT[CW1]:=$91;
END;
PROCEDURE PAUSE;
BEGIN
DELAY(2);
END;
PROCEDURE LCD_CMD1(C:BYTE);
VAR H:BYTE;
BEGIN
H:=PORT[PB] AND $9F; {LEGGE PORT PB E AZZERA RS E RW}
PORT[PB]:= H;
PORT[PA]:=C;
H:=H OR $10; {ALZA ENABLE}
PORT[PB]:=H;
69
PORT[PB]:=H AND $EF;
PAUSE;
END;
PROCEDURE LCD_CHAR1(C:CHAR);
VAR A:BYTE;
BEGIN
A:=PORT[PB] AND $9F; {LEGGE PORT PB E AZZERA RS E RW}
A := A OR $40;
PORT[PB]:=A ;
PORT[PA]:= ORD(C);
A:=A OR $10;
PORT[PB]:=A;
PORT[PB]:=A AND $EF;
PAUSE;
END;
PROCEDURE INIT_LCD1;
BEGIN
LCD_CMD1($30); { 8 BIT + 1 LINEA + 5 X 7 DOTS }
LCD_CMD1($30);
LCD_CMD1($30);
LCD_CMD1($34);
LCD_CMD1($08);
LCD_CMD1($0E);
END;
PROCEDURE CLEAR1; { CANCELLA TUTTO IL DISPLAY E PORTA IL
CURSORE POSIZIONE HOME (INDIRIZZO 0) }
BEGIN
LCD_CMD1($01);
DELAY(20);
END;
PROCEDURE HOME1;
BEGIN
LCD_CMD1($02);
DELAY(20);
END;
PROCEDURE LCD_STR1(STR:STRING);
VAR I,LS : INTEGER;
BEGIN
LS := LENGTH(STR);
IF LS > 40 THEN LS := 40;
70
FOR I := 1 TO LS DO LCD_CHAR1(STR[I]);
END;
PROCEDURE LCD_CMD2(C:BYTE);
VAR H:BYTE;
BEGIN
H:=PORT[PB] AND $9F; {LEGGE PORT PB E AZZERA RS E RW}
PORT[PB]:= H;
PORT[PA]:=C;
H:=H OR $80; {ALZA ENABLE}
PORT[PB]:=H;
PORT[PB]:=H AND $7F;
PAUSE;
END;
PROCEDURE LCD_CHAR2(C : CHAR); { INVIO DI UN CARATTERE ALL' LCD
}
VAR A:BYTE;
BEGIN
A:=PORT[PB] AND $9F; {LEGGE PORT PB E AZZERA RS E RW}
A := A OR $40;{ALZA RS}
PORT[PB]:=A ;
PORT[PA]:= ORD(C);
A:=A OR $80; {E2 A 1}
PORT[PB]:=A;
PORT[PB]:=A AND $7F; {E2 A 0}
PAUSE;
END;
PROCEDURE CLEAR2; { CANCELLA TUTTO IL DISPLAY E PORTA IL
CURSORE IN
POSIZIONE HOME (INDIRIZZO 0) }
BEGIN
LCD_CMD2($01);
DELAY(40);
END;
PROCEDURE HOME2;
BEGIN
LCD_CMD2($02);
DELAY(40);
END;
PROCEDURE LCD_LEFT;
BEGIN
LCD_CMD2($18);
END;
71
PROCEDURE LCD_RIGHT;
BEGIN
LCD_CMD2($1C);
END;
PROCEDURE INIT_LCD2;
BEGIN
LCD_CMD2($3C); { 8 BIT + 1 LINEA + 5 X 8 DOTS }
LCD_CMD2($3C);
LCD_CMD2($1C);
LCD_CMD2($06);
LCD_CMD2($0C);
END;
FUNCTION LEGGI_CONTRAVES(N:BYTE):INTEGER;
VAR C,A:BYTE;
BEGIN
C:=PORT[PB] AND $F0;{LEGGO LA SITUAZIONE SUL PORT B E MASCHERO
LA PARTE ALTA}
C:=C OR (N SHL 1);
PORT[PB]:=C;
PORT[PB]:=C OR $01;{ ABILITA IL 74LS138}
A:=PORT[PC]; { ASSEGNA ALLA VARIABILE IL VALORE DEL PORT C }
A:=NOT(A);{ RIPORTO IL DATO IN LOGICA POSITIVA }
LEGGI_CONTRAVES:=A AND $0F;
PORT[PB]:=C;
END;
FUNCTION U2:INTEGER;
VAR A:INTEGER;
BEGIN
A:= LEGGI_CONTRAVES(1)*10 + LEGGI_CONTRAVES(0);
IF A=0 THEN
BEGIN
LCD_STR1('IMPOSTARE SOGLIA U2');
DELAY(2000);
END
ELSE CLEAR1;
U2:=A;
END;
FUNCTION U1:INTEGER;
VAR A:INTEGER;
BEGIN
A:= LEGGI_CONTRAVES(3)*10 + LEGGI_CONTRAVES(2);
72
IF A=0 THEN
BEGIN
LCD_STR1('IMPOSTARE SOGLIA U1');
DELAY(2000);
END
ELSE CLEAR1;
U1:=A;
END;
FUNCTION T2:INTEGER;
VAR A:INTEGER;
BEGIN
A:= LEGGI_CONTRAVES(5)*10 + LEGGI_CONTRAVES(4);
IF A=0 THEN
BEGIN
LCD_STR1('IMPOSTARE SOGLIA T2');
DELAY(2000);
END
ELSE CLEAR1;
T2:=A;
END;
FUNCTION T1:INTEGER;
VAR A:INTEGER;
BEGIN
A:= LEGGI_CONTRAVES(7)*10 + LEGGI_CONTRAVES(6);
IF A=0 THEN
BEGIN
LCD_STR1('IMPOSTARE SOGLIA T1');
DELAY(2000);
END
ELSE CLEAR1;
T1:=A;
END;
FUNCTION ADCONV (CHANNEL:INTEGER) : INTEGER;
VAR A:REAL;
BEGIN
A:=1;
PORT[PB1]:= ((PORT[PB1] AND $F8) OR (CHANNEL AND $7));
A:=A+A;
PORT[PB1]:= (PORT[PB1] OR $10); {ALE A 1}
A:=A+A;
PORT[PB1]:= (PORT[PB1] AND $EF);{ALE A 0}
A:=A+A;
73
PORT[PB1]:= (PORT[PB1] OR $8); {START A 1}
A:=A+A;
PORT[PB1]:= (PORT[PB1] AND $F7);{START A 0}
A:=A+A;
WHILE (PORT[PC1] AND 1) = 0 DO
ADCONV:= PORT[PA1];
END;
FUNCTION T1M:INTEGER;
VAR
B:INTEGER;
BEGIN
B:= ADCONV(7);
IF (B>T1) THEN
BEGIN
LCD_STR1('SUPERATA SOGLIA T1');
DELAY(2000);
END
ELSE CLEAR1;
T1M:=B;
END;
FUNCTION T2M:INTEGER;
VAR
B:INTEGER;
BEGIN
B:= ADCONV(4);
IF (B>T2) THEN
BEGIN
LCD_STR1('SUPERATA SOGLIA T2');
DELAY(2000);
END
ELSE CLEAR1;
T2M:=B;
END;
FUNCTION U1M:INTEGER;
VAR
B:INTEGER;
BEGIN
B:= ADCONV(5);
IF (B>U1) THEN
BEGIN
LCD_STR1('SUPERATA SOGLIA U1');
DELAY(2000);
END
74
ELSE CLEAR1;
U1M:= B{*100.0/255;}
END;
FUNCTION U2M:INTEGER;
VAR
B: INTEGER;
BEGIN
B:= ADCONV(6);
IF (B>U2) THEN
BEGIN
LCD_STR1('SUPERATA SOGLIA U2');
DELAY(2000);
END
ELSE CLEAR1;
U2M:= B{*100.0/255};
END;
PROCEDURE ALL_T1;
BEGIN
IF (T1M>T1)
THEN PORT[PC1]:=PORT[PC1] OR $10
ELSE PORT[PC1]:=PORT[PC1] AND $EF;
END;
PROCEDURE ALL_T2;
BEGIN
IF (T2M>T2)
THEN PORT[PC1]:=PORT[PC1] OR $20
ELSE PORT[PC1]:=PORT[PC1] AND $DF;
END;
PROCEDURE ALL_U1;
BEGIN
IF (U1M>U1)
THEN PORT[PC1]:=PORT[PC1] OR $40
ELSE PORT[PC1]:=PORT[PC1] AND $BF;
END;
PROCEDURE ALL_U2;
BEGIN
IF (U2M>U2)
THEN PORT[PC1]:=PORT[PC1] OR $80
ELSE PORT[PC1]:=PORT[PC1] AND $7F;
END;
75
PROCEDURE LCD_STR2(STR:STRING);
VAR I,LS : INTEGER;
BEGIN
LS := LENGTH(STR);
IF LS > 80 THEN LS := 80;
FOR I := 1 TO LS DO LCD_CHAR2(STR[I]);
END;
PROCEDURE CLEAR_STR;
VAR I:INTEGER;
BEGIN
NO:='';
FOR I := 1 TO 80 DO NO := NO + ' ';
END;
PROCEDURE TEMP1(T1,T1M:INTEGER);
VAR S,S1:STRING;
I:INTEGER;
BEGIN
S:= 'T1_I';
FOR I:=1 TO LENGTH(S) DO NO[I]:=S[I];
STR(T1:2,S1);
FOR I:=1 TO LENGTH(S1) DO NO[I+5]:=S1[I];
S:='T1_M';
FOR I:=1 TO LENGTH(S) DO NO[I+8]:=S[I];
STR(T1M:2,S1);
FOR I:=1 TO LENGTH(S1) DO NO[I+13]:=S1[I];
END;
PROCEDURE UMID1(U1,U1M:INTEGER);
VAR S,S1:STRING;
I:INTEGER;
BEGIN
S:= 'U1_I';
FOR I:=1 TO LENGTH(S) DO NO[I+40]:=S[I];
STR(U1:2,S1);
FOR I:=1 TO LENGTH(S1) DO NO[I+45]:=S1[I];
S:='U1_M';
FOR I:=1 TO LENGTH(S) DO NO[I+48]:=S[I];
STR(U1M:2,S1);
FOR I:=1 TO LENGTH(S1) DO NO[I+53]:=S1[I];
END;
PROCEDURE TEMP2(T2,T2M:INTEGER);
VAR S,S1:STRING;
I:INTEGER;
BEGIN
S:= 'T2_I';
76
FOR I:=1 TO LENGTH(S) DO NO[I+16]:=S[I];
STR(T2:2,S1);
FOR I:=1 TO LENGTH(S1) DO NO[I+21]:=S1[I];
S:='T2_M';
FOR I:=1 TO LENGTH(S) DO NO[I+24]:=S[I];
STR(T2M:2,S1);
FOR I:=1 TO LENGTH(S1) DO NO[I+29]:=S1[I];
END;
PROCEDURE UMID2(U2,U2M:INTEGER);
VAR S,S1:STRING;
I:INTEGER;
BEGIN
S:= 'U2_I';
FOR I:=1 TO LENGTH(S) DO NO[I+56]:=S[I];
STR(U2:2,S1);
FOR I:=1 TO LENGTH(S1) DO NO[I+61]:=S1[I];
S:= 'U2_M';
FOR I:=1 TO LENGTH(S) DO NO[I+64]:=S[I];
STR(U2M:2,S1);
FOR I:=1
TO LENGTH(S1) DO NO[I+69]:=S1[I];
END;
BEGIN
INIT_8255;
INIT_8255A;
INIT_LCD1;
INIT_LCD2;
CLEAR1;
CLEAR2;
CLRSCR;
CHIAVE:=CHR(0);
{ASCII_TEST;}
REPEAT
{CLEAR2;}
CLEAR_STR;
TEMP1(T1,T1M);
UMID1(U1,U1M);
TEMP2(T2,T2M);
UMID2(U2,U2M);
WRITELN(NO:80);
LCD_STR2(NO);
ALL_T1;
ALL_T2;
ALL_U1;
ALL_U2;
77
DELAY(5000);
IF KEYPRESSED THEN CHIAVE:= READKEY;
UNTIL CHIAVE=CHR(27);
END.
Massa
Reset
GND
RESET
B1 A1
I/O
L I/O
CH
Channel
CK
check
B2 A2
D7
MSB Dati
DRV
Appendice A :
Espanzione PC
Alimentazione
+5V
B3 A3
D6
Richiesta di
IRQ2
B4 A4
D5
-5V
B5 A5
D4
DRQ2
B6 A6
D3
Alimentazione
-12V
B7 A7
D2
0 stati di attesa
OWS
B8 A8
D1
Alimentazione
+12V
B9 A9
D0
Massa
GND
B10 A10 I/O
Bus
XT (8 bit)
Interrupt 2
Alimentazione
Richiesta DMA2
LSB Dati
CH
RDY
Scrittura in
MEMW
LB11 A11 AEN
Memoria
Lettura in
e Indirizzi
MEMR
LB12 A12 A19
Memoria
IOW
LB13 A13 A18
Lettura I/O
IOR
LB14 A14 A17
DACK3
LB15 A15 A16
richiesta DMA3
Richiesta DMA3
DRQ3
Riconoscimento
DACK1
B16 A16 A15
LB17 A17 A14
richiesta DMA1
Richiesta DMA1
Refresh
DRQ1
B18 A18 A13
REFRESH LB19 A19 A12
memoria
Clock da scheda
CLK
B20 A20 A11
IRQ7
B21 A21 A10
madre
Richiesta di
Interrupt 7
MSB
Indirizzi
Scrittura I/O
Riconoscimento
L Abilitazion
78
Tabella?
di