清帮我看看为什么中断会运行2次
这个流水灯一个是P3.2外部中断,一个是P1.1 I/O上升沿中断,外接的是一个红外模块,不论哪个中断都会让程序运行2次(灯亮灭2次)。 代码如下#include "config.h"
#include "ai8051u.h"
void PORT1_Init(void)
{
SetP1nInitLevelHigh(PIN_ALL); //设置P1初始化电平
SetP1nQuasiMode(PIN_ALL); //设置P1为准双向口模式
SetP1nManualMode(PIN_ALL); //设置P1手动配置端口模式
DisableP1nPullUp(PIN_ALL); //关闭P1内部上拉电阻
DisableP1nPullDown(PIN_ALL); //关闭P1内部下拉电阻
EnableP1nSchmitt(PIN_ALL); //使能P1施密特触发
SetP1nSlewRateNormal(PIN_ALL); //设置P1一般翻转速度
SetP1nDrivingNormal(PIN_ALL); //设置P1一般驱动能力
SetP1nDigitalInput(PIN_ALL); //使能P1数字信号输入功能
SetP1nRisingInt(PIN_2 | PIN_1); //设置P1.2,P1.1为上升沿中断
EnableP1nInt(PIN_2 | PIN_1); //使能P1.2,P1.1口中断
SetP1IntPriority(0); //设置中断为最低优先级
//<<AICUBE_USER_PORT1_INITIAL_BEGIN>>
// 在此添加用户初始化代码
//<<AICUBE_USER_PORT1_INITIAL_END>>
}
void SYS_Init(void)
{
EnableAccessXFR();
AccessCodeFastest();
AccessIXramFastest();
IAP_SetTimeBase();
PORT1_Init(); //P1口初始化
P2M0 = 0x00; P2M1 = 0x00;
}
////////////////////////////////////////
// 项目主函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void main(void)
{
// 在此添加用户主函数初始化代码
WTST = 0; // 设置程序指令延时参数
EAXFR = 1; // 使能访问扩展寄存器区(XFR)
CKCON = 0; // 提高访问 XRAM速度
P3M0 = 0x00; // P3 准双向口模式(包含输入功能) //新改
P3M1 = 0x00;
IT0 = 0; // INT0 下降沿触发(IT0=0 为低电平触发)
EX0 = 1; // 使能 INT0 中断
EA= 1;
SYS_Init();
// 在此添加主函数中运行一次的用户代码
P2 = 0x00; //对P0端口置0,点亮整组LED
delay_ms(2000);
P2 = 0xFF; //对P0端口置0,点亮整组LED
delay_ms(100);
while (1)
{
// 在此添加主函数中用户主循环代码
}
}
////////////////////////////////////////
// 毫秒延时函数
// 入口参数: ms (设置延时的毫秒值)
// 函数返回: 无
////////////////////////////////////////
void delay_ms(uint16_t ms)
{
uint16_t i;
do
{
i = MAIN_Fosc / 6000;
while (--i);
} while (--ms);
}
void EXTI0_ISR(void) interrupt 0
{
// 在此添加中断函数用户代码
P21 = 0;
delay_ms(800);
P22 = 0;
delay_ms(800);
P23 = 0;
delay_ms(2000);
P21 = 1;
delay_ms(800);
P22 = 1;
delay_ms(800);
P23 = 1;
delay_ms(800);
}
////////////////////////////////////////
// 外部中断INT1中断服务程序
void EXTI1_ISR(void) interrupt INT1_VECTOR
{
//<<AICUBE_USER_EXTI1_ISR_CODE1_BEGIN>>
P22 = ~P22;
delay_ms(1000);
// 在此添加中断函数用户代码
//<<AICUBE_USER_EXTI1_ISR_CODE1_END>>
}
void P1_ISR(void) interrupt 38
{
u8 intf; // ← 用 u8,不是 uint8_t!
intf = P1INTF; // 读取P1口中断标志
if(intf)
{
P1INTF = 0x00; // 软件清空中断标志
if(intf & 0x02) // P1.1 产生了上升沿中断
{
P21 = 0;
delay_ms(800);
P22 = 0;
delay_ms(800);
P23 = 0;
delay_ms(2000);
P21 = 1;
delay_ms(800);
P22 = 1;
delay_ms(800);
P23 = 1;
delay_ms(800);
}
}
}
有人说中断得快进快出
其中使用delay_ms(x)延时少见
{:4_164:} 可能需要
看看教学视频
补充学习单片机知识
Ai8051U深度入门到32位51大型实战教学视频
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=11902
建议使用一个方波信号触发P3.2看看,会不会是你的红外信号有抖动? 有示波器没?看下中断脚的波形是不是有多个边沿。
“两次”,大概率是因为处理第一次中断耗时较长,后面的中断未及时响应,等第一次中断处理完,发现中断标志置位了(虽然早已没有外部信号,但标志还在、未被清除),所以再次进中断。
如果你的中断响应够快,可能会发现,实际中断次数(边沿)不止两次。
中断里面还是不要使用delay函数了吧 该函数
选中的部分
可放在main的while(1)
耗时操作放主循环
if里intf还要清零
防重复操作
lcwswust 发表于 2026-6-11 10:28
有示波器没?看下中断脚的波形是不是有多个边沿。
“两次”,大概率是因为处理第一次中断耗时较长,后面的 ...
没有示波器,我认为也是这个原因,我试试高电平能不能避免这个问题 狂热主宰 发表于 2026-6-11 11:21
该函数
选中的部分
试过了 仍然还是跑2次灯不知道什么原因第一次亮灯的间隔时间明显延长很多大约3秒左右第二次正常0.8秒间隔我试试高电平触发
页:
[1]