欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

51单片机定时器控制数码管与led共同闪烁

程序员文章站 2022-06-08 20:56:41
...

外接晶振为12MHz时,51单片机相关周期的具体值为:

振荡周期=1/12us;
状态周期=1/6us;
机器周期=1us;
指令周期=1~4us;

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

GATE是门控位, GATE=0时,用于控制定时器的启动是否受外部中断源信号的影响。只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚INT0/1也为高电平时,才能启动定时/计数器工作。即此时定时器的启动条件,加上了INT0/1引脚为高电平这一条件。
C/T :定时/计数模式选择位。C/T =0为定时模式;C/T =1为计数模式。
M1M0:工作方式设置位。定时/计数器有四种工作方式。
51单片机定时器控制数码管与led共同闪烁

控制寄存器TCON

TCON的高4位用于控
制定时/计数器的启动和中断申请。其格式如下:
51单片机定时器控制数码管与led共同闪烁
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、方式1
方式1的计数位数是16位,由TL0作为低8位,TH0
作为高8位,组成了16位加1计数器 。计数个数与计数初值的关系为:X=2(16次方)-N

2、方式2
为自动重装初值的8位计数方式。 计数个数与计数初值的关系为:X=28-N
工作方式2特别适合于用作较精确的脉冲信号发生器。所以串口通信处用此方式。

计数器初值的计算
机器周期也就是CPU完成一个基本操作所需要的时间。
机器周期=1/单片机的时钟频率。
51单片机内部时钟频率是外部时钟的12分频。也就是说当外部晶振的频率输入到单片机里面的时候要进行12分频。比如说你用的是12MHZ的晶振,那么单片机内部的时钟频率就是12/12MHZ,当你使用12MHZ的外部晶振的时候。机器周期=1/1M=1us。
而我们定时1ms的初值是多少呢,1ms/1us=1000。也就是要计数1000个数,初值=65535-1000+1(因为实际上计数器计数到66636才溢出)=64536=FC18H

中断允许寄存器IE
51单片机定时器控制数码管与led共同闪烁
EX0(IE.0),外部中断0允许位;
ET0(IE.1),定时/计数器T0中断允许位;
EX1(IE.2),外部中断0允许位;
ET1(IE.3),定时/计数器T1中断允许位;
ES(IE.4),串行口中断允许位;
EA (IE.7), CPU中断允许(总允许)位。

51单片机定时器控制数码管与led共同闪烁
主程序中需要有以下代码:
EA=1;//打开总中断开关
EX0=1;//开外部中断0
IT0=0/1;//设置外部中断的触发方式

 include <reg52.h>
#include<intrins.h>

typedef unsigned int u16;
typedef unsigned char u8;

sbit led1=P2^0;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

u16 smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					0x7f,0x6f};

void init0()
{
 	EA=1;
	ET0=1;
	TR0=1;
	TMOD=0x01;
	TH0=0xFC;
	TL0=0x18;
	LSA=0;
	LSB=0;
	LSC=0;
}
int main()
{
	init0();
	while(1);
	return 0;
}

u16 count=0;
u16 i=0;

void Init() interrupt 1
{
	count++;
	TH0=0xFC;
	TL0=0x18;
	if(count==1000)
	{
	 	led1=~led1;
		count=0;
		if(led1==0)
		{
			i++;
			i=i%10;
			P0=smgduan[i];
		}
		else
			P0=0x00;
	}
}