草庐IT

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

MEYOU_Cc 2025-02-18 原文

一、中断系统

中断系统是为使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 <REGX52.H>


/** 
  * @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 <REGX52.H>
#include "Timer0.h"
#include "Key.h"
#include <INTRINS.H>

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);
			}
		}
		
}

有关51单片机(中断系统)按键控制LED流水灯模式(2)的更多相关文章

  1. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  2. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  3. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  4. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  5. ruby - ruby 乘法语句中星号中断语法前的空格 - 2

    在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl

  6. ruby-on-rails - 在 Rails 控制台中使用 asset_path - 2

    在我的Character模型中,我添加了:字符.rbbefore_savedoself.profile_picture_url=asset_path('icon.png')end但是,对于数据库中已存在的所有角色,它们的profile_picture_url为nil。因此,我想进入控制台并遍历所有这些并进行设置。在我试过的控制台中:Character.find_eachdo|c|c.profile_picture_url=asset_path('icon.png')end但这给出了错误:NoMethodError:undefinedmethod`asset_path'formain:O

  7. ruby - 在 ASP 页面上 Mechanize 中断 - 2

    require'mechanize'agent=Mechanize.newlogin=agent.get('http://www.schoolnet.ch/DE/HomeDE.htm')agent.clicklogin.link_withtext:/Login/然后我得到Mechanize::UnsupportedSchemeError。 最佳答案 Mechanize不支持javascript但您可以将搜索字段添加到表单并为其分配搜索词并使用mechanize提交表单form=page.forms.firstform.add_fie

  8. ruby-on-rails - 带有 Pry 的 Rails 控制台 - 2

    当我进入Rails控制台时,我已将pry设置为加载代替irb。我找不到该页面或不记得如何将其恢复为默认行为,因为它似乎干扰了我的Rubymine调试器。有什么建议吗? 最佳答案 我刚发现问题,pry-railsgem。忘记了它的目的是让“railsconsole”打开pry。 关于ruby-on-rails-带有Pry的Rails控制台,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/question

  9. ruby - 将全局 $stdout 重新分配给控制台 - ruby - 2

    我正在尝试将$stdout设置为临时写入一个文件,然后返回到一个文件。test.rb:old_stdout=$stdout$stdout.reopen("mytestfile.out",'w+')puts"thisgoesinmytestfile"$stdout=old_stdoutputs"thisshouldbeontheconsole"$stdout.reopen("mytestfile1.out",'w+')puts"thisgoesinmytestfile1:"$stdout=old_stdoutputs"thisshouldbebackontheconsole"这是输出。r

  10. ruby-on-rails - Ruby 流量控制 : throw an exception, 返回 nil 还是让它失败? - 2

    我在思考流量控制的最佳实践。我应该走哪条路?1)不要检查任何东西并让程序失败(更清晰的代码,自然的错误消息):defself.fetch(feed_id)feed=Feed.find(feed_id)feed.fetchend2)通过返回nil静默失败(但是,“CleanCode”说,你永远不应该返回null):defself.fetch(feed_id)returnunlessfeed_idfeed=Feed.find(feed_id)returnunlessfeedfeed.fetchend3)抛出异常(因为不按id查找feed是异常的):defself.fetch(feed_id

随机推荐