基于51单片机的交通灯【LCD1602,左拐,独立按键】(仿真)

三色交通灯只代表转向指示,全灭表示形式的通行

1.整个系统具有开启、停止、运行等选项,在停止状态可以进行通行时间的设置;

2.可以对车辆的通行时间进行设置;

3.不同类型的通行应可以单独设置,如上下直行和左右直行可以为不同的通行时间

4.利用LCD1602(LM016L)指示各个路口通行剩余时间以及修改时间


sbit k1=P3^2;//设置
sbit k2=P3^3;//加
sbit k3=P3^4;//减
sbit k4=P3^0;//启动
sbit k5=P3^1;//停止

sbit red1	=P1^0;	  //南北方向
sbit yellow1=P1^1;
sbit green1	=P1^2;
sbit red2	=P1^3;	  //东西方向
sbit yellow2=P1^4;
sbit green2	=P1^5;
sbit left1=P1^7;//东西左拐
sbit left2=P1^6;//南北左拐

uchar sec=0,miao=0;	  //定时
uchar nan=0,dong=0;//东西南北时间
uchar mode=0;		  //路灯工作顺序
uchar nan_lim=10,dong_lim=10,left1_lim=10,left2_lim=15;//自由调整时主次干道绿灯时间
uchar yellow_time=3;//黄灯时间
uchar human_time=10;//行人通行时间
uchar moshi=10;
uchar disp[]="00s";

void delay(uint i)//延时
{
	while(i--);
}

void control()//控制路灯
{
	switch(mode)
		{
			case 0:red1=0;yellow1=1;green1=1;
				red2=1;yellow2=1;green2=0;//东西直行
				left1=1;left2=1;
				nan=dong_lim+yellow_time*2+left1_lim+2;
				dong=dong_lim;//设置初始时间
				break;
			case 1:red1=0;yellow1=1;green1=1;
				red2=1;yellow2=0;green2=1;//东西黄灯亮
				left1=1;left2=1;
				dong=yellow_time;
				break;
			case 2:red1=0;yellow1=1;green1=1;//东西左拐
				red2=1;yellow2=1;green2=1;
				left1=0;left2=1;
				dong=left1_lim;//设置初始时间
				break;
			case 3:red1=0;yellow1=1;green1=1;
				red2=1;yellow2=0;green2=1;//东西黄灯亮
				left1=1;left2=1;
				dong=yellow_time;
				break;
						
			case 4:red1=1;yellow1=1;green1=0;
				red2=0;yellow2=1;green2=1;//东西红灯亮
				left1=1;left2=1;
				nan=nan_lim;
				dong=nan_lim+yellow_time*2+left2_lim+2;//设置初始时间
				break;
			case 5:red1=1;yellow1=0;green1=1;
				red2=0;yellow2=1;green2=1;//南北黄灯亮
				left1=1;left2=1;
				nan=yellow_time;
				break;
			case 6:red1=1;yellow1=1;green1=1;
				red2=0;yellow2=1;green2=1;//南北左拐
				left1=1;left2=0;
				nan=left2_lim;
				break;
			case 7:red1=1;yellow1=0;green1=1;
				red2=0;yellow2=1;green2=1;//南北黄灯亮
				left1=1;left2=1;
				nan=yellow_time;
				break;
			case 8:red1=1;yellow1=1;green1=1;//行人通行
				red2=1;yellow2=1;green2=1;
				left1=1;left2=1;
				nan=human_time+1;
				dong=human_time;
		}
}

//清屏
void clear()
{
	write_com(0x01);//清屏
	delay(15000);
}
void main()//主函数
{
	init_1602();//初始化LCD
	TMOD=0x01;//定时器设置
	TH0=0x3c; //50ms
	TL0=0xb0;
	ET0=1;	  //开中断
	EA=1;
	TR0=1;	 //启动定时器
	red1=0;yellow1=1;green1=1;	//禁行
		red2=0;yellow2=1;green2=1;
		left1=1;left2=1;	

	while(1)
	{
		if(!k1 &&(moshi<10))	 //设置
		{				 //模式切换
			if(moshi<5)
				moshi++;
			else
				moshi=1;
			clear();//清屏
			while(!k1);
		}
		if(moshi==1)//调节南北时间
		{
			if(!k2)
			{
				if(nan_lim<99)
					nan_lim++;
				while(!k2);
			}
			if(!k3)
			{
				if(nan_lim>1)
					nan_lim--;
				while(!k3);
			}
		}
		if(moshi==2)//调节南北左拐时间
		{
			if(!k2)
			{
				if(left2_lim<99)
					left2_lim++;
				while(!k2);
			}
			if(!k3)
			{
				if(left2_lim>1)
					left2_l

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
这里提供一个基于51单片机独立按键控制LCD1602数字增加减少的实现方法。 首先,需要连接好51单片机LCD1602模块,以及独立按键。具体的连接方式可以参考相关的资料或者示例代码。 接着,在程序中需要定义好LCD1602的各种指令和显示函数。可以使用现成的库函数,也可以自己编写相应的函数。 然后,需要编写独立按键的中断服务函数。在中断服务函数中,通过检测按键的状态,来判断是执行增加操作还是减少操作,并将结果显示在LCD1602上。 最后,在主函数中,需要初始化LCD1602独立按键,并开启中断。然后进入循环,等待按键触发中断。 下面是一份示例代码,仅供参考: ``` #include <reg52.h> #define LCD1602_DATAPORT P0 sbit LCD1602_RS = P2^6; sbit LCD1602_RW = P2^5; sbit LCD1602_EN = P2^7; sbit KEY_UP = P1^0; sbit KEY_DOWN = P1^1; unsigned char num = 0; void delay(unsigned int t) // 延时函数 { while(t--); } void write_cmd(unsigned char cmd) // 写指令 { LCD1602_RS = 0; LCD1602_RW = 0; LCD1602_DATAPORT = cmd; LCD1602_EN = 1; delay(10); LCD1602_EN = 0; } void write_data(unsigned char dat) // 写数据 { LCD1602_RS = 1; LCD1602_RW = 0; LCD1602_DATAPORT = dat; LCD1602_EN = 1; delay(10); LCD1602_EN = 0; } void init_lcd() // 初始化LCD1602 { write_cmd(0x38); // 设置显示模式,16x2,5x7点阵,8位数据总线 write_cmd(0x0c); // 设置显示模式,开显示,不显示光标,不闪烁 write_cmd(0x06); // 光标右移,字符不移动 write_cmd(0x01); // 清屏 } void display_num(unsigned char num) // 显示数字 { unsigned char digit[3] = {0}; digit[2] = num % 10; digit[1] = num / 10 % 10; digit[0] = num / 100 % 10; write_cmd(0x80 + 5); // 设置光标位置 write_data('0' + digit[0]); // 显示百位数字 write_data('0' + digit[1]); // 显示十位数字 write_data('0' + digit[2]); // 显示个位数字 } void keyinterrupt() interrupt 0 // 中断服务函数 { if(KEY_UP == 0) // 按键被按下 { num++; // 数字增加1 if(num >= 100) num = 0; // 数字归零 display_num(num); // 显示数字 } else if(KEY_DOWN == 0) // 按键被按下 { num--; // 数字减少1 if(num >= 100) num = 99; // 数字限制在0-99之间 display_num(num); // 显示数字 } } void main() { EA = 1; // 允许中断 EX0 = 1; // 开启外部中断0 IT0 = 1; // 下降沿触发 init_lcd(); // 初始化LCD1602 display_num(num); // 显示数字 while(1); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白茶丫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值