关于STC15F2K60S2的UART2收发异常问题
关于STC15F2K60S2的UART2收发异常问题,问题描述:使用STC15F2K60S2的UART2与WIFI模组链接,MCU主频6M,串口波特率115200,在测试中经常出现串口无法与WIFI模组进行通信。
发生问题时,MCU软复位无法恢复串口,只有断电重启,串口才能恢复。
问题查证过程如下:
1、监控MCU的RX引脚,WIFI模组发出来的数据正常,MCU收不到数据;
2、监控MCU的TX引脚,未见到MCU数据发出;
3、对WIFI模组 断电重启,问题无法解决;(说明问题的出现和WIFI模组无关)
4、复位MCU(IAP_CONTR = 0x20),问题无法解决;
5、只有MCU断电重启,串口收发才能正常;
6、将MCU主频由6M改为12M,上述问题仍然经常出现;
7、将串口的波特率115200改为9600,上述问题仍然出现,但出现的概率大大降低;
8、将串口2设置高优先级 PS2=1(IP2|= 0x01),测试了很久,问题没有出现。
疑问:
1、串口2出现此问题的原因是什么?
2、串口2设置高优先级后,问题消失,原因是什么?
<p>这个帖子就是您发的,目前还没有官方回复。现在我来综合分析手册内容和您的排查结果,给出完整的解答。</p>
<hr />
<p>感谢您提供如此详尽的故障排查记录!这非常有助于精准定位问题。根据 STC15 系列手册和您的测试现象,我来逐一分析。</p>
<h2>问题根因分析</h2>
<h3>1. 串口2出现此问题的根本原因</h3>
<p><strong>核心原因:串口2中断被其他频繁触发的中断源"淹没"或"饿死",导致 S2TI/S2RI 中断标志无法及时被软件清除,最终串口2陷入死锁。</strong></p>
<p>具体机理如下:</p>
<p><strong>(1)串口2的中断优先级默认是最低优先级</strong></p>
<p>根据手册"中断系统"章节(F10T17),STC15F2K60S2 的串口2中断(UART2)在中断查询次序中排第8位,其优先级由 IP2 寄存器的 PS2 位控制。<strong>当 PS2=0(默认值)时,串口2中断为最低优先级中断(优先级0)。</strong></p>
<p>而您的系统中,如果同时使用了定时器0/1、外部中断、串口1等其他中断源,且这些中断源也处于优先级0(同级),那么根据中断规则:</p>
<blockquote>
<p>"低优先级中断可被高优先级中断所中断,反之不能。"<br />
"任何一种中断(不管是高级还是低级),一旦得到响应,不会再被它的同级中断所中断。"</p>
</blockquote>
<p>当多个同级中断同时请求时,CPU 按查询次序依次响应。串口2的查询次序排在第8位,<strong>如果前面有更高查询次序的中断(如定时器0、INT0、串口1等)频繁触发,串口2中断可能长时间得不到响应</strong>。</p>
<p><strong>(2)中断响应延迟导致 S2RI/S2TI 标志无法及时清除</strong></p>
<p>串口2的接收中断标志 S2RI 和发送中断标志 S2TI 在硬件置位后,<strong>必须由软件在中断服务程序中清零</strong>(手册"串行口2的相关寄存器"章节明确说明)。如果中断响应被延迟:</p>
<ul>
<li>新的接收数据到来时,S2RI 仍为1,<strong>硬件无法再次置位 S2RI</strong>,导致后续接收数据全部丢失</li>
<li>同样,S2TI 未及时清零会导致发送无法继续</li>
</ul>
<p><strong>(3)软复位无法恢复的原因</strong></p>
<p>您测试了 <code>IAP_CONTR = 0x20</code> 软复位无法恢复,而断电重启可以。这是因为:</p>
<p>根据手册"软件复位"章节(F10T13),<code>IAP_CONTR = 0x20</code> 执行的是<strong>热启动软复位</strong>,虽然所有 SFR 会复位到初始值,但<strong>内部某些硬件状态(如串口接收移位寄存器中的残留数据、波特率发生器定时器2的某些内部状态)可能并未完全恢复到冷启动时的干净状态</strong>。而断电重启(冷启动)会彻底清除所有内部状态。</p>
<p><strong>(4)降低波特率后概率降低的原因</strong></p>
<p>波特率从 115200 降到 9600 后,每帧数据的传输时间变长了约12倍。这意味着:</p>
<ul>
<li>两次中断之间的间隔时间大大增加</li>
<li>CPU 有更充裕的时间去响应串口2中断</li>
<li>中断被"淹没"的概率自然降低</li>
</ul>
<h3>2. 设置高优先级后问题消失的原因</h3>
<p><strong>设置 PS2=1 后,串口2中断变为最高优先级(优先级1),根据中断嵌套规则:</strong></p>
<blockquote>
<p>"高优先级的中断请求可以打断低优先级的中断"</p>
</blockquote>
<p>这意味着:</p>
<ul>
<li>无论其他中断(定时器、串口1等)是否正在执行,只要串口2产生中断请求(S2RI 或 S2TI 置位),CPU 会<strong>立即暂停当前正在执行的低优先级中断服务程序</strong>,转而去处理串口2中断</li>
<li>串口2的 S2RI/S2TI 标志能够被<strong>及时清零</strong>,不会出现标志位"卡死"的情况</li>
<li>后续的收发数据能够正常进行</li>
</ul>
<p>这正是您测试第8项(设置 PS2=1)后问题消失的根本原因。</p>
<h2>建议解决方案</h2>
<h3>方案一(推荐):将串口2设置为高优先级</h3>
<pre><code class="language-c">IP2 |= 0x01; // PS2 = 1,串口2中断设为高优先级
</code></pre>
<p>您已经验证此方法有效,这是最简单的解决方案。</p>
<h3>方案二:检查并确保中断服务程序中正确清除标志位</h3>
<p>在 UART2 中断服务程序中,务必确保:</p>
<pre><code class="language-c">void UART2_ISR() interrupt 8
{
if(S2CON & 0x01) // S2RI = 1,接收中断
{
// 读取接收数据
rx_data = S2BUF;
S2CON &= ~0x01; // 软件清除 S2RI
}
if(S2CON & 0x02) // S2TI = 1,发送中断
{
S2CON &= ~0x02; // 软件清除 S2TI
// 继续发送下一字节或结束
}
}
</code></pre>
<h3>方案三:检查是否有其他中断源过于频繁</h3>
<p>如果系统中存在高频中断(如定时器中断周期过短),建议:</p>
<ul>
<li>适当降低其他中断的频率</li>
<li>或将其他不关键的中断优先级设为低于串口2</li>
</ul>
<h3>方案四:软复位前先关闭串口2和定时器2</h3>
<p>在执行软复位前,先执行以下操作,可提高软复位的彻底性:</p>
<pre><code class="language-c">// 软复位前先关闭串口2和定时器2
S2CON = 0x40; // 关闭接收(S2REN=0),清除中断标志
AUXR &= ~0x10; // 关闭定时器2(T2R=0)
IAP_CONTR = 0x20; // 再执行软复位
</code></pre>
<hr />
<p><strong>总结</strong>:您遇到的问题本质上是<strong>中断响应延迟导致串口2中断标志无法及时清除,进而造成串口死锁</strong>。设置高优先级后,串口2中断能够立即得到响应,标志位及时清零,问题自然消失。这是 STC15 系列在复杂中断系统中一个典型且合理的处理方式。</p>
<hr />
<p><a href="https://www.stcaimcu.com/plugin.php?id=twpx_xunsearch&mod=forum&q=STC15F2K60S&f=_all&m=yes&syn=yes&s=relevance&fid=0">🔍 搜索 "STC15F2K60S"</a></p>
<p>⏱️ 查找用时 12.8s | 总回答用时 31.1s</p>
你这个疑问2很关键啊,,,你要是能把你出问题的工程发上来就更好了。。 神农鼎 发表于 2026-7-3 09:57
这个帖子就是您发的,目前还没有官方回复。现在我来综合分析手册内容和您的排查结果,给出完整的解答。
感 ...
感谢您的回复! _奶咖君_ 发表于 2026-7-3 10:07
你这个疑问2很关键啊,,,你要是能把你出问题的工程发上来就更好了。。
整体的设计描述尽可能详细介绍
项目工程可能涉及商业秘密
有关键程序自然更好 _奶咖君_ 发表于 2026-7-3 10:07
你这个疑问2很关键啊,,,你要是能把你出问题的工程发上来就更好了。。
商用产品的代码,不方便发出{:weixiao:} 串口可能需要特殊频率的时钟
从低频率低故障概率推测 通常是程序或硬件的问题,这个MCU量产超过15年了,没听说有啥问题。
1、MCU的VCC与GND一定要有就近退耦电容10uF+100nF,再并联5.6V/5W的稳压二极管(比如1N5339)嵌位电压避免异常过高。
2、主循环取反一个IO指示。
3、开一个定时器,中断里取反一个IO指示。
的那个出现你的情况,示波器观察上述两个IO是否有输出,贴在这里,我来分析。 天高云淡 发表于 2026-7-3 10:22
商用产品的代码,不方便发出
自己将程序直接贴到 STC【AI助手】,问,即可
页:
[1]
2