Table of Contents

8. USART

Cíle cvičení

  1. Nastavit komunikační rozhraní USART, aby MCU mohl přijímat a odesílat data po sériové lince do PC

Co je třeba si připravit

Pro komunikaci budete potřebovat vhodný seriový terminál na PC, např. Putty.

Podklady pro cvičení

Podklady pro cvičení - Skalický

Datasheet STM32F401

Referenční manuál STM32F401

Datasheet Nucleo F401RE

Podklady pro Nucleo STM32F401

Projekty

mam-usart.zip

Kódy pro cvičení

Konfigurace GPIO

USART dva GPIO piny, které slouží jako vysílací (Tx) a přijímací (Rx). Kromě standardního nastavení je třeba nastavit mód příslušných GPIO pinů jako alternativní funkce.

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
}                           

Inicializace 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
 * baudrate: 9600
 */
}

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

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