05 定时器、计数器

1.使用中断系统,定时器操作LED流水灯



#include <stc15.h>
unsigned char LED=0;
unsigned int LED_Refresh=0;
void Timer0Init(void);
void main(void)
{
	P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
	Timer0Init();
	EA=1;ET0=1;
	while(1);
	
}
void Timer0(void) interrupt 1
{
	LED_Refresh++;
	if(LED_Refresh==999)
	{
		LED_Refresh=0;
		P0=~(0X01<<LED);
		P2|=0X80;
		P2&=0X9F;//打开LED锁存器
		P2&=0X1F;//关闭LED锁存器
		if(++LED==9)LED=0;
	}
}

void Timer0Init(void)		//1毫秒@11.0592MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0xCD;				//设置定时初始值
	TH0 = 0xD4;				//设置定时初始值
//	THx,TLx=65536-11059200*0.001=54477=0XD4CD
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
}

2. 解决按键时效不稳定(S7控制LED以200ms为间隔自动向左移位,S6控制LED向右以200ms为间隔自动向右移位,S5停止循环移位,S4按键关闭所有LED历程)


#include<stc15.h>
unsigned char LED=0;
unsigned char LED_Flag=0;
unsigned int LED_tt=0;
unsigned char S7_Flag=0;S6_Flag=0;S5_Flag=0;S4_Flag=0;


void KeyScan(void);
void Delay_MS(unsigned int MS);
void Timer0Init(void);


void main(void)
{
	P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
	Timer0Init();
	EA=1;
	ET0=1;
	while(1)
	{
		KeyScan();
		if(S7_Flag==1){S7_Flag=0;LED_Flag=1;}
		if(S6_Flag==1){S6_Flag=0;LED_Flag=2;}
		if(S5_Flag==1){S5_Flag=0;LED_Flag=0;}
		if(S4_Flag==1){S4_Flag=0;P0=0XFF;}	
	}
}
void Timer0(void) interrupt 1
{
	if(LED_Flag==1)
	{
		if(++LED_tt==200)
		{
			LED_tt=0;
			P0=~(0X01<<LED);
			LED++;
			if(LED==8)LED=0;
		}
	}
			
		if(LED_Flag==2)
	{
		if(++LED_tt==200)
		{
			LED_tt=0;
			P0=~(0X80>>LED);
			LED++;
			if(LED==8)LED=0;
		}
	}
}
void Timer0Init(void)		//1毫秒@11.0592MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0xCD;				//设置定时初始值
	TH0 = 0xD4;				//设置定时初始值
//	THx,TLx=65536-11059200*0.001=54477=0XD4CD
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
}
void KeyScan(void)	
{
	if(P30==0)
		Delay_MS(10);
		if(P30==0)S7_Flag=1;
		while(!P30);
	if(P31==0)
		Delay_MS(10);
		if(P31==0)S6_Flag=1;
		while(!P31);
	if(P32==0)
		Delay_MS(10);
		if(P32==0)S5_Flag=1;
		while(!P32);
	if(P33==0)
		Delay_MS(10);
		if(P33==0)S4_Flag=1;
		while(!P33);
}
void Delay_MS(unsigned int MS)
{
	unsigned int i,j;
	for(i=0;i<MS;i++)
	for(j=853;j>0;j--);
	
}

3、利用51单片机的定时/计数器T0的模式1实现间隔定时,每隔1秒L1指示灯闪烁一下,也就是点亮0.5秒,熄灭0.5秒;每隔10秒L8指示灯闪烁一下,即点亮5秒,熄灭5秒

掌握:1、定时器计数初值的计算(12MHz的外部晶振)

2、长定时的编程思想与代码实现

#include<stc15.h>

sbit L1=P0^0;
sbit L8=P0^7;

void SelectHC573()
{
	P2 = (P2 & 0X1F) | 0X80;
}

//====
void InitTimer0()//初始化函数
{
	TMOD=0X01;
	TH0=(65535-50000)/256;//高8位
	TL0=(65535-50000)%256;
	
	ET0=1;
	EA=1;
	TR0=1;
}
//unsigned char count=0;
//unsigned char count1=0;
//void ServiceTimer0() interrupt 1
//{
//	TH0=(65535-50000)/256;//高8位
//	TL0=(65535-50000)%256;  //由于没有自动重装功能,所以要重新定义计算初值
//	
//	count++;
//	count1++;
//	if(count==10)
//	{
//		L1=~L1;
//		count=0;
//	}
//	if(count1==100)
//	{
//		L8=~L8;
//		count1=0;
//	}
//}
	

