![]() | ![]() |
|
|
8250 Uart: DESCRIZIONE ED USO
L'integrato 8250 della scheda RS 232 possiede 10 registri.
Alcuni di questi sono testabili in lettura mentre ad altri
potremo scriverci sopra per settare alcuni parametri quali il
baud rate, la parita' ecc.
Iniziamo ad elencare le varie porte legate alle comunicazioni
seriali.
Indirizzo porta Input o Output Servizio
-------- ----- ------ ----- ----- --------- ----- --------
0x3F8 Out Registro memorizzazione TX
0x3F8 In Registro dati RX
0x3F8 Out Divisore baud rate (LSB)
0x3F9 Out Divisore baud rate (MSB)
0x3F9 Out Abilitazione interruzioni
0x3FA In Identificazione interruz.
0x3FB Out Controllo linea
0x3FC Out Controllo modem
0x3FD In Stato linea
0x3FE In Stato modem
Questi indirizzi sono relativi alla porta di comunicazione COM1.
Gli indirizzi relativi alla porta COM2 si possono ottenere
sotraendo 256 agli indirizzi visti precedentemente.
Un esempio :
main()
while(porta != 1 && porta != 2);
indirizzo = 0x2F8 + 256 * (2 - porta); /* 0x3F8 se 1 */
}
Come avrete notato nell'elenco precedente alcune porte descritte
con funzioni diverse tra di loro possedevano lo stesso indirizzo.
Lo scopo di queste e' selezionabile mediante l'apposito
settaggio di un bit all'interno del registro di controllo della
linea.
Vediamolo.
Registro di controllo della linea.
+---+---+---+---+---+---+---+---+
0x3FB : 7 : 6 : 5 : 4 : 3 : 2 : 1 : 0 :
+---+---+---+---+---+---+---+---+
: : : : : : : :
: : : : : : ---Bit data---
: : : : : : 0 0 = 5 bits
: : : : : : 0 1 = 6 bits
: : : : : : 1 0 = 7 bits
: : : : : : 1 1 = 8 bits
: : : : :-Bit stop-
: : : : : 0 = 1
: : : : : 1 = 1.5 se 5 bits data
: : : :-Parity-
: : : : 0 = Nessun bit
: : : : 1 = Bit generato
: : : -Tipo-
: : : 0 = dispari
: : : 1 = pari
: :-Test.-
: : 0 = disabilitato
: : 1 = abilitato
:-Break-
: 0 = disabilitato
: 1 = forzato condizione di space
---I/O---
0 = Condizione normale
1 = Per indirizzare divisori baud rate
Come potete vedere l'ultimo bit e' quello che fa si' che se
impostato ad 1 i registri 0x3F8 e 0x3F9 vengano utilizzati per
settare i divisori del baudrate.
Da questo e' facile comprendere che e' possibile impostare
momentaneamente il valore di questo per poter settare la porta al
baudrate desiderato per poi riportarlo al valore normale (0) per
utilizzare la porta per funzioni di ricezione.
Appena avremo finito di parlare delle altre porte vedremo un
esempio che probabilmente chiarira' le idee nel caso che cio' che
e' stato detto precedentemente non sia risultato sufficentemente
chiaro.
I registri 0x3F8 e 0x3F9, nel caso che bit di cui abbiamo parlato
e' a 1, servono per settare i divisori del baud rate.
Il primo conterra' il byte meno significativo (LSB) mentre la
seconda quello piu' significativo (MSB).
I valori sono quelli riportati in tabella.
Baud rate MSB LSB
----- ----- --------- ----- -----
50 09H 00H
75 06H 00H
110 04H 17H
150 03H 00H
300 01H 80H
600 00H C0H
1200 00H 60H
2400 00H 30H
4800 00H 18H
9600 00H 0CH
Supponiamo di voler creare una funzione da abbinare a un nostro
programma di comunicazione che serva a settare il baud rate in
funzione di una scelta offerta da menu.
set_baud()
}
Il servizio 3 dell'interrupt 14H visto prima riportava lo stato
della linea e del modem.
La stessa funzione puo' essere eseguita testando direttamente i
due registri del 8250 che svolgono questo compito.
0x3FD Stato linea
+---+---+---+---+---+---+---+---+
: 7 : 6 : 5 : 4 : 3 : 2 : 1 : 0 :
+---+---+---+---+---+---+---+---+
: : : : : : : :
: : : : : : : Dato ricevuto
: : : : : : Sovrapposizione
: : : : : Errore parita
: : : : Errore di framing
: : : Break rivelato
: : Registro memorizzazione TX vuoto
: Registro scorrimento TX vuoto
Timeout
Uno bit a 1 indica che un determinato stato esiste.
0x3FE Stato del modem
+---+---+---+---+---+---+---+---+
: 7 : 6 : 5 : 4 : 3 : 2 : 1 : 0 :
+---+---+---+---+---+---+---+---+
: : : : : : : :
: : : : : : : Delta clear to send
: : : : : : Delta data set ready
: : : : : Delta ring indicator
: : : : Delta carrier detect
: : : Clear to send
: : Data set ready
: Ring indicator
Carrier detect
Oltre ai due registri precedenti, relativi allo stato della linea
e a quello del modem, esistono due registri per il controllo di
questi.
Il primo lo abbiamo gia' visto e precisamente quello relativo
al controllo della linea.
Vediamo ora il registro di controllo del modem.
0x3FC Registro controllo modem
+---+---+---+---+---+---+---+---+
: 7 : 6 : 5 : 4 : 3 : 2 : 1 : 0 :
+---+---+---+---+---+---+---+---+
0 0 0 : : : : :
: : : : DTR attivo
: : : RTS attivo
: : OUT1 Non usato
: OUT2 Deve essere 1 per
: mandare interruzioni
0 = Normale
1 = Cortocircuito
Gli ultimi 3 bit sono forzati a 0 mentre il numero 4 deve essere
a 0 per trasmissioni normali sulla porta.
Nel caso che per motivi di test si voglia cortocircuitare la
porta bastera' metterlo ad 1 .
In questo modo ogni carattere trasmesso verra' restituito di
ritorno come se fosse stato ricevuto.
Vediamo ora un esempio di utilizzo di questo registro mediante
una funzione che setta il DTR a on o ad off a seconda che
l'argomento passato sia 1 o 0.
set_dtr(stato)
int stato;
Esistono ancora i registri di abilitazione e di identificazione
interruzione che vedremo dopo il seguente esempio.
Si tratta di un programmino che mostra l'utilizzo di quanto detto
fino ad ora costituito da un modulo base che potrete voi stessi
ampliare con funzioni per vari scopi quale, ad esempio, per
catturare o trasmettere un file ASCII.
#include <stdio.h>
#define LSR 0x3FD /* Indirizzi registri 8250 */
#define DLL 0x3F8
#define MCR 0x3FC
#define LCR 0x3FB
#define DLM 0x3F9
#define MSR 0x3FE
#define CLS puts("\33[2J")
#define BEL putchar('\007');
char *msr=(char*)MSR;
char *dlm=(char*)DLM;
char *lcr=(char*)LCR;
char *lsr=(char*)LSR;
char *dll=(char*)DLL;
char *mcr=(char*)MCR;
int ind,baud,parity;
main(argc,argv)
int argc;
char *argv[];
}
baud_set(baud);
parity_set();
colloquia();
}
colloquia() /* Ciclo ricevi/trasmetti */
key = getch(); /* Se e' stato premuto */
if(key == '\033') /* guarda se e' ESC */
exit(0); /* Se si esce a DOS */
tx_char(key); /* se no lo trasmette */
}
}
parity_set() /* Setta la par., dati,stop */
rx_char() /* Riceve un carattere */
else
if((util & 0x01) != 0)
else
return(NULL); /* Non e' stato ricevuto */
}
tx_char(var) /* Trasmette un carattere */
char var;
baud_set(speed) /* Setta il baudrate */
}
set_dtr() /* Mette ad on il DTR */
Il commento iniziale "assegna il carattere 3 a 7" sara' risultato
oscuro.
Si tratta di un semplice metodo per assegnare al carattere ASCII
3 (CTRL C) il carattere 7 relativo al BEEP in modo da far si che
battendo CTRL C non si esca dal programma.
Per fare questo bisognera' invece battere ESC.
Il discorso relativo ai registri dedicati all'abilitazione e
all'identificazione dell'interruzione e' particolare in quanto
permette al programmatore di evitare di testare in continuazione
il registro di stato della linea per sapere se un determinato
evento si e' verificato o meno.
Privacy |
Articolo informazione
Commentare questo articolo:Non sei registratoDevi essere registrato per commentare ISCRIVITI |
Copiare il codice nella pagina web del tuo sito. |
Copyright InfTub.com 2025