Sistemi a Microcontrollore - Programmazione e Debug Anno Accademico 2018/2019 - UniCa

Pagina creata da Noemi D'Andrea
 
CONTINUA A LEGGERE
Sistemi a
Microcontrollore
6. Programmazione e Debug

Anno Accademico 2018/2019
Indice

• Programmazione
   Flusso di Programmazione
   Librerie
• Debug
   Debugger
   Comunicazione Seriale
Indice

• Programmazione
   Flusso di Programmazione
   Librerie
• Debug
   Debugger
   Comunicazione Seriale
Utilizzo di in un
            Microprocessore/Microcontrollore
Le applicazioni in un microprocessore possono esser viste attraverso diversi livelli di
astrazione che vanno dal software all’hardware: l’Instruction Set Architecture (ISA)
costituisce l’interfaccia tra i due mondi.

                            high-level program (e.g. C, Java)

                                               compilation

                                                                           SOFTWARE
                               Instruction Set Architecture
                                                                           HARDWARE
                                               execution

                                  dispositivo hardware
Utilizzo di in un
                  Microprocessore/Microcontrollore
In realtà il flusso di programmazione di un microprocessore/microcontrollore tipicamente
contiene più livelli e più passaggi intermedi
  high-level      source code                     1
  program                              compiler                               assembly
                                                                              program
   object
  (blocks code)                                   2
   machine                            assembler
   language
   program

                                                  3                         executable
   machine                               linker
   language                                                                   machine
     library                                                                  language
                                                                              program

                                                  4
    Flash                               loader
    memory
Compilatore

• Il compilatore traduce un linguaggio di alto
  livello (es. C) in assembly, forma simbolica del
  linguaggio macchina
   in passato molti sistemi operativi erano scritti
    direttamente in assembly per via della capacità ridotta
    delle memorie e dei compilatori inefficienti
   con il progresso dei compilatori e delle memorie, oggi la
    compilazione produce programmi assembly quasi
    come uno sviluppatore esperto di assembly
Assembler

• L’assembler ha il compito principale di tradurre il
  programma in linguaggio assembly nel
  corrispondente codice macchina (oggetto)
• L’assembler si occupa in particolare di
    tradurre pseudo-istruzioni in istruzioni native dell’ISA
    ottimizzare i salti in base agli spostamenti necessari
    estendere le istruzioni con funzionalità speciali (es. nel
     MIPS consente load immediate di due parole
     contemporaneamente tramite un registro dedicato)
Linker

• Il linker ha il compito di raggruppare tutti gli oggetti
  (codice       macchina,      dati   e     informazioni
  supplementari) corrispondenti alle procedure del
  programma e di creare l’eseguibile corrispondente
• Il linker si occupa di
    posizionare il codice e i dati in memoria
    determinare l’indirizzo di dati e delle etichette dei salti
• L’eseguibile ha il formato di un file oggetto ma
  non contiene riferimenti non risolti
Loader

• Il loader è lo strumento che permette di scaricare il
  programma nel dispositivo target ed eseguirlo
• In particolare, il loader
    determina la dimensione dei segmenti (text e data)
     del programma
    crea uno spazio di indirizzi che contenga i segmenti
    copia istruzioni e dati in memoria
    inizializza i registri della macchina (stack pointer)
    salta a una routine di inizializzazione (prologo del
     main)
Indice

• Programmazione
   Flusso di Programmazione
   Librerie
• Debug
   Debugger
   Comunicazione Seriale
Librerie

• Le librerie e le routine precompilate/preassemblate
  sono parti (blocchi) del programma che possono
  essere utilizzate all’occorrenza, senza necessità
  di svilupparle ogni volta da capo
    tipicamente sono blocchi di programma che non
     cambiano e che sono utili a gestire funzionalità
     specifiche (es. driver, chiamate a sistema)
    velocizzano lo sviluppo del codice e, se
     precompilate/preassemblate,        la    programmazione
     (linker)
    lo sviluppatore stesso può definire nuove librerie
