#include <reg52.h>
#include <intrins.h>
/********************* 定义 ********************************/
#define LCD_data P0 //数据口
sbit LCD_RS = P2 ^ 0; //寄存器选择输入
sbit LCD_RW = P2 ^ 1; //液晶读/写控制
sbit LCD_EN = P2 ^ 2; //液晶使能控制
sbit LCD_PSB = P2 ^ 3; //串/并方式控制
sbit LCD_RST = P2 ^ 5; //液晶复位端口
sbit sset=P3^4;//设置按钮
sbit spk=P1^4;
sbit sadd=P2^7;
sbit sdel=P2^6;
signed char second=0,minute=0,hour=0,count=0,keycount=0;
signed char key=0;
unsigned char code DIS1[] =
{
"距离系统爆炸时间"
};
unsigned char code DIS2[] =
{
"还剩:"
};
unsigned char code DIS31[] =
{
"时"
};
unsigned char code DIS32[] =
{
"分"
}; unsigned char code DIS33[] =
{
"秒"
};
unsigned char code DIS4[] =
{
"周林"
};
unsigned char code table2[]="0123456789";
char code reserve[3]_at_ 0x3b; //保留0x3b开始的3个字节
/*********************延时子函数**************************/
void delayNOP()//us延时子函数 (4.34us)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
void delayms(unsigned int ms)//ms延时子函数
{
unsigned char y;
while (ms--)
{
for (y = 0; y < 114; y++)
;
}
}
//******************检查LCD忙状态**************************
bit lcd_busy()//检查LCD忙状态 1忙,0闲
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P0 &0x80);
LCD_EN = 0;
return (result); }
//***********************写指令数据***********************
void lcd_wcmd(unsigned char cmd)//写指令数据到LCD
{
while (lcd_busy())
{
;
}
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 1;
P0 = cmd;
delayNOP();
LCD_EN = 0;
}
void lcd_wdat(unsigned char dat)//写显示数据到LCD
{
while (lcd_busy())
;
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 1;
P0 = dat;
delayNOP();
LCD_EN = 0;
}
void writesmh(unsigned char add,unsigned char date)//显示个位和十位数据
{
unsigned char shi,ge;
shi=date/10;
ge=date%10;
lcd_wcmd(0x80+add);
delayms(5);
lcd_wdat(table2[shi]);
delayms(5);
lcd_wdat(table2[ge]);
delayms(5);
}
//*********************初始化设定****************************
void lcd_init()
{
LCD_PSB = 1; //并口方式
LCD_RST = 0; //液晶复位
delayms(5); //液晶复位
LCD_RST = 1; //液晶复位
delayms(5); //液晶复位
lcd_wcmd(0x34); //扩充功能设定,扩充指令,选8位数据
delayms(5);
lcd_wcmd(0x30); //功能设定,基本指令操作,选8位数据
delayms(5);
lcd_wcmd(0x0C); //显示开,关光标,关光标反白允许。
delayms(5);
lcd_wcmd(0x04); //光标的移动方向
delayms(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delayms(5);
TMOD=0x01;
TH0=0x3C;
TL0=0xB0;
EA=1;
ET0=1;
TR0=0;
EX0=0; //外部中断0允许
IT0=1; //外部中断0为边沿触发方式
}
//*********************设定显示位置子函数**********************
void lcd_pos(unsigned char X, unsigned char Y)//设定显示位置
{
unsigned char pos;
if (X == 1)
{
X = 0x80;
}
else if (X == 2)
{
X = 0x90; }
else if (X == 3)
{
X = 0x88;
}
else if (X == 4)
{
X = 0x98;
}
pos = X + Y; //确定显示地址
lcd_wcmd(pos); //写显示地址
}
//*****************清屏子函数***************************
void clr_screen()//清屏子函数
{
lcd_wcmd(0x34); //扩充指令操作
delayms(5);
lcd_wcmd(0x30); //基本指令操作
delayms(5);
lcd_wcmd(0x01); //清屏
delayms(5);
}
//******************闪烁子函数**************************
void lcdflag()
{
lcd_wcmd(0x08); //关闭显示
delayms(500);
lcd_wcmd(0x0c); //开启显示
delayms(500);
lcd_wcmd(0x08);
delayms(500);
lcd_wcmd(0x0c);
delayms(500);
lcd_wcmd(0x08);
delayms(500);
lcd_wcmd(0x0c);
delayms(500);
}
//******************写字符串子函数*************************
void wr_string(unsigned char str[])//写字符串子函数
{
unsigned char num = 0;
while (str[num])
{
lcd_wdat(str[num++]); //写数据
}
}
//********************按键设置时间*************************
void keyscan()//按键设置时间
{
if(sset==0)
{
delayms(10);
if(sset==0)
{
EX0=1;
keycount++;
while(sset==0)
{
;
}
if(keycount==1)
{
TR0=0; //停止计时
key=1;
keycount=2;
lcd_wcmd(0x8e);
lcd_wcmd(0x0d);//秒位闪烁
}
if(keycount==2)
{
;
}
if(keycount==3)
{ keycount=4;
lcd_wcmd(0x8c);
lcd_wcmd(0x0d);//分位闪烁
//lcd_wcmd(0x04);光标左移一位
}
if(keycount==4)
{
;
}
if(keycount==5)
{
keycount=6;
lcd_wcmd(0x8a);
lcd_wcmd(0x0d);//时位闪烁
}
if(keycount==6)
{
;
}
if(keycount==7)
{
keycount=0;
lcd_wcmd(0x0c);//停止闪烁
TR0=1; //开始计时
EX0=1;
}
}
}
if(keycount!=0)
{
if(keycount==2)//编辑秒
{
if(sadd==0)//数值加1
{
delayms(10);
if(sadd==0)
{
second++; if(second==60)
{
second=0;
}
sadd=1;
}
writesmh(0x0e,second);
lcd_wcmd(0x8e);
lcd_wcmd(0x0d);//秒位闪烁
}
if(sdel==0)//数值减1
{
delayms(10);
if(sdel==0)
{
if(second==0)
{
second=60;
}
second--;
sdel=1;
}
writesmh(0x0e,second);
lcd_wcmd(0x8e);
lcd_wcmd(0x0d);//秒位闪烁
}
}
if(keycount==4)//编辑分钟
{
if(sadd==0)//数值加1
{
delayms(10);;
if(sadd==0)
{
minute++;
if(minute==60)
{
minute=0; }
sadd=1;
}
writesmh(0x0c,minute);
lcd_wcmd(0x8c);
lcd_wcmd(0x0d);//分位闪烁
}
if(sdel==0)//数值减1
{
delayms(10);
if(sdel==0)
{
if(minute==0)
{
minute=60;
}
minute--;
sdel=1;
}
writesmh(0x0c,minute);
lcd_wcmd(0x8c);
lcd_wcmd(0x0d);//分位闪烁
}
}
if(keycount==6)//编辑小时
{
if(sadd==0)//数值加1
{
delayms(10);
if(sadd==0)
{
hour++;
if(hour==24)
{
minute=0;
}
sadd=1;
}
writesmh(0x0a,hour);
lcd_wcmd(0x8a);
lcd_wcmd(0x0d);//时位闪烁 }
if(sdel==0)//数值减1
{
delayms(10);
if(sdel==0)
{
if(hour==0)
{
hour=24;
}
hour--;
sdel=1;
}
writesmh(0x0a,hour);
lcd_wcmd(0x8a);
lcd_wcmd(0x0d);//时位闪烁
}
}
}
} }
//主函数主函数主函数主函数主函数主函数主函数主函数主函数主函数主函数主函数主函
void main()
{
delayms(100); //上电,等待稳定
lcd_init(); //初始化LCD
lcd_pos(1, 0); //设置显示位置为第一行
wr_string(DIS1);
lcd_pos(2, 0); //设置显示位置为第二行
wr_string(DIS2);
lcd_pos(3, 3); //设置显示位置为第四行
wr_string(DIS31);
lcd_pos(3, 5); //设置显示位置为第四行
wr_string(DIS32);
lcd_pos(3, 7); //设置显示位置为第四行
wr_string(DIS33);
lcd_pos(4, 6); //设置显示位置为第四行 wr_string(DIS4);
writesmh(0x0e,second);
delayms(5);
writesmh(0x0c,minute);
delayms(5);
writesmh(0x0a,hour);
delayms(5);
while (1)
{
keyscan();
}
}
//**********************中断***************************
void time0() interrupt 1 using 0//倒计时中断
{
TH0=0x3C;
TL0=0xB0;
count++;
if(count==20)
{
count=0;
second--;
if(second<0)
{
second=59;
minute--;
if(minute<0)
{
minute=59;
hour--;
if(hour<0)
{
hour=24;
}
lcd_pos(3, 2); //设置显示位置为第三行,第七列
writesmh(0x0a,hour);
} lcd_pos(3, 4); //设置显示位置为第三行,第七列
writesmh(0x0c,minute);
}
lcd_pos(3, 6); //设置显示位置为第三行,第七列
writesmh(0x0e,second);
if((second==0)&&(minute==0)&&(hour==0))//到点后响铃
{
TR0=0;
spk=0;
second=0;
minute=0;
hour=0;
lcdflag();
spk=1;
}
}
}
void encoder(void) interrupt 0//外部中断0 旋转码开关中断程序
{
if(INT1==1)
{
sadd=0;
sdel=1;
}
if(INT1==0)
{
sdel=0;
sadd=1;
}
}
//*********************************************************
|