C'è un modo per non dover eseguire il polling della UART di un AVR?


10

Ricevo dati su UART da un altro AVR. Tuttavia sto facendo altre cose, quindi non voglio continuare a eseguire il polling costante di UART. So che ci sono interruzioni ma ne vedo solo una per la ricezione completa, che presumo mi richieda ancora il sondaggio per completare il trasferimento.


1
Perché dovresti effettuare il polling per avviare un trasferimento? Comunque, ci sono anche interruzioni per il completamento della trasmissione. Non mi piacciono molto gli AVR, ma questi possono essere chiamati "TX vuoto" o "FIFO vuoto" o soglia FIFO "o simili.
Eugene Sh.

Risposte:


20

Esistono vettori di interruzione per RXC e TXC (RX e TX completi) su AVR. Non dovresti mai fare sondaggi per questi a meno che tu non voglia.

AVRFreaks ha un bel post su questo, e anche il produttore .


3
Sarei stato tutto "perché il link AppNote punta a Microchip, è un prodotto Atmel!" Non riesco a credere di non aver mai sentito che Microchip ha acquistato Atmel, ti allontani dai microcontrollori per 5 anni ...
Zac Faragher,

2
@ZacFaragher NXP + Freescale + Qualcomm. Analog + LT. ON + Fairchild. Infineon + IR. Tutto questo negli ultimi 1-2 anni. Trova il tuo peggior / unico concorrente e poi fonditi con loro, praticamente.
Lundin,

1
@Lundin Qualcomm NXP non è avvenuto e non sembra più essere preso in considerazione dal pubblico . Poteva ancora, o qualcos'altro - c'era dopo tutto un tempo in cui era stato Dialog a comprare Atmel.
Chris Stratton

2

La routine di interrupt memorizza i dati in un buffer (un buffer circolare con puntatori put e get funziona bene). Il ciclo principale controlla se ci sono dati nel buffer e quando c'è, li estrae. Il ciclo principale può fare altre cose ma deve controllare e rimuovere i dati prima che il buffer di interruzione trabocchi (quando il put si incontra con il get).

Non verrà compilato ma questo illustra il metodo.

char circ_buf[BUFFER_SIZE];
int get_index, put_index;

void initialize(void) {
    get_index = 0;
    put_index = 0;
}

isr serial_port_interrupt(void) {                       // interrupt
    circ_buf[put_index++] = SERIAL_PORT_REGISTER;
    if(put_index==get_index) error("buffer overflow");  // oops
    if(put_index==BUFFER_SIZE) put_index = 0;           // circular buffer
}

void background routine(void) {
    while(put_index!=get_index) {                       // or if()
        ch = circ_buf[get_index++];
        // do something with ch
        if(get_index==BUFFER_SIZE) get_index = 0;
        }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.