掌握 51 单片机外部中断计数,实现数码管显示

2、掌握外部中断的中断初始化和中断服务函数的程序编写方法,编程实现实现数码管上显示外部中断计数。原理图如下,其中的八段数码管为7SEG-MPX1-CA,按键与P3端的P3.2INT0相连(外部中断0请求输入端,低电平有效,这里采用电平触发方式):

1.实验要求

【目的】

1、熟悉51单片机的5个中断源;

2、掌握外部中断的中断初始化及中断服务函数编程方法,并实现编程将外部中断计数值在数码管上显示出来。

【实验内容】

1、使用Proteus绘制硬件原理图,设置元器件参数;

2、使用KeilC51软件对数码管进行外部中断计数的编程。

【硬件要求】

连接方法:P2.0-P2.7接共阳7段LED数码管,按钮K1接单片机的P3.2(INT0)引脚。

二、知识要点(一)数码管

数码管是一种半导体发光器件,其基本单元是发光二极管,玻璃管内有一个由金属丝网制成的阳极和多个阴极,可以显示数字等信息。

根据其内部结构,即发光二极管单元的连接方式,可分为共阳极和共阴极两种类型的数码管。共阳极数码管是指管内发光二极管的阳极连接在一起,形成公共阳极(COM)的数码管。当某一场的发光二极管阴极为低电平时,对应的场亮,当某一场的阴极为高电平时,对应的场不亮;共阴极数码管与共阳极数码管相反。

当使用共阳极LED数码管时,公共极COM应接+5V;当使用共阴极LED数码管时,公共极COM应接地线GND。

2、八段数码管的字符编码

下面是八段数码管的字形编码表,方便使用时参考:

字符共享阳极和阴极

碳氢化合物

3FH

F9H

06小时

A4H

5BH

B0H

4楼

99H

66H

92H

6DH

82H

7D

F8H

07H

80H

7楼

90H

6FH

(三)C51变量定义的四要素

C51变量定义的四个要素如下:

1. 存储类型(重要!)

存储类型分为auto、extern、static、register四类,默认的存储类型是自动变量(auto),一般不需要写出来。

自动变量的作用域在定义它的函数体或语句块内,执行结束后,变量占用的内存会被释放。

外部变量在其源文件中定义后,只有将其声明为extern后才能在其他源文件中使用。

静态类型与自动类型相反,它所占用的内存单元在执行结束后还会继续保留。

寄存器型变量是指变量对应的存储单元被指定为通用寄存器,可以提高程序的运行速度。

2.数据类型

数据类型分为整型、长整型、字符型、浮点型、指针五种。

3.存储类型(重要!)

C51编译器的三种编译模式对应三种默认的存储类型:SMALL对应data类型,COMPACT对应pdata类型,LARGE对应xdata类型,一般如果没有特殊声明,都采用SMALL编译模式。

数据类型变量的存储区域位于直接寻址区域(片内低位128B RAM),该区域数据访问速度最快,容量较小,作为普通变量或者临时变量存储;

idata类型变量的存储区域位于间接寻址区域(芯片上高位128B RAM);

xdata类型变量的存储区位于外部寄存器(芯片外的64KB RAM),常用于存储不经常使用的变量或者需要处理的数据;

pdata类型变量的存储区域位于分页寻址区域(芯片外的低位256B RAM),常用于外部设备访问;

代码型变量的存储区域位于程序存储区(ROM)中,常用于存储数据表等固定的信息;

bdata类型变量的存储区域位于位可寻址区域(片内位可寻址区域),允许位和字节混合访问。

(四)中断源

C51单片机的中断系统共有5个中断源,分为2个外部中断源和3个内部中断源,分别是两个外部中断INT0(P3.2)和INT1(P3.3),两个片内定时器/计数器T0和T1,一个片内串口发送或接收中断请求源T1或R1。

另外它具有两级中断优先级,由中断优先级控制寄存器IP控制,每个中断源的优先级都可以通过编程来控制,允许中断受CPU中断、中断源中断两级控制。

(五)相关特殊功能寄存器 1.定时/计数器控制寄存器TCON

定时器/计数器控制寄存器TCON控制定时器/计数器的启动与停止及标志定时器的溢出、中断状态。TCON既可以采用字节寻址,也可以采用位寻址。当51单片机系统复位时,TCON的所有位将被清零。

TCON的格式如下,高4位控制定时器/计数器的启动和中断请求,低4位控制外部中断:

(1)TR1、TR0为操作控制位,当它们等于0时,定时器停止工作,当它们等于1时,定时器开始工作(例如启动定时器T1:TR1=1);

(2)TF1、TF0为溢出中断标志,当定时器溢出时,由硬件自动置1,CPU响应中断后,硬件自动清0(例如TF1=0时,表示无溢出;TF1=1时,表示有溢出)。

(3)IT1、IT0为外部中断INT0、INT1的触发方式控制位,通过软件置1或者清0来控制外部中断的触发方式。(例如当IT1=1时,外部中断INT1由下降沿触发,当IT1=0时,外部中断INT1由低电平触发);

(4)IE1、IE0为外部中断的请求标志,当该引脚上出现中断请求信号(低电平或者脉冲下降沿)时,硬件自动将IEX置1,从而产生中断请求标志。当CPU响应中断时,由硬件消除(例如外部中断INT0P3.2引脚上有中断请求信号时,IE0置1,即IE0=1)。

2.中断使能控制寄存器IE

在中断系统中,中断源向CPU发出中断请求后,由中断使能控制寄存器IE和中断优先级控制寄存器IP(本实验中未使用)对CPU进行管理。

中断使能控制寄存器IE控制中断源的开启或者屏蔽,共6位,字节地址为A8H,如下:

