Existe-t-il un moyen de ne pas avoir à interroger l'UART d'un AVR?

10

Je reçois des données via UART d'un autre AVR. Cependant, je fais d'autres choses, donc je ne veux pas continuer à interroger constamment l'UART. Je sais qu'il y a des interruptions, mais je ne peux en voir qu'une pour la réception complète, ce qui, je suppose, nécessite encore que je relève pour terminer le transfert.

Adam Makin
la source
1
Pourquoi auriez-vous besoin d'interroger pour lancer un transfert? Quoi qu'il en soit, il existe également des interruptions pour l'achèvement de la transmission. Je ne suis pas très amateur d'AVR, mais ceux-ci peuvent être appelés "TX vide" ou "FIFO vide" ou seuil FIFO "ou similaire.
Eugene Sh.

Réponses:

20

Il existe des vecteurs d'interruption pour RXC et TXC (RX et TX complets) sur les AVR. Vous ne devriez jamais avoir à les interroger sauf si vous le souhaitez.

AVRFreaks a un bon article à ce sujet, tout comme le fabricant .

evildemonic
la source
3
J'allais être tout "pourquoi le lien AppNote pointe-t-il vers Microchip, c'est un produit Atmel!" Je ne peux pas croire que je n'ai jamais entendu dire que Microchip a acheté Atmel, vous vous éloignez des microcontrôleurs pendant 5 ans ...
Zac Faragher
2
@ZacFaragher NXP + Freescale + Qualcomm. Analogique + LT. ON + Fairchild. Infineon + IR. Tout cela au cours des 1-2 dernières années. Trouvez votre pire / seul concurrent puis fusionnez avec eux, à peu près.
Lundin
1
@Lundin Qualcomm NXP ne s'est pas produit et ne semble plus être activement examiné par le public . Cela pouvait encore, ou quelque chose d'autre - il y avait après tout un temps où c'était Dialog qui allait acheter Atmel.
Chris Stratton
2

La routine d'interruption stocke les données dans un tampon (un tampon circulaire avec des pointeurs put et get fonctionne bien). La boucle principale vérifie s'il y a des données dans le tampon et quand il y en a, les retire. La boucle principale peut faire d'autres choses, mais doit vérifier et supprimer les données avant que le tampon d'interruption ne déborde (lorsque le put rencontre le get).

Il ne sera pas compilé mais cela illustre la méthode.

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;
        }
}
Garenne
la source