USART в stm32

Когда речь заходит об интерфейсах передачи данных, USART (в народе S часто упускают) — самая нужная штуковина. Благодаря ему разработчики имеют возможность организовать передачу данных по интерфейсам RS-232, RS-485 и даже 1-Wire.

USART (Universal Synchronous/Asynchronous Receiver/Transmitter) — универсальный синхронный/асинхронный (вот тут и зарыт секрет буквы S) приемопередатчик.

Как может пригодиться USART начинающему радиолюбителю?

Вы можете организовать передачу данных на ваш компьютер, через COM порт. Используя простую терминальную утилиту, вы получаете возможность просматривать данные полученные контроллером и отправлять управляющие сигналы в него.
Если же у вас нет COM порта можете воспользоваться переходником на основе микросхемы ft232.
Все проще чем разбираться с километровыми спецификациями USB. Конечно их знание весомый плюс, но новичку в них разобраться ох как сложно.

Использование USART в stm32

В контроллерах stm32 модулей USART целая туча. Вы можете пользоваться любым. Я покажу на примере USART1.
Весь код будет построен на основе библиотеки от ST.

Для работы подключаем такие модули библиотеки:

#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_usart.h"

Объявим две структуры для хранения настроек периферии.

//Структуры для инициализации GPIOA и USART1
GPIO_InitTypeDef    GPIO_InitStruct;
USART_InitTypeDef    USART_InitStruct;

Прототипы функций:

void Usart1_Init(void); //Объявление функции инициализации периферии
void Usart1_Send_symbol(uint8_t); //Объявление функции передачи символа
void Usart1_Send_String(char* str); //Объявление функции передачи строки

Функция инициализации USART1:

void Usart1_Init() {
  //Включаем тактирование GPIOA, USART1
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

  //Инициализация вывода PA9 - USART1_Tx
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; //Настройки вывода PA9
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // скорость порта
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // режим альтернативной функции
  GPIO_Init(GPIOA, &GPIO_InitStruct); // заданные настройки сохраняем в регистрах GPIOА

  //Инициализация вывода PA10 - USART1_Rx
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; // настройки вывода PA10
  GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF; // режим альтернативной функции
  GPIO_Init(GPIOA, &GPIO_InitStruct); // заданные настройки сохраняем в регистрах GPIOА

  GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
  GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);

  //Инициализация USART1
  USART_InitStruct.USART_BaudRate = 1200; // скорость обмена 1200 бод
  USART_InitStruct.USART_WordLength = USART_WordLength_8b; // длина слова 8 бит
  USART_InitStruct.USART_StopBits = USART_StopBits_1; // 1 стоп-бит
  USART_InitStruct.USART_Parity = USART_Parity_No ; // без проверки четности
  USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // без аппаратного контроля
  USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // включен передатчик и приемник USART1
  USART_Init(USART1, &USART_InitStruct); // заданные настройки сохраняем в регистрах USART1

  USART_Cmd(USART1, ENABLE); // включаем USART1
}

Функция передачи байта через USART:

void Usart1_Send_symbol(uint8_t data) {
  while(!(USART1->SR & USART_SR_TC)); // проверяем установку флага TC - завершения предыдущей передачи
  USART1->DR = data; // записываем значение в регистр данных - передаем символ
}

Фунция передачи строки через USART:

void Usart1_Send_String(char* str) {
  uint8_t i=0;
  while(str[i]) {
    Usart1_Send_symbol(str[i]);
    i++;
  }
  // передаем сивол конца строки
  Usart1_Send_symbol('\n');
  Usart1_Send_symbol('\r');
}

Для использования необходимо провести инициализацию соответствующей функцией и отправить нужные байты.

int main() {
  Usart1_Init(); //Вызов функции инициализации периферии

  //Передаем строку, сообщающую о готовности микроконтроллера к обмену данными
  Usart1_Send_String("I'm ready!");

  while(1) {

  }
}

Как видите ничего страшного. Даже профан может разобраться с этим.
Тут рассмотрен простейший вариант асинхронного передатчика. В реальной задаче могут понадобиться еще много дополнительных сигналов, которые делают передачу более надежной и быстрой.
На практике считается нормальной скорость в 9600 бод. Но я «на коленке» не сумел получить стабильную передачу на скорости выше 2400.

Также очень часто используют прерывания по наявности принимаемых данных, но это уже другая история.
Для приема данных через USART нужна функция подобная функции отправки, только вместо проверки флага завершения передачи необходимо проверить флаг наявности данных.

uint8_t Usart1_Get_symbol () {
        while((USART1->SR & USART_SR_RXNE)==0) {}//ожидание приема
        return USART1->DR;                        //прочитать принятый байт
}

Вот так выглядит эта функция.

А это результат выполнения описанной программы.

 

Похожий код:

Фото аватара
Алексей Петров

Программист, разработчик с 5 летним опытом работы. Учусь на разработчика игр на Unity и разработчика VR&AR реальности (виртуальной реальности). Основные языки программирования: C#, C++.

Оцените автора
Бла, бла код
Добавить комментарий

  1. Евгений

    интересно

    Ответить