51单片机实现简易交通灯,加三种特殊情况用定时器解决

该程序使用51单片机的定时器0和定时器1,分别以10MS和50MS的周期进入中断,用于扫描按键和实现延时功能。在中断服务函数中,对按键状态进行检测,并根据按键操作改变LED灯的状态。同时,程序详细设定了定时器的工作模式和中断处理方式。
摘要由CSDN通过智能技术生成

题目要求

仿真图

 程序用定时0每10MS进入中断扫描按键和定时器1每50MS进入中断作为延时来实现功能

#include<reg51.h>

#define TL1_L 50000
#define uchar unsigned char
typedef unsigned char u8;
typedef unsigned int u16;
sbit R_NB = P1^3;
sbit Y_NB = P1^4;
sbit G_NB = P1^5;

sbit G_DX = P1^2;
sbit Y_DX = P1^1;
sbit R_DX = P1^0;

sbit KEY1 = P3^4;
sbit KEY2 = P3^5;
sbit KEY3 = P3^6;
sbit KEY4 = P3^7;



uchar key=0;
u16 p;
void Deng(void);
void Deng_Init(void);
void display(uchar _duan,uchar _wei);

void time50ms(unsigned int i)
{
unsigned int k;
for(k=0;k<i;k++)
{
	TH1=(65536-TL1_L)/256;// 由于晶振为11.0592,故所记次数应为46080,计时器每隔50000微秒发起一次中断。
	TL1=(65536-TL1_L)%256;//46080的来历,为50000*11.0592/12
  TR1=1;
  while(!TF1);
  TF1=0;
 }
}
void delay(unsigned int i)
{
	u16 j,k;
  for(j=i;j>0;j--)
    for(k=125;k>0;k--);
}
void main()
{
	TMOD=0x11;		 //模式设置,00000001,可见采用的是定时器0,工作与模式1(M1=0,M0=1)。
	TR0=1;			 //打开定时器
	TR1=1;
	TH0=0xDC;// 由于晶振为11.0592,故所记次数应为563200,计时器每隔10Ms发起一次中断。
	TL0=0x00;//
	TH1=(65536-TL1_L)/256;// 由于晶振为11.0592,故所记次数应为46080,计时器每隔50000微秒发起一次中断。
	TL1=(65536-TL1_L)%256;//46080的来历,为50000*11.0592/12

	ET0=1;			 //开定时器0中断
	ET1=1;
	EA=1;			 //开总中断
	Deng_Init();
	while(1)
	{
		Deng();
  }
}
void KEY_Init(void)
{
	KEY1=1;
	KEY2=1;
	KEY3=1;
	KEY4=1;
	if(KEY1==0)
	{
		delay(10);
		if(KEY1==0)
		{
			while(!KEY1);
			p=P1;
			Deng_Init();
			G_DX=0;
			R_NB=0;
			time50ms(140);
			P1=p;
		}
	}
	if(KEY2==0)
	{
		delay(10);
		if(KEY2==0)
		{
			while(!KEY2);
			p=P1;
			Deng_Init();
			R_DX=0;
			G_NB=0;
			time50ms(140);
			P1=p;
		}
	}
	if(KEY3==0)
	{
		delay(10);
		if(KEY3==0)
		{
			while(!KEY3);
			p=P1;
			Deng_Init();
		//	G_DX=0;
			R_NB=0;
			R_DX=0;
			time50ms(100);
			P1=p;
		}
	}
}

void T0_Interrupt() interrupt 1
 {
	TH0=0xDC;// 由于晶振为11.0592,故所记次数应为563200,计时器每隔10Ms发起一次中断。
	TL0=0x00;//
  KEY_Init();
	 
 }
void T1_Interrupt() interrupt 3
	{
	  TH1=(65536-TL1_L)/256;// 由于晶振为11.0592,故所记次数应为46080,计时器每隔50000微秒发起一次中断。
	  TL1=(65536-TL1_L)%256;//46080的来历,为50000*11.0592/12
		
 }
void Deng_Init(void)
{
	P1=0xff;
}
void G_dxs(void)
{
	uchar i;
	for(i=0;i<3;i++)
	{
   	G_DX=1;
		time50ms(10);
		G_DX=0;
		time50ms(10);

	}
}
void G_nbs(void)
{
	uchar i;
	for(i=0;i<3;i++)
	{
   	G_NB=1;
		time50ms(10);
		G_NB=0;
		time50ms(10);

	}
}

void Deng(void)
{
	R_NB=0;
	G_DX=0;
	time50ms(280);
	G_dxs();
	G_DX=1;
	R_NB=0;
	Y_DX=0;
	time50ms(60);
	R_NB=1;
	Y_DX=1;
	
	R_DX=0;
	G_NB=0;
	time50ms(280);
	G_nbs();
	R_DX=0;
	G_NB=1;
	Y_NB=0;
	time50ms(60);
	R_DX=1;
	Y_NB=1;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值