目录
中断系统
中断概念
中断发生:处理a,发生事件b请求cpu去处理
中断响应和中断服务:cpu暂时中断当前工作处理事件b
中断返回:b处理完毕,回到a中断的地方继续处理事件a
中断系统
中断源:引起cpu中断的根源(中断源向cpu提出中断请求)
断点:事件b处理完毕后,回到原来中断的地方
中断系统结构(51)
5个中断源,2个优先级,可实现二级中断嵌套
外部中断
IT0是通过ICON配置的
P3^2是外部中断INT0,
IE0 中断标志位
寄存器
TCON/IE/IP 都为寄存器,需要程序控制
置位/复位
置位为1,复位为0
定时计数器中断
TF0管计数器定时器T0,当T0发生溢出,TF0发生置位
串行口中断请求
RI 接收一帧串行数据,RI置1
TI 发送一帧串行数据,TI置1
中断允许控制
IE寄存器
CPU对中断系统所有中断(EA) 某个中断(5个)的开关控制。(看构造图)中断请求控制
IT0、IT1:外部中断触发方式选择,=1时边沿,=0时电平
IE0、IE1:外部中断请求标志位,当接收到IT0、IT1有效,则置1(看构造图)
优先级
优先级的三条原则
同时接收几个中断时候,首先响应优先级别最高的中断请求
正在进行的中断过程不能被新的同级或者低优先级别的中断请求打断
正在进行的低优先级中断服务,能被高优先级别中断请求所中断
实现上述两条原则方法
中断源
中断号
写程序时候需要用到中断号,也就是当程序输入0时候,外部输入0可以中断,如果再写入一个2,就可以当2发生中断请求,cpu就执行事件3.。。如果想要0中断,但是程序却写成1,那么中断就不回执行了。
中断响应条件
中断源的中断请求
此中断源的中断允许为1
CPU开中断(EA=1)
以上三条满足,CPU才有可能响应中断
使用中断思路,程序员应该干什么?
想使用的中断是哪个?选择相应的中断号
你所希望的触发条件是什么?
你希望中断后干什么?
例子
主程序是为了让中断系统打开
中断服务函数是为了在里面编写中断后运行的程序
Interrupt 0;0是中断号,表示选择中断源,但是首先得打开中断系统的这个寄存器
定时器与计数器
目录
1,51单片机定时计数器
2,CPU时序
3,各个周期值的转换
4,计数器的模
5,分频
6,工作原理
7,内部结构
工作方式寄存器TMOD
控制寄存器TCON
8,工作方式
9,初始化
10,计数器初值的计算
51单片机定时计数器
有两组定时器/计数器,既可以定时又可以计数
定时器/计数器是与CPU互相独立,定时器计数器工作过程是自动完成
定时器/计数器是根据机器内部的时钟或者外部的脉冲信号对寄存器的数据加1
可以增加单片机的效率,简单重复的事情可以交给定时器,cpu处理复杂的事情
定时器可以精确定时
CPU时序
振荡周期:单片机提供的定时信号的振荡源(晶振周期,外加振荡周期)
状态周期(S):2个振荡周期,S周期或时钟周期
机器周期:6个状态周期,12个振荡周期;
指令周期:完成一条指令所占的全部时间,以机器周期为单位
各个周期值的转换
振荡周期=1/12us;
状态周期=1/6us;
机器周期=1us;
指令周期=1~4us;
周期等于频率的倒数
一个字节=8位
计数器的模
计数器运行时,从某一个状态开始依次遍历不重复的各个状态后完成一次循环,所经历的状态总数叫做计数器的模,M表示
分频
分频是指将单一频率的信号降低为原来的1/N,就叫N分频。实现分频的电路或者装置叫做分频器,这里的分频单指信号而言。如33MHZ的信号2分频得到16.5MHZ的信号,3分频得到11MHZ的信号,10分频得到3.3MHZ的信号
工作原理
实质是加1计数器,随着输入脉冲自加1,也就是每来一个脉冲,计数器就加1,加到全为1时,再输入一个脉冲就可以使计数器全为0(51系列单片机内部有两个计数器/定时器,是加1计数器,就是每个机器周期计数值就加1,如原来值是10,加1后就为11.如果是减1计数器就减1,减1后就为9.搞清是加1还是减1,在使用时是有区别的.例如,让单片机计50个数,如果是减1计数器的话,那初始值就是50,每个计数事件后就减1,当50次后就减为0,则计数结束.可是如果是加1计数器的话,还要看计数的最大值是多少,如8位时,最大值是255,模是256,则初始值=256-50=206,这样,每个计数事件后加1,一直加到255,再加1个就是模256了,也就是计数50次后,就要回0,则计数结束.所以,区别是在计算初始值时的方法是不同的.)且计数器的溢出使相应的中断标志位置1,向CPU发出中断请求(定时/计数器中断允许时)。
如果定时器/计数器工作在定时模式,表示定时时间已到。如果工作在计数模式,表示计数值已满。
可见,由溢出时计数器值减去计数初值才是加1计数器的计数值(8位,计数值=256-206=50)
周期
周期等于频率分之一
内部结构
由高8位和低8位两个寄存器THx,TLx组成
TMOD是定时器/计数器的工作方式寄存器,确定工作方式和工作
TCON控制寄存器,控制中断哪个T0,T1的启动和停止,设置溢出标志。
工作方式寄存器TMOD
低四位控制T0,高四位控制T1
Gate门控位,gate=0时,用于控制器的启动是否受外部中断的影响,用TCON中TR0或TR1=1,就可以启动定时计数器工作
Gate=1时,INT0/1=1(高电平),TR0或者TR1=1,可以启动定时计数器。
(一般使用gate=0)
C/T:定时器/计数器模式选择位。C/T=0为定时模式,C/T=1为计数模式。
M1M0:工作方式设置位。定时/计数器有四种工作方
控制寄存器TCON
TF1:溢出中断请求标志位,当T1溢出硬件控制TF1置1。CPU响应中断后TF1由硬件自动清0.T1工作时,CPU可随时查TF1状态。所以可以作测试的标志,同时TF1可以软件置1清0.
TR1:T1运行控制位。置1工作,置0停止。软件控制
工作方式
方式0
定时器模式时有:N=t/Tey
(t:想用定时器定的时间,如1ms
Tey:周期,过1周期计数加1,是时钟频率的倒数,求得想要计数的个数,才是这么长的计时,X为初值,写THx和TLx)
方式1
计数个数与计算初值的关系
X=216-N
方式2
自动重装载,当低8位满了会自动重新装载,从新装载初值不会累加,不会进位
方式3
初始化
对TMOD赋值,确定T0,T1的工作方式
计算初值,并将其写入TH0和TL0或TH1和TL1。
中断方式时,则对EA赋值,开放定时器中断
使TR0或者TR1置位,启动定时器/计数器定时或者计数
计数器初值的计算
机器周期就是CPU完成一个基本操作所需的时间
机器周期=1/单片机的时间频率
机器周期
我们的单片机完成一个操作的最短时间。机器周期主要针对汇编语言而言,在汇编语言下程序的每一条语句执行所使用的时间都是机器周期的整数倍,而且语句占用的时间是可以计算出来的,而 C 语言一条语句的时间是不确定的,受到诸多因素的影响。一个机器周期等于12个时钟周期,所以12✖1/12=1
定时器0实验
- #include<reg52.h>
- typedef unsigned char u8;
- typedef unsigned int u16;
- /*
- 使用定时器,该做哪些工作初始化程序应完成如下工作:
- 对T MOD赋值, 以确定T 0和T 1的工作方式。
- 计算初值,并将其写入TH0、TL0或TH1、TL1。
- 中断方式时,则对EA赋值,开放定时器中断。
- 使TR0或TR1置位,启动定时/计数器定时或计数。
- // TMOD是定时器/计数器的工作方式寄存器,确定工作方式和工作 TCON控制寄存器,控制中断哪个T0,T1的启动和停止,设置溢出标志
- //Gate门控位,gate=0时,用于控制器的启动是否受外部中断的影响,用TCON中TR0或TR1=1,就可以启动定时计数器工作
- //Gate=1时,INT0/1=1(高电平),TR0或者TR1=1,可以启动定时计数器。
-
- //(一般使用gate=0)
-
- //C/T:定时器/计数器模式选择位。C/T=0为定时模式,C/T=1为计数模式。
-
- //M1M0:工作方式设置位。定时/计数器有四种工作方式
- //工作方式寄存器TMOD 工作方式寄存器TMOD用于设置定时/计数器的工作方式,低四位用于T0,高四位用于T1。
- //不明白自己搜索“工作方式寄存器TMOD"
- // 机器周期也就是CPU完成一个基本操作所需要的时间。
- //机器周期=1/单片机的时钟频率。
- //51单片机内部时钟频率是外部时钟的12分频。也就是说当外部晶振的频率输入到单片机里面的时候要进行12分频。比如说你用的是12MHZ的晶振,那么单片机内部的时钟频率就是12/12MHZ,当你使用,12MHZ的外部晶振的时候。机器周期=1/1M=lus。
- //而我们定时1ms的初值是多少呢, 1ms/lus=1000。
- //也就是要计数1000个数,初值=65535-1000+1 (因为实际上计数器计数到66636才溢出)=64536=FC18H
- */
- sbit led=P2^0; //D1
-
- void delay(u16 i);
-
- void Timer0Init()
- {
- TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
-
- TH0=0XFC; //给定时器赋初值,定时1ms
- TL0=0X18;
- ET0=1;//打开定时器0中断允许
- EA=1;//打开总中断
- TR0=1;//打开定时器
-
- }
-
- void main()
- {
- Timer0Init(); //定时器0初始化
- while(1);
-
- }
- void delay(u16 i)
- {
- while(i--);
- }
- void Timer0() interrupt 1 //中断函数
- {
- static u16 i;
- TH0=0XFC; //给定时器赋初值,定时1ms
- TL0=0X18;
- i++;
- if(i==1000)
- {
- i=0;
- led=~led;
- }
- }
外部中断0试验
- /**************************************************************************************
- * 外部中断0实验 *
- 实现现象:下载程序后按下K3按键可以对D1小灯状态取反。
- 注意事项:无。
- 中断响应条件中断源有中断请求;
- 此中断源的中断允许位为1;
- CPU开中断(即EA=1)。
- 以上三条同时满足时,CPU才有可能响应中断
- 以外部中断0为例:
- 主程序中需要有以下代码:
- EA=1;//打开总中断开关
- EX0=1;V/开外部中断0
- ITO=0/1;//设置外部中断的触发方式
- 中断源
- 中断源符号 名称 中断引起原因 中断号
- /INTO 外部中断0 P3.2引脚低电平或下降沿信号 0
- T0 定时器0中断 定时/计数器0计数回0溢出 1
- /INT1 外部中断1 P3.3引脚低电平或下降沿信号 2
- T1 定时器1中断 定时/计数器1计数回0溢出 3
- TI/RI 串行口中串行通信完成一帧数据发送或接收引起中断 4
- ***************************************************************************************/
-
- #include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
-
- typedef unsigned int u16; //对数据类型进行声明定义
- typedef unsigned char u8;
-
- sbit k3=P3^2; //定义按键K3
- sbit led=P2^0; //定义P20口是led
-
- /*******************************************************************************
- * 函 数 名 : delay
- * 函数功能 : 延时函数,i=1时,大约延时10us
- *******************************************************************************/
- void delay(u16 i)
- {
- while(i--);
- }
-
- /*******************************************************************************
- * 函 数 名 : Int1Init()
- * 函数功能 : 设置外部中断1
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Int0Init()
- {
- //设置INT0
- IT0=1;//跳变沿出发方式(下降沿)
- EX0=1;//打开INT0的中断允许。
- EA=1;//打开总中断
- }
-
- /*******************************************************************************
- * 函 数 名 : main
- * 函数功能 : 主函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void main()
- {
- Int0Init(); // 设置外部中断0
- while(1);
- }
-
- /*******************************************************************************
- * 函 数 名 : Int0() interrupt 0
- * 函数功能 : 外部中断0的中断函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
-
- void Int0() interrupt 0 //外部中断0的中断函数
- {
- delay(1000); //延时消抖
- if(k3==0)
- {
- led=~led;
- }
- }