07-中断系统与外部中断应用

外部中断的基本操作与应用

关于51单片机的中断系统
一般来说,51单片机有5个中断源(忽略定时/计数器2),分2个优先级,这个5个中断源按照自然优先级从高到低依次为:
外部中断0INT0

定时/计数器0TF0

外部中断1INT1

定时/计数器1TF1

串口中断RI/TI

下面一图将充分说明51单片机的中断系统结构:

171231xqxwduha6qx6hfff.jpg.thumb

每个中断源都对应着一个固定的入口地址,也就是中断向量,它们依次是:

0 0x0003INT0
1 0x000BTF0
2 0x0013INT1
3 0x001BTF1
4 0x0023RI/TI

也就是说,不管主程序执行到什么地方,只要外部中断1产生请求,内核要响应该中断,就会到0x0013这个地址去执行代码。如果你是在使用汇编语言进行程序开发的时候,你需要记住每个中断源对应的地址;如果你使用的是C语言,你只需要记住中断源的顺序就可以了,也就是最左边的中断号

3、中断相关的寄存器
中断相关的寄存器有4个,每个寄存器都是可以位寻址的,这该编程带来了方便。 其中2个为控制寄存器:IE寄存器IP寄存器

165617a1cwsz3qkjthbn8f.png.thumb

另外2个为中断请求标志:TCON寄存器SCON寄存器

205324oahcr5z126920711.png.thumb

4、关于中断服务函数程序的编写
一般情况下,中断的处理函数有两个,其一为中断初始化函数,其二为中断服务函数。初始化函数就是一个普通的函数,而中断服务函数却有特殊的格式要求:
<1> 中断函数没有返回值,也不能带参数。
<2> 函数名后面要跟一个关键字interrupt,说明这是一个中断服务函数。
<3> 在关键字interrupt后面要跟上中断号,说明这个中断服务函数是为那个中断服务的。

中断服务函数的格式为:
void 函数名() interrupt 中断号
{ ----函数体---- }
我们要利用定时器0来进行间隔定时,中断程序架构我们C语言可以这样写:

165742v1q9l997b455bb5q.png.thumb

20231005144114

由上可知将J5跳帽接到2~3脚,S5按键可以操作外部中断INT0

原理图如下:

20231005162624

方法一:

copy
#include <REGX52.H> sbit L1 = P0^0; sbit L8 = P0^7; // 延时函数 void Delay_ms(unsigned int xms) { unsigned int i,j; for(i = 0; i<xms; i++) { for(j=0;j<299;j++); } } // 10us void Delay(unsigned int t) { while(t--); while(t--); while(t--); } void _74HC138(unsigned char n) { switch(n) { case 4:P2=(P2 & 0x1f) | 0x80; break; case 5:P2=(P2 & 0x1f) | 0xa0; break; case 6:P2=(P2 & 0x1f) | 0xc0; break; case 7:P2=(P2 & 0x1f) | 0xe0; break; } } void SystemInit(void) { _74HC138(5); P0=0X00; _74HC138(4); P0 = 0XFF; } void Working(void) { _74HC138(4); L1 = 0; Delay_ms(1000); // 1us = 1000ms L1 = 1; Delay_ms(1000); } void Init_INT0() { // 源类型选择器 // IT0 = 0; 低电平触发, IT0=1;下降沿触发 IT0 = 1; // 中断使能 EX0 = 1; // 打开总中断 EA = 1; } void main(void) { SystemInit(); Init_INT0(); while(1) { Working(); } } // 由于P3_2口和INT0引脚一致 void Int0_Routine(void) interrupt 0 { L8 = 0; Delay_ms(1000); L8 = 1; Delay_ms(1000); }

方法二:

copy
#include <REGX52.H> sbit L1 = P0^0; sbit L8 = P0^7; // 延时函数 void Delay_ms(unsigned int xms) { unsigned int i,j; for(i = 0; i<xms; i++) { for(j=0;j<299;j++); } } // 10us void Delay(unsigned int t) { while(t--); while(t--); while(t--); } void _74HC138(unsigned char n) { switch(n) { case 4:P2=(P2 & 0x1f) | 0x80; break; case 5:P2=(P2 & 0x1f) | 0xa0; break; case 6:P2=(P2 & 0x1f) | 0xc0; break; case 7:P2=(P2 & 0x1f) | 0xe0; break; } } void SystemInit(void) { _74HC138(5); P0=0X00; _74HC138(4); P0 = 0XFF; } void Working(void) { _74HC138(4); L1 = 0; Delay_ms(1000); // 1us = 1000ms L1 = 1; Delay_ms(1000); } void Init_INT0() { // 源类型选择器 // IT0 = 0; 低电平触发, IT0=1;下降沿触发 IT0 = 1; // 中断使能 EX0 = 1; // 打开总中断 EA = 1; } unsigned char stat_int = 0; void LED_INT() { if(stat_int == 1) { L8 = 0; Delay_ms(1000); L8 = 1; Delay_ms(1000); } stat_int = 0; } void main(void) { SystemInit(); Init_INT0(); while(1) { Working(); LED_INT(); } } // 由于P3_2口和INT0引脚一致 void Int0_Routine(void) interrupt 0 { stat_int = 1; }
posted @   夏日清凉~  阅读(122)  评论(0编辑  收藏  举报
相关博文:
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起