PIC中断程序的设计技巧

2020-02-15来源: eefocus关键字:PIC  中断程序  设计技巧

1 简 述

所有的中档系列PIC单片机,PORTB端口最高的4个引脚(RB7~RB4)在设为输入模式时,当输入电平由高到低或由低到高发生变化时,可以让单片机产生中断。这就是通常所说的引脚状态变化中断。


在设计引脚中断程序时,有三个需要特别注意的地方。一是,在清除P0RTB中断标志位RBIF之前,必须安排一条必不可少的,以PORTB端口数据寄存器 PORTB为源寄存器的读操作指令。放置这一指令的目的有时并不只是为了读刃用的数据,而是为了取消状态变化的硬件信号,以便顺利清除RBIF标志位,为 下一次中断做好准备。二是,由于端口PORTB是引脚电子变化中断,即无论引脚出现上升沿还是下降沿都会产生中断请求,所以必须处理好不需要的虚假中断。 三是,一般都利用PIC单片机的引脚功能来检测按键,所以必须处理好按键消抖的问題。


2 引脚中断程序设计

在主程序里先设置有关的寄存器。

设置TRISB寄存器,使RB7~RB4相关的引脚处于输入状态; 如果需要弱上拉,通过OPTION_REG的第7位设置; RBIF=O; RBIE=1; GIF=1。


响应状态变化后的中断服务程序。

检查RBIF是否为l,为l则是引脚变化引起的中断; 调用延时程序,延时20~30 ms,目的是为了按键去抖; 判断是引脚出现上升沿还是下降沿引起的中断; 调用按键处理程序; 读PORTB口的值,取消状态变化的硬件信号; 清除RBIF标志。


笔 者认为上面程序设计最大的问题是在中断程序里调用延时程序。大家知道,中档PIC单片机只有8层深度的硬件堆栈,在中断里调用于程序出现极易堆栈溢出的情 况。另外,PIC单片机中断程序人口只有一个,在响应中断的请求时,PIC单片机就会自动把全局中断的使能位(INTCON的第7位GIF)清除,这样其 他中断就暂时不能被响应(此时,如果别的中断发出的中断请求,标志位将一直保留着),直到这个中断程序退出后才会得到响应。这就要求我们设计中断程序的时 候必须尽量短,避免调用子程序,更不要在中断里进行复杂的运算。


下面给出笔者设计程序时的思路。


当引脚状态变化引起中断时,在中断子程序里首先判断引起中断的原因是不是我们需要的变化引起的中断。如果是,不要在这里延时,而是设置一个标志位,接着清除中断标志,退出中断。中断程序如下:

else if((RBIE&RBlF)==1){ //如果引脚变化引起中断

if(RB4==0){ //RB4上的按钮接地

key=1; //按键标志位置位

}

RBIF=0; //清除引脚中断标志位

}


其中,if(RB4==0)语句相当于读取了PORTB端口数据寄存器,取消了状态变化的硬件信号。


下面详细介绍怎么样进行按键去抖。


首先,在定时器中断里设置一个lms的时间基准标志位“SYSlms”,每到lms,“SYSlms”便置位。程序如下:


unsigned char count;


if((ToIE&TOIF)==1){ //定时器中断


TMRO+=0x09; //每250μs中断一次


if(count==4){


count=0;


SYSlms=l; //系统时间标志


couot++;


}


T0IF=0; //清除时钟中断标志位


}


有了这个时间基准,便可以在主程序里进行按键去抖处理了。为了更好地利用这个时间基准,定义一个消息标志SYSTime,笔者把它称作时间消息。为了让这个消息有自我发布和自我消失的功能.定义了如下一个宏:


bit SYSTime;


#defincTimeEnahle()SYSTime=0,if(SYSlms){SYSTime=l;SYSlms=0;)


可以把TimeEnable()放到主程序死循环的任何地方,每当程序执行这个宏,SYSTime就会清零,这就是标志位的自我消失.如果在定时器时间基 准标志位SYSlms已经置位的话,SYSTime就会置1,这样别的程序就可以利用这个时间消息了,这就是消息的自我发布。下面就是利用这个时间消息来 进行按键延时去抖的,首先看一下按键扫描子程序;


void seaakey(){


unsigned char KeyTime,KeyTask;//定义任务时间参数、


//任务参数


switch(KeyTask){


case0:if(key){


KeyTime=30; //准备延时30 ms


KeyTask++; //准备好下一个任务


kcy=0;


}


break;


case I:KeyTime--; //延时30 ms




if(KeyTime==0)Key+ask++;


break;


case2;if(RB4==o){


//调按键处理程序


KeyTask=0;


}


else KeyTask=0;//退出任务


break;


}


}




在主程序的死循环中这样用:


