学习单片机第三天——中断(定时器中断的使用)

一、与中断相关的要素
1.中断源:
学习单片机第三天——中断(定时器中断的使用)_第1张图片
2.中断允许寄存器IE:

学习单片机第三天——中断(定时器中断的使用)_第2张图片
此寄存器的各位应该熟,相当于中断动作的开关,即允许中断的发生

3.中断优先级寄存器IP:
学习单片机第三天——中断(定时器中断的使用)_第3张图片
附:中断默认优先级表:
学习单片机第三天——中断(定时器中断的使用)_第4张图片
中断序号很重要,需记,在中断程序中会用到

二、定时器中断
1.实质是加1计数器,由高八位和低八位两个寄存器组成
2.定时器系统是单片机的一个独立硬件部分,与CPU和晶振通过控制线连接并相互作用

3.与定时器中断有关的两个寄存器:
学习单片机第三天——中断(定时器中断的使用)_第5张图片

TMOD工作方式寄存器:
学习单片机第三天——中断(定时器中断的使用)_第6张图片 一般使用工作方式1

TCON控制寄存器
学习单片机第三天——中断(定时器中断的使用)_第7张图片学习单片机第三天——中断(定时器中断的使用)_第8张图片
附:定时器0方式1的工作逻辑图:
学习单片机第三天——中断(定时器中断的使用)_第9张图片
4.定时器计数时间的计算:
首先要清楚:计数器的计数值=溢出时计数器的值-计数初值
学习单片机第三天——中断(定时器中断的使用)_第10张图片
三、利用数码管和计时器中断实现时钟(时-分-秒)
代码实现如下:

#include
#define uchar unsigned char
#define uint unsigned int

//138编译器的申明(控制位选——查看真值表)
sbit _A = P2 ^ 2;
sbit _B = P2 ^ 3;
sbit _C = P2 ^ 4;
uint num1, num2, num3;

//相应段选对应的0~9数码管字符
uchar code table[] = {
0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f
};//分号不要掉!!!!

//延时函数
void delay_ms(uint s)
{
	uint i, j;
	for (i = s; i > 0; i--)
		for (j = 110; j > 0; j--);
}


//中断函数

void T0_time()interrupt 1
{
	//重装初始值
	TH0 = (65536 - 45872) / 256;
	TL0 = (65536 - 45872) % 256;
	num1++;
	num2++;
	num3++;



}

void display()
{
	uchar num_sec, num_min, num_h;
	uchar sec_shi, sec_ge, min_shi, min_ge, h_shi, h_ge;

	//各显示位计算


	   //秒两位数的计算
	if (num1 == 20)
	{
		num1 = 0;
		num_sec++;
		if (num_sec == 60)
			num_sec = 0;
		else
		{
			sec_shi = num_sec / 10;
			sec_ge = num_sec % 10;
		}

	}

	//分两位数的计算
	if (num2 == 1200)
	{
		num2 = 0;
		num_min++;
		if (num_min == 60)
			num_min = 0;
		else
		{
			min_shi = num_min / 10;
			min_ge = num_min % 10;
		}
	}

	//时两位数的计算
	if (num3 == 72000)
	{
		num3 = 0;
		num_h++;
		if (num_h == 60)
			num_h = 0;
		else
		{
			h_shi = num_h / 10;
			h_ge = num_h % 10;
		}
	}


	//各显示位的显示


		 //时间显示中的横杠显示

		   //数码管3

	_A = 0; _B = 1; _C = 0;
	P0 = 0x40;
	delay_ms(1);

	//数码管6

	_A = 1; _B = 0; _C = 1;
	P0 = 0x40;
	delay_ms(1);



	//时间显示中的秒显示

	  //数码管1
	P0 = 0;//消影,将段选熄灭再输入位选信号
	_A = 0; _B = 0; _C = 0;
	P0 = table[sec_ge];
	delay_ms(1);

	//数码管2
	P0 = 0;
	_A = 1; _B = 0; _C = 0;
	P0 = table[sec_shi];
	delay_ms(1);


	//时间显示中的分显示

	  //数码管4
	P0 = 0;
	_A = 1; _B = 1; _C = 0;
	P0 = table[min_ge];
	delay_ms(1);

	//数码管5
	P0 = 0;
	_A = 0; _B = 0; _C = 1;
	P0 = table[min_shi];
	delay_ms(1);


	//时间显示中的时显示

	   //数码管7
	P0 = 0;
	_A = 0; _B = 1; _C = 1;
	P0 = table[h_ge];
	delay_ms(5);

	//数码管8
	P0 = 0;
	_A = 1; _B = 1; _C = 1;
	P0 = table[h_shi];
	delay_ms(5);
}

void main()
{
	TMOD = 0x01;//设置定时器0的工作方式为1(M1M0为01)
	TH0 = (65536 - 45872) / 256;//装初值  当晶振11.0592M时,定时50ms数为45872
	TL0 = (65536 - 45872) % 256;

	EA = 1;//打开总中断
	ET0 = 1;//打开定时器0中断
	TR0 = 1;//启动定时器0


	while (1)
	{

		display();


	}



}

对此代码的说明:
1.中断函数interrupt后面为中断序号(前面已提到)
对中断函数的写法要熟知。
2.数码管的各位显示数字的计算方法应了解
3.计时效果可能不太好,需自己通过设置初始值和延时函数来调整。

今日学习小结:
1.定时器中涉及的寄存器比较多,刚开始接触明显比较混乱,但经过多遍浏览与梳理,对各寄存器各位的功能有所了解。
2.刚开始对加一计时的原理并不清楚,思考过“溢出”后明白了计时原理。
3.代码实现时刚开始出现了两个警告,没有管,结果烧录出来单片机无法正常工作,是if的判断语句==出现了问题,后排除成功。
总之,本小节的内容较难理解记忆,需要自己的反复浏览,思考,动手,后面应该针对此节内容勤加复习。

你可能感兴趣的:(单片机)