左左右学堂 · 课程目录

第21期 一节课讲明白usart接收不定长数据

观看B站原视频 · 文稿与高清画面

helllo,小伙伴们,大家好。这里是左左右。这期视频我们通过使用串口屏制作的串口助手。来实现不定长数据的接收。还是老样子,打开cubeide,将上期视频做好的项目复制一份下来。回忆下前面usart通信那期视频。大家有没有这样一个疑问?发送数据寄存器中的值是哪来的?同理,接收数据寄存器中的值去了哪里?

其实,发送数据寄存器中值是由cpu从内存中搬运而来,而接收数据寄存器中的值也是由cpu搬运到内存中去了。如果我们在某一个项目中要频繁的通过usart接收和发送数据,那么cpu是不是就会很忙碌?这时cpu就没时间去处理其他数据了。这里你可以把stm32理解成一家公司,而cpu就是这家公司的老板。

这就相当于让老板去搬砖。这样的公司还能有发展吗?所以,这种事要交给像我这样的牛马来做。那么,在stm32中有没有这样的牛马呢?答案是肯定的,它就是DMA。它是数据的搬运工,工作勤勤恳恳,替老板分忧。回到cubeide来设置一下。打开.ioc文件中的usart1,接着打开DMA Settings点击ADD。

添加接收和发送的DMA通道就可以了。接着,往下看,这里的Mode可选项有Normal和Circular两种模式。其中Circular通过字面意思不难猜出它是循环模式。他的特点的是循环往复,永不停止。这种模式我会在后面讲ADC数据采集时用到,而Normal模式DMA会在传输完成指定数据后停止。

视频画面 03:07.4
视频画面 03:07.4 · 1080P 原图 · 查看对应视频

正是我们USART通信要用到的模式。所以,这里我们选择Normal模式。由于我们将接收到的数据要存入连续的内存缓冲区,所以,地址递增这里就选择Memory。

另外,一个英文是外设的意思。这里用不到我们放到后面的视频讲解。好的 DMA的设置就到这里了。接着,回到main.c文件。这里只需要将uart接收和发送中断函数中的IT改为DMA就可以了。点击编译看一下,是不是也没有问题?前面我们接收的数据长度都是固定的,下面我们讲一下如何接收不定长数据?

视频画面 03:57.5
视频画面 03:57.5 · 1080P 原图 · 查看对应视频

先把之前的字符串定义的长一点。接收不定长数据我们用到的是HAL_UARTEx_ReceiveToIdle_DMA这个函数。空闲中断(IDLE)是 UART 通信中用于检测数据帧结束的核心硬件机制。特别适用于通信协议不固定或数据包长度变化的场景。这里有一点需要注意,这里的size不是接收到数据的实际长度,而是最大可接收数据的长度,这里的值需小于等于receive_data的字符串长度。

视频画面 06:27.8
视频画面 06:27.8 · 1080P 原图 · 查看对应视频

为了方便,我们直接用sizeof就可以了。这个函数的回调函数是这个RxEventCallback。我们找一下并重写。这里先判断一下进来的中断是不是uart1?接着,把从串口屏接收到的数据再发回串口屏。这里的size就用传参进来的Size,也就是接收到数据的实际长度。

视频画面 05:37.7
视频画面 05:37.7 · 1080P 原图 · 查看对应视频

最后,把DMA的接收中断再重新开启一下。点击编译,没有报错。点击运行把写好的代码下载到stm32中,打开串口屏模拟器。是不是就可以实现串口助手的功能了?使用它我们是不是随时可以找到任何字符对应16进制的asc码值了?我们输入a就可以得到对应16进制的asc码值。我们将maic.c中的huart1改为huart2。

并将串口助手下载到串口屏,输入hello。是不是stm32就实现不定长数据的接收了?我将做好的串口助手放到资料包了,免费提供给大家。需要的小伙伴们可以自行去取。由于这个串口助手涉及的串口屏知识太多,我们将在以后单独做一期视频讲解,还有就串口助手这个项目放到仿真软件达不到预期的效果。

所以,就没在这里给大家演示。仿真难免会有问题的,以后能实现的我都会给大家演示。没有演示的就说明仿真软件实现不了。好的,今天的视频就到这里了。您的关注,点赞和收藏是我持续更新下去的最大动力。