Gibt es eine Möglichkeit, den UART eines AVR nicht abfragen zu müssen?

10

Ich empfange Daten über UART von einem anderen AVR. Allerdings mache ich andere Sachen, also möchte ich nicht ständig den UART abfragen. Ich weiß, dass es Interrupts gibt, aber ich kann nur einen für den vollständigen Empfang sehen. Ich gehe davon aus, dass ich immer noch eine Abfrage durchführen muss, um die Übertragung abzuschließen.

Adam Makin
quelle
1
Warum müssen Sie eine Umfrage durchführen, um eine Übertragung zu initiieren? Auf jeden Fall gibt es auch Interrupts für den Abschluss der Übertragung. Ich bin nicht sehr in AVR, aber diese können als "TX leer" oder "FIFO leer" oder FIFO-Schwelle "oder ähnlich bezeichnet werden.
Eugene Sh.

Antworten:

20

Es gibt Interrupt-Vektoren für RXC und TXC (RX und TX abgeschlossen) auf AVRs. Sie sollten niemals nach diesen suchen müssen, es sei denn, Sie möchten.

AVRFreaks hat einen schönen Beitrag dazu, ebenso wie der Hersteller .

bösartig
quelle
3
Ich wollte alles sein "Warum verweist der AppNote-Link auf Microchip, es ist ein Atmel-Produkt!" Ich kann nicht glauben, dass ich nie gehört habe, dass Microchip Atmel gekauft hat. Sie treten 5 Jahre lang von Mikrocontrollern zurück ...
Zac Faragher
2
@ZacFaragher NXP + Freescale + Qualcomm. Analog + LT. ON + Fairchild. Infineon + IR. All dies in den letzten 1-2 Jahren. Finden Sie Ihren schlechtesten / einzigen Konkurrenten und verschmelzen Sie dann mit ihm.
Lundin
1
@Lundin Qualcomm NXP ist nicht aufgetreten und scheint nicht mehr in der Öffentlichkeit aktiv zu sein . Es konnte immer noch oder etwas anderes - es gab schließlich eine Zeit, in der Dialog Atmel kaufen würde.
Chris Stratton
2

Die Interrupt-Routine speichert die Daten in einem Puffer (ein Ringpuffer mit Put- und Get-Zeigern funktioniert gut). Die Hauptschleife prüft, ob sich Daten im Puffer befinden, und nimmt sie heraus, wenn sie vorhanden sind. Die Hauptschleife kann andere Aufgaben ausführen, muss jedoch die Daten überprüfen und entfernen, bevor der Interrupt-Puffer überläuft (wenn der Put mit dem Get übereinstimmt).

Es wird nicht kompiliert, aber dies veranschaulicht die Methode.

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;
        }
}
Labyrinth
quelle