Link Statico di Librerie
• Il link alle librerie utilizzate nel programma viene fatto
  prima dell’esecuzione del programma (in
  compilazione).
• È il modo più rapido per chiamare routine di libreria,
  ma presenta degli svantaggi:
    le routine di libreria divengono parte del codice
     eseguibile, per cui nuove versioni delle librerie non
     verrebbero integrate se non si rigenera l’eseguibile
    tutte le routine di libreria chiamate in qualunque parte
     dell’eseguibile   vengono        caricate,    anche  se
     successivamente non vengono effettivamente eseguite,
     causando uno spreco di risorse di memoria
Link Dinamico di Librerie
• Nelle librerie con link dinamico (DLLs, dynamically
  linked libraries) le routine non sono linkate e caricate
  prima dell’esecuzione, ma vi sono informazioni
  aggiuntive nelle librerie e nel programma relative alla
  collocazione delle routine di libreria.
    le prime DLLs avevano un loader che faceva il link
     dinamico sfruttando tali informazioni aggiuntive per trovare
     le routine di libreria e aggiornarle nell’eseguibile (vi era
     comunque il caricamento di tutte le routine di libreria a
     prescindere dal loro effettivo utilizzo)
    le DLLs recenti effettuano il link di ogni routine solo dopo
     che la stessa routine viene chiamata (in tempo di
     esecuzione)
