Table of Contents

11. 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í

Datasheet STM32F401

Referenční manuál STM32F401

Datasheet Nucleo F401RE

Podklady pro Nucleo STM32F401

Podklady pro 11. cvičení-Skalický

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