PROGCONT.RU

Форма входа







Регистрпция Вход/

STM32F USART настрой и использование с помощью SPL.

В статье я опишу как настроить USART и использовать для приёма-передачи данных а так же подключить к выводам контроллера используя функцию переназначения(Remap). Если кто не знает в чём различие между UART и USART это наличие у последнего возможности использования дополнительной линии для синхронизации передачи данных, а так они одинаковы.

Для примера я буду использовать популярный контроллер STM32f103C8, USB-UART на чипе CH340G переходник(преобразователь) и свою программу UART терминал-помощник(скачать можно в разделе программы).

Первым делом нужно разобраться с подключением или сопряжением двух устройств, основное условие это то, что каждое устройство должно обеспечить подтяжку своей линии RX через резистор к питанию в моём случае микросхема CH340G обеспечивает внутрисхемную подтяжку как линии RX так и TX, подтягивающие резисторы не нужны.

Схема подключения обычное(Default) и к дополнительным выводам через перенаправление(Remap) а также пример соединение двух контроллеров на примере USART2 и USART3.

NO

Пример настройки для обычного подключения, к выводам по умолчанию.

#include "stm32f10x.h" int main(){ RCC_DeInit(); RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1| RCC_APB2Periph_GPIOA, ENABLE); /*Настройка выводов контроллера для USART.*/ GPIO_InitTypeDef gpio_uart; gpio_uart.GPIO_Mode=GPIO_Mode_AF_OD; gpio_uart.GPIO_Pin=GPIO_Pin_9; gpio_uart.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init( GPIOA,&gpio_uart); gpio_uart.GPIO_Mode=GPIO_Mode_IN_FLOATING; gpio_uart.GPIO_Pin=GPIO_Pin_10; GPIO_Init( GPIOA,&gpio_uart); /*Настройка самого USART.*/ USART_InitTypeDef settings_UART1; settings_UART1.USART_BaudRate=9600; settings_UART1.USART_HardwareFlowControl=USART_HardwareFlowControl_None; settings_UART1.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; settings_UART1.USART_Parity=USART_Parity_No; settings_UART1.USART_StopBits=USART_StopBits_1; settings_UART1.USART_WordLength=USART_WordLength_8b; USART_Init(USART1,&settings_UART1); USART_Cmd(USART1, ENABLE); while(1){} return 0; }


Для подключения через переназначение нам нужно знать какие выводы контроллера являются альтернативными, смотрим Datasheets.

NO

Пример перенаправления выводов и настройки USART.

#include "stm32f10x.h" int main(){ RCC_DeInit(); RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1| RCC_APB2Periph_GPIOB| RCC_APB2Periph_AFIO, ENABLE); GPIO_InitTypeDef gpio_uart; gpio_uart.GPIO_Mode=GPIO_Mode_AF_OD; gpio_uart.GPIO_Pin=GPIO_Pin_6; gpio_uart.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init( GPIOB,&gpio_uart); gpio_uart.GPIO_Mode=GPIO_Mode_IN_FLOATING; gpio_uart.GPIO_Pin=GPIO_Pin_7; GPIO_Init( GPIOB,&gpio_uart); /*Переназначаем выводы USART.*/ GPIO_PinRemapConfig( GPIO_Remap_USART1, ENABLE); USART_InitTypeDef settings_UART1; settings_UART1.USART_BaudRate=9600; settings_UART1.USART_HardwareFlowControl=USART_HardwareFlowControl_None; settings_UART1.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; settings_UART1.USART_Parity=USART_Parity_No; settings_UART1.USART_StopBits=USART_StopBits_1; settings_UART1.USART_WordLength=USART_WordLength_8b; USART_Init(USART1,&settings_UART1); USART_Cmd(USART1, ENABLE); while(1){} return 0; }


Пример подключения двух микросхем через USART, у меня будут соединены USART2 и USART3 данного контроллера.

#include "stm32f10x.h" int main(){ RCC_DeInit(); RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA| RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2| RCC_APB1Periph_USART3, ENABLE); GPIO_InitTypeDef gpio_uart; gpio_uart.GPIO_Mode=GPIO_Mode_AF_OD; gpio_uart.GPIO_Pin=GPIO_Pin_2; gpio_uart.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init( GPIOA,&gpio_uart); gpio_uart.GPIO_Pin=GPIO_Pin_10; GPIO_Init( GPIOB,&gpio_uart); /*Выводы RX подтянуты к питанию.*/ gpio_uart.GPIO_Mode=GPIO_Mode_IPU; gpio_uart.GPIO_Pin=GPIO_Pin_3; GPIO_Init( GPIOA,&gpio_uart); gpio_uart.GPIO_Pin=GPIO_Pin_11; GPIO_Init( GPIOB,&gpio_uart); USART_InitTypeDef settings_UART; settings_UART.USART_BaudRate=9600; settings_UART.USART_HardwareFlowControl=USART_HardwareFlowControl_None; settings_UART.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; settings_UART.USART_Parity=USART_Parity_No; settings_UART.USART_StopBits=USART_StopBits_1; settings_UART.USART_WordLength=USART_WordLength_8b; USART_Init(USART2,&settings_UART); USART_Cmd(USART2, ENABLE); USART_Init(USART3,&settings_UART); USART_Cmd(USART3, ENABLE); while(1){} return 0; }

