0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

STM32CubeMX之串口接收不定长数据

撞上电子 2023-05-11 09:59 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

基本串口通信通常只能接收到定长数据,无法稳定接收不定长数据,本章介绍利用STM32单片机的IDLE空闲中断,接收不定长数据。

使能串口1的异步串行通信模式,开启Usart1的全局中断。添加DMA通道。b858f22c-ef9b-11ed-ba01-dac502259ad0.png

使用Stm32Cubemx生成源码, 打开生成的源码,删除whiel循环中的语句。

打开usart.h文件,在文件开头的USER CODE BEGIN Includes下方引入stdio.h头文件b88d39ba-ef9b-11ed-ba01-dac502259ad0.png

打开usart.c文件,在USER CODE BEGIN 0与 USER CODE END 0之间添加下列代码。

#if 1 struct __FILE { int handle; };
FILE __stdout; //定义_sys_exit()以避免使用半主机模式 void _sys_exit(int x) { x = x; } //重定义fputc函数int fputc(int ch, FILE *f){ while((USART1->SR&0X40)==0);//循环发送,直到发送完毕 USART1->DR=(uint8_t)ch; return ch;}#endif

打开uart.c文件,在文件顶部的USER CODE BEGIN 0下方添加下列变量。

volatile uint8_t rx1_len = 0; //接收一帧数据的长度volatile uint8_t rec1_end_flag = 0; //一帧数据接收完成标志uint8_trx1_buffer[BUFFER_SIZE]={0}; //接收数据缓存数组

打开uart.c文件,在文件末尾的USER CODE BEGIN 1下方添加下列函数。

void Usart1_IDLE(void) //USART1的IDLE接收{ uint32_t tmp_flag = 0; uint32_t temp; tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位 if((tmp_flag != RESET))//idle标志被置位 { __HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位 HAL_UART_DMAStop(&huart1); // 停止DMA传输,防止 temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数 rx1_len = BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数 rec1_end_flag = 1; // 接受完成标志位置1 }}
void Usart1_Handle() //USART1对接收的一帧数据进行处理{ DMA_Usart1_Send(rx1_buffer, rx1_len); //将接收到的数据回发给发送端 rx1_len = 0;//清除计数 rec1_end_flag = 0;//清除接收结束标志位 HAL_UART_Receive_DMA(&huart1,rx1_buffer,BUFFER_SIZE);//重新打开DMA接收}
void DMA_Usart1_Send(uint8_t *buf,uint8_t len) //串口发送封装{ if(HAL_UART_Transmit_DMA(&huart1,buf,len)!= HAL_OK) //判断是否发送正常,如果出现异常则进入异常中断函数 { Error_Handler(); }}

b8b4cf48-ef9b-11ed-ba01-dac502259ad0.png

打开usart.h文件,在文件开头的USER CODE BEGIN Includes下方添加如下语句:

#include "stdio.h"#include "string.h"#define BUFFER_SIZE 100
extern volatile uint8_t rx1_len; //接收一帧数据的长度extern volatile uint8_t rec1_end_flag; //一帧数据接收完成标志extern uint8_t rx1_buffer[BUFFER_SIZE]; //接收数据缓存数组
void Usart1_Handle(void);void DMA_Usart1_Send(uint8_t *buf,uint8_t len);//串口发送封装voidUsart1_IDLE(void);

b8df94e4-ef9b-11ed-ba01-dac502259ad0.png

进入main.c文件,找到入口函数void mian(void), 在USER CODE BEGIN 2下方开启串口1的DILE中断,并打开DMA接收。

__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断 HAL_UART_Receive_DMA(&huart1,rx1_buffer,BUFFER_SIZE); //开启DMA接收

在while语句中添加接收查询语句。

if(rec1_end_flag) //判断是否接收到1帧数据{ Usart1_Handle(); //前往数据处理函数处理接收到的数据。}

b8ff32fe-ef9b-11ed-ba01-dac502259ad0.png

打开stm32f4xx_it.c文件,在文件开头引入usart.h头文件。

b9383bee-ef9b-11ed-ba01-dac502259ad0.png

向下翻stm32f4xx_it.c文件,找到void USART1_IRQHandler(void)函数,此函数为串口1的中断入口函数。在此函数中添加之前在usart.c文件中创建的IDLE接收函数。

b94cf58e-ef9b-11ed-ba01-dac502259ad0.png

源码修改完毕后,编译下载,打开串口助手,随意发送100个字节以内的任意长度内容进入单片机,都可得到同样的回复。

