好的,我现在有了足够的信息来全面分析这个问题了。让我综合所有信息给出完整回答。
问题分析
根据论坛帖子内容和电路图,我来分析为什么外部中断 INT1 没有生效。
一、电路图分析(核心问题所在)
这个电路是一个市电50Hz过零检测电路,存在问题:
电路结构:
- 50Hz交流信号源 → 680nF电容耦合 → 1M电阻 + 稳压管(Zener)构成钳位/整形网络 → 二极管整流 → 两个820k电阻串联分压 → 输出到P3.3
问题1:P3.3接入点的直流偏置问题
从图中可以看到,P3.3 旁边标注了 "0 V"。这意味着在这条分压支路上,P3.3 的直流电平被钳位在 0V 附近。
但是关键问题是:两个 820k 电阻的分压点只有通过电容和稳压管网络与市电耦合。这个电路的过零检测点并不是直接产生一个干净的数字方波。当市电过零时,信号变化可能非常缓慢或幅度不足,无法让施密特触发器产生可靠的边沿。
问题2:电路本质是"无隔离"的容性耦合过零检测
这类电路常见的缺陷是:
- 680nF电容 + 820k+820k分压的高通滤波截止频率设计不当
- 稳压管钳位电平不合适
- 信号经过耦合后在P3.3上产生的波形不是干净的50Hz方波,而是类似正弦波被截断后的小幅振荡信号
正如论坛那位工程师所说:"用示波器看一下P33波形就明白了。这个电路得不到你想要的波形。"
二、代码配置问题
P3M0 = (P3M0 & ~0x0e) | 0x01; P3M1 = (P3M1 & ~0x09) | 0x06;
逐位分析:
P3M0 = 0x01 → P3.0 推挽输出(LED开关,正确)
P3M1 = 0x06 → P3.1、P3.2 高阻输入
**P3.3 的组合是 M1=0、M0=0,即准双向口!** 标准参考例程中,INT1引脚通常也是保持默认为准双向模式(手册示例代码中 P3M0=0x00, P3M1=0x00),所以P3.3准双向配置本身不是致命问题。
但是这里有一个重要的注意点:准双向口读外部状态前要锁存为'1'。如果P3.3的端口锁存器被写为'0',它会有强下拉,外部信号就无法将其拉高,导致中断永远无法触发!
另一个注意点:手册中提到 IT1=1 设置INT1为下降沿触发。过零检测电路输出的是交流信号变换后的波形,P3.3上信号变化本身可能不够陡峭——施密特触发器虽然有干扰抑制,但如果信号变换太慢或不完整,边沿识别会失效。
三、建议排查步骤
-
用示波器观察P3.3引脚波形
这是最关键的诊断手段。确认P3.3上是否真的有从高到低的干净边沿信号,并且电平能正常摆动到单片机识别的高/低电平阈值范围。
-
确认P3.3端口锁存器为'1'
在配置前先 P33 = 1;(即写锁存器为1),避免准双向口被内部强下拉拉住。
-
将P3.3配置为高阻输入
建议将P3.3配置为 高阻输入(P3M1.3=1, P3M0.3=0),避免内部上拉/下拉对来自820k分压的弱信号产生影响。
P3M0 &= ~0x08; // P3.3 = 高阻输入
P3M1 |= 0x08;
-
检查过零检测电路本身
论坛回复已经指出:"这个电路得不到你想要的波形"。建议:
- 用示波器确认P3.3上信号是否是一个干净的方波
- 如果信号幅度不足或边沿不陡,需要重新设计电路(例如使用光耦隔离方案,或采用标准的电阻分压+二极管钳位方案)
四、参考代码修正
#include <stc8g.h>
sbit ext = P3^3;
sbit sw = P3^0;
unsigned char cnt = 0;
void INT1_Isr(void) interrupt 2
{
++cnt;
if(cnt > 9)
{
sw = 0; // LED开关关闭
EX1 = 0; // 关闭INT1中断
cnt = 0;
}
}
void main()
{
// P3.0: 推挽输出(LED)
P3M0 = (P3M0 & ~0x0e) | 0x01;
P3M1 = (P3M1 & ~0x09) | 0x06;
P3M1 |= 0x08; // P3.3设为高阻输入,确保能正确读取外部信号
P3M0 &= ~0x08;
P5M0 &= ~0x30;
P5M1 = (P5M1 & ~0x20) | 0x10;
P33 = 1; // 确保P3.3锁存器为1(高阻输入下也需要)
sw = 1;
IT1 = 1; // 下降沿触发
EX1 = 1; // 使能INT1
EA = 1; // 打开总中断
while(1);
}
五、总结
核心结论: 中断没生效的根本原因是过零检测电路本身输出的波形无法让INT1可靠地检测到下降沿。P3.3上得到的不是一个干净的数字方波信号,可能信号幅度不足、边沿不陡,无法满足施密特触发器对边沿识别的要求。论坛的工程师回复也印证了这一点。
建议优先用示波器确认P3.3上的实际波形,再决定是修改电路还是调整代码。如果确认电路无问题,再按上述代码将P3.3配置为高阻输入以确保接口状态正确。
如果你能提供P3.3用示波器看到的波形截图,我可以帮你进一步分析判断。
🔍 搜索 "STC8H 单片机 例程 下载"
⏱️ 查找用时 36.5s | 总回答用时 50.7s