有没有一种方法不必轮询AVR的UART?


10

我正在通过UART从另一个AVR接收数据。但是我在做其他事情,所以不想一直不断轮询UART。我知道有中断,但只能看到一个要接收的中断,我认为仍然需要轮询才能完成传输。


1
您为什么需要轮询才能开始转移?无论如何,也有中断来完成传输。我不太喜欢AVR,但可以将其称为“ TX空”或“ FIFO空”或FIFO阈值”或类似名称
Eugene Sh。19年

Answers:


20

AVR上有用于RXC和TXC的中断向量(RX和TX完成)。除非您愿意,否则您不必轮询这些。

AVRFreaks 在此方面有不错的文章制造商也是如此。


3
我全是“为什么AppNote链接指向Microchip,这是Atmel产品!” 我不敢相信我从未听说过Microchip收购了Atmel,您离开微控制器已有5年了……
Zac Faragher

2
@ZacFaragher NXP + Freescale + Qualcomm。模拟+ LT。开+童话。英飞凌+ IR。所有这些在过去的1-2年中。找到最糟糕/唯一的竞争对手,然后与他们合并。
伦丁

1
@Lundin Qualcomm NXP尚未发生,并且似乎不再受到公众的积极考虑。它仍然可能,或者还有其他可能-曾经有一次Dialog打算收购Atmel。
克里斯·斯特拉顿

2

中断例程将数据存储在缓冲区中(带有put和get指针的循环缓冲区很好地工作)。主循环检查缓冲区中是否有数据,何时将其取出。主循环可以做其他事情,但是需要在中断缓冲区溢出之前(当put与get相遇时)检查并删除数据。

它不会编译,但这说明了该方法。

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;
        }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.