Italiano - English

La Porta Seriale

Sommario

    Esercitazioni di Informatica Industriale
    1. Architettura di un sistema basato su microprocessore Intel 8086
    2. Gestione degli Interrupt su micropocessori 80/86
    3. Programmable Interrupt Controller (PIC Intel 8259a)
    4. Demo Kernel Multitasking
    5. La Porta Seriale
    6. La Porta Parallela

    Viene presentata la porta seriale standard RS232. La sua gestione e programmazione su un sistema MS-DOS con un semplice esempio di un software di comunicazione.

    Introduzione

    DISPOSITIVO PER IL COLLEGAMENTO DEL COMPUTER AD ALTRI COMPUTER O PERIFERICHE, COME MODEM O MACCHINE CONTROLLO NUMERICO

    porta seriale, Recommended Standard 232 Revision C (RS-232C), Universal Asynchronous Receiver Transimitter (UART), sono tutti sinonimi per indicare una interfaccia di tipo seriale verso il mondo esterno

    COMUNICAZIONE SERIALE SIGNIFICA CHE OGNI PAROLA DA TRASMETTERE (RICEVERE) VIENE TRASMESSA (RICEVUTA) UN BIT ALLA VOLTA

    LA PORTA SERIALE TRASMETTE (RICEVE) BIT PARTI DI PAROLE CHE SCOMPONE (RICOMPONE) AUTOMATICAMENTE

    L'UTENTE DELLA PORTA SERIALE TRASMETTE (RICEVE) PAROLE

    Protocollo di comunicazione

    PRIMA CHE DUE COMPUTER (O ALTRO) POSSANO COMUNICARE, E' NECESSARIO CHE PARLINO LA STESSA LINGUA.

    • A CHE VELOCITA' VENGONO TRASMESSI I BIT ?
    • DA QUANTI BIT E' COMPOSTA UNA PAROLA ?
    • COME FARE PER VERIFICARE CHE QUELLO CHE E' STATO RICEVUTO E' PROPRIO QUELLO CHE E' STATO TRASMESSO ??

    LO STANDARD RS-232 HA DEFINITO DELLE CONVENZIONI CHE UNIFORMANO LA COMUNICAZIONE SERIALE. 

    • BAUD RATE: Velocità di trasmissione in bit/s (50..115200 bit/s)
    • WORD LENGTH: Numero di bit che compongono una parola (5,6,7,8 bit)
    • STOP BITS: Numero di bit usati per separare due parole consecutive (1,2 bit)
    • PARITY: bit opzionale utilizzato per fare una verifica sull'integrità della parola trasmessa (pari, dispari,nessuna)

    PARLARE LA STESSA LINGUA SIGNIFICA IMPOSTARE ALLO STESSO MODO I PARAMETRI DEL PROTOCOLLO

    Accesso alla porta seriale

    • IMPOSTAZIONE DEL PROTOCOLLO
    • IMPOSTAZIONE ALTRI SERVIZI LOCALI (indipendenti dal protocollo)

    E' possibile accedere alla porta seriale attraverso:

    • Interrupt DOS
    • Interrupt BIOS
    • Accesso diretto alla porta

    Il DOS dispone dell'interrupt 21h servizo 75 che accede alla porta seriale, ma è inefficiente e poco documentato, quindi sconsigliato.

    Il BIOS dispone di una serie interrupt 14h che permettono di impostare, leggere e scrivere la porta seriale. Questi interrupt presentano alcune carenze, soprattutto ad alte velocità (baud > 1200).

    Attualmente il metodo più efficiente per ricevere e trasmettere ad alta velocità è quello di accedere direttamente ai registri della porta seriale.

    I personal computer sono dotati di un microprocessore dedicato alle trasmissioni seriali (8250 UART), al quale si può accedere direttamente con istruzioni di I/O

    I registri UART

     

    Registro Nome Offset Direzione
    trasmissione
    TRANSMITTER HOLDING REGISTER
    THR 0F8h output
    ricezione
    READ DATA REGISTER
    RHR 0F8h output
    div.baud LSB
    BAUD RATE DIVISOR
    BRD 0F8h output
    div.baud MSB
    BAUD RATE DIVISOR
    BRD 0F9h output
    abilitazione Interrupt
    INTERRUPT ENABLE REGISTER
    IER 0F9h output
    riconoscimento Interrupt
    INTERRUPT ID REGISTER
    IIR 0FAh input
    controllo linea
    LINE CONTROL REGISTER
    LCR 0FBh output
    controllo modem
    MODEM CONTROL REGISTER
    MCR 0FCh output
    stato linea
    LINE STATUS REGISTER
    LSR 0FDh intput
    stato modem
    MODEM STATUS REGISTER
    MSR 0FEh intput

    I REGISTRI DELLA UART-COM1 NORMALMENTE HANNO BASE IN 300h (200h PER COM2)

    THR:Contiene il carattere da trasmettere. Prima di scrivere un nuovo carattere testare il bit 5 di LSR

    RDR: contiene il carattere ricevuto che viene mantenuto fino a quando ne giunge uno nuovo. Il bit 0 di LSR indica se è giunto un nuovo carattere. Il bit 1 di LSR indica che il carattere precedente non è stato letto.

    BRD: la velocità di trasmissione è data da:

    BaudRate = 1,843,200/(divisore x 16)
    divisore = 1,843,200/(BaudRate x 16)

    i due registri BRD contengono il divisore a 16 bit.I valori validi per BaudRate sono: 50,110,150,300,600,1200,1800,2000,2400,3600,4800,7200,9200,9600,38400,115200.

    BRD-LSB: condivide il registro xF8 con THR e RDR. Prima di scrivere BRD-LSB è necessario impostare il bit 7 (DLAB) di LSR. DLAB viene azzerato scrivendo in BRD-MSB.

    IER: E' possibile far generare dal PIC un interrupt (IRQ*) quando si verificano le seguenti condizioni:

    1. RDR pieno (è arrivato un carattere) (bit 0)
    2. THR è vuoto (buffer trs vuoto) (bit 1)
    3. errore sulla linea (bit 2)
    4. è cambiato lo stato del modem (bit 3)

    1 = interrupt abilitato

     

    *IRQ4 (INT 0Ch) per COM1, IRQ3 (INT 0Bh) per COM2.

    IIR:questo registro permette di identificare quale dei quattro casi ha generato l'interrupt corrente (bit 1,2). Inoltre indica anche se c'è un INT pendente (bit 0 = 0).

    b2,b1 TIPO INTERRUPT PRIORITA' RESET CON:
    00 modem status change 3 (low) read MSR
    01 transmit-register-empty 2 write THR
    10 data-available 1 read LDR
    11 line-status 0 (high) read LSR

    LCR:permette di impostare i parametri del protocollo.

    b7. . . . . . b0
    7 6 5 4 3 2 1 0
    ¦ ¦ ¦ ¦ ¦ ¦ +-+-- lunghezza parola
    ¦ ¦ ¦ ¦ ¦ ¦   00 = 5 bits (bit1=1 -> 1.5 bit di stop)
    ¦ ¦ ¦ ¦ ¦ ¦  01 = 6 bits
    ¦ ¦ ¦ ¦ ¦ ¦  10 = 7 bits
    ¦ ¦ ¦ ¦ ¦ ¦  11 = 8 bits
    ¦ ¦ ¦ ¦ ¦ +---- 0 = 1 stop bit, 1 = 1.5 or 2
    ¦ ¦ ¦ ¦ +----- 0 = no parity generated, 1 =parity generated
    ¦ ¦ ¦ +------ 0 = parita dispari, 1 = parita pari
    ¦ ¦ +------- 0 = parity disabled,1 = enabled
    ¦ +-------- 0 = turn break off, 1 = force spacing break state
    +--------- 1 = baud rate divisor (DLAB); 0 = RDR, THR or IER
    

    MCR: Questo registro controlla i segnali Data Terminal Ready (DTR bit 0), e Request To Send (RTS bit 1). Inoltre il bit 3 se alto permette agli int generati dal UART di essere ascoltati dal PIC. Per una comunicazione Interrupt Driven MCR deve essere impostato a: 0000 1011 (0Bh)

    LSR: Questo registro contiene informazioni relativi ai dati in transito (in/out). Il bit 0 = 1 se è arrivato un carattere. Viene azzerato leggendo in RDR i bit 1,2,3,4 indicano diverse condizione di errore Il bit 5 = 1 se THR è vuoto (THR-E). Viene azzerato scrivendo in THR

    MSR: contiene lo stato dei segnali modem. I primi quattro bit sono 1 se i segnali collegati hanno cambiato il loro stato dall'ultima volta che sono stati letti dalla cpu.

    Software di comunicazione

    PROBLEMA PRINCIPALE DELLA COMUNICAZIONE E' LA RICEZIONE

    POLLING: Lettura continua de LSR. Se arrivato un nuovo carattere, viene computato (almeno memorizzato)
    VANTAGGI: Semplicità di implementazione
    PROBLEMI:Sincronismo,velocità,interoperabilità

    INTERRUPT DRIVEN: ad ogni carattere arrivato, viene generata una interruzione del processo corrente. Questa và riprogrammata per memorizzare il nuovo carattere. Un secondo processo può computare il carattere memorizzato:
    VANTAGGI:velocità, interoperabilità, computazione e ricezione sono disaccopiati con un buffer FIFO
    PROBLEMI: conoscenza dettagliata dell'UART 

    Coda FIFO (buffer circolare)

    UNA CODA FIFO PUO' ESSERE IMPLEMENTATA COME UN BUFFER (ARRAY) CIRCOLARE.

    UN BUFFER CIRCOLARE E' DOTATO DI DUE PUNTATORI. UNO RELATIVO AL PROSSIMO CARATTERE DA SCRIVERE (BufIn), ED UNO PER IL PROSSIMO CARATTERE DA LEGGERE (BufOut).

    QUANDO UNO DEI PUNTATORI RAGGIUNGE LA FINE DEL BUFFER, ALLORA VIENE MESSO A 0 (QUINDI CIRCOLARE)

    QUANDO I DUE PUNTATORI COINCIDONO ALLORA IL BUFFER E' VUOTO.

    QUANDO IL PUNTATORE DI SCRITTURA RAGGIUNGE QUELLO DI LETTURA, ALLORA IL BUFFER E' PIENO ALLORA SI PERDONO DATI

    PROBLEMA !! DIMENSIONARE IL BUFFER IN MODO CHE NON SIA MAI PIENO

    Esempio di un sw di comunicazione - Modulo Terminal

    Il modulo terminal è composto dai file:

    TERMINAL.H TERMINAL.C
    PRVTM.C 

    TERMINAL E' UN SEMPLICE MODULO DI TRASMISSIONE RICEZIONE SU PORTA SERIALE

    PERMETTE:

    • Trasmissione e ricezione contemporanea
    • Ricezione interrupt driven
    • Buffer circolare non accessibile ma dimensionabile dall'utente

    MIGLIORAMENTI:

    • Impostazione del protocollo con accesso diretto alla porta, per avere velocità fino a 115200 baud/s
    • Distinzione degli errori sulla linea
    • Verifica sulla presenza di portante prima di trasmettere
    • Buffer dinamico in fase di ricezione
    • Disposizione di "sensori" del traffico
    • ....

    ESPORTA:

    • Simboli per la definizione del protocollo
    • Funzioni di attivazione e disattivazione del modulo (TerminalOn e TerminalOFF)
    • Funzione di variazione protocollo (SetPort)
    • Funzione di Lettura dal buffer circolare (LeggiDatoDaBuffer)
    • Funzione di trasmissione (Trasmetti)

    FUNZIONI INTERNE:

    • Attivazione e disattivazione delle porte seriali (ComON e ComOFF)
    • Interrupt per la gestione della ricezione (ReadRS232)

    DATI INTERNI:

    • Simboli offset indirizzi registri UART
    • Stato del sistema TERMINAL (ON OFF)
    • Buffer circolare (array di unsigned char)
    • Puntatori in lettura e scrittura buffer
    • Indirizzo base porta seriale selezionata
    • Indirizzo vecchio vettore interrupt per la porta selezionata

    NOTA: Il modulo terminal è composto dai file TERMINAL.H da includere nel programma utente e TERMINAL.C da compilare e linkare con il programma utenete. Il file PRVTM.C è un semplice programma per la prova del modulo TERMINAL

    Vota questa pagina:

    4 Commenti:

    #1 Inviato da Sauro Baietta 26-09-2009

    Data la usuale confusione fra bit(s) e bytes(s) rimane il dubbio se una porta seriale a 9.600 baud trasmetta 200 kb in soli 22" oppure in 3'
    Un esempio numerico completo avrebbe chiarito il dubbio (per il quale sono arrivato aquesta bella Vs. pagfina che, però, non mi ha risolto il dubbio).
    Inoltre il codice di verifica di prima aveva un carattere assurdo, indecifrabile...
    ed inviare il voto mi ha pure cancellato questo testo !
    ho dovuto abbassato il rating della pagina....

    #2 Inviato da PkLab 26-09-2009

    Ok accolgo le osservazioni di Sauro e miglioro i codici di verifica :)

    Riguardo ai baud...
    Per prima cosa preciso che un Byte, la cui abbreviazione è "B", è composto da 8 bit la cui abbreviazione è "b".

    quindi 1B = 8b
    Nelle abbreviazioni nasce la confusione, anche gli addetti al settore utilizzano impropriamente "b" per byte quindi spesso non è esattamente chiaro ciò di cui si sta parlando.

    se con 200kb intendi 200 kilo byte, ovvero 200KB, si ha:
    200KByte = 200*1024*8 = 1638400bit
    con una trasmissione a 9600bps (byte per secondo) impiego
    1638400bit / 9600bps = 170.6 secondi, circa 3minuti

    Ad esere precisi, se si utilizza un protocollo seriale, si dovrebbe tener conto anche dei parametri del protocollo. (vedi sopra LCR) ovvero
    - lunghezza parola: 5,6,7,8 bit
    - bit di stop:1,1.5,2
    - bit di parita: attiva/non attiva
    Se si configura la comunicazione con una parola da 7 bit, con 1 bit di stop e parità attiva, vuol dire che il protocollo richiede 2 bit di controllo ogni 7 bit di dati quindi

    200KByte = 200*1024*8 = 1638400bit
    1638400bit / 7 = 234058 parole
    234058 parole * 2 bit = 468116 bit di controllo

    così i bit da trasmettere diventano
    1638400b+468116b = 2106516b
    a 9600bps impiego
    2106516b / 9600bps = 219 secondi circa 3.6minuti

    Questo è il caso ideale, infatti è frequente avere la linea disturbata. Il disturbo provoca errori di trasmissione che il protocollo spesso è in grado di rilevare grazie ai bit di controllo. Nel caso il ricevente rileva errori di parità, richiede al trasmittente il reinvio di una parte della trasmissione.
    Questa gestione occupa la linea con ulteriore traffico che andrebbe aggiunto ai bit da trasmettere. Come effetto si ottiene una ulteriore abbassamento della velocità di trasmissione, difficilmente calcolabile.

    Il ragionamento fatto per il protocollo seriale è valido anche per internet , TCP/IP , ADSL,Sat ecc..

    La velocità di trasmissione è nominale ovvero indica la massima velocità raggiungibile dal protocollo di comunicazione.

    Spesso gli internet provider giocano sulla ambiguità tra bit e Byte.
    Per una linea ADSL a 7 mega si intente
    7Mbit/s = 7*1024*1024/8 = 917504Byte/s = 896KB/s

    Un'altra imprecisione è nella conversione da Mega a Kilo e da bit a Byte.
    Per semplificare i calcoli, si usa pensare a un Byte = 10bit e 1M = 1000K
    con questa approssimazione
    7Mb/s circa uguale a 700KB/s

    I tempi in cui si comunicava via modem con le BBS (http://it.wikipedia.org/wiki/Bulletin_Board_System) locali a 9600bps sono ormai dimenticati ...intorno 1996 le prime connessioni internet dial-up a 56Kbit/s ...sembrava di navigare col vento in poppa!

    #3 Inviato da tool 17-03-2010

    good start

    #4 Inviato da john 14-09-2010

    Buongiorno!

    Premessa: non ci capisco quasi nulla di c/c++ ma...

    Sto provando ad usare il vs. terminal, ma non riesco a compilare i file a causa di una serie di warning/errori del mio compilatore.

    sto usando il DEV C++ 4.9.7.0 e come s.o. ho WXP professional

    ho creato una directory con i file

    terminal.c
    terminal.h
    prvterm.c

    Se provo a compilare terminal.c ho il seguente errore:

    alloc.h: No such file or directory.

    Ho scaricato da internet il file alloc.h e l\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'ho incluso nella mia directory.

    Se nel file terminal.c cambio: #include <alloc.h> in #include \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"alloc.h\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
    allora riesco ad andare un passo avanti...

    ... ma all\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'interno di alloc.h ho dovuto cambiare la riga:
    // era: #include <crtdll/stdlib.h>
    #include <stdlib.h>

    Ora ricompilando terminal.c ottengo tutti i seguenti errori/warning:

    54 parse error before `*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'

    54 `interrupt\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' declared as function returning a function
    55 parse error before `ReadRS232\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
    55 [Warning] data definition has no type or storage class
    [Warning] In function `TerminalON\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\':
    75 `oldintr\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' undeclared (first use in this function)
    [Build Error] (Each undeclared identifier is reported only once
    [Build Error] for each function it appears in.)
    [Warning] In function `TerminalOFF\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\':
    96 `oldintr\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' undeclared (first use in this function)
    [Warning] In function `SetPort\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\':
    159 storage size of `regs\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' isn\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'t known
    [Build Error] At top level:
    251 parse error before `ReadRS232\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'

    Cosa posso fare?

    Lascia il tuo commento:

    Note:
    • La tua email non è obligatoria e non sarà visibile in alcun modo
    • Si prega di inviare solo commenti relativi a questa pagina
    • Commenti inappropriati o offensivi saranno modificati o eliminati
    • Codici HTML non sono consentiti. Prego usare i BB code:
      [b]bold[/b], [u]underline[/u], [i]italic[/i], [code]code[/code]
    Il codice, le illustrazioni e gli esempi riportati in questa pagina sono solo a scopo illustrativo. L'autore non prende alcuna responsabilità per il loro utilizzo da parte dell'utente finale.
    Questo materiale è di proprietà di Pk Lab ed è utilizzabile liberamente a condizione di citarne la fonte.