找回密码
 注册会员
img_loading
智能检测中
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

2009单片机终极学习(五)-中断及数码管的静态显示

[复制链接]
admin 发表于 2012-9-2 04:41:51 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
中断系统

一、中断的概念

5_42316_2b2efe53f265784.jpg


5_42316_38c74abac31a899.jpg

引起CPU中断的根源,称为中断源。中断源向CPU提出的中断请求。CPU暂时中断原来的事务A,转去处理事件B。对事件B处理完毕后,再回到原来被中断的地方(即断点),称为中断返回。实现上述中断功能的部件称为中断系统(中断机构)。

随着计算机技术的应用,人们发现中断技术不仅解决了快速主机与慢速I/O设备的数据传送问题,而且还具有如下优点:
? 分时操作。CPU可以分时为多个I/O设备服务,提高了计算机的利用率;
? 实时响应。CPU能够及时处理应用系统的随机事件,系统的实时性大大增强;
? 可靠性高。CPU具有处理设备故障及掉电等突发性事件能力,从而使系统可靠性提高。

80C51中断系统的结构
80C51的中断系统有5个中断源(8052有 6个) ,2个优先级,可实现二级中断嵌套 。

5_42316_5cb95a00bd9713b.jpg

RX TX是一个中断源!!


外部中断0
T0 定时器 0


外部中断1
T1 定时器 1
RX TX 串行接收发送

5_42316_29c930c7122e4a6.jpg

5个中断源的中断要求是否得到响应,受允许中断寄存器IE的控制;

它们的优先级分别由中断优先级寄存器IP的各位确定。

IE——允许中断寄存器

EA X ET2 ES ET1 EX1 ET0 EX0
1. EA 总允许位。EA=0,禁止一切中断。EA=1,则每个中断源是允许还是禁止,分别由各自的允许位确定;
2. — 保留位;
3. ET2 定时器2中断允许位。ET2=0,禁止定时器2中断;(80c52有的)
4. ES串行口中断允许位。ES=0,禁止串行口中断;
5. ET1 定时器中断允许位,ET1=0,禁止定时器1中断;
6. EX1 外部中断1允许位,EX1=0,禁止外部中断1允许位;
7. ET0 定时器0中断允许位,ET0=0,禁止定时器0中断;
8. EX0 外部中断0允许位,EX=0,禁止外部中断0.。


IP——允许中断优先级寄存器

X X PT2 PS PT1 PX1 PT0 PX0

1) — 保留位;
2) — 保留位;
3) PT2 定时器2中断优先级设定位。PT2=1,设定为高优先级;
4) PS 串行口中断优先级设定位,PS=1,设定为高优先级;
5) PT1 定时器1中断优先级,PT1=1,设定为高优先级;
6) PX1 外部中断1优先级,PX1=1,设定为高优先级;
7) PT0 定时器0中断优先级设定位,PT0=1.设定为高优先级;
8) PX0 外部中断0优先级设定位,PX0=1,设定为高优先级。


优先级结构
靠IP寄存器把各中断源的优先级分为高低两级。它们遵循这样两条基本规则:
1 低优先级中断可被高优先级所中断,反之不能;
2 一种中断(不管是什么优先级)一旦得到响应,与他同级的中断不能再中断它。


为了实现上述两条原则, 中断系统内部设有两个用户不能寻址的优先级状态触发器。其中一个置1,表示正在响应高优先级的中断,它将阻断后来所有的中断请求;另一个置1,表示正在响应低优先级中断,它将阻断后来所有的低优先级中断请求。


当同时收到几个同一优先级的中断要求时,哪一个要求得到服务,取决于内部的查询顺序,相当于在每个优先级内,还同时存在另一个辅助优先级结构。

5_42316_4ee9cdf508aa52a.jpg



二、中断请求标志
1、TCON的中断标志(控制外部中断的中断标志)



外部中断的激活方式分为两种:一种是电平激活;另外一种是边沿激活
这两种方式可以靠TCON寄存器中的中断方式IT1或IT0来控制。
ITx=0. 采用电平激活方式;在INTx引脚上测到低电平,则触发外部中断。
ITx=1.采用边沿激活方式; 在相继的两个周期中,对INTx引脚进行连续两次采样,若第一次采样值为高(就是一个下降沿),第二次为低时,则TCON寄存器中的中断请求标志位被置1,以请求中断。
由于外部中断引脚每个机器周期被采样一次,为确保采样,由引脚INTx输入的信号应至少保持一个机器周期,即12个振荡周期。如果外部中断为边沿激活方式,则引脚处的高电平和低电平值至少各保持一个机器周期,才能保持 CPU测到电平的跳变,而把中断请求标志IEx置1。
IT0(TCON.0),外部中断0触发方式控制位。
当IT0=0时,为电平触发方式。
当IT0=1时,为边沿触发方式(下降沿有效)。
IE0(TCON.1),外部中断0中断请求标志位。
IT1(TCON.2),外部中断1触发方式控制位。
IE1(TCON.3),外部中断1中断请求标志位。
TF0(TCON.5),定时/计数器T0溢出中断请求标志位。
TF1(TCON.7),定时/计数器T1溢出中断请求标志位。


