找回密码
 立即注册
查看: 138|回复: 8

清帮我看看为什么中断会运行2次

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2026-07-01 22:51:25
已绑定手机

7

主题

8

回帖

55

积分

注册会员

积分
55
发表于 2026-6-10 23:21:11 | 显示全部楼层 |阅读模式
这个流水灯  一个是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);
        }
    }
}


回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:316
  • 最近打卡:2026-07-22 06:56:11
已绑定手机

70

主题

874

回帖

3225

积分

论坛元老

DIY玩家

积分
3225
发表于 2026-6-11 10:00:44 | 显示全部楼层
有人说中断得快进快出
其中使用delay_ms(x)延时少见
永怀这学徒心
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:316
  • 最近打卡:2026-07-22 06:56:11
已绑定手机

70

主题

874

回帖

3225

积分

论坛元老

DIY玩家

积分
3225
发表于 2026-6-11 10:14:35 | 显示全部楼层
可能需要
看看教学视频
补充学习单片机知识

Ai8051U深度入门到3251大型实战教学视频

https://www.stcaimcu.com/forum.php?mod=viewthread&tid=11902




永怀这学徒心
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:410
  • 最近打卡:2026-07-21 09:39:09

83

主题

7972

回帖

1万

积分

超级版主

积分
17025
发表于 2026-6-11 10:26:27 | 显示全部楼层
建议使用一个方波信号触发P3.2看看,会不会是你的红外信号有抖动?
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:153
  • 最近打卡:2026-07-21 14:44:21
已绑定手机

5

主题

356

回帖

6446

积分

论坛元老

积分
6446
发表于 2026-6-11 10:28:16 | 显示全部楼层
有示波器没?看下中断脚的波形是不是有多个边沿。
“两次”,大概率是因为处理第一次中断耗时较长,后面的中断未及时响应,等第一次中断处理完,发现中断标志置位了(虽然早已没有外部信号,但标志还在、未被清除),所以再次进中断。
如果你的中断响应够快,可能会发现,实际中断次数(边沿)不止两次。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:961
  • 最近打卡:2026-07-22 07:54:56
已绑定手机

62

主题

2105

回帖

3182

积分

论坛元老

积分
3182
发表于 2026-6-11 10:40:46 | 显示全部楼层
中断里面还是不要使用delay函数了吧
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:316
  • 最近打卡:2026-07-22 06:56:11
已绑定手机

70

主题

874

回帖

3225

积分

论坛元老

DIY玩家

积分
3225
发表于 2026-6-11 11:21:49 | 显示全部楼层
该函数
选中的部分
截图202606111122073313.jpg
可放在main的while(1)
耗时操作放主循环

if里intf还要清零
防重复操作
永怀这学徒心
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2026-07-01 22:51:25
已绑定手机

7

主题

8

回帖

55

积分

注册会员

积分
55
发表于 2026-6-11 21:47:55 | 显示全部楼层
lcws*** 发表于 2026-6-11 10:28
有示波器没?看下中断脚的波形是不是有多个边沿。
“两次”,大概率是因为处理第一次中断耗时较长,后面的 ...

没有示波器,我认为也是这个原因,我试试高电平能不能避免这个问题
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2026-07-01 22:51:25
已绑定手机

7

主题

8

回帖

55

积分

注册会员

积分
55
发表于 2026-6-11 21:51:31 | 显示全部楼层
狂热*** 发表于 2026-6-11 11:21
该函数
选中的部分

试过了 仍然还是跑2次灯  不知道什么原因  第一次亮灯的间隔时间明显延长很多  大约3秒左右  第二次正常0.8秒间隔  我试试高电平触发
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-7-22 10:31 , Processed in 0.081660 second(s), 77 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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