Когда речь заходит об интерфейсах передачи данных, 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; //прочитать принятый байт }
Вот так выглядит эта функция.
А это результат выполнения описанной программы.
интересно