Esempio: avr/io.h

   • Un esempio di libreria per i microcontrollori AVR
     è la quella definita dall’header avr/io.h che, per
     l’ATmega328p richiama a sua volta avr/iom328p.h
       int main(void) {

             volatile int* PORTB = (volatile int*) 0x0025;        // declare and initialize PORTB pointer
             volatile int* DDRB = (volatile int*) 0x0024;         // declare
                                                             // decalre   and and     initialize
                                                                                 init ADC        DDRB pointer
                                                                                            pointers
             long int i;                                          // declare
                                                             volatile           index i= (volatile int*) 0x007C;
                                                                       int* ADMUX
             char state = 0x00;                                   // declare
                                                             volatile           and initialize
                                                                       int* ADCSRA               led state
                                                                                         = (volatile  int*) 0x007A;
             *DDRB = 0x02;                                        // set  port   B  as output
                                                             volatile int* ADCH = (volatile int*) 0x0079;
int main(void) {                                             volatile int* ADCL = (volatile int*) 0x0078;
             while(1) {                                           // infinite loop
                   i = 0; = (volatile int*) 0x002A;
     volatile int* DDRD                                           // initialize
                                                          // declare              index
                                                                      and initialize
                                                             int adc_read     (int      {i
                                                                                    ch) DDRB    pointer
                   while(i
Esempio: avr/io.h

• La libreria avr/io.h facilita l’accesso agli input e
  output del microcontrollore fornendo i puntatori
  delle risorse mappate in memoria e l’indice dei
  relativi bit di interesse attraverso delle variabili
  rappresentative
    #define DDRB _SFR_IO8(0x04)   #define ADCL _SFR_MEM8(0x78)
    #define DDB0 0                #define ADCL0 0
    #define DDB1 1                #define ADCL1 1
    #define DDB2 2                #define ADCL2 2
    #define DDB3 3                #define ADCL3 3
    #define DDB4 4                #define ADCL4 4
    #define DDB5 5                #define ADCL5 5
    #define DDB6 6                #define ADCL6 6
    #define DDB7 7                #define ADCL7 7
Esempio: avr/io.h

• La libreria avr/io.h definisce anche le variabile per
  la gestione degli interrupt ed in particolare
  assegna un identificativo ai vettori corrispondenti
  alle sorgenti supportate dal microcontrollore
  /* Interrupt Vectors */
  /* Interrupt Vector 0 is the reset vector. */
  …
  #define INT0_vect_num 1
  #define INT0_vect _VECTOR(1) /* External Interrupt Request 0 */
  …
  #define TIMER0_COMPA_vect_num 14
  #define TIMER0_COMPA_vect _VECTOR(14) /* TimerCounter0 Compare Match A */
  …
Esempio: avr/interrupt.h

• La libreria avr/interrupt.h definisce i costrutti per
  poter utilizzare gli interrupt nel codice di alto
  livello (C)
    occorre specificare che una porzione di codice (una
     funzione) è una interrupt service routine (ISR) o meno
     in modo che il compilatore inserisca delle opportune
     istruzioni di salto nelle locazioni fisse associate alla
     specifica sorgente di interrupt
Esempio: avr/interrupt.h

• La libreria avr/interrupt.h mette a disposizione dei
  costrutti per specificare l’ISR relativo a ogni
  sorgente di interrupt
    vector specifica il vettore a cui si riferisce l’ISR
    a differenza di SIGNAL, il costrutto ISR permette di
     specificare funzionalità aggiuntive (abilitazione globale
     interrupt, no prologo ed epilogo) attraverso gli attributi
  /** Introduces an interrupt handler function (interrupt service routine) that runs with
  global interrupts initially disabled by default with no attributes specified.**/
  #define ISR(vector, [attributes])

  /** Introduces an ISR that runs with global interrupts initially disabled.**/
  #define SIGNAL(vector)
Esempio: avr/interrupt.h

• La libreria avr/interrupt.h tra l’altro espone
  direttamente al programmatore C
    le istruzioni di sei e cli che consentono di abilitare o
     meno gli interrupt globalmente
    l‘istruzione di reti per il ritorno da interrupt (utile quando
     si definisce un ISR senza prologo ed epilogo)
  /** Disables all interrupts by clearing the global interrupt mask.**/
  #define sei()

  /** Disables all interrupts by clearing the global interrupt mask. **/
  #define cli()

  /** Returns from an interrupt routine, enabling global interrupts. **/
  #define reti()
Indice

• Programmazione
   Flusso di Programmazione
   Librerie
• Debug
   Debugger
   Comunicazione Seriale
Debug

• Il debug di un programma sviluppato per il
  microcontrollore consiste nella sua esecuzione in
  condizioni simili a quelle reali e la verifica che il
  comportamento sia quello desiderato
• Se si verificano errori o anomalie, il programma
  viene corretto e testato nuovamente
    si procede iterativamente finché il comportamento non è
     quello desiderato per ogni condizione operativa

           SVILUPPO                          TEST
Debug

• Tipicamente i microcontrollori forniscono delle
  funzionalità di debugging
• Il debugger è un software che si connette al
  microcontrollore      per    monitorarne      il
  comportamento in tempo reale
   i principali compiti del debugger sono: connettersi alla
    scheda di sviluppo, programmare il microcontrollore,
    debuggare il programma
   talvolta il debugger richiede circuiteria addizionale
    (spesso integrata nelle schede di sviluppo)
Debug

• Il debugger solitamente ha accesso al
  microcontrollore tramite una porta dedicata che
  può supportare una o più interfacce di debug
     Joint Test Action Group (JTAG)
     Serial Wire Debug (SWD)
     Background Debug Mode (BDM)
     debugWIRE
Debug

• Strumenti del debugger
     breakpoints/watchpoints
     monitoraggio variabili
     monitoraggio registri/memorie
     monitoraggio stack
Breakpoints/Watchpoints

• I breakpoint e i watchpoint forniscono un modo
  per interrompere l’esecuzione del programma in
   in base al raggiungimento di una prefissata riga di
    codice (breakpoint)
   in base al cambiamento del valore di una variabile o di
    un’espressione (watchpoint)
• Il numero di breakpoint consentiti per
  un’esecuzione può essere limitato a seconda del
  microcontrollore
Monitoraggio Variabili

• È possibile monitorare delle variabili durante
  l’esecuzione
   le variabili monitorate possono essere lette o
    modificate quando l’esecuzione viene interrotta
• Talvolta è anche possibile monitorare espressioni
  che vengono calcolate in tempo di esecuzione
   anche in questo caso le espressioni possono essere
    lette o modificate solo quando l’esecuzione viene
    interrotta
Monitoraggio Registri/Memorie

• Spesso il debugger permette di monitorare il
  contenuto dei registri (interni alla CPU, speciali e
  relativi alle periferiche) e delle memorie presenti
  nel sistema
    è possibile monitorarne il contenuto quando
     l’esecuzione viene interrotta
    spesso è anche possibile modificarne il contenuto,
     sempre previa interruzione
Monitoraggio Stack

• Alcuni debugger consentono il monitoraggio della
  gerarchia delle chiamate attraverso l’accesso allo
  stack
   dallo stack è possibile risalire alle funzioni chiamate a
    partire dal rispettivo stack frame
   è possibile leggere il contenuto dello stack solamente
    quando l’esecuzione viene interrotta
   questa funzionalità risulta essere particolarmente utile
    nei microcontrollori che supportano il multi-threading
Indice

• Programmazione
   Flusso di Programmazione
   Librerie
• Debug
   Debugger
   Comunicazione Seriale
Comunicazione Seriale

• Al di là del debugger, uno strumento molto
  utilizzato per la verifica di un programma nei
  microcontrollori è la comunicazione seriale
• Anche se il microcontrollore non ha bisogno di
  comunicare serialmente con un’altra periferica,
  durante la fase di sviluppo si ha quasi sempre
  bisogno di utilizzare una comunicazione seriale
  per connettere il sistema all’esterno durante
  l’esecuzione
UART

• Il dispositivo hardware più utilizzato per la
  comunicazione seriale nei microcontrollori è lo
  Universal Asynchronous Receive-Transmit
  (UART)

              tx                 rx

         UART rx                 tx UART
          0                          1
             GND                 GND
USART

• I     dispositivi     Universal     Synchronous-
  Asynchronous Receive-Transmit (USART) sono
  un’evoluzione degli UART che consentono anche
  trasmissioni sincrone, ovvero temporizzate da un
  segnale di clock (raggiungono data rate maggiori)
               tx                 rx

          UART rx                 tx
                                     UART
           0 clk                  clk 1

              GND                 GND
UART

 In trasmissione, la UART converte dei dati paralleli
  (es. a 8 bit), che arrivano dal dispositivo che la controlla
  (tipicamente una CPU) in seriali (a 1 bit) per inviarli ad
  una UART ricevente
            parallel                    serial
                            UART
                       …
              input                     output

 In ricezione, la UART converte dei dati seriali (a 1 bit),
  ricevuti da una UART trasmittente, in paralleli (es. 8 bit)
  per inviarli al dispositivo che la controlla (tipicamente
  una CPU)
             serial                     parallel
                            UART
                                   …

             input                      output
Funzionamento della UART

• La UART trasmette i dati in maniera asincrona
   non è previsto nessun clock per sincronizzare la
    trasmissione
   tuttavia per consentire una corretta ricezione sono
    aggiunti dei bit di start e di stop al pacchetto di dati
    che viene trasmesso
     • i bit di start e di stop definiscono l’inizio e la fine del
       pacchetto, in modo tale che la UART ricevente sappia
       quando iniziare a leggere i bit di dato
Funzionamento della UART

• Quando la UART ricevente trova un bit di start,
  inizia a leggere i bit successivi a una frequenza
  specifica detta baud rate (bit per secondo, bps)
   entrambe le UART devono operare allo stesso baud
    rate (errore massimo del 10% tra i due baud rate)
   entrambe le UART devono anche essere configurate
    per trasmettere e ricevere lo stessa struttura del
    pacchetto dati
Funzionamento della UART
   START                DATA       PARITY    STOP
   1 bit                5-9 bit    0-1 bit   1-2 bit

• Il pacchetto dati contiene
      1 bit di start
      da 5 a 9 bit di dato
      1 bit di parità opzionale
      1 o 2 bit di stop
Funzionamento della UART
  START             DATA             PARITY     STOP
   1 bit           5-9 bit           0-1 bit    1-2 bit

• START bit
   le linee di comunicazione della UART sono
    normalmente poste a 1 (livello di voltaggio alto) quando
    non vi è una trasmissione
   quando la UART trasmittente inizia un trasferimento,
    pone la linea a 0 per un periodo di baud
   quando la UART ricevente legge uno 0 sulla linea
    inizia a leggere i bit di DATA al baud rate prestabilito
Funzionamento della UART
  START            DATA             PARITY     STOP
   1 bit           5-9 bit           0-1 bit   1-2 bit

• DATA bit
   la porzione DATA contiene i dati che vengono
    trasmessi in un certo istante
   può contenere da 5 a 8 bit se viene usato il bit di
    parità
   può contenere da 5 a 9 bit se non viene usato il bit di
    parità
   spesso il dato è trasmesso a partire da bit meno
    significativo (LSB)
Funzionamento della UART
  START                DATA               PARITY       STOP
   1 bit               5-9 bit             0-1 bit     1-2 bit

• PARITY bit
   il bit di parità costituisce un metodo di rilevazione di
    errore nella trasmissione
   gli errori sono causati da radiazioni elettromagnetiche,
    baud rate non coincidenti o distanze troppo lunghe
   il valore del PARITY bit dipende dal numero di 1 del dato
       • se il numero di 1 in DATA è pari, PARITY sarà 0
       • se il numero di 1 in DATA è dispari, PARITY sarà 1
Funzionamento della UART
  START            DATA             PARITY     STOP
   1 bit           5-9 bit          0-1 bit   1-2 bit

• STOP bit
   il bit di stop segnala la fine del pacchetto trasmesso
   lo stop viene indicato mandando la linea di
    trasmissione a 1 per 1 o 2 periodi di baud
   durante una trasmissione dunque vi è sempre un
    passaggio da 0 a 1 garantito dalla presenza dei bit di
    start e di stop
TRANSMITTED DATA

  1
  0
  1
  1
  0
  0
  1
  0
                                                  LSB

MSB
                                  SRC
                                 UART
                                tx
                                          START
                                        DATA[0]
                                        DATA[1]
                                        DATA[2]
                                        DATA[3]
                                        DATA[4]
                                        DATA[5]
                                        DATA[6]
                                        DATA[7]
                                         PARITY
      0 0 1 0 0 1 1 0 1 0 1

                                           STOP
                                rx
                                  DST
                                 UART
                                                        Funzionamento della UART

                                                  LSB

MSB
         1
         0
         1
         1
         0
         0
         1
         0

                              RECEIVED DATA
Vantaggi e Svantaggi della UART

• Vantaggi
     •   sono necessarie solamente due connessioni (tx e rx)
     •   non è necessario un segnale di clock
     •   è possibile rilevare degli errori con il bit di parità
     •   la struttura del pacchetto dati può essere modificata
• Svantaggi
     • la grandezza massima dei dati trasmessi è di 9 bit
     • non è possibile avere UART con master e/o slave multipli
     • i baud rate degli interlocutori possono differire massimo per
       un 10% dal valore nominale
UART negli AVR

• L’AVR ATmega328p integra un dispositivo
  USART con
   modalità di funzionamento asincrona o sincrona
   generatore di baud rate ad alta risoluzione
   supporto per campo dati a 5, 6, 7, 8 o 9 bit e per 1 o 2
    bit di stop
   generazione e verifica di parità
   interrupt per tx completata, registro tx vuoto e rx
    completata
   due velocità in modalità asincrona
UART negli AVR
          XCKn                             TxDn                    RxDn

                                parity                                     parity
                              generator                                    check

     baud rate
     generator
                                    Tx shift register          Tx shift register
                 oscillator

     UBRRnL/H                             UDRn Tx       UDRn      UDRn Rx

      UCSRnA                              UCSRnB                   UCSRnC

USART n

 TOVn IRQ                                                                 data bus
UART negli AVR

• Modalità di funzionamento del dispositivo USART
  nei microcontrollori AVR
   a seconda della modalità di funzionamento
    dell’USART e della frequenza operativa del
    microcontrollore, occorre settare un diverso valore di
    UBRRn per avere un certo Baud Rate (BAUD)
        operating mode          baud rate calculation       UBRRn calculation
    asynchronous normal       BAUD=fclk/(16*UBRRn+1)    UBRRn=fclk/(16*BAUD) - 1
         (U2Xn=0)
  asynchronous double speed   BAUD=fclk/(8*UBRRn+1)     UBRRn=fclk/(8*BAUD) - 1
          (U2Xn=1)
     synchronous master       BAUD=fclk/(8*UBRRn+1)     UBRRn=fclk/(8*BAUD) - 1
Baud Rate nell’ATmega328p
                                           fclk = 16 MHz
Baud Rate (bps)           U2Xn=0                                   U2Xn=1
                  UBRRn            error                   UBRRn            error
    2400          416              -0.1%                   832              0.0%
    4800          207              0.2%                    416              -0.1%
    9600          103              0.2%                    207              0.2%
    14.4k          68              0.6%                    138              -0.1%
    19.2k          51              0.2%                    103              0.2%
    28.8k          34              -0.8%                    68              0.6%
    38.4k          25              0.2%                     51              0.2%
    57.6k          16              2.1%                     34              -0.8%
    76.8k          12              0.2%                     25              0.2%
   115.2k          8               -3.5%                    16              2.1%
   230.4k          3               8.5%                     8               -3.5%
    250k           3               0.0%                     7               0.0%
    0.5M           0               0.0%                     3               0.0%
     1M            0               0.0%                     1               0.0%
UART negli AVR
                            RXB
                            TXB
    7     6      5      4         3   2     1      0

• USART I/O Data Register (UDRn)
   tramite lo stesso indirizzo mappato in memoria, è
    possibile accedere al Receive data Buffer (RXB) o al
    Transmit data Buffer (TXB) a seconda del fatto che si
    acceda rispettivamente in lettura o in scrittura
   RXB e TXB contengono il dato ricevuto e il dato da
    inviare nella comunicazione seriale
UART negli AVR
  RXCn   TXCn UDREn    FEn   DORn UPEn U2Xn      MPCMn
    7     6      5      4      3      2      1      0

• USART Control and Status Register A (UCSRnA)
   USART Receive Complete (RXCn): settato quando ci
    sono dati non letti nel registro RXB
   USART Transmit Complete (TXCn): settato quando un
    dato è stato inviato completamente e non ci sono altri
    dati da trasmettere
   USART Data Register Empty (UDREn): indica se il
    registro TXB è vuoto e quindi pronto a ricevere altri
    dati
UART negli AVR
  RXCn   TXCn UDREn     FEn   DORn UPEn U2Xn        MPCMn
    7      6      5      4      3       2      1      0

• USART Control and Status Register A (UCSRnA)
   USART Frame Error (FEn): settato quando il dato
    ricevuto nel registro RXB contiene degli errori di stop
    bit
   USART Data OverRun (DORn): settato quando è stato
    ricevuto un dato (RXB pieno e non letto) e un nuovo
    dato da ricevere è pronto sullo shifter register
   USART Parity Error (UPEn): settato quando il dato
    ricevuto nel registro RXB contiene degli errori di parità
UART negli AVR
  RXCn   TXCn UDREn    FEn   DORn UPEn U2Xn      MPCMn
    7     6      5      4      3      2      1      0

• USART Control and Status Register A (UCSRnA)
   Double the USART Transmission Speed (UX2n): ha
    effetto solo in modalità asincrona e, se settato,
    raddoppia la velocità di trasmissione
   Multi-Processor Communication Mode (MPCMn): abilita
    la modalità multi-processore (possibilità di ricezione
    da sorgenti multiple mediante indirizzamento)
UART negli AVR
  RXCIEn TXCIEn UDRIEn RXENn TXENn UCSZn2 RXB8n   TXB8n
    7     6      5      4     3      2      1       0

• USART Control and Status Register B (UCSRnB)
   RX Complete Interrupt Enable (RXCIEn): maschera di
    abilitazione dell’interrupt RX Complete
   TX Complete Interrupt Enable (TXCIEn): maschera di
    abilitazione dell’interrupt TX Complete
   USART Data Register Empty Interrupt Enable
    (UDRIEn): maschera di abilitazione dell’interrupt
    UDRE
UART negli AVR
  RXCIEn TXCIEn UDRIEn RXENn TXENn UCSZn2 RXB8n     TXB8n
      7     6      5      4      3      2      1      0

• USART Control and Status Register B (UCSRnB)
     Receive Enable (RXENn): abilita il ricevitore USART
     Transmit Enable (TXENn): abilita il trasmettitore USART
     Character Size (UCSZn2): indica il numero di bit DATA
     Receive Data Bit 8 (RXB8n): nono bit del dato ricevut
     Transmit Data Bit 8 (TXB8n): nono bit del dato
      trasmesso
UART negli AVR
  UMSELn1   UMSELn2   UPMn1     UPMn2   USBSn UCSZn1 UCSZn0        UCPOLn

    7         6         5         4       3       2           1      0

• USART Control and Status Register C (UCSRnC)
   i bit UMSEL1:0 selezionano la                              modalità     di
    funzionamento del dispositivo USART
    UMSELn1            UMSELn0                  operation mode
      0                  0                    asynchronous USART
        0                   1                 synchronous USART
        1                   0                      reserved
        1                   1                     master SPI
UART negli AVR
  UMSELn1   UMSELn2   UPMn1     UPMn2   USBSn UCSZn1 UCSZn0          UCPOLn

    7         6         5         4       3        2           1       0

• USART Control and Status Register C (UCSRnC)
   i bit UPM1:0 selezionano la                                modalità       di
    generazione/valutazione del bit di parità
    UMSELn1            UMSELn0          parity generation/validation mode
      0                  0                           disabled
        0                   1                       reserved
        1                   0                 enabled, even parity
        1                   1                  enabled, odd parity
UART negli AVR
  UMSELn1   UMSELn2   UPMn1   UPMn2   USBSn UCSZn1 UCSZn0   UCPOLn

    7         6         5       4       3     2      1        0

• USART Control and Status Register C (UCSRnC)
   Stop Bit Select (USBSn): determina il numero di bit di
    stop. Se a 0 vi sarà 1 bit di stop, se a 1 ve ne saranno 2
   Clock POLarity (UCPOLn): determina la polarità del
    clock (quando cambia il dato rispetto al periodo di
    clock) nella modalità sincrona. Se a 0 il dato trasmesso
    cambia nei fronti positivi e quello ricevuto va campionato
    in quelli negativi, se a 1 viceversa
UART negli AVR
  UMSELn1   UMSELn2   UPMn1     UPMn2   USBSn UCSZn1 UCSZn0       UCPOLn

       7      6         5         4       3     2             1     0

• USART Control and Status Register C (UCSRnC)
   i bit UCSZn2:0 selezionano il numero di bit dei dati
 UCSZn2      UCSZn1     UCSZn0                  descrizione
   0           0            0                       5-bit
   0           0            1                       6-bit
   0           1            0                       7-bit
   0           1            1                       8-bit
   1           0            0                    reserved
   1           0            1                    reserved
   1           1            0                    reserved
   1           1            1                       9-bit
Esempio: Inizializzazione UART
#include 

int freq = 16000000; // calc ubrr value
int baud = 9600;
int ubrr = freq/(16*baud) – 1;

UBRR0H = (ubrr >> 8); // set baud rate
UBRR0L = (ubrr);

// enable rx and tx
UCSR0B = (1
Esempio: Trasmissione/Ricezione UART

 #include 

 // wait till tx buffer is empty
 while( !(UCSR0A & (1
Puoi anche leggere