unsigned char count=0;
void ServeiceTimer0() interrupt 1
{
	TH0=(65535-50000)/256;//高8位
	TL0=(65535-50000)%256;  //由于没有自动重装功能,所以要重新定义计算初值
	
	count++;
	if(count%10==0)  //10的倍数执行一次L1的取反
	{
		L1=~L1;
	}
	if(count==100)
	{
		L8=~L8;
		count=0;
	}

	
}
//====
void main()
{
	SelectHC573();
	InitTimer0();
	while(1)
	{

	}
}

4、利用定时器T0、数码管模块和2个独立按键(J5的2~3短接),设计一个秒表,具有清零、暂停、启动功能。

1、显示格式为:分-秒-0.05秒(即50ms)

08-26-18表示:8分26秒900毫秒

2、独立按键S4为:暂停/启动

独立按键S5为:清零

按键均为按下有效

#include<reg52.h>
sbit S4=P3^3;
sbit S5=P3^2;

unsigned char t_m=0;
unsigned char t_s=0;
unsigned char t_005s=0;
unsigned char code SMG_duanma[18]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,
                              0X82,0XF8,0X80,0X90,0X88,0X80,
                              0XC6,0XC0,0X86,0X8E,0XBF,0X7F};

void SelectHC573(unsigned char channel)
{
	switch(channel)
	{
		case 4:
		P2=(P2&0X1F)|0X80;
		break;
		case 5:
		P2=(P2&0X1F)|0XA0;
		break;
		case 6:
		P2=(P2&0X1F)|0XC0;
		break;
		case 7:
		P2=(P2&0X1F)|0XE0;
		break;
	}
	
}

void DisplaySMG_Bit(unsigned char value,unsigned char pos)
{
	SelectHC573(6);
	P0=0X01<<pos;
	SelectHC573(7);
	P0=value;
}
void DelaySMG(unsigned char t)
{
	while(t--);
}
void DisplayTime()
{
	DisplaySMG_Bit(SMG_duanma[t_005s%10],7);
	DelaySMG(500);
	DisplaySMG_Bit(SMG_duanma[t_005s/10],6);
	DelaySMG(500);
	DisplaySMG_Bit(SMG_duanma[16],5);
	DelaySMG(500);
	
	DisplaySMG_Bit(SMG_duanma[t_s%10],4);
	DelaySMG(500);
	DisplaySMG_Bit(SMG_duanma[t_s/10],3);
	DelaySMG(500);
	DisplaySMG_Bit(SMG_duanma[16],2);
	DelaySMG(500);
	
	DisplaySMG_Bit(SMG_duanma[t_m%10],1);
	DelaySMG(500);
	DisplaySMG_Bit(SMG_duanma[t_m/10],0);
	DelaySMG(500);
	
}
//===定时器相关函数
void InitTimer0()
{
	TMOD=0X01;
	TH0=(65535-50000)/256;
	TL0=(65535-50000)%256;
	
	ET0=1;
	EA=1;
	TR0=1;
}
void ServeiceTimer0() interrupt 1
{
	TH0=(65535-50000)/256;
	TL0=(65535-50000)%256;
	
	t_005s++;
	if(t_005s==20)
	{
		t_s++;
		t_005s=0;
		if(t_s==60)
		{
			t_m++;
			t_s=0;
			if(t_m==99)
			{
				t_m=0;
			}
		}
	}
	
}

//======
void Delayk(unsigned char t)
{
	while(t--);
}
void ScanKeys()
{
	if(S4==0)//秒表启动与暂停
	{
		Delayk(100);
		if(S4==0)
		{
			TR0=~TR0;
			while(S4==0)
			{
				DisplayTime();
			}
			
		}
	}
	
	if(S5==0)//秒表清零
	{
		Delayk(100);
		if(S5==0)
		{
			t_m=0;
			t_s=0;
			t_005s=0;
			while(S5==0)
			{
				DisplayTime();
			}
		}
	}
}
void main()
{
	InitTimer0();
	while(1)
	{
		DisplayTime();
		ScanKeys();
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值