(1)EA为中断使能控制位,控制CPU开放中断。当EA=0时,CPU屏蔽所有中断请求;当EA=1时,CPU开放中断(5个中断源的中断请求是否允许,取决于中断请求使能控制位)。

(2)EX0、EX1 分别为外部中断 0 使能位、外部中断 1 使能位。当 EX0=0 时,外部中断 0 关闭,当 EX0=1 时,外部中断 0 使能;当 EX1=0 时,外部中断 1 关闭,当 EX1=1 时,外部中断 1 使能。

(3)ET0、ET1 分别为定时器/计数器 Tx(x=0,1)溢出中断使能位。当 ET0、ET1 等于 0 时,Tx(x=0,1)中断禁止,当 ET0、ET1 等于 1 时,Tx(x=0,1)中断使能。

(4)ES为串口中断使能位,当ES=0时,禁止串口中断,当ES=1时,使能串口中断。

(六)中断程序

中断程序由两部分组成:中断初始化和中断服务。

1.中断初始化步骤

中断初始化就是用户对特殊功能寄存器中的各个控制位进行赋值,步骤如下:

第一步,通过中断使能控制寄存器IE,使能相应中断源的中断;

步骤2*(两个以上的中断需要设置优先级),设置所使用的中断源的中断优先级,通过中断优先级控制寄存器IP;

第三步,如果是外部中断,则需要通过定时器控制寄存器TCON来指定触发方式,即触发方式是电平触发方式还是脉冲触发方式。

当外部中断采用电平触发时,CPU在每个机器周期的S5P2检测INT0、INT1引脚的输入电平,若检测到低电平则认为是中断信号,并且中断服务结束前必须清除低电平,否则中断返回前又会再次产生中断。

当外部中断采用脉冲触发时,CPU在每个机器周期的S5P2时刻检测INT0、INT1引脚的输入电平,需要连续检测两次(第一次检测为高电平,第二次检测为低电平),即检测到下降沿才认为是有效的中断请求信号。

2.中断服务程序函数

中断服务是指单片机检测到中断后,响应中断事件。中断服务的步骤如下:

第一步,在中断向量入口处放置一个跳转指令,使得程序从该入口跳转到实际代码的起始位置;

第二步,保存当前寄存器内容;

第三步,清除中断标志,处理中断事件;

第四步,恢复寄存器的内容,返回原来执行主程序;

即创建一个中断服务子程序函数。函数定义格式如下,其中,n为中断源号,可以是0~31之间的整数。前面的interrupt表示该函数声明为中断服务函数,使用m是因为工作寄存器组切换,所以在中断服务子程序中选择的工作寄存器组号(0~3):

返回值 函数名称([参数])interrupt n[using m]{
}

需要注意的是,中断服务函数不能传递参数,也没有返回值(中断服务函数可以定义为void类型),另外,中断服务函数也不能直接调用,否则会造成编译错误。

3.Proteus仿真软件绘制原理图

原理图如下,八段数码管为7SEG-MPX1-CA,按键接在P3端的P3.2INT0(外部中断0请求输入端,低电平有效,此处采用电平触发):

4.用Keil编程软件编写程序

首先创建一个数组Tab[]。根据C51变量定义的四个要素,将数组Tab定义为unsigned char code Tab[]。code的意思就是用代码在程序存储器中定义数组Tab[]。通俗的讲就是定义一个无符号字符(自动变量)数组Tab[],变量位于ROM中。根据共阳数码管段码,unsigned char code Tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};。

设置延时函数,依然设置一个有参数的函数,调用函数delay(1000)延时1秒:

//延时函数
void delay(unsigned int x)
{
	unsigned int i,j;
	for(i=0;i<x;i++)
		for(j=0;j<125;j++);
}

编写中断服务程序函数如下:

unsigned char m;
...
//中断服务程序函数
void counter(void) interrupt 0
{
	EX0=0;		   //禁止外部中断0中断
	m++;		   //中断计数
	P2=Tab[m];	   //依次取数组Tab内的元素
	if(m==10)
	{
		m=0;
		P2=Tab[m];
	}
	EX0=1;		   //允许外部中断0中断
}

完整程序代码如下:

#include
unsigned char m;
unsigned char code Tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};	//共阳极,对应八段数码管的数字0-9  
void delay(unsigned int x)	//延时函数
{
	unsigned int i,j;
	for(i=0;i<x;i++)
		for(j=0;j<125;j++);
}
void counter(void) interrupt 0
{
	EX0=0;		   //禁止外部中断0中断
	m++;		   //中断计数
	P2=Tab[m];	   //依次取数组Tab内的元素
	if(m==10)
	{
		m=0;
		P2=Tab[m];
	}
	EX0=1;		   //允许外部中断0中断
}
void main()
{
	EX0=1;		//允许外部中断0中断
	IT0=1;		//外部中断INT0为下降沿触发
	EA=1;		//使能CPU,CPU开放中断
	while(1)
	{
		P2=Tab[m];			//依次取数组Tab内的元素
		delay(1000);		//调用延时函数,参数为1000,即1s
	}
}

五、实验结果 (一)模拟结果

导入可执行文件,点击开始模拟:

按一次按钮:

第二次按:

…以此类推,直到第九次,当数字达到 9 时:

(二)连接电路

注意电缆的接线方法,否则数码管将显示错误:

(三)烧录并观察实验现象

烧写完毕后实验现象如下,按下按钮:

再次按下该键,数字变为 2:

…第九次按下按钮,将显示数字 9:

单片机

基于单片机的汽车倒车防撞系统设计及应用

2024-6-10 14:12:07

单片机

花卉网藿香图片频道:全面展示藿香形态,轻松获取种植信息

2024-6-10 15:15:06

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索