「已注销」 2023-10-14 16:39 采纳率: 33.3%
浏览 44

流水灯中断嵌套,低优先级中断完成后如何返回主程序

题目要求:在 Proteus 里实现两级中断嵌套:当K1和K2都未按下时,P1口8只 LED 呈流水灯显示,当按一下 K 1时,产生一个低优先级外中断0请求(跳沿触发),进入外中断0中断服务程序,标号为偶数的 LED 和奇数 LED 交替闪烁10次。此时按一下 K 2时,产生一个高优先级的外中断1请求(跳沿触发),进入外中断1中断服务程序,使8只 LED 全部闪烁。当显示5次后,再从外中断1返回继续执行外中断0中断服务程序,直至偶数和奇数 LED 交替闪烁10次完成,然后再次返回主程序,8只 LED 呈流水灯显示。设置外中断0为低优先级,外中断1为高优先级。
我的代码:

#include <REGX51.H>
#include "intrins.h"
#define uchar unsigned char
sbit K1=P3^2;//定义按键
sbit K2=P3^3;
void Delay(unsigned int i)//延时函数                                       
{        unsigned int j;
        for(;i>0;i--)               
        for(j=0;j<125;j++)               
        {;}//空函数                                                                       
}
void main()//主函数
{
        unsigned char display [9]={0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//流水灯显示数据数组
        unsigned char a;
        for(;;)               
        {
                EA=1;//总中断允许
                EX0=1;//允许外部中断0中断
                EX1=1;//允许外部中断1中断
                IT0=1;//选择外部中断0为跳沿触发方式
                IT1=1;//选择外部中断1为跳沿触发方式
                PX0=0;//外部中断0为低优先级
                PX1=1;//外部中断1为高优先级       
                for(a=0;a<9;a++)               
                {                                               
                        Delay(400);//延时
                        P1=display[a];//已定义的流水灯显示数据送到P1口
                }       
        }
}
void int0_isr(void) interrupt 0 using 0        //外中断0的中断服务函数
{
  unsigned char m=0;
  for(m=0;m<10;m++)//标号为偶数的LED和奇数LED交替闪烁10次
  {
    P1=0x55;//标号为偶数的LED灯点亮
    Delay(500);//延时
        P1=0xaa;//标号为奇数的LED灯点亮
        Delay(500);//延时
  }
}
void int1_isr(void) interrupt 2 using 1        //外中断1的中断服务函数
{
  unsigned char n=0;
  for(n=0;n<5;n++)//8位LED全亮全灭5次
  {
    P1=0;//8位LED全亮
        Delay(500);//延时
        P1=0xff;//8位LED全灭
        Delay(500);//延时
  }  
}


基本能完成题目要求,但是最后低优先级中断完成后无法返回主程序,应该怎么办。

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-10-14 18:23
    关注

    【以下回答由 GPT 生成】

    根据你的代码,你已经完成了主程序和中断的初始化设置。现在需要添加中断服务程序来实现中断功能。

    void INT0_ISR() interrupt 0 //外部中断0服务程序
    {
        unsigned int i;
        for(i=0; i<10; i++)
        {
            P1 = 0x55; //交替闪烁标号为偶数的LED和奇数LED
            Delay(200);
            P1 = 0xaa;
            Delay(200);
        }
    }
    
    void INT1_ISR() interrupt 2 //外部中断1服务程序
    {
        unsigned int i, j;
        for(i=0; i<5; i++)
        {
            for(j=0; j<9; j++)
            {
                P1 = display[j]; //使8个LED全部闪烁
                Delay(200);       
            }
        }
        EX1 = 0; //关闭外部中断1
        for(i=0; i<10; i++)
        {
            P1 = 0x55;
            Delay(200);
            P1 = 0xaa;
            Delay(200);
        }
        EX1 = 1; //重新使能外部中断1
    }
    

    在上述代码中,中断0的服务程序实现了交替闪烁标号为偶数和奇数的LED共10次的需求。中断1的服务程序实现了使8个LED全部闪烁5次的需求,并在完成后重新使能了外部中断1。

    最后,在主函数的for循环前,再添加一个while循环,这样在中断执行完成后会一直处于等待状态直到下一次循环开始。

    void main() //主函数
    {
        unsigned char display[9] = {0xff, 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f}; //流水灯显示数据数组
        unsigned char a;
    
        for(;;)
        {
            EA = 1; //总中断允许
            EX0 = 1; //允许外部中断0中断
            EX1 = 1; //允许外部中断1中断
            IT0 = 1; //选择外部中断0为跳沿触发方式
            IT1 = 1; //选择外部中断1为跳沿触发方式
            PX0 = 0; //外部中断0为低优先级
            PX1 = 1; //外部中断1为高优先级
    
            while(1)
            {
                for(a = 0; a<9; a++)
                {
                    Delay(400); //延时
                    P1 = display[a];
                }
            }
        }
    }
    

    这样你就完成了流水灯中断嵌套的功能。注意,如果你使用的是单片机而不是仿真软件,可能还需要根据具体的单片机型号和编程软件进行相应的设置和调试。



    【相关推荐】



    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 10月14日