使用stm32的hal库完成接受不定长的数据

本文详细介绍了如何在STM32单片机上使用STM32CubeMX配置USART1进行异步通信,并利用DMA提高CPU效率,设置中断处理接收数据并通过串口发送。最后,展示了如何在Keil中编写代码并测试接收功能。

使用软件:STM32CubeMX

                   keil

        首先打开STM32CubeMX,创建一个新的工程项目,我是用的单片机是stm32f108c8t6,创建好项目后,我们就可以设置stm32的引脚和其他选项了。首先点击RCC,将High Speed Clock选择下图中的选项,这个选项是设置系统的时钟。

        接着我们可以选择Connectivity选项卡里的USART1,将Mode设置为异步通信(Asynchronous) 。在Parameter Setting选项中我们可以对波特率,字节长度,校验位和停止位进行设置,这里我们使用默认配置。

 

        这里我们使用的是DMA及直接存储器访问,使用这种方式可以大大提高cpu的效率。选择DMA Setting选项,点击Add添加USART1_RX和USART1_TX,其他设置默认。

        接着选择NVIC Setting(中断设置),因为在我们完成接收数据后,需要触发一个中断来完成中断事件。本文中这个中断事件是将接受到的数据在通过串口发送出去。完成中断设置只需要在USART1 global interrupt后面的选项打勾就行。

         现在看看我们的串口状态,这里的I2C是我用来链接屏幕的,与本次的通信无关。

         完成以上的配置后我们就完成了用DMA来接受不定长的数据,接着我们只要对Clock Configuration中的HCLK设置为72就完成了时钟的配置。

                接下来我们就将配置好的项目保存,这里我是用keil打开,详细配置见下图。

        完成以上步骤后我们就可以进入keil去写代码了。点击Generate Code,我们就可以进入Keil了,进入keil界面后,首先我们需要一个数组变量来接受不定长的数据。

        接着我们用HAL_UARTEx_ReceiveToIdle_DMA(&huart1,receiveData,sizeof(receiveData))来接收不定长的数据,相关参数含义可以查询函数定义,这里就不详细介绍了。

        当我们收到数据后,会触发一个中断事件来完成相关操作,这里我们是使用void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)函数,详细代码的如下,其含义为通过DMA发送接受的数据,然后进入接受不定长数据的状态。这段代码是中断函数所以在主函数之外。

        完成代码后,我们就可以找一个串口助手来测试我们的代码了,这里我是用B站keysking制作的波特律动 串口助手 (keysking.com)来测试。

        

效果和预期的一样 ,以上就是hal库接收不定长数据的全部内容。

### 使用 STM32 HAL 实现接收不定长数据 为了有效地利用STM32 HAL来处理不确定长度的数据包,一种常见方法是结合DMA和串口中断功能。这种方法不仅提高了效率还增强了系统的响应速度[^3]。 当涉及到具体实施细节时,在初始化阶段需设置好相应的硬件资源以及配置参数。这通常涉及到了解并适当调整DMA通道、串口波特率以及其他必要的选项以匹配特定应用场景的需求[^4]。 下面是一个具体的代码实例展示如何使用 DMA 和 UART 中断配合完成这一目标: ```c #include "stm32f1xx_hal.h" UART_HandleTypeDef huart1; uint8_t aRxBuffer[64]; // 定义用于存储接收到的数据缓冲区大小为64字节 void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); int main(void){ /* 初始化所有已配置的外围设备 */ HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); /* 启动DMA接收模式 */ if (HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, sizeof(aRxBuffer)) != HAL_OK) { Error_Handler(); } while(1){} } // 当检测到空闲线状态时调用此回调函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ if(huart->Instance== USART1){ // 处理接收到的数据... // 重新启动DMA接收下一个数据HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, sizeof(aRxBuffer)); } } ``` 上述程序片段展示了基本框架,其中包含了主要组件及其相互作用的方式。通过这种方式可以在不预先知道消息确切尺寸的情况下可靠地捕获来自外部源的信息流[^5]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值