Есть ли способ не опрашивать UART AVR?


10

Я получаю данные через UART от другого AVR. Однако я занимаюсь другими вещами, поэтому не хочу постоянно опрашивать UART. Я знаю, что есть прерывания, но я вижу только одно для получения завершения, которое, я полагаю, все еще требует от меня опроса, чтобы завершить передачу.


1
Зачем вам нужно опросить, чтобы инициировать перевод? Во всяком случае, есть прерывания и для завершения передачи. Я не очень люблю AVR, но их можно назвать «пустой TX», «пустой FIFO» или «порог FIFO» или что-то подобное.
Евгений Ш.

Ответы:


20

На AVR есть векторы прерываний как для RXC, так и для TXC (завершены RX и TX). Вы никогда не должны опрашивать их, если вы не хотите.

У AVRFreaks есть хороший пост на эту тему, как и у производителя .


3
Я хотел сказать: «Почему ссылка AppNote указывает на Microchip, это продукт Atmel!» Я не могу поверить, что я никогда не слышал, что Microchip купил Atmel, вы отошли от микроконтроллеров на 5 лет ...
Зак

2
@ZacFaragher NXP + Freescale + Qualcomm. Аналоговый + LT. ON + Fairchild. Infineon + IR. Все это в последние 1-2 года. Найдите своего худшего / единственного конкурента, а затем объединитесь с ним.
Лундин

1
@Lundin Qualcomm NXP не произошло, и, похоже, больше не находится под активным общественным рассмотрением. Это могло все еще, или что-то еще могло - в конце концов, было время, когда Диалог собирался купить Atmel.
Крис Страттон

2

Подпрограмма прерывания сохраняет данные в буфере (круговой буфер с указателями put и get отлично работает). Основной цикл проверяет, есть ли данные в буфере и, если они есть, удаляет их. Основной цикл может выполнять другие действия, но ему необходимо проверять и удалять данные до того, как буфер прерываний переполнится (когда пут встречается с 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;
        }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.