2、SCON的中断标志(控制串口的中断标志)

5_42316_a788e562712ccf4.jpg


? RI(SCON.0),串行口接收中断标志位。当允许串行口接收数据时,每接收完一个串行帧,由硬件置位RI。注意,RI必须由软件清除。
? TI(SCON.1),串行口发送中断标志位。当CPU将一个发送数据写入串行口发送缓冲器时,就启动了发送过程。每发送完一个串行帧,由硬件置位TI。CPU响应中断时,不能自动清除TI,TI必须由软件清除。

中断响应条件
? 中断源有中断请求;
? 此中断源的中断允许位为1;
? CPU开中断(即EA=1)。
以上三条同时满足时,CPU才有可能响应中断。

那我们就先来写个外部中断的程序练习练习吧!

我们想在外部中断1发生时(电平激活方式),发光二级管第一个亮起来 ,当中断结束时,发光二级管灭,主函数我们让数码管依次两1~f数字!
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit wela=P1^5;//位选定义
sbit dula=P1^4;//段选定义
sbit d1= P0^0;
uchar num;
unsigned char code Tab[]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
void delay(uint z);
void main()
{
EA=1;//最先改打开总中断
EX0=1;//开外部中断0(就是你想打开哪个中断)
IT0=0;//用的是电平激活方式(再设置你想使用什么的方式激活中断)
// TCON=0x01;//用TCON形式定义边沿激活方式,如果不设置就是默认为电平激活方式,这里使用的是边沿触发方式,就是当CPU检测到一个下降沿的时候,中断启动
led_cs=0;//流水灯锁存器锁存端
wela=1;
P0=0xea;
wela=0;
while(1)
{
led_cs=1;
P0=0xff;
led_cs=0; 这为什么会这样 大家讨论下 呵呵 讨论才有进步是吧
for(num=0;num<16;num++)
{

d1=0;//中断结束,关闭发光二极管
dula=1;
P0=table[num];
dula=0;
delay(1000);
}
}
}

void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}

void exter0() interrupt 0//这就是中断子程序,与子函数不同的就是它有个 interrupt 以及后面的数字是代表 你用的是哪个中断源,上面的图中(带黄色数字的)我已经编号了,中断子程序是不用申明的。
{
dula=0;
wela=0;
led_cs=1;
P0=0xfe;//中断发生,我们让第一个发光二极管亮起来,

led_cs=0;
P0=0xff;
}
我们再来学习下80C51的定时/计数器


实现定时功能,比较方便的办法是利用单片机内部的定时/计数器。也可以采用下面三种方法:
软件定时:软件定时不占用硬件资源,但占用了CPU时间,降低了CPU的利用率。
采用时基电路定时:例如采用555电路,外接必要的元器件(电阻和电容),即可构成硬件定时电路。但在硬件连接好以后,定时值与定时范围不能由软件进行控制和修改,即不可编程。
采用可编程芯片定时:这种定时芯片的定时值及定时范围很容易用软件来确定和修改,此种芯片定时功能强,使用灵活。在单片机的定时/计数器不够用时,可以考虑进行扩展。
定时/计数器的结构和工作原理
一、定时/计数器的结构
定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器组成。TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。


5_42316_78f7a6dd6db242a.jpg

加1计数器输入的计数脉冲有两个来源:
一个是由系统的时钟振荡器输出脉冲经12分频后送来(定时器);
一个是T0或T1引脚输入的外部脉冲源。每来一个脉冲计数器加1(计数器),当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使TCON中TF0或TF1置1,向CPU发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。
可见,由溢出时计数器的值减去计数初值才是加1计数器的计数值。

80C51单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD用于设置其工作方式;TCON用于控制其启动和中断申请。
一、工作方式寄存器TMOD
工作方式寄存器TMOD用于设置定时/计数器的工作方式,低四位用于T0,高四位用于T1。其格式如下:

5_42316_ba1c3a1761cbcf7.jpg


GATE:门控位。GATE=0时,只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚或也为高电平时,才能启动定时/计数器工作。即此时定时器的启动多了一条件。
:定时/计数模式选择位。 =0为定时模式; =1为计数模式。
 楼主| admin 发表于 2012-9-2 04:42:01 | 显示全部楼层
M1M0:工作方式设置位。定时/计数器有四种工作方式,由M1M0进行设置。

5_42316_946aa81fb1ddb7a.jpg

