中断 就是 单片机main运行的时候 如果外部传来一个信号,那么就暂时停止现在的正在处理的 事情,转而去处理 这个信号。
处理这个信号完毕以后 又返回去main去继续处理之前的
有个比较好的例子是,
你正在晾衣服
你正在晾衣服,突然水烧开了,你要去把烧水的火关了,然后回来继续晾衣服
中断是有优先级的,如果同时来了多个中断信号,那么就会按一定的优先级来处理
你正在晾衣服,突然水烧开了,这个时候 电话又来了,你要先去接个电话,然后去把烧水的火关了,然后回来继续晾衣服
先权自高到低的顺序即:
外部中断0>定时/计数0>外部中断1>定时/计数1>串行接口
外部中断:
看到外部中断,INT0 是 在P3.2
然而 这个INT0是输入 “副功能”,如果设置某个寄存器的话 这个副功能是不打开的,这个口只是一个P3 的IO口
这个寄存器 是IE
如果要打开这个功能 需要两个 打开IE寄存器的EA,和INT0位,赋值为1
做到这个还单单不够,外部中断还分中断方式,
1、电平触发方式时,中断标志寄存器不锁存中断请求信号,当为这个 P3.2 INT0 口,为低电平的时候出发
2、边沿触发方式时,中断标志寄存器锁存了中断请求。,当这个P3.2 INT0扣为 高电平转为低电平时出发
通过设置TCON这个寄存器来设置上面的触发方式。
IT0 为1的时候 使用电平触发方式,并设置IE0 = 0;
IE0 为1的时候,使用边缘触发方式,并设置IT0 = 0;
在做实验的时候如何 让 INT0口 变为低电平,用杜邦线,接到这个口,然后另外一头接到地GND
///定时器
定时器 通过设置TMOD TCON IE 来控制,
经过的过程是
1.设置TMOD 来设置计时器的模式
3.设置计数的初始值TL0 TH0
3.设置IE 启动中断模式
4.设置TCON 启动计时器
其中 上面的过程3,4都可以打乱,
/**
每秒闪烁一次LED
**/
#include <REGX52.H>
#define MAX_INT 4394967295
sbit led = P1^0;
unsigned int count = 0;
void main(){
//设置计时器,
TMOD = T0_M0_;
//设置时间,50000次一次中断(一个机器周期 50微秒)那么一次中断 下面的就 50ms;
//通常 为了方便计算 ,和 节省资源 这里设置50ms 最合适,
TH0 = (65536-50000)/256;
TL0 = (65536-50000)%256;
//启动计时器0
TR0 = 1;
//开启中断
EA = 1;
ET0 = 1;
while(1);
}
void flash() interrupt 1{
count++;
if(count > MAX_INT){
count = 0;
}
//因为 这里设置了 50ms 一次中断,所以基本20次 就是一秒
if(count%20 == 0){
led = !led;//闪烁
}
}
发现 会有现象因为计数器只有65536个,而一个时钟周期 是只有1微秒,这个根本不够一秒的计数,所以在自己 的那里 在做个%20的判断来计算,
现在按 50ms一次来算是最省资源的
总的来说 用到3个寄存器
IE 控制中断开关
TCON 控制中断启动
TMOD 控制 中断的模式,
关于 计时 :
当一个 一个机器周期(等于12个震荡周期,一个震荡周期 等 1/晶振的频率,单位是微秒)过后,计数器就会+1,然后通过这样来计算,
如果一个 晶振是12MHZ 的那么一个 机器周期 就是 1ms,也就是说 计数器 每+1000 就是秒。