Apakah ada cara untuk tidak harus melakukan polling terhadap UART AVR?

10

Saya menerima data melalui UART dari AVR lain. Namun saya sedang melakukan hal-hal lain jadi saya tidak ingin terus-menerus memilih UART. Saya tahu ada interupsi, tetapi saya hanya bisa melihat satu untuk menerima lengkap, yang saya anggap masih mengharuskan saya untuk polling untuk menyelesaikan transfer.

Adam Makin
sumber
1
Mengapa Anda perlu polling untuk melakukan transfer? Lagi pula, ada gangguan untuk penyelesaian transmisi juga. Saya tidak terlalu suka AVR, tetapi ini bisa disebut "TX empty" atau "FIFO empty" atau FIFO threshold "atau serupa
Eugene Sh.

Jawaban:

20

Ada vektor interupsi untuk RXC dan TXC (RX dan TX complete) pada AVR. Anda tidak harus melakukan polling untuk ini kecuali Anda mau.

AVRFreaks memiliki postingan yang bagus tentang ini, dan begitu pula produsennya .

jahat
sumber
3
Saya akan menjadi semua "mengapa tautan AppNote mengarah ke Microchip, ini adalah produk Atmel!" Saya tidak percaya saya tidak pernah mendengar bahwa Microchip membeli Atmel, Anda menjauh dari mikrokontroler selama 5 tahun ...
Zac Faragher
2
@ZacFaragher NXP + Freescale + Qualcomm. Analog + LT. ON + Fairchild. Infineon + IR. Semua ini dalam 1-2 tahun terakhir. Temukan pesaing terburuk / satu-satunya Anda kemudian bergabung dengan mereka, cukup banyak.
Lundin
1
@Lundin Qualcomm NXP belum terjadi, dan tampaknya tidak lagi dipertimbangkan publik . Masih bisa, atau sesuatu yang lain bisa - ada saat ketika Dialog yang akan membeli Atmel.
Chris Stratton
2

Interupsi rutin menyimpan data dalam buffer (buffer melingkar dengan put dan get pointer berfungsi dengan baik). Loop utama memeriksa untuk melihat apakah ada data di buffer dan ketika ada, mengeluarkannya. Loop utama dapat melakukan hal-hal lain tetapi perlu memeriksa dan menghapus data sebelum buffer overflow meluap (ketika put bertemu dengan get).

Itu tidak akan dikompilasi tetapi ini menggambarkan metode.

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;
        }
}
Warren
sumber