10
\$\begingroup\$

I'm receiving data over UART from another AVR. However I'm doing other stuff so don't want to have constantly keep polling the UART. I know there are interrupts but I can only see one for receive complete, which I assume still requires me to poll to complete the transfer.

\$\endgroup\$
  • 1
    \$\begingroup\$ Why would you need to poll to initiate a transfer? Anyway, there are interrupts for transmission completion as well. I am not very into AVR, but these can be called "TX empty" or "FIFO empty" or FIFO threshold" or similar. \$\endgroup\$ – Eugene Sh. Feb 25 at 18:21
20
\$\begingroup\$

There are interrupt vectors for both RXC and TXC (RX and TX complete) on AVRs. You should never have to poll for these unless you want to.

AVRFreaks has a nice post on this, and so does the manufacturer.

\$\endgroup\$
  • 3
    \$\begingroup\$ I was gonna be all "why does the AppNote link point to Microchip, it's an Atmel product!" I can't believe I never heard that Microchip bought Atmel, you step away from microcontrollers for 5 years... \$\endgroup\$ – Zac Faragher Feb 26 at 3:50
  • 2
    \$\begingroup\$ @ZacFaragher NXP+Freescale+Qualcomm. Analog+LT. ON+Fairchild. Infineon+IR. All this in the past 1-2 years. Find your worst/only competitor then merge with them, pretty much. \$\endgroup\$ – Lundin Feb 26 at 14:16
  • 1
    \$\begingroup\$ @Lundin Qualcomm NXP has not happened, and does not appear to be under active public consideration any more. It could still, or something else could - there was after all a time when it was Dialog who was going to buy Atmel. \$\endgroup\$ – Chris Stratton Mar 1 at 18:14
2
\$\begingroup\$

The interrupt routine stores the data in a buffer (a circular buffer with put and get pointers works nicely). The main loop checks to see if there is data in the buffer and when there is, takes it out. The main loop can do other things but needs to check and remove the data before the interrupt buffer overflows (when the put meets up with the get).

It won't compile but this illustrates the method.

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;
        }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.