一、中断系统
中断系统是为使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);
}
}
}
当我在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)(人们推荐的最少
我正在使用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.
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个: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
在我的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
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
当我进入Rails控制台时,我已将pry设置为加载代替irb。我找不到该页面或不记得如何将其恢复为默认行为,因为它似乎干扰了我的Rubymine调试器。有什么建议吗? 最佳答案 我刚发现问题,pry-railsgem。忘记了它的目的是让“railsconsole”打开pry。 关于ruby-on-rails-带有Pry的Rails控制台,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/question
我正在尝试将$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
我在思考流量控制的最佳实践。我应该走哪条路?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