ESTE: UART - Interrupts and Circular Buffer

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar

This experiment is part of this project.

Here we are going to do an experiment to aprimorate the UART and Interrupts concepts and implement a solution for problems with interrupts. In our last UART application we used the interrupts generated by the income and transmission of data on serial ports. Now we will have two types of interrupts, one for the income of data and one for the transmission of data. For that reason, in each interrupts handler we would need to deal with the income/transmission of bytes and treatment of them among other activities. But these other treatments and routines happen much more slowly when compared to data sending and incoming. Therefore we will handle all these another routines on the main program and we will use the interrupts only for the transmission/reception of bytes. We also need to store all the data we are receiving or sending by the interrupts temporarily until we handle them on the main program and thus we will use circular buffers to store the data that are going to be sent and received. But why a circular buffer? Circular buffer is extremely useful in buffering serial communication data for some reasons: it makes possible avoid data loss when processing the received data; permits memory to be reusable; is an array that wraps around – where it overwrites old data in the buffer if the microcontroller processing speed is unable to momentarily keep up with the incoming data rate; and is a FIFO (first-in-first-out) buffer. So the exercise here proposed is to send and receive bytes, from the serial port, with the interrupts and handle the data stored on buffers at the main program. To complete this experiment it is recommended to see at first the UART - Basic Interrupts script.

Pseudo code

Let's begin with a solution. The pseudo code (actual coding is up to you) is below:

// We need 2 buffers, one to store data received from serial, and another to store data that will be sent through the serial
byte rx_buf[BUFFER_SIZE];
byte tx_buf[BUFFER_SIZE];

int main(void) {
    //Configure serial to 9600 8N1
    baud_rate = 9600;
    data_len = 8;
    parity = 0;
    stop_bits = 1;

    //Implement loopback application - just remove older byte in the receive queue and enqueue it on the output buffer
    while(1) {  
        if(rx_buffer_has_data()){
            byte aux = pop(rx_buf);
            push(tx_buf, aux);
        }
    }
    return 0;
}

// Finished sending one byte
tx_interrupt_handler(){
    byte aux = pop(tx_buf);
    send(aux);
}

// Finished receiving one byte
rx_interrupt_handler(){
    byte aux = receive();
    push(rx_buf, aux);
}


Schematic

Fig. 1 Schematic of the circuit

Part List

  • 1 LED
  • 1 220 ohm resistor for the led
  • 1 Protoboard
  • 2 copper wires (tinned) or jumpers


Assembly

Fig. 2 Assembly of the circuit

Solutions

Tools

References