T04 - UART communication

Write a program for Nucleo STM32F401RE to send and receive characters over USART.

Instructions:

  1. Send single character from Nucleo to PC, see template.
  2. Modify template to send string (word or sentence).
  3. Modify template to receive character (or more) and display it on Experimental shield.
  4. Use Putty to communicate with Nucleo

Lecture

Template

Project: usart.zip

GPIO settings

USART needs two of GPIO pins to serve as transmit and receive line. To enable it, GPIO pins mode shall be set like an alternate function.

  • GPIOx MODER: p. 157 of reference manual
  • GPIOx AFR: p. 162 of reference manual

void gpio_init (void)
{
  setbit(RCC->AHB1ENR, 0);     // Enable AHB1 clock
  setbit(GPIOA->MODER, 5);     // PA2 alternate function, 
  setbit(GPIOA->MODER, 7);     // PA3 alternate function
 
  GPIOA->AFR[0] |= 0x0700;     // alternate function, PA2 will be USART2_TX
  GPIOA->AFR[0] |= 0x7000;     // alternate function, PA3 will be USART2_RX                             
                               // see p. 45 of STM32F401xE datasheet
}                           

USART

/*
 * USART2 init
 * USART2 is connected to APB1 bus
 * USART2 uses PA2 as TX and PA3 as RX
 */
void usart_init (void)
{        
  setbit(RCC->APB1ENR, 17);    // Enable APB1 clock
  setbit(USART2->CR1, 13);     // Enable USART2
  setbit(USART2->CR1, 2);      // USART2 - enable receive
  setbit(USART2->CR1, 3);      // USART2 - enable transmit
  USART2->BRR = (104 << 4);    // USART2 baudrate,  first 4 bits are dedicated to fraction
/*
 * STM32F401 default clock is 16MHz HSI 
 * BRR ~ fclk/(8*(OVER8-2)*baudrate)
 * OVER8 reset state is 0
 * see p. 514 of STM32F401 reference manual
 */
}

USART - transmit byte

void usart_tx (unsigned char ch)  {
  // wait till transmit register is empty 7th bit of SR
  while (!readbit(USART2->SR, 7));
  USART2->DR = ch;
}

USART - receive byte

int usart_rx (unsigned char *x)
{
   // read from DR while receive register is not empty - 5th bit of SR
   if (getbit(USART2->SR, 5)) {
	   *x = USART2->DR;
	   return 1;
   }
   return 0;
}

main program

int main(void)
{
    char mess[20];
    char a;
    int i = 0;
 
    gpio_init();
    usart_init();
 
    while (1)
    {
        if (usart_rx (&a))
        {
            if (a != '\r' && a != '\n')
                mess[i++] = a;
            else 
            {
                send_string(mess, i);
                i = 0;
            }
        }
    }
}

courses/be2m37mam/tasks/task04.txt · Last modified: 2020/11/19 21:52 by viteks