完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
串口数据收发(轮询)初始化步骤:
第一步:调用HAL_UART_Init函数初始化串口参数,函数如下: HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart); 函数传入结构参数如下: typedef struct { USART_TypeDef *Instance; // 传入串口的基地址 UART_InitTypeDef Init; // 传入串口初始化参数,波特率、奇偶校验等 uint8_t *pTxBuffPtr; // 传入串口发送缓冲区地址 uint16_t TxXferSize; // 传入串口发送缓冲区大小 __IO uint16_t TxXferCount; // 传入串口发送缓冲区数据个数 uint8_t *pRxBuffPtr; // 传入串口发送缓冲区地址 uint16_t RxXferSize; // 传入串口接收缓冲区大小 __IO uint16_t RxXferCount; // 传入串口接收缓冲区数据个数 DMA_HandleTypeDef *hdmatx; // 当串口使用DMA传输时,传入发送引脚TX的DMA初始化配置参数 DMA_HandleTypeDef *hdmarx; // 当串口使用DMA传输时,传入接收引脚RX的DMA初始化配置参数 HAL_LockTypeDef Lock; // 锁定对象 __IO HAL_UART_StateTypeDef gState; // 当前串口Tx引脚状态信息 __IO HAL_UART_StateTypeDef RxState; // 当前串口Rx引脚状态信息 __IO uint32_t ErrorCode; // 串口错误代码 }UART_HandleTypeDef; 第二步、重定义HAL_UART_MspInit函数初始化,初始化串口硬件参数。当调用HAL_UART_Init串口初始化函数时,该函数内部会调用HAL_UART_MspInit函数,用来初始化串口使用到的引脚。这实际是HAL库的一个优点,它通过开放一个回调函数HAL_UART_MspInit,让用户自己去编写与串口有关的硬件初始化,而与串口相关的参数配置则放在HAL_UART_Init函数中,这样当我们移植程序到别的STM32平台时,使用串口只需要修改HAL_UART_MspInit函数中配置即可。 第三步、调用串口接收数据库函数HAL_UART_Receive(),实现功能如下: ①.函数传入4个参数,分别为串口初始化结构体参数UART_HandleTypeDef、接收数据缓冲区地址pData、接收数据缓冲区宽度Size、和接收数据最大等待时间。 ②. 函数中首先初始化结构体UART_HandleTypeDef里面错误代码变量“ErrorCode”,接收数据缓冲区大小“RxXferSize”等变量。 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) { uint16_t* tmp; uint32_t tickstart = 0U; /* Check that a Rx process is not already ongoing */ if(huart->RxState == HAL_UART_STATE_READY) { if((pData == NULL ) || (Size == 0)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(huart); huart->ErrorCode = HAL_UART_ERROR_NONE; huart->RxState = HAL_UART_STATE_BUSY_RX; /* Init tickstart for timeout managment */ tickstart = HAL_GetTick(); huart->RxXferSize = Size; huart->RxXferCount = Size; ③.接下来根据初始化的接收数据个数变量进行while循环,循环中接收个数递减。 ④.接下来根据串口初始化的接收数据个数、有无奇偶校验等参数来初始化临时存储数据变量pData。 ⑤.在while循环中,调用UART_WaitOnFlagUntilTimeout函数,根据接收数据寄存器非空标志位(UART_FLAG_RXNE:当RDR移位寄存器的内容转移到USART_DR寄存器时,硬件将设置此位)状态位依次接收每个字节数据,并判断等待每个字节是否超出溢出时间,如果未超过定义的等待时间,则将数据存储到pData变量中,否则返回错误状态HAL_TIMEOUT。 /* Check the remain data to be received */ while(huart->RxXferCount > 0U) { huart->RxXferCount--; if(huart->Init.WordLength == UART_WORDLENGTH_9B) { if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) { return HAL_TIMEOUT; } tmp = (uint16_t*) pData; if(huart->Init.Parity == UART_PARITY_NONE) { *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF); pData +=2U; } else { *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF); pData +=1U; } } else { if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) { return HAL_TIMEOUT; } if(huart->Init.Parity == UART_PARITY_NONE) { *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF); } else { *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F); } } } 3、调用串口发送数据库函数HAL_UART_Transmit(),函数实现与HAL_UART_Receive类似,请参考上面函数。 串口数据收发bsp_uart.c完整程序如下: #include "bsp_uart.h" UART_HandleTypeDef UART1_Handler; //UART 句柄 // 初始化串口函数 void UART_Init(void) { UART1_Handler.Instance = USART1; // 串口1 UART1_Handler.Init.BaudRate = 115200; // 波特率 UART1_Handler.Init.HwFlowCtl = UART_HWCONTROL_NONE; // 无硬件流控 UART1_Handler.Init.Mode = UART_MODE_TX_RX; // 收发模式 UART1_Handler.Init.Parity = UART_PARITY_NONE; // 无奇偶校验 UART1_Handler.Init.StopBits = UART_STOPBITS_1; // 一个停止位 UART1_Handler.Init.WordLength = UART_WORDLENGTH_8B; // 字长为8位格式 HAL_UART_Init(&UART1_Handler); // 初始化串口 } // 初始化低级硬件 void HAL_UART_MspInit(UART_HandleTypeDef *huart) { if(huart->Instance == USART1) { GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOA_CLK_ENABLE(); // 使能GPIO引脚 __HAL_RCC_USART1_CLK_ENABLE(); // 使能串口 GPIO_Initure.Mode = GPIO_MODE_AF_PP; // 复用推挽模式 GPIO_Initure.Pin = GPIO_PIN_9|GPIO_PIN_10; // PA9、PA10 GPIO_Initure.Pull = GPIO_PULLUP; //上拉 GPIO_Initure.Speed = GPIO_SPEED_FAST; //高速 GPIO_Initure.Alternate = GPIO_AF7_USART1; // 复用为 USART1 HAL_GPIO_Init(GPIOA, &GPIO_Initure); // 初始化 PA9、PA10 } } void UART_Transmit(uint8_t *pData, uint16_t Size) { HAL_UART_Transmit(&UART1_Handler, pData, Size, HAL_MAX_DELAY); } void UART_Receive(uint8_t *pData, uint16_t Size) { HAL_UART_Receive(&UART1_Handler, pData, Size, HAL_MAX_DELAY); } 主函数程序如下: uint8_t buffer[10]; int main(void) { CLOCLK_Init(); // 配置系统时钟为168M UART_Init(); while(1) { UART_Receive(buffer, 5); UART_Transmit(buffer, 5); } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1935浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
728浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
568浏览 3评论
593浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
551浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 15:10 , Processed in 0.844311 second(s), Total 47, Slave 41 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号