Теперь печатайте на последовательном мониторе с вашего микроконтроллера, как босс (или, по крайней мере, не как любитель)

UART/USART — один из наиболее часто используемых протоколов связи наряду с I2C и SPI. UART означает универсальный асинхронный приемник/передатчик. S в USART означает синхронный.

Я не буду вдаваться в подробности того, как работает протокол, поэтому не стесняйтесь читать эту статью, чтобы получить четкое представление о том, с чем вы имеете дело. Если вы уже знаете, давайте начнем. STM32F411CEU6 — это плата, которую мы используем, но это относится ко всем устройствам STM32Fx. Блок USART в серии STM32Fx включает в себя множество подобных протоколов, таких как LIN (локальная сеть межсоединений), протокол смарт-карт и IrDA (объединение инфракрасных данных). В этом посте я расскажу об UART, а остальное настраивайте.

Кадр UART состоит из стартового бита, битов данных (8 или 9) и стоповых битов (0,5, 1, 1,5, 2). Биты данных могут быть настроены на 8 или 9, а стоповые биты на 0,5, 1, 1,5, 2. Скорость передачи данных (фактически скорость передачи данных) может быть настроена, и для нее предусмотрены специальные регистры. Аппаратное управление может быть включено.

Давайте сначала настроим блок UART. Процедура для этого указана ниже.

  • Включите USART, записав бит UE в регистр USART_CR1 в
  • Запрограммируйте бит M в USART_CR1, чтобы определить длину слова.
  • Запрограммируйте количество стоповых битов в USART_CR2.
  • Выберите желаемую скорость передачи с помощью регистра USART_BRR.
  • Установите бит TE в USART_CR1, чтобы отправить кадр ожидания в качестве первой передачи.
  • Запишите данные для отправки в регистр USART_DR (это очистит бит TXE). Повторите это для каждых данных, которые должны быть переданы в случае одного буфера.
  • После записи последних данных в регистр USART_DR подождите, пока TC=1. Это указывает на то, что передача последнего кадра завершена. Это требуется, например, когда USART отключен или переходит в режим остановки, чтобы избежать искажения последней передачи.

Мы настроим USART1 STM32F411CEU6. Контакты A9 используются как TX, а A10 — как RX. Эти контакты должны быть настроены как альтернативные функциональные двухтактные контакты, как показано ниже:

RCC -> AHB1ENR |= RCC_AHB1ENR_GPIOAEN;  
RCC -> APB2ENR |= RCC_APB2ENR_USART1EN;  
GPIOA -> MODER   |= (2 << 18) | (2 << 20); //9 -> tx 10 -> rx  
GPIOA -> OTYPER  |= (0 << 9)  | (0 << 10);  
GPIOA -> OSPEEDR |= (3 << 9)  | (3 << 10);  
GPIOA -> PUPDR   |= (0 << 18) | (0 << 20);  
GPIOA -> AFR[1]  |= (7 << 4)  | (5 << 8);

Если требуется аппаратное управление потоком,

GPIOA -> MODER   |= (2 << 22)  | (2 << 24); //11 -> CTS 12->RTS   GPIOA -> OTYPER  |= (0 << 12)  | (0 << 11);   
GPIOA -> OSPEEDR |= (3 << 12)  | (3 << 11);   
GPIOA -> PUPDR   |= (0 << 22)  | (0 << 24);   
GPIOA -> AFR[1]  |= (7 << 12)  | (5 << 16);

Теперь, чтобы настроить аппаратный блок, убедитесь, какие переменные вы хотите настроить, такие как скорость передачи данных, длина данных и стоповые биты. Наиболее распространенные настройки: скорость передачи = 9600, длина данных = 8 и стоповые биты = 1. Мы будем использовать то же самое для настройки нашего блока.

USART1 ->CR1 |= USART_CR1_UE; 
USART1 ->BRR = (int)(SystemCoreClock / (16*UART.baudrate)) << 4; USART1 -> CR2 &= ~USART_CR2_STOP;
USART1 -> CR3 &= ~USART_CR3_HDSEL;
USART1 ->CR1 |= USART_CR1_TE | USART_CR1_RE  ;

Включите блок USART1, установив бит USART_CR1_UE в регистре USART1_CR1. Чтобы установить скорость передачи данных, используйте следующую формулу:

x = PClk / (16 * desired_baud_rate)
Pclk = peripheral clock fed to the hardware block, if USART1 is used it'll be 96 MHz.
Baud_rate = can be any of the acceptable values like 9600, 115200, etc

Сдвиньте значение, полученное с помощью приведенной выше формулы, и сдвиньте влево 4 цифры, так как младшие 4 разряда регистра USART_BRR предназначены для дроби. Поместите 0 в 12-й разряд регистра USART_CR2, чтобы настроить стоповые биты. Сбросьте бит HDSEL, чтобы настроить USART в полнодуплексном режиме. Установите биты TE и RE, чтобы разрешить как передачу, так и прием данных. Это все для предварительной настройки UART.

Для передачи данных по линии TX запишите данные в регистр USART_DR, установите бит USART_CR1_SBK в регистре USART_CR1 и подождите, пока не установится USART_SR_TC.

USART1 ->DR = data; 
USART1 -> CR1 |= USART_CR1_SBK; 
while((USART1->SR & USART_SR_TC) == 0);

Чтобы получить данные по линии RX, дождитесь установки бита USART_SR_RXNE. Как только он установлен, данные доступны для чтения в регистре USART_DR.

while((USART1 ->SR & USART_SR_RXNE) == 0); 
c =  USART1-> DR;

Если вы хотите включить часы и превратить UART в USART, просто установите бит USART_CR2_CLKEN в регистре USART_CR2.

USART1 -> CR2 |= USART_CR2_CLKEN;

Точно так же, если вы хотите использовать аппаратное управление потоком, вам необходимо установить биты USART_CR3_CTSE и USART_CR3_RTSE в регистре USART_CR3.

USART1 -> CR3 |= USART_CR3_CTSE | USART_CR3_RTSE;

После того, как вы закончите написание кода для настройки, вы можете распечатать на последовательном мониторе следующее:

char *d = "Hello World! My name is Kuna Salvi and welocome to my medium post \n\r";
int x = strlen(d);
for(int i = 0; i < x; i++)
{
   USART1 ->DR = d[i]; 
   USART1 -> CR1 |= USART_CR1_SBK; 
   while((USART1->SR & USART_SR_TC) == 0);
}

Я загрузил простой и готовый к использованию драйвер на свой Github. Убедитесь, что вы разветвили его и подписались.

Следите за мной на Medium в Kunal Salvi.

Инстаграм у Ziran_Daruwala и Blackshield Engineering.

Полный код и последнюю версию можно найти на моей Странице Github.