Có cách nào để không phải thăm dò UART của một AVR không?


10

Tôi đang nhận dữ liệu qua UART từ một AVR khác. Tuy nhiên, tôi đang làm những việc khác vì vậy không muốn liên tục bỏ phiếu cho UART. Tôi biết có những gián đoạn nhưng tôi chỉ có thể thấy một để nhận được hoàn thành, mà tôi cho rằng vẫn yêu cầu tôi bỏ phiếu để hoàn thành việc chuyển tiền.


1
Tại sao bạn cần thăm dò ý kiến ​​để bắt đầu chuyển khoản? Dù sao, có những ngắt để hoàn thành truyền là tốt. Tôi không thích lắm về AVR, nhưng những cái này có thể được gọi là "TX trống" hoặc "FIFO trống" hoặc ngưỡng FIFO "hoặc tương tự.
Eugene Sh.

Câu trả lời:


20

Có các vectơ ngắt cho cả RXC và TXC (hoàn thành RX và TX) trên các AVR. Bạn không bao giờ phải bỏ phiếu cho những điều này trừ khi bạn muốn.

AVRFreaks có một bài viết hay về điều này, và nhà sản xuất cũng vậy .


3
Tôi sẽ là tất cả "tại sao liên kết AppNote trỏ đến Microchip, đó là một sản phẩm của Atmel!" Tôi không thể tin rằng tôi chưa bao giờ nghe nói rằng Microchip đã mua Atmel, bạn rời khỏi vi điều khiển trong 5 năm ...
Zac Faragher

2
@ZacFaragher NXP + Freescale + Qualcomm. Tương tự + LT. BẬT + Fairchild. Infineon + IR. Tất cả điều này trong 1-2 năm qua. Tìm đối thủ tệ nhất / duy nhất của bạn sau đó hợp nhất với họ, khá nhiều.
Lundin

1
@Lundin Qualcomm NXP đã không xảy ra và dường như không được xem xét công khai tích cực nữa. Nó vẫn có thể, hoặc một cái gì đó khác có thể - sau tất cả thời gian đó là Dialog, người sẽ mua Atmel.
Chris Stratton

2

Thường trình ngắt lưu trữ dữ liệu trong một bộ đệm (bộ đệm tròn với các con trỏ put và get hoạt động độc đáo). Vòng lặp chính kiểm tra xem có dữ liệu trong bộ đệm không và khi có, lấy nó ra. Vòng lặp chính có thể làm những việc khác nhưng cần kiểm tra và xóa dữ liệu trước khi tràn bộ đệm ngắt (khi lệnh put gặp với get).

Nó sẽ không biên dịch nhưng điều này minh họa cho phương pháp.

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;
        }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.