b9702af4-ef9b-11ed-ba01-dac502259ad0.png

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据
    +关注

    关注

    8

    文章

    7348

    浏览量

    95008
  • STM32
    +关注

    关注

    2313

    文章

    11189

    浏览量

    374570
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    如何在 STM32Cube CMake 工程中添加源文件

    STM32CubeMX 能够很方便的导出 CMake 工程。例如,如下图所示在 STM32CubeMX的 ToolChain/IDE 中选择 Cmake。CMake 工程可以很容易被
    发表于 04-15 16:07 0次下载

    LAT1574_如何在 STM32Cube CMake 工程中添加源文件

    STM32CubeMX 能够很方便的导出 CMake 工程。例如,如下图所示在 STM32CubeMX的 ToolChain/IDE 中选择 CmakeCMake 工程可以很容易被
    发表于 03-11 10:46 0次下载

    请问CW32L的UART是不是没有空闲中断?

    CW32L083的UART是不是没有空闲中断?大家一般怎么实现不定长数据接收?是串口中断+定时器吗?
    发表于 12-15 07:28

    串口空闲中断与串口超时中断介绍

    。 特点 依赖总线物理状态,而非时间。 常用于检测不定长数据帧的结束,无需依赖特定结束符。 应用场景 Modbus通信:不定长数据包的接收
    发表于 11-21 08:31

    请问RT-Thread与stm32cubemx联合开发的原理是什么?

    在使用RT-Thread与stm32cubemx联合开发的原理是什么,cubemx在其中主要起到了哪些功能呢?
    发表于 10-11 15:49

    意法半导体:STM32CubeMX将不再集成到STM32CubeIDE中

    从2025年11月发布的版本开始,我们将仅以 独立 版本的形式提供 STM32CubeIDE 和 STM32CubeMXSTM32CubeMX将不再集成到STM32CubeIDE
    的头像 发表于 09-01 17:18 3862次阅读

    【RA4M2-SENSOR】—— 12.串口接收不定长度数据

    ;, U1_RxBuff);//打印收到的数据 user_uart_clear();//清空接收缓冲区 } HAL_Delay(10); } 编译代码,烧录到板子 打开串口助手 发送
    发表于 09-01 11:22

    使用STM32CubeMX的时候创建的工程已经使用的板载资源如何去掉?

    在使用STM32CubeMX的时候创建的工程已经使用的板载资源如何去掉?在基于开发板进行工程创建的时候会把板载资源直接初始化,后面想要用不同的功能配置,如何把初始配置去掉?
    发表于 07-22 07:13

    对于在STM32CubeMx使用FMC中的NAND FLASH里面配置这些时间有什么说明吗?

    对于在STM32CubeMx使用FMC中的NAND FLASH里面配置这些时间有什么说明吗?
    发表于 07-21 07:07

    STM32L433VCT6进入STOP模式2之后,功耗依然和正常运行模式没有差别,为什么?

    背景:STM32L433VCT6 运行时钟在2Mhz,所有的外设和IO口几乎全部使用,如图所示 外设使用: 1、三个串口,其中一个串口为IRDA模式;发送和接收都使用了DMA;利用空
    发表于 07-21 06:42

    stm32cubemx上的g031j6的管脚和数据手册不一致,请问哪个是正确的呢?

    stm32cubemx上的g031j6的管脚和数据手册不一致,请问哪个是正确的呢?
    发表于 07-10 06:39

    STM32CubeMX配置STM32G070RBT6TR时为什么无法使能PVD中断?

    STM32CubeMX 配置STM32G070RBT6TR时无法使能PVD中断
    发表于 06-18 07:59

    STM32CubeMX配置STM32G070RBT6TR时无法使能PVD中断怎么办?

    STM32CubeMX 配置STM32G070RBT6TR时无法使能PVD中断
    发表于 06-16 06:32

    【RA-Eco-RA4M2开发板评测】定时器辅助串口不定长数据接收

    assert(status==FSP_SUCCESS); }   2.定时器辅助串口接收,实现不定长数据接收。定时器回调函数实现如下:
    发表于 04-30 14:44

    使用STM32CubeMX进行配置USB的时候,有哪些小的需要注意的细节?

    在使用STM32CubeMX进行配置USB的时候,是参照例程进行的配置,自己配置的就是没有成功,例程就灭有问题,总感觉哪里没有打开?有人遇到过需要注意的小细节吗?
    发表于 04-23 06:54