找回密码
 立即注册
查看: 51|回复: 5

提问,串口DMA发送问题

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-10-01 18:54:43
已绑定手机

1

主题

2

回帖

19

积分

新手上路

积分
19
发表于 3 天前 | 显示全部楼层 |阅读模式
使用官方stc32g的官方例程测试,我的是STC32G864K
如图
截图202509301610137337.jpg
当使用延时Delay1000ms();的时候,DMA只在上电时发送了一次
当把Delay1000ms();注释,DMA能会一直发送数据
把DMA_UR1T_CR = 0xc0;注释掉,也是只发一次数据
但加了延时后好像就进不去if((DmaTxFlag))这个条件
DmaTxFlag只在中断中置1,
截图202509301616337947.jpg
那是不是 delay导致中断进不去了?还是有什么其他原因?delay是官方isp上复制的应该不会有错吧?
有没有大佬遇到过这种情况的解答一下
回复

使用道具 举报 送花

3

主题

1928

回帖

704

积分

等待验证会员

积分
704
发表于 3 天前 | 显示全部楼层
你提出的问题是关于 STC32G864K 芯片在使用 串口DMA发送数据 时,加入延时函数 Delay1000ms() 后,DMA发送只执行一次,而去掉延时则能持续发送数据。你怀疑延时函数是否影响了中断的响应,从而导致 DmaTxFlag 无法置位。

下面我将从 硬件原理、DMA机制、中断响应、延时函数实现机制 等角度,结合你的代码片段,进行详细分析并给出建议。

一、问题现象总结

1. 使用 STC32G 官方例程,串口通过 DMA 发送数据。
2. 当加入 Delay1000ms(); 时,DMA 只发送一次。
3. 注释掉 Delay1000ms(); 后,DMA 可持续发送。
4. 注释掉 DMAUR1TCR = 0xc0; 后,也只发送一次。
5. DmaTxFlag 是在中断中置位的,但加了延时后无法进入 if(DmaTxFlag) 分支。

二、可能的原因分析

1. 延时函数占用 CPU 时间,阻塞中断响应

你提到的 Delay1000ms(); 是“阻塞式延时函数”,即在这1秒内,CPU 会一直执行空循环,不做其他事情。这种延时方式会 完全阻塞主程序流程,并且 可能屏蔽中断响应。
如果 Delay1000ms(); 是基于 关闭中断 的方式实现的(例如使用 EA = 0;),那么在延时期间,DMA发送完成中断将无法被响应。
即使没有关闭全局中断,如果延时函数本身是一个“死循环”,那么在延时期间,中断服务程序虽然触发了,但主程序没有机会去处理中断标志位(如 DmaTxFlag)。

2. DMA发送配置不完整或未重新使能
DMAUR1TCR = 0xc0; 是用于启动DMA传输的寄存器操作。如果每次发送后没有重新设置该寄存器,DMA可能不会再次启动。
在DMA中断中,是否对 DMA 通道进行了 重新初始化或重新使能?如果没有,DMA只能发送一次。

3. DmaTxFlag 未正确清除或未及时处理
如果 DmaTxFlag 没有在中断中正确置位,或者在主程序中未及时清除,可能导致程序逻辑判断失效。
若中断未被及时响应(如因延时函数阻塞),DmaTxFlag 的置位也会被“延迟”,主程序可能已经跳过判断。

三、建议解决方案

1. 避免使用阻塞式延时函数
尽量使用 定时器中断+标志位 实现延时,避免阻塞CPU。
或者使用 非阻塞延时函数,例如:
  1. c
  2.   void DelayMs(uint16t ms) {
  3.       while (ms--) {
  4.           DelayUs(1000);
  5.       }
  6.   }
复制代码
  但前提是 DelayUs() 不关闭中断。

2. 检查中断使能配置

确保以下中断使能已正确开启:
  1. c
  2. EA = 1;             // 全局中断使能
  3. DMAIE = 1;         // DMA中断使能
复制代码

此外,检查DMA通道的中断使能是否开启。

3. 在DMA中断中重新启动DMA传输

