stm32F103RCT6的DMA使用经历
DMA可以直接传输数据,减少了CPU的负担,是个很好的功能,但是用的时候难免会一头雾水。这次做个小小的串口收发程序就碰到了许多问题。
之前没有注意,选择了DMA的circular模式,然后奇怪的事情发生了
很明显我这个HAL_UART_Transmit_DMA是写在while(1)外面的,但是串口调试的结果与我的预期刚刚好相反
我认为它应该是只发送一次的,很明显,当时的我对于DMA完全不了解(现在也是)
后面想了一下觉得应该是DMA的模式的问题,就改成了Normal模式,输出就正常了,就输出了一次语句
在此之后,我又做了一些试验,以下是部分源码
#include "main.h" #include "dma.h" #include "usart.h" #include "gpio.h" #include <stdio.h> #include <string.h> uint8_t str_Tx1[] = "Hello World! This is stm32F103RCT6!\r\n"; uint8_t str_Tx2[64]; uint8_t str_Rx1 = 0; uint8_t str_Rx2[64]; void SystemClock_Config(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DMA_Init(); MX_UART4_Init(); HAL_UART_Transmit_DMA(&huart4,str_Tx1,sizeof(str_Tx1)); while (1) { HAL_UART_Receive(&huart4,&str_Rx1,1,1000); // 等待用户发送数据,1秒后无响应则执行后面的语句 HAL_UART_Transmit_DMA(&huart4,&str_Rx1,sizeof(str_Rx1)); // 发送用户所发送的数据 HAL_UART_Receive(&huart4,str_Rx2,64,1000); // 等待用户发送数据,1秒后无响应则执行后面的语句 HAL_UART_Transmit_DMA(&huart4,str_Rx2,sizeof(str_Rx2)); // 发送用户所发送的数据 } }
打开串口之后如下图所示
与此同时我注意到了右下角的接收数据量还是在一直增加的
先加1,再加64(也就是我两个字符串的数据量)
然后我发送了一个9,应该是第一句接收到了
HAL_UART_Receive(&huart4,&str_Rx1,1,1000); // 等待用户发送数据,1秒后无响应则执行后面的语句
我再发送了一个Hello,应该是第二个字符串接收到了
HAL_UART_Receive(&huart4,str_Rx2,64,1000); // 等待用户发送数据,1秒后无响应则执行后面的语句
这时候如果我发送一个2,就会覆盖掉这个字符串的第一位
发送66,则会出现以下情况
也就是后面的发送数据写入字符串是覆盖写入,当写入量等于1的时候会覆盖第二个字符串的首位字符,当写入数量大于1的时候会写入第一个字符串,输入的第一个字符写入第一个字符串,其余的覆盖掉第二个字符串
鉴于我对于DMA的认识还是很浅,很多细节还是不甚了解,希望有大神不吝赐教,能在评论区指出我的过错,非常感谢!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用