51单片机 时间控制的不同时段交通灯控制设计(简单版)

Freda ·
更新时间:2024-11-01
· 801 次阅读

这个交通灯的设计时简单版,只有一个路口(不是十字路口)的那种(想要实现十字路口可以对代码稍加修改) 使用的开发软件:Keil uVision5 单片机类型为:C51 语言类型:C语言
在这里说一下实现的功能
STC12C5A60S2(引脚排序及基本功能同AT89S51)作为主控芯片,设计格局时间选择不同红绿灯交替时间的交通灯控制电路。一是交通灯的正常指示设计;二是扩展DS12C887等相应的外围电路,利用LCD显示时间;三是设计2个交通灯交替间隔,根据时间不同自动选择,可以通过按键来选择3中不同的功能。
先在这里附上几张实现的图片
白天模式
夜晚模式
自动模式
LED灯的图片
在这里贴出代码 #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=20) //达到50ms * 20 = 1s条件 { TimeOutNum = 0; //中断次数清0 SD_DisplayTime--; //白天的红灯及绿灯15S SD_DisplayTime1--; //夜晚的黄灯 SD_DisplayTime2--; //白天的黄灯 SD_DisplayTime3--; //夜晚的红灯及绿灯10S ASD_DisplayTime--; //白天的红灯及绿灯15S ASD_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; //白天的红灯及绿灯15S SD_DisplayTime2=8; //白天的黄灯8S WorkMode=1; } else if(Key_Value==1) { SD_DisplayTime1=5; //夜晚的黄灯 SD_DisplayTime3=10; //夜晚的红灯及绿灯10S WorkMode=2; } else if(Key_Value==2) { ASD_DisplayTime=15; //白天的红灯及绿灯15S ASD_DisplayTime2=8; //白天的黄灯8S ASD_DisplayTime1=5; //夜晚的黄灯 ASD_DisplayTime3=10; //夜晚的红灯及绿灯10S WorkMode=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单片机 交通 单片机

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章
Ipo 2020-01-31
789