Отправка и приём данных через USART.

Тут будем пробовать отправлять и принимать данные, для этого качаем мою программу UART терминал-помощник, устанавливаем и подключаем наш контроллер через USB-URAT конвертер к компьютеру.

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

#include "stm32f10x.h" int main(){ RCC_DeInit(); RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1| RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef gpio_uart; gpio_uart.GPIO_Mode=GPIO_Mode_AF_OD; gpio_uart.GPIO_Pin=GPIO_Pin_9; gpio_uart.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init( GPIOA,&gpio_uart); gpio_uart.GPIO_Mode=GPIO_Mode_IN_FLOATING; gpio_uart.GPIO_Pin=GPIO_Pin_10; GPIO_Init( GPIOA,&gpio_uart); USART_InitTypeDef settings_UART1; settings_UART1.USART_BaudRate=9600; settings_UART1.USART_HardwareFlowControl=USART_HardwareFlowControl_None; settings_UART1.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; settings_UART1.USART_Parity=USART_Parity_No; settings_UART1.USART_StopBits=USART_StopBits_1; settings_UART1.USART_WordLength=USART_WordLength_8b; USART_Init(USART1,&settings_UART1); USART_Cmd(USART1, ENABLE); while(1){ /*Проверяем наличие принятых данных.*/ if(USART_GetFlagStatus( USART1, USART_FLAG_RXNE)){ /*Читаем данные и после этого сам сбрасывается флаг приёма данных.*/ uint16_t data = USART_ReceiveData(USART1); /*Отвечаем, отсылаем обратно принятый байт данных.*/ USART_SendData(USART1, (uint8_t)(data)); while(!USART_GetFlagStatus( USART1, USART_FLAG_TXE)); } } return 0; }Для сброса флага принятого байта данных нужно прочесть принимающий регистр функцией uint16_t USART_ReceiveData(USART_TypeDef* USARTx); или самостоятельно сбросить функцией USART_ClearFlag( USART_TypeDef* USARTx, USART_FLAG_RXNE);.При отправке данных особенно циклическим методом обязательно ждите пока освободится сдвиговой регистр кодом while(!USART_GetFlagStatus( USART1, USART_FLAG_TXE));, иначе контроллер может не успеть отправить данные и вы их перепишите.


И последний пример отправки и приёма данных в прерывании. Программа будет принимать пять байт данных и отправлять их обратно.

#include "stm32f10x.h" /*Массив для отправки данных и его счётчик. */ uint8_t send_data[5]; uint16_t count_dataSend=0; /*Массив для приёма данных и его счётчик.*/ uint8_t received_data[5]; uint16_t count_dataReceived=0; int main(){ RCC_DeInit(); RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1| RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef gpio_uart; gpio_uart.GPIO_Mode=GPIO_Mode_AF_OD; gpio_uart.GPIO_Pin=GPIO_Pin_9; gpio_uart.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init( GPIOA,&gpio_uart); gpio_uart.GPIO_Mode=GPIO_Mode_IN_FLOATING; gpio_uart.GPIO_Pin=GPIO_Pin_10; GPIO_Init( GPIOA,&gpio_uart); USART_InitTypeDef settings_UART1; settings_UART1.USART_BaudRate=9600; settings_UART1.USART_HardwareFlowControl=USART_HardwareFlowControl_None; settings_UART1.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; settings_UART1.USART_Parity=USART_Parity_No; settings_UART1.USART_StopBits=USART_StopBits_1; settings_UART1.USART_WordLength=USART_WordLength_8b; USART_Init(USART1,&settings_UART1); USART_ClearFlag( USART1, USART_FLAG_RXNE); USART_ITConfig( USART1, USART_IT_RXNE, ENABLE); /*Включаем прерывание.*/ NVIC_EnableIRQ( USART1_IRQn); USART_Cmd(USART1, ENABLE); while(1){ /*Если принято 5 байт данных то отсылаем их обратно.*/ if( count_dataReceived == 5 ){ /*Переписываем счётчик отправляемых данных и массив для отправки данных.*/ count_dataSend = count_dataReceived; for( uint16_t count = 0; count != count_dataReceived; count++ ){ send_data[count] = received_data[count];}// count_dataReceived = 0; /*Включаем прерывание если пустой регистр отправки данных.*/ USART_ITConfig( USART1, USART_IT_TXE, ENABLE); } } return 0; } /*Обработчик прерываний USART приёма и отправки данных.*/ void USART1_IRQHandler(){ /*Принимаем данные и копируем их в массив.*/ if( USART_GetFlagStatus( USART1, USART_FLAG_RXNE )){ received_data[ count_dataReceived ] = USART_ReceiveData( USART1 ); count_dataReceived++; } /*Отправка данных, после отправки всех данных выключаем прерывание.*/ if( count_dataSend > 0 ){ /*Данные отправляются в обратном порядке.*/ USART_SendData( USART1, (uint8_t)( count_dataSend)); count_dataSend--; if(count_dataSend == 0){ USART_ITConfig( USART1, USART_IT_TXE, DISABLE);} } }

Комментариев нет  Только зарегистрированные пользователи могут оставлять комментарии!