Чи є спосіб, щоб не довелося опитувати UART AVR?


10

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


1
Навіщо вам потрібно опитуватись, щоб ініціювати передачу? У будь-якому випадку, є і перерви для завершення передачі. Я не дуже в AVR, але це можна назвати "TX порожнім" або "FIFO порожнім" або FIFO поріг "або подібне.
Євген Ш.,

Відповіді:


20

Існують вектори переривань як для RXC, так і для TXC (RX і TX завершено) на AVR. Вам ніколи не доведеться опитувати їх, якщо ви цього не хочете.

AVRFreaks має хороший пост з цього приводу, як і виробник .


3
Я збирався бути всім "чому посилання AppNote вказує на Microchip, це продукт Atmel!" Я не можу повірити, що я ніколи не чув, щоб Microchip купував Atmel, ви відходили від мікроконтролерів протягом 5 років ...
Зак Фарагер

2
@ZacFaragher NXP + Freescale + Qualcomm. Аналоговий + LT. ON + Fairchild. Інфінеон + ІЧ. Все це за останні 1-2 роки. Знайдіть свого найгіршого / єдиного конкурента, а потім злитеся з ними.
Лундін

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

2

Процедура переривання зберігає дані в буфері (круговий буфер з покажчиками put and 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;
        }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.