51单片机 时间控制的不同时段交通灯控制设计(简单版)
这个交通灯的设计时简单版,只有一个路口(不是十字路口)的那种(想要实现十字路口可以对代码稍加修改)
- 使用的开发软件:Keil uVision5
- 单片机类型为:C51
- 语言类型:C语言
在这里说一下实现的功能
STC12C5A60S2(引脚排序及基本功能同AT89S51)作为主控芯片,设计格局时间选择不同红绿灯交替时间的交通灯控制电路。一是交通灯的正常指示设计;二是扩展DS12C887等相应的外围电路,利用LCD显示时间;三是设计2个交通灯交替间隔,根据时间不同自动选择,可以通过按键来选择3中不同的功能。
先在这里附上几张实现的图片
在这里贴出代码
#include "reg51.h"
#include"absacc.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
unsigned char Key_Value; //读出的键值
/* 液晶 1602 口地址 */
#define wr_com XBYTE[0xC000] //写命令
#define wr_data XBYTE[0xC100] //写数据
#define rd_com XBYTE[0xC200] //读命令
#define rd_data XBYTE[0xC300] //读数据
/* DS12887 口地址 */
#define DS_A XBYTE[0x100A] //寄存器A
#define DS_B XBYTE[0x100B] //寄存器B
#define DS_C XBYTE[0x100C] //寄存器C
#define Years XBYTE[0x1009] //年
#define Month XBYTE[0x1008] //月
#define Day XBYTE[0x1007] //日
#define Week XBYTE[0x1006] //星期
#define Hour XBYTE[0x1004] //时
#define Minute XBYTE[0x1002] //分
#define Second XBYTE[0x1000] //秒
BYTE ah,al,gao,di;
WORD d,e,a,DisplayTime,SD_DisplayTime,DModeStep,SD_DisplayTime1,WorkMode,SD_DisplayTime2,SD_DisplayTime3,ASD_DisplayTime,ASD_DisplayTime1,ASD_DisplayTime2,ASD_DisplayTime3;
sbit P22 = P2^2;//红灯
sbit P23 = P2^3;//黄灯
sbit P24 = P2^4;//绿灯
void IintUart();
void InitADC();
void SendData(BYTE dat);
void GetADCResult(BYTE ch);
void Delay(WORD n);
void Delay2(WORD n);
void ShowResult(BYTE ch);
void lcd_init(void); // lcd初始化
void write_cmd(BYTE cmd); // lcd写命令
void write_data(BYTE dat) ; // 写数据
void set_display_place(BYTE line,column);
void write_string_lcd(BYTE line,column,unsigned char *string);
void write_data_lcd(BYTE line,column,dat);
void red_led(WORD c);
void green_led(WORD c);
void yellow_led(WORD c);
void nred_led(WORD c);
void ngreen_led(WORD c);
void nyellow_led(WORD c);
void Delay3(int Time_ms);
unsigned char Keyscan();
void bt_bt();
void Daytime_mode();
void Night_mode();
void automatic();
void LcdDisplay1(int a);
//void Timer0Interrupt(void) interrupt 1
void InitTimer0(void);
void timer_red();
void timer_green();
void DMode();
void bt_bt1();
void AMode();
void ADMode();
void ANMode();
/*************************************************************
Function name: write_cmd
Descriptions: 向lcd 输入指令
**************************************************************/
void write_cmd(BYTE cmd)
{
BYTE dl;
do { dl=rd_com;
} while((dl&0x80)!=0); //判忙
wr_com= cmd;
Delay(1); } /**********************************************************
Function name: write_data
Descriptions: 写入数据
*********************************************************/
void write_data(BYTE dat)
{
BYTE dl;
do { dl=rd_com; } while((dl&0x80)!=0); //判忙
wr_data= dat;
Delay(1); } /**********************************************************
Function name: read_data
Descriptions: 读出数据
*********************************************************/
void read_data(BYTE dat)
{
BYTE dl;
do { dl=rd_com; } while((dl&0x80)!=0); //判忙
rd_data= dat;
Delay(1); }
/************************************************************
Function name: write_string
Descriptions: 写入字符串
*************************************************************/
void write_string(BYTE *s)
{ while(*s != '\0') //'\0'为字符串结束标志
{ write_data(*s);
s++; } }
/***********************************************************
Function name: set_display_place
Descriptions: 设置字符的显示位置
***********************************************************/
void set_display_place(BYTE line,column)
{ BYTE address;
if(line == 1)
{
address = 0x80 + column;
}
else if(line == 2)
{
address = 0xc0 + column;
} write_cmd(address); }
/**************************************************************
Function name: 将字符串写到指定的位置
Descriptions: 将字符串显示在 lcd 的特定位置
***************************************************************/
void write_string_lcd(BYTE line,column,unsigned char *string){
set_display_place(line,column);
write_string(string);
Delay(1);
}
/***************************************************************Function name: 将字符写到指定的位置
Descriptions: 将字符串显示在 lcd 的特定位置
****************************************************************/
void write_data_lcd(BYTE line,column,dat)
{ set_display_place(line,column);
write_data(dat);
Delay(1);
}
/***************************************************
液晶模块初始化
****************************** *********************/
void lcd_init(void)
{ write_cmd(0x38); write_cmd(0x38); write_cmd(0x06); write_cmd(0x0c); write_cmd(0x01);
} /***************************************************
DS12887 初始化程序
****************************************************/
void DS_init()
{
DS_A=0x20;
DS_B=0x12;
} void write_time() {
DS_A=0x2f; //寄存器A
DS_B|=0x80;
Years=0x19; //年
Month=0x12; //月
Day=0x26; //日
Week=0x02; //星期
Hour=0x14; //时
Minute=0x04; //分
Second=0x00; //秒
DS_B &=0x7f; //寄存器A
} /***************************************************************
显示时间
***************************** ************************************/
void crt_time(BYTE line)
{
BYTE dhi,dli;
set_display_place(1,0);
dli=Years;
dhi=dli & 0xf0;
dhi>>=4;
dhi+=0x30;
dli &=0x0f;
dli +=0x30;
write_data(dhi);
write_data(dli);
dli=0x2d;
write_data(dli);
dli=Month;
dhi=dli & 0xf0;
dhi>>=4;
dhi+=0x30;
dli &=0x0f;
dli +=0x30;
write_data(dhi);
write_data(dli);
dli=0x2d;
write_data(dli);
dli=Day;
dhi=dli & 0xf0;
dhi>>=4;
dhi+=0x30;
dli &=0x0f;
dli +=0x30;
write_data(dhi);
write_data(dli);
dli=0x20;
write_data(dli);
write_data(dli);
write_data(dli);
set_display_place(2,0);
dli=Hour; //0x15
dhi=dli & 0xf0; dhi>>=4;
dhi+=0x30;
dli &=0x0f;
dli +=0x30;
write_data(dhi);
write_data(dli);
gao=dhi;
di=dli;
dli=0x3a; //-
write_data(dli);
dli=Minute;
dhi=dli & 0xf0;
dhi>>=4;
dhi+=0x30;
dli &=0x0f;
dli +=0x30;
write_data(dhi);
write_data(dli);
dli=0x3a;
write_data(dli);
dli=Second;
dhi=dli & 0xf0;
dhi>>=4;
dhi+=0x30;
dli &=0x0f;
dli +=0x30;
write_data(dhi);
write_data(dli); }
void Delay(WORD n){
WORD x; while(n--) { x=500;
while(x--);} } void Delay2(WORD n)
{
WORD x;
while(n--)
{ x=5000;
while(x--);} }
void Delay3(int Time_ms)//延时
{int i;
unsigned char j;
for(i=0;i<Time_ms;i++)
{
for(j=0;j<=150;j++)
{
}
}
}
void InitTimer0(void) //初始化定时器0
{TMOD = 0x01; //模式1TH0 = 0x3C; //定时器装载值TL0 = 0xB0;EA = 1; //使能总中断ET0 = 1; //使能定时器0中断TR0 = 1; //启动定时器0
}
void Timer0Interrupt(void) interrupt 1 //定时器0中断处理函数
{static unsigned char TimeOutNum = 0;int i=0;d=DisplayTime;TH0 = 0x3C; //重新装载值TL0 = 0xB0;TimeOutNum++; //中断次数++, 即50ms的次数if(TimeOutNum>=20) //达到50ms * 20 = 1s条件{TimeOutNum = 0; //中断次数清0SD_DisplayTime--; //白天的红灯及绿灯15SSD_DisplayTime1--; //夜晚的黄灯SD_DisplayTime2--; //白天的黄灯SD_DisplayTime3--; //夜晚的红灯及绿灯10SASD_DisplayTime--; //白天的红灯及绿灯15SASD_DisplayTime1--; //夜晚的黄灯ASD_DisplayTime2--; //白天的黄灯ASD_DisplayTime3--; //夜晚的红灯及绿灯10S}
}
void LcdDisplay1(int a) //lcd显示
{set_display_place(2,14); write_data('0'+a/10);set_display_place(2,15); write_data('0'+a%10); }
unsigned char Keyscan() //行列式键盘扫描 { unsigned char i,j, temp, Buffer[4] = {0xef, 0xdf, 0xbf, 0x7f}; //让矩阵键 盘的每行分别为低电平 for(j=0; j<4; j++) { P1 = Buffer[j]; temp = 0x01; for(i=0; i<4; i++) { if(!(P1 & temp)) //判断 P1 口高 4 位某一行为低电平 { return (j+i*4); //返回键码 } temp <<= 1; } } return 0; }
void bt_bt1()
{P1 = 0xf0; if(P1 != 0xf0) //判断有无按键按下 { Delay3(15); //按键消抖 if(P1 != 0xf0) { Key_Value = Keyscan(); if(Key_Value==0){SD_DisplayTime=15; //白天的红灯及绿灯15SSD_DisplayTime2=8; //白天的黄灯8SWorkMode=1;} else if(Key_Value==1) {SD_DisplayTime1=5; //夜晚的黄灯SD_DisplayTime3=10; //夜晚的红灯及绿灯10SWorkMode=2;}else if(Key_Value==2) {ASD_DisplayTime=15; //白天的红灯及绿灯15SASD_DisplayTime2=8; //白天的黄灯8SASD_DisplayTime1=5; //夜晚的黄灯ASD_DisplayTime3=10; //夜晚的红灯及绿灯10SWorkMode=3;}} }
}
void DMode() //白天工作模式
{write_string_lcd(1,9,"Dmode");switch(DModeStep) {case 1: write_string_lcd(2,9,"Red :");P22=0;LcdDisplay1(SD_DisplayTime);if(SD_DisplayTime ==0 ) //如果通行时间走完,即等于0{P22=1;DModeStep = 2;SD_DisplayTime2=8; } break;case 2: write_string_lcd(2,9,"Yel :");P23=0;Delay(50);P23=1;Delay(50);LcdDisplay1(SD_DisplayTime2);if(SD_DisplayTime2 == 0) //如果通行时间走完,即等于0{P23=1;DModeStep = 3; SD_DisplayTime=15; } break;case 3: write_string_lcd(2,9,"Gre :");P24=0;LcdDisplay1(SD_DisplayTime);if(SD_DisplayTime == 0) //如果通行时间走完,即等于0{P24=1;DModeStep = 4; SD_DisplayTime2=8; } break;case 4: write_string_lcd(2,9,"Yel :");P23=0;Delay(50);P23=1;Delay(50);LcdDisplay1(SD_DisplayTime2);if(SD_DisplayTime2 == 0) //如果通行时间走完,即等于0{P23=1;DModeStep = 1; SD_DisplayTime=15; break;}
}
}
void NMode() //夜晚工作模式
{write_string_lcd(1,9,"Nmode");switch(DModeStep) {case 1: write_string_lcd(2,9,"Red :");P22=0;LcdDisplay1(SD_DisplayTime3);if(SD_DisplayTime3 ==0 ) //如果通行时间走完,即等于0{P22=1;DModeStep = 2;SD_DisplayTime1=5;} break;case 2: write_string_lcd(2,9,"Yel :");P23=0;Delay(50);P23=1;Delay(50);LcdDisplay1(SD_DisplayTime1);if(SD_DisplayTime1 == 0) //如果通行时间走完,即等于0{P23=1;DModeStep = 3; SD_DisplayTime3=10; } break;case 3: write_string_lcd(2,9,"Gre :");P24=0;LcdDisplay1(SD_DisplayTime3);if(SD_DisplayTime3 == 0) //如果通行时间走完,即等于0{P24=1;DModeStep = 4; SD_DisplayTime1=5; } break;case 4: write_string_lcd(2,9,"Yel :");P23=0;Delay(50);P23=1;Delay(50);LcdDisplay1(SD_DisplayTime1);if(SD_DisplayTime1 == 0) //如果通行时间走完,即等于0{P23=1;DModeStep = 1; SD_DisplayTime3=10; break;}
}
}void ADMode() //自动白天工作模式
{switch(DModeStep) {case 1: write_string_lcd(2,9,"Red :");P22=0;LcdDisplay1(ASD_DisplayTime);if(ASD_DisplayTime ==0 ) //如果通行时间走完,即等于0{P22=1;DModeStep = 2;ASD_DisplayTime2=8; } break;case 2: write_string_lcd(2,9,"Yel :");P23=0;Delay(50);P23=1;Delay(50);LcdDisplay1(ASD_DisplayTime2);if(ASD_DisplayTime2 == 0) //如果通行时间走完,即等于0{P23=1;DModeStep = 3; ASD_DisplayTime=15; } break;case 3: write_string_lcd(2,9,"Gre :");P24=0;LcdDisplay1(ASD_DisplayTime);if(ASD_DisplayTime == 0) //如果通行时间走完,即等于0{P24=1;DModeStep = 4; ASD_DisplayTime2=8; } break;case 4: write_string_lcd(2,9,"Yel :");P23=0;Delay(50);P23=1;Delay(50);LcdDisplay1(ASD_DisplayTime2);if(ASD_DisplayTime2 == 0) //如果通行时间走完,即等于0{P23=1;DModeStep = 1; ASD_DisplayTime=15; break;}
}
}void ANMode() //自动夜晚工作模式
{switch(DModeStep) {case 1: write_string_lcd(2,9,"Red :");P22=0;LcdDisplay1(ASD_DisplayTime3);if(ASD_DisplayTime3 ==0 ) //如果通行时间走完,即等于0{P22=1;DModeStep = 2;ASD_DisplayTime1=5;} break;case 2: write_string_lcd(2,9,"Yel :");P23=0;Delay(50);P23=1;Delay(50);LcdDisplay1(ASD_DisplayTime1);if(ASD_DisplayTime1 == 0) //如果通行时间走完,即等于0{P23=1;DModeStep = 3; ASD_DisplayTime3=10; } break;case 3: write_string_lcd(2,9,"Gre :");P24=0;LcdDisplay1(ASD_DisplayTime3);if(ASD_DisplayTime3 == 0) //如果通行时间走完,即等于0{P24=1;DModeStep = 4; ASD_DisplayTime1=5; } break;case 4: write_string_lcd(2,9,"Yel :");P23=0;Delay(50);P23=1;Delay(50);LcdDisplay1(ASD_DisplayTime1);if(ASD_DisplayTime1 == 0) //如果通行时间走完,即等于0{P23=1;DModeStep = 1; ASD_DisplayTime3=10; break;}
}
}void AMode() //自动工作模式
{write_string_lcd(1,9,"Amode");if((gao=='0'&&di=='1')||(gao=='0'&&di=='2')||(gao=='0'&&di=='3')||(gao=='0'&&di=='4')||(gao=='0'&&di=='5')||(gao=='0'&&di=='0'))
{ANmode();
}
else
{ADmode();
}
}void if_workmode()
{switch(WorkMode) //工作模式判断{case 1: //白天模式DMode();break;case 2: //夜间模式NMode();break;case 3: //自动模式AMode();break;}
}void main()
{
int a=0;
SP=0x60;
SD_DisplayTime = 15;
SD_DisplayTime1=5;
SD_DisplayTime2=8;
SD_DisplayTime3=10;
ASD_DisplayTime=15; //白天的红灯及绿灯15S
ASD_DisplayTime2=8; //白天的黄灯8S
ASD_DisplayTime1=5; //夜晚的黄灯5S
ASD_DisplayTime3=10; //夜晚的红灯及绿灯10S
DModeStep = 1;
WorkMode = 3;
InitTimer0();
lcd_init();
DS_init();
write_time();//DS12C887 时间设置
while(1)
{
bt_bt1();
if_workmode();
if ((DS_C & 0x10) != 0)//显示时间
{
crt_time(1);
}
Delay2(1);
}
}
代码直接可以使用,如有不懂之处可以评论,我看到之后会回复哦
51单片机 时间控制的不同时段交通灯控制设计(简单版)相关推荐
- 基于机器视觉的交通灯控制系统设计
基于机器视觉的交通灯控制系统设计 摘 要 Abstract 引言 1 课题背景 1.1概述 1.2传统交通路口信号灯 1.3基于机器视觉的交通灯控制智能系统 1.3.1国内研究现状 1.3.2国外研究 ...
- STMARL:用于合作交通灯控制的时空多智能体强化学习方法
<STMARL: A Spatio-Temporal Multi-Agent Reinforcement Learning Approach for Cooperative Traffic Li ...
- 【Proteus仿真】51单片机汇编数显大型交通灯控制
[Proteus仿真]51单片机汇编数显大型交通灯控制 Proteus仿真 学汇编的人虽然 不多,但是还是有的,分享一个汇编的案例,给需要的人予以参考学习,有些时候我们还是需要懂一些汇编指令比较好. ...
- 【Proteus仿真】【51单片机】交通灯控制系统设计
文章目录 一.功能简介 二.软件设计 三.实验现象 联系作者 一.功能简介 本项目使用Proteus8仿真51单片机控制器,使用数码管.按键.交通信号灯模块等. 系统运行后,交通灯系统开始运行,数码管 ...
- 交通灯控制系统c语言编程,基于单片机的交通灯控制系统设计(本科)毕业论文设计.doc...
基于单片机的交通灯控制系统设计 摘 要 当你路过一个十字路口时,你是否注意到各个方向车辆和行人有有条不紊的通过十字路口.这样井然有序的情境靠什么来实现的呢?靠的是交通灯控制系统.在论文中我使用单片机S ...
- 单片机怎么通过按键控制计时器的开始和停止_学习电路仿真:基于proteus电路仿真软件的交通灯控制电路设计...
电路仿真软件是当代重要软件之一,缺乏电路仿真软件,模拟运行环境将无法搭建.对于电路仿真软件,虽然市面上类别众多,但知名电路仿真软件为proteus.本文对于电路仿真软件的介绍,为基于proteus的交 ...
- 怎么用C51语言实现50ms延时,单片机入门-C51语言实现简单的红绿LED交通灯控制
原标题:单片机入门-C51语言实现简单的红绿LED交通灯控制 视频教程如下: 本文介绍了用C51语言实现十字路口交通灯控制: 四个路口各有红.绿2个LED,模拟交通灯的控制,即东西走向的灯变红,南北走 ...
- 嵌入式综合实验交通灯linux,单片机与嵌入式系统实验十五 交通灯控制
实验十五 交通灯控制 一 . 实验目的 1.学习外部中断技术的基本使用方法. 2.进一步掌握中断处理程序的编程方法. 3.学习顺序控制的编程方法. 二 . 实验内容 本实验模拟交通信号灯控制,一般情况 ...
- 基于at89c51单片机的交通灯控制设计
** 单片机自主学习项目*设计分析 -模拟LED交通灯 ** 一.开发背景与需求 1 开发背景 交通事业蓬勃发展,交通流量年年增长,道路交通繁忙,经常有严重堵车现象,特别是在交叉口,为了在叉口的各条干 ...
最新文章
- java不是有效_单选(2分) 以下哪个不是有效的Java变量名?
- python在线编译-python在线编译器的简单原理及简单实现代码
- 单片机如何使用振动传感器801s_振动传感器如何跟踪测量机器的健康状况
- Visual Entity 手册
- Photon多人游戏开发教程
- java es 数据批量导入_ElasticSearch—Java批量导入导出
- 不要过打折的生活,当你发现这些你有了,说明你开始成熟了
- 商业方向的大数据专业_好程序员大数据培训分享大数据就业方向有哪些
- artcam 9.0英文版本下载_Jenkins版本升级(修复漏洞)
- 关于configure: error: no acceptable C compiler found in $PATH
- C是一个结构化语言它的重点在于算法和数据结构
- CodeForces-4C Registration system
- Fiddler自动保存抓包内容到文件
- Gradle下载及安装,配置IDEA
- lingo与excel
- allegro 导 bom
- 提高笔记本无线网络速度
- CentOS 7.5版本成功安装后修改基本配置以及可视化远程桌面解决办法
- 魏鹏机器人_3D打印室、机器人工程挑战室……山东这所学校的“网红教室”火了!...
- 无法使用内置管理员账户打开应用商店