PIC单片机中断程序的设计技巧
PIC单片机中断程序设计技巧
![PIC单片机中断程序设计技巧](https://img.taocdn.com/s3/m/bf2d12c47c1cfad6195fa7fd.png)
PIC 单片机中断程序设计技巧
所有的中档系列PIC 单片机,PORTB 端口最高的4 个引脚(RB7~RB4)在设为输入模式时,当输入电平由高到低或由低到高发生变化时,可以让单片
机产生中断。
这就是通常所说的引脚状态变化中断。
在设计引脚中断程序时,有三个需要特别注意的地方。
一是,在清除
P0RTB 中断标志位RBIF 之前,必须安排一条必不可少的,以PORTB 端口数据寄存器PORTB 为源寄存器的读操作指令。
放置这一指令的目的有时并
不只是为了读取有用的数据,而是为了取消状态变化的硬件信号,以便顺利
清除RBIF 标志位,为下一次中断做好准备。
二是,由于端口PORTB 是引脚电子变化中断,即无论引脚出现上升沿还是下降沿都会产生中断请求,所以
必须处理好不需要的虚假中断。
三是,一般都利用PIC 单片机的引脚功能来检测按键,所以必须处理好按键消抖的问题。
引脚中断程序设计
在主程序里先设置有关的寄存器。
◇设置TRISB 寄存器,使RB7~RB4 相关的引脚处于输入状态;
◇如果需要弱上拉,通过OPTION_REG 的第7 位设置;
◇RBIF=O;。
PIC系列单片机的中断资源特点及其应用方法详解
![PIC系列单片机的中断资源特点及其应用方法详解](https://img.taocdn.com/s3/m/fdee83587fd5360cba1adb7c.png)
PIC系列单片机的中断资源特点及其应用方法详解1 PIC单片机简介PIC系列单片机是美国Microchip技术公司推出的高性能价格比的8位嵌入式控制器(Embedded Controller),它采用了精简指令集计算机RISC (Reduced Instruction Set Computer)和哈佛(Harvard)双总线以及两级指令流水线结构。
具有高速度、低工作电压、低功耗等特点和优良的性能价格比,因而PIC系列单片机越来越受到单片机开发与应用工程技术人员的青睐。
该系列独特的结构和中断资源使其在使用时与其它系列的单片机有许多不同之处。
下面以PIC16CXX系列微控制器为例来介绍PIC 系列单片机的中断资源特点以及应用方法。
2 中断资源的开发与屏蔽图1是PIC16C64/64A/65/65A的中断逻辑电路图,其它型号芯睡的中断资源也大致相同,只是资源多少不一而已,但它们的中断入口只有一个(入口地址在004H)。
PIC 单片机的中断大致可以分为两类。
第一类是由中断控制器INTCON直接控制的中断,包括外部引脚中断INT的RB口电平变化中断以及定时器TMRO溢出中断,它们的中断允许位和中断标志都在INTCON寄存器中。
引脚中断INT和定时器TMRO溢出中断与其它微处理器相同。
RB口电平变化中断是PIC 单片机特有的中断,当把RB口高4位I/O口线设置为输入时,只要这4位I/O 口线上的电平发生变化就会引起中断。
RB口的电平中断特性对用户是非常有用的。
用户可以直接利用这些口线的关键部位进行电平检测,并可利用中断进行保护性控制等操作;另一方面,电平中断特性还可以利用RB口的软件控制弱上拉特性组成一个矩阵键盘,并用按键唤醒CPU,这对于那些以电池供电的系统特别有用。
另一类是外围接口中断,包括定时器TMR1溢出中断、TMR溢出或匹配中断、同步串行口中断、异步串行口中断、并行从动口中断和CCP(Capture/Compare/PWM)中断等,而带A/D功能的PIC16C7X系列微处理器还有A/D转换完成中断。
PIC单片机中断程序设计技巧
![PIC单片机中断程序设计技巧](https://img.taocdn.com/s3/m/bf2be94916fc700abb68fc58.png)
PIC单片机中断程序设计技巧
所有的中档系列PIC 单片机,PORTB 端口最高的4 个引脚(RB7~RB4)在设为输入模式时,当输入电平由高到低或由低到高发生变化时,可以让单片机产
生中断。
这就是通常所说的引脚状态变化中断。
在设计引脚中断程序时,有三个需要特别注意的地方。
一是,在清除P0RTB 中断标志位RBIF 之前,必须安排一条必不可少的,以PORTB 端口数据寄存
器PORTB 为源寄存器的读操作指令。
放置这一指令的目的有时并不只是为了
读取有用的数据,而是为了取消状态变化的硬件信号,以便顺利清除RBIF 标
志位,为下一次中断做好准备。
二是,由于端口PORTB 是引脚电子变化中断,即无论引脚出现上升沿还是下降沿都会产生中断请求,所以必须处理好不需要
的虚假中断。
三是,一般都利用PIC 单片机的引脚功能来检测按键,所以必须处理好按键消抖的问題。
引脚中断程序设计
在主程序里先设置有关的寄存器。
◇设置TRISB 寄存器,使RB7~RB4 相关的引脚处于输入状态;
◇如果需要弱上拉,通过OPTION_REG 的第7 位设置;
◇RBIF=O;
◇RBIE=1;
◇GIF=1。
响应状态变化后的中断服务程序。
◇检查RBIF 是否为l,为l 则是引脚变化引起的中断;
◇调用延时程序,延时20~30 ms,目的是为了按键去抖;。
PIC中档单片机的中断总结
![PIC中档单片机的中断总结](https://img.taocdn.com/s3/m/3b60851353d380eb6294dd88d0d233d4b14e3f5d.png)
PIC中档单片机的中断总结对于来说,一次中断的过程大致有下列阶段:为了使得解释形象和直观,本文采纳一些诙谐的语句来比方解释:中断哀求---------比方成申请买经济适用房的哀求中断标记-------一份申请书本中断使能xxIE-----本单位领导PEIE-------------户口办公室主任GIE--------------银行的管理信贷的科长中断哀求:房子太少,儿子要结婚了,得买房了,可资源和财力有限,不能卖商品房,只好按特别状况处理,写一份申请书(中断标记位IF 置1);本单位领导xxIE看了之后,假如给你盖了一个戳:(即该中断使能位IE=1),那么恭喜你,这份申请书可以提交到更高一级的部门;假如没盖(xxIE= 0),那么对不起,先放我这里吧,等我们讨论讨论好后再说。
假如你不愉快,要拿回申请书撕掉,呵呵,那么IF=0;你的购房哀求之梦破灭;xxIE领导将按照户口,将这些哀求书给分类,一类是外地迁来的户口,提交给户口办公室PEIE主任审查,PEIE主任假如给你盖了个戳(PEIE= 1),那么,他将会把申请书提交给银行的GIE科长批准,否则就是放在这里再讨论讨论或者你要回归撕毁;一类是本地户口,可挺直提交给银行的GIE科长批准,然后你将申请书带到GIE科长的办公室。
GIE科长盖了章之后(GIE=1),然后,你就可以拿着申请书去找房地产商要房子了(此时PC指针=0004H),由于GIE科长有无数事情要做,所以他每盖了一次戳之后(注重是一次不是一个,由于大概有多个中断同时发生,也就是说有其他地方的人来请GIE盖戳),就在办公室门外挂了个牌子:请勿打搅。
他自己则歇息去了,直到接到RETFIE的电话或者有人打他的手机。
房地产商预备给房子了,不过你最好得先把各项手续给填好,叫5w押第1页共4页。
PIC单片机实验5-中断的使用
![PIC单片机实验5-中断的使用](https://img.taocdn.com/s3/m/e4a7ae0f4a7302768e993957.png)
学 班Leabharlann 号 级:106032008176 :08 电信四班
学会 RB 中断的使用,掌握中断处理程序的编程方法
MPLAB IDE v8.33,PIC 实验板
1 2 3 4
根据题目要求画出相应的流程图,见过程分析图例 根据流程图写出程序,并进行软件调试 将调试好的程序下载到 PIC 实验板中进行硬件调试 按键按下,观察 LED 灯的亮灭情况
GOTO LOOP1 ;回到 LOOP1 RETURN ;返回调用程序 ;************************************************************************* END ;程序结束 ;**********************************************************************88
MOVLW 0DH MOVWF 20H LOOP1 MOVLW 0FFH MOVWF 21H LOOP2 DECFSZ 21H GOTO LOOP2 DECFSZ 20H 间跳
;送立即数 0D 到 W 寄存器 ;将 W 寄存器内容的值送到 20H 寄存器 ;移立即数 0FF 到 W 寄存器 ;将 W 寄存器的内容送到 21h 单元 ;21h 单元的内容减一,是否为 0,为 0 则间跳。 ;否,回到 LOOP2 ;20h 单元的内容自减一,检测是否为 0,为 0 则
-------------------------以下内容为教师填写-------------------------教师评阅:
成绩:
PIC单片机中断系统详细汇总
![PIC单片机中断系统详细汇总](https://img.taocdn.com/s3/m/21bb1880ab00b52acfc789eb172ded630b1c98ed.png)
随着物联网、人工智能等技术的发展,中断系统与其他系 统的融合成为未来的发展方向。
在物联网和人工智能应用中,设备需要实时响应各种事件 ,如传感器数据变化、网络数据包到达等。因此,将中断 系统与操作系统、网络协议栈等其他系统进行融合,可以 实现更高效的事件处理和资源调度,提高系统的实时性和 可靠性。
串行通信中断的配置
需要设置串行通信的波特率、数据位、停止位、奇偶 校验等参数,以及中断触发方式。
串行通信中断的应用
在RS-232、RS-485、SPI等串行通信协议中广泛应 用。
外部事件中断
外部事件中断
01
用于实现外部事件触发中断,例如按键按下、传感器触发等。
外部事件中断的配置
02
需要设置外部事件的检测方式、触发条件以及中断处理程序。
中断的作用:提高CPU的效率,实现对外部事件的实时响应 和处理。
PIC单片机的中断源
外中断
由外部硬件设备产生的中断,例如定 时器溢出、串口接收数据等。
内中断
由单片机内部硬件产生的中断,例如 比较器匹配、捕获比较器等。
中断优先级和向量
中断优先级
用于标识不同中断的优先级,优先级高的中断会优先得到处理。
中断处理程序执行
一旦PIC单片机响应中断,它会跳转 到相应的中断向量表地址,执行中断 处理程序。
中断返回和清除
中断返回
中断处理程序执行完毕后,PIC单片机会自动返回到被中断的程序继续执行。
中断清除
某些中断源在响应后会自行清除中断标志位,而有些则需要手动清除。
03
PIC单片机中断系统的应用
定时器中断
中断处理程序应遵循一定的编写规范,以确 保程序正确、稳定地运行。例如,应避免在 中断处理程序中进行耗时的操作,以减小对 系统性能的影响。
PIC单片机RB口中断程序设计
![PIC单片机RB口中断程序设计](https://img.taocdn.com/s3/m/412c4865f5335a8102d22003.png)
2 引ISB寄存器,使RB7~RB4相关的引脚处于输入状态;
◇如果需要弱上拉,通过OPTION_REG的第7位设置;
◇RBIF=O;
◇RBIE=1;
◇GIF=1。
响应状态变化后的中断服务程序。
bit SYSTime;
#defineTimeEnable()SYSTime=0,if(SYSlms){SYSTime=l;SYSlms=0;)
可以把TimeEnable()放到主程序死循环的任何地方,每当程序执行这个宏,SYSTime就会清零,这就是标志位的自我消失.如果在定时器时间基准标志位SYSlms已经置位的话,SYSTime就会置1,这样别的程序就可以利用这个时间消息了,这就是消息的自我发布。下面就是利用这个时间消息来进行按键延时去抖的,首先看一下按键扫描子程序;
首先,在定时器中断里设置一个lms的时间基准标志位“SYSlms”,每到lms,“SYSlms”便置位。程序如下:
unsigned char count;
if((ToIE&TOIF)==1){ //定时器中断
TMRO+=0x09; //每250μs中断一次
if(count==4){
if(RB4==0){ //RB4上的按钮接地
key=1; //按键标志位置位
}
RBIF=0; //清除引脚中断标志位
}
其中,if(RB4==0)语句相当于读取了PORTB端口数据寄存器,取消了状态变化的硬件信号。
下面详细介绍怎么样进行按键去抖。
void seaakey()
{
unsigned char KeyTime,KeyTask;//定义任务时间参数、
PIC单片机之中断程序
![PIC单片机之中断程序](https://img.taocdn.com/s3/m/4577af92ad51f01dc281f158.png)
PIC单片机之中断程序
什么是中断程序呢?
形象的生活比喻就比如你现在这在看我的文章,突然你的朋友喊你一起去烤地瓜,这时候你就中断了看文章和朋友烤地瓜去了,烤完地瓜之后你又回来看文章。
烤地瓜这件事就好比中断程序,他中断了你看文章这件事。
在程序方面来说当CPU 在执行一个程序的时候,突然产生了中断事件CPU 就去执行中断程序了,当执行完成后CPU 又回来执行原先的程序。
中断事件
什么是中断事件,就是引起中断的事件。
对于单片机来说这些事件是多种多样的。
比如说一个按键按下,一定的时间到了,一串数据发送完毕,或接收完一个数据。
讲到中断不得不讲讲和中断相对的查询。
其实不管是按键按下还是时间到,还是数据发送完毕,这些事实上都可以用查询的方式办到。
比如你是经理如果你想知道属下任务完成了没有一种方式就是去询问属下,任务完成没有。
早上没完成,下午在问。
下午没完成第二天再问。
一直到完成为止这种方式就相当于查询的方式,另一种就是然属下完成任务好直接汇报,在下属执行任务的期间你无需去打挠下属,当下属任务完成后就第一时间向你汇报,这种方式就好像中断。
查询方式:缺点就是可能会大量浪费CPU 的时间,不断去查询。
如果事情
不多还好,可是一旦事情多了会明显感到运行速度变慢。
中断方式:可以用在对时间和响应速度有要求的场合。
具体有哪些事件会引起中断可以看
1,中断控制寄存器INTCON。
pic单片机中断
![pic单片机中断](https://img.taocdn.com/s3/m/0fefa197a0116c175f0e484a.png)
PIC18系列的低优先级中断入口地址在0x0018地址,下面的代码是在入口地址处放置一个向量函数,这个向量函数里就是一个内嵌汇编的GOTO指令,GOTO到低优先级的中断服务函数InterruptHandlerLow。
//----------------------------低优先级中断入口-----------------------------------1#pragma code InterruptVectorLow = 0x18 //用#pragma伪指令定义一个名字叫InterruptVectorLow的段,并把这个段放到0x18地址起始的代码空间2void InterruptVectorLow (void) //低优先级中断向量函数3 {4_asm5goto InterruptHandlerLow //内嵌汇编指令6_endasm7 }8#pragma code //这里不是多余的,它是告诉连接器回到默认的代码段,如果不加的话,连接器就会傻傻地把后面的代码紧跟着上面的代码一直放下去。
而LKR文件里定义了向量区最多到0x29地址,所以如果没加此行通常会报错910#pragma interruptlow InterruptHandlerLow //这里使用interruptlow这个关键词来声明InterruptHandlerLow这个函数是低优先级中断服务函数,用了关键词后,这个函数将会由编译器自动产生基本的现场保护,并且这个函数的返回将是使用RETFIE 返回的。
111213void InterruptHandlerLow (void)14 {15/* 低优先级服务函数的代码写在这里*/16 }PIC18系列的高优先级中断入口地址在0x0008地址,下面的代码是在这个入口地址处放置一个向量函数,这个向量函数里就是一个内嵌汇编的GOTO指令,GOTO到高优先级的中断服务函数InterruptHandlerHigh 。
PIC单片机中断系统详细汇总
![PIC单片机中断系统详细汇总](https://img.taocdn.com/s3/m/b4809d24793e0912a21614791711cc7931b778b8.png)
PIC单片机中断系统详细汇总在PIC单片机中,中断系统的实现主要包括以下几个方面的内容:1.中断向量表:PIC单片机中的中断系统采用了向量表的形式来管理不同类型的中断。
向量表是一个存放中断服务子程序入口地址的表格,当中断发生时,单片机根据中断号在向量表中查找相应的中断服务子程序入口地址,并跳转到该地址处执行相应的操作。
2.中断优先级:PIC单片机中的中断系统支持多级中断优先级。
不同的中断可以设置不同的优先级,当多个中断同时发生时,系统会根据优先级的设置,优先处理优先级较高的中断,从而保证重要的中断不会被忽略。
3.中断源:PIC单片机支持多个中断源,包括外部中断(外部引脚上的信号触发的中断)、定时器中断(由定时器溢出或比较事件触发的中断)和串口中断(由串口接收/发送数据触发的中断)等。
每个中断源都有对应的中断标志位,当中断发生时,对应的中断标志位会被设置,以便主程序判断中断类型并做出相应的处理。
4.中断使能和屏蔽:PIC单片机中的中断系统提供了中断使能和屏蔽的功能。
通过设置相应的中断使能和中断屏蔽寄存器的位,可以控制一些中断源的中断是否启用,以及在一些中断源触发中断后,是否允许继续触发该中断。
5.中断服务子程序:PIC单片机的中断系统需要用户自行编写中断服务子程序来处理中断事件。
中断服务子程序是一个与主程序独立的子程序,它会在中断发生时被自动调用,并执行特定的操作。
在编写中断服务子程序时,需要注意子程序的实时性和占用资源的情况,以确保中断的及时响应和系统的稳定性。
6.中断处理流程:PIC单片机中的中断处理流程可以简单描述为:当中断发生时,系统会根据中断号在中断向量表中查找相应的中断服务子程序入口地址,并跳转到该地址处执行中断服务子程序。
在中断服务子程序中,可以对中断事件进行处理,清除中断标志位,并在需要的情况下触发其他操作,比如发送数据、修改相关寄存器等。
当中断服务子程序执行完毕后,系统会自动返回到主程序的执行流程中,继续执行之前的任务。
PIC单片机的中断程序
![PIC单片机的中断程序](https://img.taocdn.com/s3/m/08d2fe2b58fafab068dc0214.png)
PIC单片机的中断程序PIC 单片机的中断程序中断是 PIC 高手必须掌握的武器,转贴一篇,还希望大家补充发表对中断应用的见解。
与 51 或者其他系列的单片机相比,PIC 单片机的中断机制有其特殊之处,针对我们一些初学者存在的一些问题和疑惑,我在此做一个个人总结,不当的地方,请站友们指正。
先摘引三个对 PIC 中断理解的回帖,然后我再对中断活动的过程、应该注意的事项、及一个疑惑进行较详细的总结和解释。
--------------- john frank :关于 pic 中断有些不明白的地方借用大虾的程序中断服务代码 btfss INTCONT0IE 判断是否为 T0 中断 goto other_int btfssINTCONT0IF it ?s the time of T0 int goto other_int bcf INTCONT0IF 是T0 中断清除中断标志 movlw 0x10 微秒的高位字节加上定时时间 256x16 分频40960x1000 的高位0x10addwf us1goto end_intother_int 可添加其他中断服务代码nop other isr code can be added end_int 恢复现场假如又有新的中断正好在这段程序中间产生 btfss INTCONT0IFgoto other_intbcf INTCONT0IF 程序岂不是要出错跑飞了 john frank:谢谢你的关注。
我讲一下自己的理解,权做回答,不当之处,还请站友们指点。
pic 中档单片机系列没有“硬件中断优先级别”(请允许我这样说),含义是指:当内核正在处理当前的中断服务 A 时,在这个期间里,其他任何中断的产生,只能使其标志位 xxIF 置 1,不能剥夺当前中断服务对CPU 的占用权(反应在 PC 指针不能被新的中断改变指向),必须等到当前中断服务处理 A 完毕,然后,根据 goto other_int 语句的转向,依次判断。
PIC单片机的端口RB中断的设计思路及电路设计
![PIC单片机的端口RB中断的设计思路及电路设计](https://img.taocdn.com/s3/m/b5c498702e3f5727a4e9622b.png)
PIC单片机的端口RB中断的设计思路及电路设计
1. 设计思路本例利用PIC16F877 的RB 端口中断设计一个抢答器,该抢答器可供不多于4 个参赛队或者个人的抢答比赛场合使用。
每个参赛队的座位前安装1 只抢答按钮开关和1 个信号灯。
主持人的座位前安装1 只复原按钮开关、1 只蜂呜器和1 个抢答器工作状态指示灯。
每当主持人发出允许抢答的命令之后,哪个队先按下座位J 的按钮开关,该座位的信号灯就先被点亮,司时封锁其他按钮开关的活动,并且熄灭主掎人座位阝的状态指小灯和发出3 声类似于电话振铃的提示声,以声明此次抢答动作已经完成。
在主持人确认后,按下“复原”按钮,状态指示灯重新点亮,并且同时发
出“笛、笛”声,为下一次的抢答做好准备。
2.电路设计
电路原理图如图所示。
图电路原理图
电路中的蜂鸣器FM 是一只带有助音腔的压电陶瓷蜂鸣器,用于模拟发
出报警声,在FM 发声的同时,灯D6 也在发光。
FM 可以看作是一个电容性负载,本身不能流过直流电流。
发声的原理是,作用在两个电极极板的电位在发生变化时陶瓷材料就发生弯曲,从而振动空气发出声音。
FM 和4 只按钮开关SWa~SWd 以及4 只电阻Ra~Rd 都是在演示板的基础上额外添加的。
由于端口RB 内部具有上拉电阻,只要用软件设置其有效,即可省略在4 只端口引脚上外接的上拉电阻。
按钮开关和指示灯与座位的对应关系如表所示。
PIC单片机的INT中断设计思路及程序设计
![PIC单片机的INT中断设计思路及程序设计](https://img.taocdn.com/s3/m/07644f42581b6bd97f19eadf.png)
PIC单片机的INT中断设计思路及程序设计
1. 设计思路PIC 单片机端口RC 连接8 只发光二极管LED 作为流水灯模拟发光部件。
利用片内的定时器/计数器TMR0 模块和中断逻辑功能部件,使TMR0 工作在定时器模式,并且在超时溢出时向CPU 发送中断请求信号,
外部中断信号输入脚INT 作为电源故障检测端。
电源电压检测模块电路原理图如图1 所示,流水灯电路原理图如图2 所示.
图1 电源电压检测模块电路原理图
图2 流水灯电路原理图
2. 程序设计
程序设计流程如图3~图6 所示。
图3 主程序流程
图4 中断服务程序流程
图5 延时子程序1 流程
图6 延时子程序2 流程tips:感谢大家的阅读,本文由我司收集整编。
仅供参阅!。
《PIC16系列单片机C程序设计与proteus仿真》学习之1----RB0_INT中断编程
![《PIC16系列单片机C程序设计与proteus仿真》学习之1----RB0_INT中断编程](https://img.taocdn.com/s3/m/b59b576a1eb91a37f1115cda.png)
《PIC16系列单片机C程序设计与proteus仿真》学习之一----RB0/INT中断编程//用RB0/INT按键,每按一下,LED翻转亮,晶振4MHZ#include<pic.h>//#include<pic16f8xx.h>__CONFIG(0x3f71);//配置为设定:XT,WDT,off等#define LED RB1 //所有有LED字符的地址实际上是RB1char A; //全局变量,保存LED的状态void DELAY(unsigned int);void interrupt ISR(void);void main(){OPTION=0b00000000; //B口弱上拉,RB0为下降沿触发中断TRISB =0b00000001;//设定RB0为输入,RB1为输出(置1为输入,置0为输出)INTCON=0B10010000; //允许RB/INT中断LED=1; //RB1=1,先让LED灯亮A=1;while(1); //原地等待中断}//-------delay n msvoid DELAY(unsigned int n){unsigned int j;char k;for(j=0;j<n;j++)for(k=246;k>0;k--) NOP();}//----interrupt isrvoid interrupt ISR(void){if(INTF==1)//如果是INT中断才执行以下程序{DELAY(30);//先延时消抖INTF=0; //消抖后才将INT中断标志清零if(A==1){A=0;LED=0;}else{A=1;LED=1;}}}-------------------------------------------------PROTEUS如下:PS:详情请参考《PIC系列单片机设计与PROTEUS仿真》一书P114。
PIC-RB口中断设计
![PIC-RB口中断设计](https://img.taocdn.com/s3/m/b8b46532b90d6c85ec3ac6ad.png)
所有的中档系列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)清除,这样其他中断就暂时不能被响应(此时,如果别的中断发出的中断请求,标志位将一直保留着),直到这个中断程序退出后才会得到响应。
这就要求我们设计中断程序的时候必须尽量短,避免调用子程序,更不要在中断里进行复杂的运算。
PIC实验报告(中断、定时、PWM、AD程序代码)
![PIC实验报告(中断、定时、PWM、AD程序代码)](https://img.taocdn.com/s3/m/b937fe6ea98271fe910ef941.png)
实验一:定时器1. 实验目的:利用定时器0,定时器1,定时2实现4盏流水灯2. 实验内容 a,程序框图定时器0:/************************************************** 计算公式:(256-X)*K*T=25 000us,定时器延时25ms,预分频为K 为64,利用软件编程实现1s 脉冲输出,RB0作为输出 ************************************************/ #include<pic.h>__CONFIG(0x20F1); __CONFIG(0x3F71); #define T0_25MS 61 char a=0;void interrupt ISR() {if(T0IF==1)定时器1定时500MS定时器0定时50MS 、定时器1定时器2定时50MS时间到? 时间到? 时间到?a 的值加1 led 灯循环左移一位 a 的值加1a=20?a=10?a=0,led 灯循环左移一位 a=0,led 灯循环左移一位开始开始开始T0IF=0;TMR0=T0_25MS;a++;if(a==20) //输出1s脉冲{PORTD=(PORTD<<1);a=0;if(PORTD==0x10)PORTD=0x01;}}}void timer0init(){OPTION=0b10000110; //,预分频器给TMR0,TMR0预分频系数为1:64 INTCON=0b10100000; //GIE,PEIE置1}void main(){timer0init();TRISD=0;PORTD=0x01;while(1);}定时器1:/**************************************************计算公式:(65536-X)*K*T=500 000us,定时器延时500ms,预分频为8,利用软件编程实现1s脉冲输出,RB0作为输出************************************************/#include<pic.h>__CONFIG(0x20F1);__CONFIG(0x3F71);#define T1_500MS 3036void interrupt ISR(){if(TMR1IF==1){TMR1IF=0;TMR1H=T1_500MS>>8;TMR1L=T1_500MS;PORTD=(PORTD<<1);if(PORTD==0x10)PORTD=0x01;}void timer1init(){TMR1H=T1_500MS>>8;TMR1L=T1_500MS;TMR1IE=1;INTCON=0b11000000; //GIE,PEIE置1T1CON=0b00110001;; //TMR1预分频系数为1:8}void main(){timer1init();TRISD=0;PORTD=0x01;while(1);}定时器2:/**************************************************计算公式:(PR2+1)*K1*K2*T=50 000us,定时器延时50ms,预分频为K1为16,后分频器K2为15利用软件编程实现1s脉冲输出,RB0作为输出************************************************/#include<pic.h>__CONFIG(0x20F1);__CONFIG(0x3F71);#define LED RB0char a=0;void interrupt ISR(){if(TMR2IF==1){TMR2IF=0;a++;if(a==10) //1秒到了{PORTD=(PORTD<<1);a=0;if(PORTD==0x10)PORTD=0x01;}}}void timer2init()TMR2IE=1;PR2=207;INTCON=0b11000000; //GIE,PEIE置1T2CON=0B001110111; //TMR2预分频系数为1:16,后分频器为1:15 }void main(){timer2init();TRISD=0;PORTD=0x01;while(1);}实验二:RB0中断1.实验目的:a.利用外部中断RB0实现流水灯左移2.程序框图:开始RB0按下?进入中断,led灯循环左移一位程序:#include<pic.h>__CONFIG(0x20F1);__CONFIG(0x3f71);void delaynms(unsigned int n);void interrupt ISR(void);void main(){OPTION=0b00000000;ANS12=0;WPUB0=1;TRISB=0b00000001;INTCON=0b10010000;TRISD=0b00000000;PORTD=0x01;while(1);}void interrupt ISR(void){if(INTF==1){delaynms(30);INTF=0;PORTD=(PORTD<<1);if(PORTD==0x10)PORTD=0x01;}}void delaynms(unsigned int n){unsigned int j;char k;for(j=0;j<n;j++)for(k=246;k>0;k--)NOP();}实验三:AD转换1.实验目的:利用PIC内部AD转换器,AN0通道口采集模拟数据,通过LCD1602显示结果2.程序框图:程序:#include<pic.h>__CONFIG(0x3F39); __CONFIG(0x20F1); #define RS RD4 #define RW RD5 #define E RD6#define uint unsigned int char QW,BW,SW,GW;//8段共阳LED 显示代码,0位-7位分别控制a -h 段const char LED_CODE[]={0b11000000, 0b11111001,0b10100100,0b10110000,0b10011001, 0b10010010,0b10000010,0b11111000,0b10000000,0b10010000,0b01111111}; uint AD_SUB(char k);void init1602(); //1602初始化 void write_com(char com);//写指令 void write_date(char data);//写数据 void delaynms(unsigned int n); void spiinit();void SPI_WRITE(char ); void displayled(); void display1602(); void BCD(uint R1); void main() {uint y;TRISA=0b00000001;选择AD 通道启动ADGODON E=0?数据送1602显示初始化数据送数码管显示 开始ANSEL=0b11111111; //AN0~AN7为模拟输入,上电默认,可不设TRISD=0; //D口设置为输出PORTD=0;spiinit();init1602();while(1){y=AD_SUB(0); //0表示第0个通道BCD(y);displayled();display1602();delaynms(500); //此不不能忽略}}void BCD(uint R1){QW=0;BW=0;SW=0;GW=0;while(R1>=1000){R1-=1000;QW++;}while(R1>=100){R1-=100;BW++;}while(R1>=10){R1-=10;SW++;}GW=R1;}void displayled(){SPI_WRITE(GW); //先发个位SPI_WRITE(SW); //发十位SPI_WRITE(BW); //发百位SPI_WRITE(10); //发小数点SPI_WRITE(QW); //发千位}void display1602(){write_com(0x80);write_date(0x30+QW);write_date(0x2e); //小数点write_date(0x30+BW);write_date(0x30+SW);write_date(0x30+GW);write_date(0x56); //"V"}void SPI_WRITE(char b){char BUF;BUF=LED_CODE[b];SSPBUF=BUF; //发出数据while(BF==0);BUF=SSPBUF;}void spiinit(){TRISC=0b00010000;SSPEN=1;CKP=1;SSPM3=0;SSPM2=0;SSPM1=0;SSPM0=1;SMP=1;CKE=0;}uint AD_SUB(char k){char i;uint temp;float x;ADCON0=0b01000001; //TAD=8TOSC,ADFM=1; //设置成右对齐ADCON0|=(k<<4);for(i=1;i<5;i++)NOP(); //打开AD通道后延时20us左右GODONE=1; //开始AD转换while(GODONE==1); //等待转换完成ADIF=0;temp=ADRESH<<8;temp|=ADRESL;x=temp/1023.0*5.0;temp=x*1000;return(temp);}void init1602(){delaynms(20); //延时时间大于15mswrite_com(0x03);delaynms(5);write_com(0x03);delaynms(5);write_com(0x03);delaynms(5);write_com(0x02); //归HOME位,此不不可少delaynms(5);write_com(0x28); //工作方式设置,4位数据线,2行字符,5*7字体write_com(0x0c); //显示开关设置,画面开,光标消失,禁止闪烁write_com(0x06); //输入方式设置,AC为加一计数器write_com(0x01); //清屏write_com(0x80); //开始显示位置delaynms(2);}void write_com(char com){RS=0; //写指令RW=0;PORTD&=0xf0; //低四位清0E=1; //有效发送PORTD|=((com>>4)&0x0f);//先发高四位delaynms(5);E=0;PORTD&=0xf0;E=1;PORTD|=(com&0x0f);//再发低四位delaynms(5);E=0;}void write_date(char data){RS=1; //写数据RW=0;PORTD&=0xf0;E=1;PORTD|=((data>>4)&0x0f);//先发高四位delaynms(5);E=0;PORTD&=0xf0;E=1;PORTD|=(data&0x0f); //再发低四位delaynms(5);E=0;RS=0;}void delaynms(unsigned int n){unsigned int j;char k;for(j=0;j<n;j++)for(k=246;k>0;k--)NOP();}实验四:PWM1.实验目的:通过PIC单片机输出PWM不同占空比脉冲波形2.程序流程:程序:#include<pic.h>__CONFIG(0x3f3a);char a;void CSH();void interrupt ISR(void);void delaynms(unsigned int n); void main(){CSH();while(1){if(a==0)开始初始化占空比为0.1RB0是否按下进入中断,a加1a=1,则输出占空比0.1 a=2,则输出占空比0.3a=3,则输出占空比0.6a=4,则输出占空比0.9a=5,则a清0,占空比为0.1CSH();}}void CSH(){TRISC2=0;TRISD=0;PR2=249;CCPR1L=0x32;CCP1CON=0x0c;T2CON=0x05;OPTION=0b00000000;ANS12=0;WPUB0=1;TRISB=0b00000001;INTCON=0b10010000;}void interrupt ISR(void){if(INTF==1){delaynms(30);if(RB0==0){INTF=0;a++;switch(a){case 1:CCPR1L=0x19;PR2=249;CCP1CON=0x0c;T2CON=0x05;break; //占空比0.1 case 2:CCPR1L=0x4b;PR2=249;CCP1CON=0x0c;T2CON=0x05;break; //占空比0.3 case 3:CCPR1L=0x96;PR2=249;CCP1CON=0x0c;T2CON=0x05;break; //占空比0.6 case 4:CCPR1L=0xe1;PR2=249;CCP1CON=0x0c;T2CON=0x05;break;// 占空比0.9 case5:a=0;break;}}}}void delaynms(unsigned int n){unsigned int j;char k;for(j=0;j<n;j++)for(k=246;k>0;k--)NOP();}。
pic单片机串口中断写法
![pic单片机串口中断写法](https://img.taocdn.com/s3/m/844c9c850d22590102020740be1e650e52eacfc3.png)
pic单片机串口中断写法在PIC单片机中,串口中断的写法通常涉及到以下几个步骤:1. 配置串口:首先,你需要配置PIC单片机的串口模块。
这包括设置波特率、数据位、停止位等参数。
2. 配置中断:接下来,你需要配置PIC单片机的中断模块。
你需要设置中断触发方式(上升沿、下降沿或电平变化),并启用串口中断。
3. 编写中断服务程序:最后,你需要编写串口中断服务程序。
当串口接收到数据或发送数据完成时,将触发中断。
在中断服务程序中,你可以执行相应的操作,例如读取接收到的数据或发送数据。
下面是一个简单的例子,展示了如何编写PIC单片机的串口中断服务程序:```cinclude <>define _XTAL_FREQ // 定义振荡器频率为4MHzvoid main(void)// 配置振荡器OSCICN = 0b; // 设置振荡器频率为4MHz// 配置串口SPBRG = 0x18; // 设置波特率为9600,根据需要调整TXSTA = 0b; // 设置数据位为8位,无奇偶校验位,停止位为1位 RCSTA = 0b; // 启用串口模块,使能发送和接收TRISC6 = 1; // 将TX引脚设置为推挽输出模式TRISC7 = 0; // 将RX引脚设置为输入模式// 配置中断INTCON = 0b; // 启用全局中断,并设置触发方式为下降沿触发 PIR1 = 0b; // 清除串口接收中断标志位PIE1 = 0b; // 使能串口接收中断// 主循环while (1){// 在此处添加其他代码...}// 串口接收中断服务程序void __ISR _U1RXInterrupt(void) interrupt 5 using 2{char receivedByte;receivedByte = RCREG; // 读取接收到的字节// 在此处添加处理接收到的字节的代码...}```请注意,上述代码只是一个简单的示例,实际应用中可能需要根据具体需求进行修改和扩展。
PIC单片机中断程序的设计技巧
![PIC单片机中断程序的设计技巧](https://img.taocdn.com/s3/m/2e2db74c77c66137ee06eff9aef8941ea66e4b70.png)
PIC单片机中断程序的设计技巧设计PIC单片机中断程序时,需要根据具体的需求和硬件环境进行合理的设计。
下面是一些设计中断程序的技巧:1.确定中断触发源:首先需要确定中断是由什么触发的,例如定时器溢出、外部中断引脚等。
根据不同的触发源,可以选择不同的中断方式,如正边沿触发、负边沿触发等。
2.中断优先级设置:如果系统中存在多个中断源,需要明确中断的优先级。
可以通过优先级控制寄存器来设置不同中断的优先级,确保在同时触发多个中断的情况下,能够正确处理高优先级的中断。
3.中断服务程序的编写:中断服务程序是在中断发生时自动执行的程序,因此需要编写相应的中断服务程序。
中断服务程序的编写需要注意以下几点:-保持中断向量表的正确性:中断向量表保存了中断向量地址,确保中断服务程序被正确调用。
需要在程序中配置中断向量表的地址,并确保中断向量表的内容正确无误。
-快速响应中断并尽快执行中断服务程序:由于中断发生时需要尽快进行响应,所以中断服务程序需要尽可能地简短和高效。
可以通过减少循环次数、使用高效的算法等方式来提高中断服务程序的执行效率。
-使用全局变量:中断服务程序通常会修改全局变量的值,所以需要在设计中考虑全局变量的使用规则,防止数据冲突问题的发生。
可以通过使用互斥机制或者禁止一些中断来解决这个问题。
4.确定中断处理的顺序和时间:如果系统中存在多个中断源,需要明确中断处理的顺序和时间。
不同的中断源可能具有不同的优先级,所以需要在设计中明确不同中断的处理顺序,确保每个中断按照优先级进行处理。
5.合理的中断延迟时间:中断处理需要一定的时间,因此需要根据具体需求和硬件环境来确定合理的中断延迟时间。
如果中断处理时间过长,可能会导致系统响应速度变慢,影响整体性能。
因此需要合理地设置中断延迟时间,确保系统能够及时地响应中断。
6.中断嵌套的处理:在一些情况下,可能会存在中断嵌套的情况,即一些中断服务程序中又发生了另一个中断。
在设计中断程序时,需要考虑到中断嵌套的处理方式,例如设置屏蔽中断或者暂时禁止其他中断的发生,确保中断的处理顺序正确无误。
PIC单片机引脚中断程序的设计技巧
![PIC单片机引脚中断程序的设计技巧](https://img.taocdn.com/s3/m/0499689468dc5022aaea998fcc22bcd126ff42d6.png)
PIC单片机引脚中断程序的设计技巧
殷建彬
【期刊名称】《单片机与嵌入式系统应用》
【年(卷),期】2005(000)008
【摘要】所有的中档系列PIC单片机,PORTB端口最高的4个引脚(RB7~RB4)在设为输入模式时,当输入电平由高到低或由低到高发生变化时,可以让单片机产生中断。
这就是通常所说的引脚状态变化中断。
【总页数】2页(P69-70)
【作者】殷建彬
【作者单位】山东省宁阳一中
【正文语种】中文
【中图分类】TP3
【相关文献】
1.Microchip拓展低引脚数产品推出多功能全新20引脚PIC(R)单片机 [J],
2.“精通PIC单片机”实用技术讲座(二)PIC系列单片机的开发(上)—建立源程序的方法 [J], 新鸿
3.“精通PIC单片机”实用技术讲座(九)PIC16F62X的性能和实验板电路—中断程序实例之一 [J], 丁锦源
4.“精通PIC单片机”实用技术讲座(十):PIC单片机指令及其应用——TMRO 中断实验程序 [J], 丁锦源
5.基于低功耗PIC单片机中断技术的液位开关设计 [J], 夏汝华;吴杉;王设计
因版权原因,仅展示原文概要,查看原文内容请购买。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
PIC单片机中断程序的设计技巧
所有的中档系列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开销小,效率高,不会出现堆浅溢出的问题,提高了系统的实时性。