11 votos

¿Hay alguna manera de no tener que sondear la UART de un AVR?

Estoy recibiendo datos por UART desde otro AVR. Sin embargo, estoy haciendo otras cosas así que no quiero tener constantemente el sondeo de la UART. Sé que hay interrupciones, pero sólo puedo ver una para la recepción completa, que supongo que todavía me requiere para sondear para completar la transferencia.

1 votos

¿Por qué hay que hacer una encuesta para iniciar una transferencia? De todos modos, también hay interrupciones para la finalización de la transmisión. No estoy muy metido en el AVR, pero pueden llamarse "TX empty" o "FIFO empty" o FIFO threshold" o similares.

20voto

Adam Puntos 126

Existen vectores de interrupción para RXC y TXC (RX y TX completos) en los AVR. Nunca deberías tener que hacer un sondeo para estos a menos que quieras.

AVRFreaks tiene un buen post sobre esto, y también lo hace el fabricante .

3 votos

Iba a decir "¿por qué el enlace de AppNote apunta a Microchip, es un producto de Atmel?". No puedo creer que nunca escuché que Microchip compró Atmel, te alejas de los microcontroladores durante 5 años...

3 votos

@ZacFaragher NXP+Freescale+Qualcomm. Analog+LT. ON+Fairchild. Infineon+IR. Todo esto en los últimos 1-2 años. Encuentra a tu peor/único competidor y luego fúndete con él, más o menos.

2 votos

@Lundin Qualcomm NXP no ha pasado, y no parece estar en activo público consideración más. Todavía podría, o algo más podría - después de todo hubo un tiempo en el que era Dialog quien iba a comprar Atmel.

3voto

farina Puntos 1166

La rutina de interrupción almacena los datos en un buffer (un buffer circular con punteros put y get funciona bien). El bucle principal comprueba si hay datos en el buffer y cuando los hay, los saca. El bucle principal puede hacer otras cosas pero necesita comprobar y eliminar los datos antes de que el buffer de interrupción se desborde (cuando el put se encuentra con el get).

No compilará, pero esto ilustra el método.

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

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X