pic单片机中断优先级怎么算中断时间

PIC单片机引脚中断程序的设计技巧
PIC单片机引脚中断程序的设计技巧
$!yzk
& e|hiD
&  所有的中档系列PIC 单片机 ,PORTB端口最高的4个引脚(RB7~RB4)在设为输入模式时,当输入电平由高到低或由低到高发生变化时,可以让单片机产生中断。这就是通常所说的引脚状态变化中断。
J mES X&-:
& *]R.{,j-I
&  在设计
$!yzk
& e|hiD
&  所有的中档系列PIC 单片机 ,PORTB端口最高的4个引脚(RB7~RB4)在设为输入模式时,当输入电平由高到低或由低到高发生变化时,可以让单片机产生中断。这就是通常所说的引脚状态变化中断。
J mES X&-:
& *]R.{,j-I
&  在设计引脚中断程序时,有三个需要特别注意的地方。一是,在清除PORTB中断标志位RBIF之前,必须安排一条必不可少的,以PORTB端口数据寄存器PORTB为源寄存器的读操作指令。放置这一指令的目的有时并不只是为了读取有用的数据,而是为了取消状态变化的硬件信号,以便顺利清除RBIF标志位,为下一次中断做好准备。二是,由于端口PORTB是引脚电平变化中断,即无论引脚出现上升沿还是下降沿都会产生中断请求,所以必须处理好不需要的虚假中断。三是,一般都利用PIC 单片机 的引脚功能来检测按键,所以必须处理好按键消抖的问题。
v/-lKBrB'
& &#59=H
&2 引脚中断程序设计
& &#_Gz"|{
&  在主程序里先设置有关的寄存器。
e}4xd.G
& Z=3)j}jrP
&  ◇ 设置TRISB寄存器,使RB7~RB4相关的引脚处于输入状态;
wwvD
&  ◇ 如果需要弱上拉,通过OPTION_REG的第7位设置;
&  ◇ RBIF=0;
&  ◇ RBIE=1;
&  ◇ GIF=1。
& (y&JMZD3 
&  响应状态变化后的中断服务程序。
7\0GAm%
& qX=&v}x $
&  ◇ 检查RBIF是否为1,为1则是引脚变化引起的中断;
5Xwt~&U~[
&  ◇ 调用延时程序,延时20~30 ms,目的是为了按键去抖;
K2m= Al%9#
&  ◇ 判断是引脚出现上升沿还是下降沿引起的中断;
BPScZ)|!
&  ◇ 调用按键处理程序;
$Wr=Q8P
&  ◇ 读PORTB口的值,取消状态变化的硬件信号;
@&T (iUD)
&  ◇ 清除RBIF标志。
b(-oh$
& @|E1AJz0b
&  笔者认为上面程序设计最大的问题是在中断程序里调用延时程序。大家知道,中档PIC 单片机 只有8层深度的硬件堆栈,在中断里调用子程序出现极易堆栈溢出的情况。另外,PIC单片机中断程序入口只有一个,在响应中断的请求时,PIC单片机就会自动把全局中断的使能位(INTCON的第7位GIF)清除,这样其他中断就暂时不能被响应(此时,如果别的中断发出的中断请求,标志位将一直保留着),直到这个中断程序退出后才会得到响应。这就要求我们设计中断程序的时候必须尽量短,避免调用子程序,更不要在中断里进行复杂的运算。
tD,ARy
& aM/RJP
&  下面给出笔者设计程序时的思路。
gQ6UtM4
& mVwB7mG
&  当引脚状态变化引起中断时,在中断子程序里首先判断引起中断的原因是不是我们需要的变化引起的中断。如果是,不要在这里延时,而是设置一个标志位,接着清除中断标志,退出中断。中断程序如下:
()l"5Xt
& ; a^F
&else if ( (RBIE & RBIF) == 1) {//如果引脚变化引起中断
C:PWUV
&  if (RB4==0) {//RB4上的按钮接地
z~c5f
&  key=1;//按键标志位置位
gd%]* X(9
R9c+o|~
&  RBIF=0;//清除引脚中断标志位
}.|k,ZI(g
& Wpcs/_Oy
&  其中,if (RB4==0)语句相当于读取了PORTB端口数据寄存器,取消了状态变化的硬件信号。
#a`IvX'
& zc do+"
&  下面详细介绍怎么样进行按键去抖。
IQMv]on!X
& 56"#0UX
&  首先,在定时器中断里设置一个1 ms的时间基准标志位“SYS1ms”,每到1ms,“SYS1ms”便置位。程序如下:
,/\`U"
& o}.^jMWU!
cljUo`M
&if ( (T0IE & T0IF) == 1) {//定时器中断
K@}6%5^
&TMR0 += 0x09; //每250 μs中断一次
[U_}\ijm
&if(count==4) {
v(YYc$N&3
&  count=0;
p:R1ke*y
&  SYS1ms=1;//系统时间标志
8~'khzD
pK]UZBK{%
&T0IF = 0;//清除时钟中断标志位
ohV]f
b'=EX!:Qe
& "; &%sun
&  有了这个时间基准,便可以在主程序里进行按键去抖处理了。为了更好地利用这个时间基准,定义一个消息标志SYSTime,笔者把它称作时间消息。为了让这个消息有自我发布和自我消失的功能,定义了如下一个宏:
& Cf CJ_~J6
Ao:B)3NyD
&#define TimeEnable()SYSTime=0; if(SYS1ms){ SYSTime=1; SYS1ms=0; }
(@\|Wp9
& yZJ+yCW
&  可以把TimeEnable()放到主程序死循环的任何地方,每当程序执行这个宏,SYSTime就会清零,这就是标志位的自我消失。如果在定时器时间基准标志位SYS1ms已经置位的话,SYSTime就会置1,这样别的程序就可以利用这个时间消息了,这就是消息的自我发布。下面就是利用这个时间消息来进行按键延时去抖的,首先看一下按键扫描子程序:
}rq=Wz$.
& ;zG? X:{A
&void sCANkey() {
K)I/5bfoy:
&  unsigned char KeyTime,KeyT //定义任务时间参数、
&  //任务参数
/sgd9%~G
&  switch(KeyTask) {
&    case 0: if(key) {
wc3[kER
&      KeyTime=30; //准备延时30 ms
_V9 )0aVD
&      KeyTask++; //准备好下一个任务
&      key=0;
'?1g$T[3
&      }
CQ?qbTa
&      
8 +X/K7f
&    case 1:KeyTime--;//延时30 ms
 wvyJrW_
&      if(KeyTime==0) KeyTask++;
&      
Pq VG
&    case 2:if(RB4==0) {
j&;%8 [c]
&      //调按键处理程序
d!$)Wm
&      KeyTask=0;
bD|5B0A'
&      }
wiQEY
&      else KeyTask=0; //退出任务
o2iie_3
&      
gZ&g)~''
y1T&iB^kx
&[d@{[z\
& Xy"bu6W
&  在主程序的死循环中这样用:
F6&QuAt};
& Y"&\~AN
&while(1) {
Kcv]q -/4
&  TimeEnable();
!I/L@kD
&  If(SYSTime==1) {scankey();}
`uK+g29%p
&  //在此可以添加其他程序
Mh~JWD|)
& mvFT:@7
&  只有有时间消息的时候才执行按键扫描程序。可以看到,进入扫描程序执行第一次的时候,程序首先判断按键标志位有没有置位,置位的话(也就是有按键按下的话),任务时间参数(KeyTime)赋值为30,这是延时30 ms去抖,当然你也可以设置为其他的时间值;同时任务参数(KeyTask)加1。1 ms后,再进入扫描程序,这个时候扫描程序执行case 1的语句,这样30次后(延时了30 ms),任务参数(KeyTask)加1,值为2。1 ms后,再进入扫描程序,将执行case 2的语句,首先在这里再次判断是不是按键还在按下,如果是就调按键的处理程序,如果不是,就退出按键扫描程序。在这里,还可以加入按键是否抬起的判断程序。
Dm\-a)Tus
& &S- aT/X
&  这样设计的引脚变化程序,CPU开销小,效率高,不会出现堆浅溢出的问题,提高了系统的实时性。
型号/产品名
绍兴市华龙微电子有限公司
深圳市钜泽电子科技有限公司
深圳市文鼎兴电子商行关于PIC中断
PIC单片机有多个中断源,16系列只有一个中断入口,18系列有两个中断入口,不同编译器下书写格式又不大一样。网上资源千篇一律,也不够系统,只是简单的罗列程序,代码生存的环境不一样也少有说明。在此做个简单的总结,因为又走了弯路...
1.先说18系列(MCC18编译器下):
C18不自动把中断服务程序放在中端向量处。通常将GOTO指令放在中断向量处,从而把控制权转交给相应中断服务程序。
void low_isr(void);
void high_isr(void);&
*****************************低级中断入口及服务子程序************************************/
#pragma code low_vector=0x18//低优先级中断入口
void interrupt_at_low_vector(void)
&_asm& GOTO
low_isr& _endasm
#pragma interrupt low_isr
#pragma code
void low_isr(void)
//低优先级中断服务函数写在这里
*****************************高级中断入口及服务子程序************************************/
#pragma code high_vecotr=0x08//高优先级中断入口
void interrupt_at_high_vector(void)
&_asm& GOTO
high_isr& _endasm
#pragma code
#pragma interrupt high_isr
void high_isr(void)
//高优先级中断服务函数写在这里
2.再说18系列(PICC18编译器下):
//void PIC18F_High_isr(void);
//void PIC18F_Low_isr(void);
*****************************低级中断服务子程序************************************/
#pragma interrupt&
lowlow_priority&&
PIC18F_Low_isr
void PIC18F_Low_isr (void)
//低优先级中断服务函数写在这里
*****************************高级中断服务子程序************************************/
#pragma interrupt& PIC18F_High_isr
void PIC18F_High_isr (void)
//高优先级中断服务函数写在这里
3.三说16系列(PICC编译器下)(只有一个中断入口,无所谓高了就):
void interrupt isr (void)
//中断服务函数写在这里
&void init_interrupt()
//TMR1IE=1;
//TMR1IF=0;
//TMR1IP=0;
//TMR1L=61;&&&&&&&&&&&&&&&&&&&&
//T1CON=0xC7;//set up timer0 - 8bit -prescaler
&&&&&//TMR0IE=1;
&&&&&//TMR0IF=0;&
&&&&&//TMR0IP=0;
&&&&//TMR0L=61;&&&&&&&&&&&&&&&&&&&&&
&&&&//T0CON=0xC7;//set
up timer0 - 8bit -prescaler 1:256&
就写到这里吧,留着自己看,不再这再走弯路
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。PIC单片机PIC16F1786编程之内部定时实现TIMER2中断
PIC单片机PIC16F1786编程之内部定时实现TIMER2中断
Timer2只能用作8位定时器模式,因为它没有外部输入引脚;可以与CCP模块一起产生PWM信号;相关寄存器说明:TMR2:定时器寄存器存放计数器的值,可以赋初值。TMR2寄存器的值与PR2寄存器中值相比较,两者相等, TMR2值立刻置零,同时产生中断。T2CON:TMR2控制寄存器Bit6~Bit3/T2OUTPS&3:0&:TMR2后置分频器的分频配置比设置:0000 —— 预分频系数1:1;0001 —— 预分频系数1:2;。。。。。。1111 —— 预分频系数1:16;Bit2/TMR2ON:TMR2计数允许/禁止控制位:0 —— 禁止TMR2计数;1 —— 允许TMR2计数;Bit1~Bit0/T2CKPS&1:0&:TMR2前置分频器的分频配置比设置:00 —— 预分频系数1:1;01 —— 预分频系数1:4;10 —— 预分频系数1:16;11 —— 预分频系数1:64;INTCON:中断控制寄存器Bit7/GIE:总中断使能0 —— 禁止所有中断;1 —— 使能所有中断,但各中断源还受各自的中断使能位控制。比如TMR0中断还得使能 TMR0IE;Bit6/PEIE:与TMR1中断有关的外围中断使能控制位:0 —— 禁止所有外围中断源模块的中断请求,包括TMR2中断;1 —— 使能所有外围中断源模块的中断请求,包括TMR2中断;PIE1:第一外围中断使能寄存器Bit1/TMR2IE:TMR2溢出中断使能位:0 —— 禁止TMR2中断;1 —— 使能TMR2中断;PIR1:第一外围中断标志寄存器Bit2/TMR1IF:TMR2溢出中断标志位:0 —— TMR2中断未发生;1 —— TMR2中断已发生;PR2:周期寄存器可由软件设置其值,该值即为TMR2计数器溢出值。关于TMR2定时设置:Timer2的功能Timer0有些不同,Timer2是一个八位的计数器,有一个八位的计数寄存器TMR2,Timer2具有以下功能:有两个分频器,一个是前分频器,一个是后分频器.分频可以软件进行设置,另外,Timer2的时钟源是指令时间(FOSC/4),Timer2有一个寄存器 PR2,此寄存器的功能是当TMR2增加到PR2的值时,将产生中断,当然,中断必须允许,然后PR2的值会重新变为00H.下面来介绍Timer2的编程:Timer2的控制寄存器T2CON作用是设置Timer2的开启关闭和前后分频的分频系数,寄存器T2CON的 TOUTPS&3:0& 位设置后分频系数,可以被设置成1:1~1:16;位TMR2ON为1时,Timer2开启,为0时,Timer2关闭;位T2CKPS&1: 0&可以设置前分频系数,可以被设置成1、4、16。Timer2的中断可以这样控制,允许Timer2中断位TMR2IE(位于 PIE1寄存器内)被置1时,Timer2中断被允许,被置0时, Timer2中断禁止.寄存器INTCON的PEIE位置1,同时总中断位GIE(位于寄存器INTCON中)置为1.通过上面的设置,Timer2就可以产生中断了.当定时器产生中断的时候,会把中断标志T2IF置为1(位于寄存器PIR1中),然后PC指针指向0004H地址.中断标志位T2IF必须软件清除.TMR2设置定时时间:TMR2的周期寄存器(寄存器分为控制、周期寄存器),即当TMR2的值=PR2+1时,TMR2将溢出,即TMR2自动被清0。如你用的是4MHz晶振,希望延时2ms,可以这样计算:指令周期=4M/4=1MHz,则Tcy=1us,2000=(PR2+1)×Tcy×K,这里,K为预分频系数为了先得到K,假设PR2=255,即最大值,可以得到K=7.8125,由于TMR2的预分频系数只有1,4,16三种可选,而且必须选比理论计算的值(7.8125)大一点的那个系数,因此这里K选16再把K代入公式计算,求PR2:2000=(PR2+1))×Tcy×16,得到PR2=124,如果有小数,按四舍五入取整。也就是说,如果把TMR2设置成预分频比为1:16,PR2设置为124,在4MHz晶振时,每隔2ms溢出一次,溢出时TMR2被清0。
本文仅代表作者观点,不代表百度立场。系作者授权百家号发表,未经许可不得转载。
百家号 最近更新:
简介: 更新有意思的科技带给你
作者最新文章PIC单片机定时器初值计算方法及几种周期小结 - PIC单片机 - 电子工程世界网
PIC单片机定时器初值计算方法及几种周期小结
12:29:18来源: 51hei
PIC也用是蛮多的,据说网上还有计算初值的强力软件,不过我还是手动算下吧。总结了下————
PIC的是4个震荡周期,在没有使用的情况下,TMR0 会在每个指令周期信号(等于产生的主时钟周期的 4 倍)到来时自动加 1。在配置了分频器的情况下,TMR0 会在每次收到由分频器将指令周期信号分频一个固定倍数后产生的信号时自动加 1。如果 TMR0在累加计数的过程中,CPU 执行一条往 TMR0 中写入数据的指令,则累加计数器的加 1 操作将被推迟两个指令周期,重新开始计数。这两个指令周期的偏差在用户编写时间精度要求较高的程序时应引起注意,可以通过在每次写入 TMR0 时给一个调整值的方法来解决。
假设的是时钟频率为 4MHz。因此,一个指令周期就是一个微秒(μs)的时间。
,也就是计数一次时间是1us。
没有分频比定时器的初值计算公式:T0=256-Tc+2
&& 其中TC是想得到的次数。加2的原因是写值的时候要消耗两个指令周期。
如果分频器给了定时器,最好不要再读写TMR0了,不然会照成误差。
假设分频器是16,晶振是4Mhz,一次由00到FF的时间是16*256=4096us。假设50ms的时间
在中断每次加上4096,
主程序检查是不是超过5000,超过了就减掉5000,这样算是50ms就得到了。
再来张图,就更加一目了然了,有木有?哈哈。
晶振8M 需定时25us 分频比1:2
初值(EE)=256 - 25/ (4/8*2) + 14/2& = 256- 25 + 7 = 238
简述时钟周期、机器周期、指令周期的概念及三者之间的关系
时钟周期也称为振荡周期,定义为时钟脉冲的倒数(可以这样来理解,时钟周期就是外接晶振的倒数,例如12M的晶振,它的时间周期就是1/12 us),是计算机中最基本的、最小的时间单位。
在一个时钟周期内,CPU仅完成一个最基本的动作。对于某种单片机,若采用了1MHZ的时钟频率,则时钟周期为1us;若采用4MHZ的时钟频率,则时钟周期为250us。由于时钟脉冲是计算机的基本工作脉冲,它控制着计算机的工作节奏(使计算机的每一步都统一到它的步调上来)。显然,对同一种机型的计算机,时钟频率越高,计算机的工作速度就越快。但是,由于不同的计算机硬件电路和器件的不完全相同,所以其所需要的时钟周频率范围也不一定相同。我们学习的80的时钟范围是1.2MHz-12MHz。
在8051单片机中把一个时钟周期定义为一个节拍(用P表示),二个节拍定义为一个状态周期(用S表示)。
在计算机中,为了便于管理,常把一条指令的执行过程划分为若干个阶段,每一阶段完成一项工作。例如,取指令、存储器读、存储器写等,这每一项工作称为一个基本操作。完成一个基本操作所需要的时间称为机器周期。一般情况下,一个机器周期由若干个S周期(状态周期)组成。8051系列单片机的一个机器周期同6个S周期(状态周期)组成。前面已说过一个时钟周期定义为一个节拍(用P表示),二个节拍定义为一个状态周期(用S表示),8051单片机的机器周期由6个状态周期组成,也就是说一个机器周期=6个状态周期=12个时钟周期。
指令周期是执行一条指令所需要的时间,一般由若干个机器周期组成。指令不同,所需的机器周期数也不同。对于一些简单的的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。
通常含一个机器周期的指令称为单周期指令,包含两个机器周期的指令称为双周期指令。
关键字:&&&&
编辑:什么鱼 引用地址:
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
微信扫一扫加关注 论坛活动 E手掌握
微信扫一扫加关注
芯片资讯 锐利解读
大学堂最新课程
汇总了TI汽车信息娱乐系统方案、优质音频解决方案、汽车娱乐系统和仪表盘参考设计相关的文档、视频等资源
热门资源推荐
频道白皮书
何立民专栏
北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

我要回帖

更多关于 pic单片机的中断 的文章

 

随机推荐