while(1){


TimeEnable();


If(SYSTime==1){scankey();)


//在此可以添加其他程序


只有有时问消息的时候才执行按键扫描程序。可以看到,进入扫描程序执行第一次的时候,程序首先判断按键标志位有没有置位,置位的话(也就是有按键按下的 话),任务时间参数(KeyTime)赋值为30,这是延时30ms,去抖,当然你也可以设置为其他的时间值;同时任务参数 (KeyTask)加1。1ms后,再进入扫描程序,这个时候扫描程序执行casel的语句,这样30次后(延时了30ms),任务参数 (KeyTask)加1,值为2。lms后,再进入扫描程序,将执行case 2的语句,首先在这里再次判断是不是按键还在按下,如果是就调按键的处理程序,如果不是。就退出按键扫描程序。在这里,还可以加入按键是否抬起的判断程 序。


这样设计的引脚变化程序,CPU开销小,效率高,不会出现堆浅溢出的问题,提高了系统的实时性。

关键字:PIC  中断程序  设计技巧 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic488341.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:PIC16C72A在汽车智能仪表中的应用
下一篇:PIC单片及定时器溢出中断的设计思路及程序设计

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

PIC16F1829 TIMER0初始化程序
简介:本文和大家分享一个PIC16F1829 TIMER0初始化程序,感兴趣的朋友可以看看。//timer0 分频值#define TIMER0_DIV2 (0<<0)#define TIMER0_DIV4 (1<<0)#define TIMER0_DIV8 (2<<0)#define TIMER0_DIV16 (3<<0)#define TIMER0_DIV32 (4<<0)#define TIMER0_DIV64 (5<<0)#define TIMER0_DIV128 (6<<0)#define
发表于 2020-02-08
PIC16F1829 TIMER1初始化程序
简介:在这里和大家分享一个PIC16F1829 TIMER1初始化程序,感兴趣的朋友可以看看。//timer1 分频值#define TIMER1_DIV1 (0<<4)#define TIMER1_DIV2 (1<<4)#define TIMER1_DIV4 (2<<4)#define TIMER1_DIV8 (3<<4)//-------------#define T1_FOSC (1<<6) #define T1_FOSC_4 (0<<6)//---------------#define TIMER1_IEN_ENB
发表于 2020-02-08
PIC16F690 时钟初始化实例
简介:在这里和大家分享一个PIC16F690时钟初始化的程序。//时钟源选择#define CLKS_INT (1<<1)//内部时钟#define CLKS_CONFIG (0<<1)//由配置1决定时钟//内部振荡频率选择 #define IRCF_31KLF      (0<<4)#define IRCF_125KMF    (1<<4)#define IRCF_500KMF    (3<<4)#define IRCF_1MHF   
发表于 2020-02-08
PIC单片机振荡电路中怎样选择晶体?
PIRX 注: X可以是1 2 3 4.。。。不同型号的单片机数目不同INTCON 中断控制寄存器讲解:1开启或关闭 全体的中断功能(GIE)2开启或关闭全体外设的中断功能(PEIE)外设就是在外设中断允许/标志寄存器里面所写的设备。3开启一些中断事件。PIEX 与 PIRX 是相互对应的如:当把PIE1的TMR1IE设置为1 定时器timr1将开启中断。等到TMR1定时器溢出后,则会在PIR1的TMRIF将为1,并且执行中断程序。实例讲解:我们把上一讲的《PIC单片机之定时器》中的实例修改成中断方式 实现 每隔 50MS亮起LED,每隔50MS灭掉LED。/*开发环境MPLAB X IDE 芯片型号PIC
发表于 2020-02-08
PIC单片机程序设计需要注意的一些问题及看法
一、区分指令的大小写编写PIC单片机的源程序,除了源程序的开始处需要严格的列表指令外,还须注意源程序中字母符号的大小写规则,否则在PC机上汇编程序时不会成功。在源程序中都会使用伪指令INCLUDE。这条指令将列表中指定的单片机文件(在MPLAB中)渎入源程序作为源程序的一部分,所以凡是MPLAB中有关该单片机已有的寄存器在源程序中无须再用赋值指令(EQU)赋值,这就使所建立的源程序大为简化。此外,由于有了伪指令INCLUDE,所以根据MPLAB软件中的格式,在源程序中的操作数凡是涉及MPLAB已规定的寄存器名称的,其字母一律只能大写,不能小写。其余操作码、符号字母可任意大小写,但0x中的X应小写。否则汇编不会成功。鉴于上述原因
发表于 2020-02-08
关于PIC单片机之探讨低功耗
1、睡眠(sleep)睡眠方式是我们最常用的一种方式来降低功耗,但睡眠期间单片机不能做任何的事情。对于那些没事情就睡着,有事情就做一下的情况睡眠无疑是功耗最低的处理方式。比如:睡眠+ I/O电平变化中断唤醒当按键没按下时,单片机睡眠,当按键按下后,执行相应的工作。睡眠+数据接收中断唤醒这样单片机就可以再没有接收到数据时候进入睡眠状态,接收到数据的时候就唤醒然后处理数据。当然首先单片机要有相关的外设比如SPI ,I2C,USART,等这些支持这些通讯的模块。睡眠+看门狗唤醒这个可以用在需要定时唤醒做事情的场合2、降低时钟频率如果即想功耗低,又想单片机在能低功耗的情况下工作。这无疑是个最好的选择。PIC单片机 比如PIC
发表于 2020-02-08
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved