#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);
}
}
代码直接可以使用,如有不懂之处可以评论,我看到之后会回复哦