在DMA发送完成后,应在中断服务程序中重新配置并启动DMA:
  1. c
  2. void DMAISR(void) interrupt 18 {
  3.     if (DMAISRTXDONEFLAG) {
  4.         DmaTxFlag = 1;
  5.         DMAUR1TCR = 0xc0;   // 重新启动DMA发送
  6.         DMAISRTXDONECLEAR; // 清除中断标志
  7.     }
  8. }
复制代码

注意:具体寄存器名称和位定义请参考STC32G的官方手册。

4. 优化主循环逻辑

不要在主循环中频繁调用长时间延时函数。可以使用如下方式:
  1. c
  2. uint32t lastTime = 0;
  3. while (1) {
  4.     if (DmaTxFlag) {
  5.         DmaTxFlag = 0;
  6.         // 重新准备数据并启动DMA
  7.     }
  8.     if (GetSysTime() - lastTime >= 1000) {
  9.         lastTime = GetSysTime();
  10.         // 执行1秒周期性操作
  11.     }
  12. }
复制代码

其中 GetSysTime() 可以是一个基于定时器的毫秒级时间戳函数。

四、总结

| 问题点 | 原因分析 | 建议 |
|--------|----------|------|
| 加延时后DMA只发一次 | 延时函数阻塞中断响应 | 改用非阻塞延时或定时器 |
| 注释DMA启动寄存器后只发一次 | DMA未重新使能 | 中断中重新启动DMA |
| DmaTxFlag未进入判断 | 中断未响应或标志未置位 | 检查中断配置与标志处理 |
| 延时函数是否错误 | 可能关闭了中断 | 查看Delay函数实现是否影响中断 |

五、附加建议
使用调试器(如STC-ISP或Keil+STC-Link)观察中断是否真正触发。
打印调试信息:可通过串口输出调试信息,确认中断是否执行。
阅读官方手册:STC32G的DMA和串口部分,确认寄存器配置是否符合预期。

如果你能提供完整的代码片段(尤其是DMA中断服务程序和延时函数的实现),我可以进一步帮你定位具体问题。

如有需要,我也可以帮你改写为非阻塞式延时版本,或者提供基于定时器的周期性任务处理方案。

如需进一步帮助,请继续提问。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:315
  • 最近打卡:2025-10-02 12:32:59
已绑定手机

83

主题

3209

回帖

7092

积分

荣誉版主

无情的代码机器

积分
7092
发表于 3 天前 | 显示全部楼层
楼主打包上传下问题工程看看
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-10-01 18:54:43
已绑定手机

1

主题

2

回帖

19

积分

新手上路

积分
19
发表于 3 天前 | 显示全部楼层
erci*** 发表于 2025-9-30 16:53
楼主打包上传下问题工程看看

刚刚测试 使用了计数延时,也还是不行

串口1使用DMA中断模式与电脑收发测试.rar

44.6 KB, 下载次数: 3

点评

可以复现,取消共用用户中断号恢复正常,发一包255字节回一包. 感觉加上延时刚好遇到中断冲突导致的bug。 [attachimg]116634[/attachimg] 关于大于31中断号的使用可以看手册这个章节: [attachimg]116637[/atta  详情 回复 发表于 3 天前
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:315
  • 最近打卡:2025-10-02 12:32:59
已绑定手机

83

主题

3209

回帖

7092

积分

荣誉版主

无情的代码机器

积分
7092
发表于 3 天前 | 显示全部楼层
15180*** 发表于 2025-9-30 17:20
刚刚测试 使用了计数延时,也还是不行


可以复现,取消共用用户中断号恢复正常,发一包255字节回一包.
感觉加上延时刚好遇到中断冲突导致的bug。
截图202509301906309781.jpg

串口1使用DMA中断模式与电脑收发测试-delay.zip (59.69 KB, 下载次数: 2)

关于大于31中断号的使用可以看手册这个章节:

截图202509301909059166.jpg
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-10-01 18:54:43
已绑定手机

1

主题

2

回帖

19

积分

新手上路

积分
19
发表于 前天 18:54 来自手机 | 显示全部楼层
ercircle 发表于 2025-9-30 19:09
可以复现,取消共用用户中断号恢复正常,发一包255字节回一包.
感觉加上延时刚好遇到中断冲突导致的bug ...

好的谢谢,等过完假期试试
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-10-3 08:51 , Processed in 0.134719 second(s), 77 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表