51单片机(中断系统)按键控制LED流水灯模式(2)

您所在的位置:网站首页 流水灯c51单片机程序 51单片机(中断系统)按键控制LED流水灯模式(2)

51单片机(中断系统)按键控制LED流水灯模式(2)

2024-07-12 13:57| 来源: 网络整理| 查看: 265

一、中断系统

中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的。

       当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后,再回到原来被中断的地方,继续原来的工作,这样的过程称为中断。实现这种功能的部件称为中断系统,请示CPU中断的请求源称为中断源。微型机的中断系统一般允许多个中断源,当几个中断源同时向CPU请求中断,要求为它服务的时候,这就存在CPU优先响应哪一个中断源请求的问题。通常根据中断源的轻重缓急排队,优先处理最紧急事件的中断请求源,即规定每一个中断源有一个优先级别。CPU总是先响应优先级别最高的中断请求。        当CPU正在处理一个中断源请求的时候(执行相应的中断服务程序),发生了另外一个优先级比它还高的中断源请求。如果CPU能够暂停对原来中断源的服务程序,转而去处理优先级更高的中断请求源,处理完以后,再回到原低级中断服务程序,这样的过程称为中断嵌套。这样的中断系统称为多级中断系统,没有中断嵌套功能的中断系统称为单级中断系统。

二、STC89C52中断资源

        STC89C52系列单片机提供了8个中断请求源,它们分别是:外部中断0(INT0)、定时器0中断、外部中断1(INT1)、定时器1中断、串口(UART)中断、定时器2中断、外部中断2(INT2)、外部中断3(INT3)。所有的中断都具有4个中断优先级。

       用户可以用关总中断允许位(EA/IE.7)或相应中断的允许位来屏蔽所有的中断请求,也可以用打开相应的中断允许位来使CPU响应相应的中断申请:每一个中断源可以用软件独立地控制为开中断或关中断状态;每一个中断的优先级别均可用软件设置。高优先级的中断请求可以打断低优先级的中断,反之,低优先级的中断请求不可以打断高优先级及同优先级的中断。

       当两个相同优先级的中断同时产生时,将由查询次序来决定系统先响应哪个中断。STC89C52系列单片机的各个中断查询次序如下表所示:

以上也是中断服务函数,在初始化中断时也要配置相关的寄存器

 注意:中断的资源和单片机的型号是关联在一 起的,不同的型号可能会有不同的中断资源,例如中断源个数不同、中断优先级个数不同等等。

                                                                配置中断的触发方式

三、定时器和中断系统

 四、代码

timer0.c标准模板

#include /** * @brief 定时器0初始化,1毫秒@12MHz * @param 无 * @retval 无 */ void Timer0Init(void) //1毫秒@12.000MHz { TMOD &= 0xF0; //设置定时器模式,这里是为了不影响定时器1的配置 TMOD |= 0x01; //设置定时器模式 TL0 = 0x18; //设置定时初值 TH0 = 0xFC; //设置定时初值 TF0 = 0; //中断请求标志位 清除TF0标志 TR0 = 1; //定时器0开始计时 ET0=1; //定时器中断允许控制位 EA=1; //总中断允许控制位 PT0=0; //定时器中断优先级设置 } /*定时器中断服务函数模板,这个中断服务函数一般是放在main.c中的 void Timer0_Routine() interrupt 1 { static unsigned int T0Count; TL0 = 0x18; //设置定时初值 TH0 = 0xFC; //设置定时初值 T0Count++; if(T0Count>=1000) { T0Count=0; } } */

 timer0.c解释模板

void Timer0_Init() //1毫秒@12.000MHz { // TMOD=0x01;//0000 0001 配置定时器的工作模式寄存器TMOD //但是用这一行代码,影响配置定时器1,如果要用定时器1的话 TMOD=TMOD&0xF0;//把TMOD的低四位清零,高四位保持不变 TMOD=TMOD|0x01;//把TMOD的最低位置1,高四位保持不变 //用这两行代码,可以配置低四位,而不影响高四位 TH0=64535/256;//给定时器赋初值 TL0=64535%256; TF0=0; //中断请求标志位 清除TF0标志 TR0=1; //定时器0开始计时 ET0=1; //定时器中断允许控制位 EA=1; //总中断允许控制位 PT0=0; //定时器中断优先级设置 } /*定时器中断服务函数模板,这个中断服务函数一般是放在main.c中的 void Timer0_Routine() interrupt 1 { static unsigned int T0Count;/*放在函数外边是全局变量,放在函数里是局部变量, 因为T0Count是需要计数到1000的,而定时器1ms到后去 执行中断函数,中断函数执行结束后T0Count会被销毁, 无法记录执行次数,因此放在函数体内要加静态变量static 这样T0Count会保留上次的值 */ // TH0=64535/256;//初始化定时器从64535开始计数,溢出后计数从0开始,因此要重新赋值 // TL0=64535%256; TL0 = 0x18; //设置定时初值 TH0 = 0xFC; //设置定时初值 T0Count++; if(T0Count>=1000) { P2_0=~P2_0; T0Count=0; } }

 用STC-ISP软件生成定时器代码:

 删除AUXR,另外会自动生成TL和TH的值。

main.c

#include #include "Timer0.h" #include "Key.h" #include unsigned char KeyNum,LEDMode; void main() { P2=0xFE; Timer0Init();//初始化定时器 while(1) { KeyNum=Key(); if(KeyNum) { if(KeyNum==1) { LEDMode++; if(LEDMode>=2)LEDMode=0; } } } } void Timer0_Routine() interrupt 1 { static unsigned int T0Count;/*放在函数外边是全局变量,放在函数里是局部变量, 因为T0Count是需要计数到1000的,而定时器1ms到后去 执行中断函数,中断函数执行结束后T0Count会被销毁, 无法记录执行次数,因此放在函数体内要加静态变量static 这样T0Count会保留上次的值 */ // TH0=64535/256;//初始化定时器从64535开始计数,溢出后计数从0开始,因此要重新赋值 // TL0=64535%256; TL0 = 0x18; //设置定时初值 TH0 = 0xFC; //设置定时初值 T0Count++; if(T0Count>=1000) { T0Count=0; if(LEDMode==0) { P2=_crol_(P2,1); } if(LEDMode==1) { P2=_cror_(P2,1); } } }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3