二、控制寄存器TCON?
TF1(TCON.7):T1溢出中断请求标志位。T1计数溢出时由硬件自动置TF1为1。CPU响应中断后TF1由硬件自动清0。T1工作时,CPU可随时查询TF1的状态。所以,TF1可用作查询测试的标志。TF1也可以用软件置1或清0,同硬件置1或清0的效果一样。
? TR1(TCON.6):T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。
? TF0(TCON.5):T0溢出中断请求标志位,其功能与TF1类同。
? TR0(TCON.4):T0运行控制位,其功能与TR1类同。
(我们主要用方式1讲解)
定时/计数器的工作方式
一、方式0
方式0为13位计数,由TL0的低5位(高3位未用)和TH0的8位组成。TL0的低5位溢出时向TH0进位,TH0溢出时,置位TCON中的TF0标志,向CPU发出中断请求。


5_42316_07fed5f715a80a6.jpg

? 设置为定时器模式时,加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,即计数频率为晶振频率的1/12)。计数值N乘以机器周期Tcy就是定时时间t 。
? 设置为计数器模式时,外部事件计数脉冲由T0或T1引脚输入到计数器。在每个机器周期的S5P2期间采样T0、T1引脚电平。当某周期采样到一高电平输入,而下一周期又采样到一低电平时,则计数器加1,更新的计数值在下一个机器周期的S3P1期间装入计数器。由于检测一个从1到0的下降沿需要2个机器周期,因此要求被采样的电平至少要维持一个机器周期。当晶振频率为12MHz时,最高计数频率不超过1/2MHz,即计数脉冲的周期要大于2 ms。
定时器模式时有:N=t/ Tcy
计数初值计算的公式为:X=213—N(N为你想设计中断发生地时间)
定时器的初值还可以采用计数个数直接取补法获得。
计数模式时,计数脉冲是T0引脚上的外部脉冲。
二、方式1
方式1的计数位数是16位,由TL0作为低8位、TH0作为高8位,组成了16位加1计数器 。


5_42316_7fdb86db2be2580.jpg

计数个数与计数初值的关系为: X=2 16-N
三、方式2
方式2为自动重装初值的8位计数方式。

5_42316_22f2bab88e98c2e.jpg

计数个数与计数初值的关系为: X=28-N
工作方式2特别适合于用作较精确的脉冲信号发生器。

四、方式3
方式3只适用于定时/计数器T0,定时器T1处于方式3时相当于TR1=0,停止计数。

5_42316_7e5ef73048d88cb.jpg

工作方式3将T0分成为两个独立的8位计数器TL0和TH0 。

初始化程序应完成如下工作:
? 对TMOD赋值,以确定T0和T1的工作方式。
? 计算初值,并将其写入TH0、TL0或TH1、TL1。
? 中断方式时,则对IE赋值,开放中断。
? 使TR0或TR1置位,启动定时/计数器定时或计数。
好!我们现在就来写个程序,让我们看看定时器是怎么用起来的。

我们主程序是这样进行的,还是数码管的第一个数码管在从1到F的亮着,定时中断发生时,我们让它进入定时器延时!
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit wela=P1^5;//位选定义
sbit dula=P1^4;//段选定义
sbit d1=P0^0;
uchar num,num1;tt;
unsigned char code Tab[]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};//共阴极数码管编码
//void delay(uint z);
void main()
{
num=0;
tt=0;
TMOD=0x01;//设置定时器0为工作方式1
TH0=(65536-10000)/256;//给定时器0的高八位写入初值
TL0=(65536-10000)%256;// 给定时器0的低八位写入初值
这个可能大家不明白为什么,可以讨论讨论,大家只要记住是这样赋初值的就好了!
EA=1;//开总中断
ET0=1;//开定时器0中断
TR0=1;//启动定时器0

wela=1;
P0=0xea;
wela=0;

dula=1;
P0=0x3f;
dula=0;

while(1)
{
if(tt==100)
{
tt=0;
num++;
if(num==16)
num=0;
dula=1;
P0=Tab[num];
dula=0;
}
}
}

/*void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}*/

void time0() interrupt 1
{
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
tt++;
}

好 ,由于内容很多,但不影响我们学习的热情,我现在给大家几个题,让我们彻底记住外部中断和定时器的编程
1.主函数自己设计,流水灯也好 ,数码管也好 ,中断发生时,流水灯一秒间隔流动起来
2、利用定时/计数器T1产生定时时钟,由P1口控制8个发光二极管,使8个指示灯依次一个一个闪动,闪动频率为10次/秒(8个灯依次亮一遍为一个周期),循环

5_42316_6e1e1163699a635.jpg


5_42316_a6339a6d2a14897.jpg


5_42316_a05d3d63bd9b24f.jpg

5_42316_1c1d1ee33af9ecf.jpg



大家动起来,终极学习单片机,好的程序,我将做为答案置顶
让我们一起学好单片机!!!
[ 此贴被mai1258在2009-06-03 00:38重新编辑 ]
您需要登录后才可以回帖 登录 | 注册会员

*滑块验证:
img_loading
智能检测中
本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2025-7-25 10:26 , Processed in 0.076953 second(s), 13 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表