|
#include <reg51.h>
#include <stdio.h>
#include <intrins.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit lcden=P2^5;//液晶使能
sbit lcdrw=P2^4;//液晶讀寫
sbit lcdrs=P2^3;//液晶命令/數(shù)據(jù)
sbit ds1302rst=P2^0;//1302復(fù)位端
sbit ds1302clk=P2^1;//1302時(shí)鐘輸入
sbit ds1302io=P2^2;//1302IO口
sbit key1=P1^2;//功能選擇鍵
sbit key2=P1^3;//數(shù)值增加鍵
sbit key3=P1^4;//數(shù)值減少鍵
sbit key4=P1^5;//啟動(dòng)確認(rèn)鍵
sbit key5=P1^6;//12/24小時(shí)切換鍵
sbit key6=P1^7;
sbit key7=P1^1;//鬧鐘設(shè)置
sbit beep=P1^0;
char year=10,mon=9,day=8;hou=14,min=33,sec=12;
char naohou=20,naomin=25;
u8 key1pushflag,key2pushflag,key3pushflag,key4pushflag,key5pushflag=0,key6pushflag=0;//定義按鍵1,2,3,4,5標(biāo)志位
u8 countkey1,runmode=1,naomode=0,countkey2=0;//按鍵1標(biāo)志,運(yùn)行標(biāo)志位
u8 init_display1[]="2010-09-08";
u8 init_display2[]="14:33:12";
void delay(u16 ms){
u8 i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}
//液晶顯示模塊
void write_com(u8 com){//寫命令
lcdrs=0;
lcden=0;
lcdrw=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_date(u8 date){//寫數(shù)據(jù)
lcdrs=1;
lcden=0;
lcdrw=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init_lcd(){//初始化顯示函數(shù)
u8 num;
lcden=0;
write_com(0x38); //設(shè)置16*2行顯示,5*7點(diǎn)陣,8位數(shù)據(jù)口
write_com(0x0c); //開(kāi)顯示,不顯示光標(biāo)
write_com(0x06); //寫一個(gè)字符后地址自動(dòng)加一
write_com(0x01); //顯示清零,數(shù)據(jù)指針清零
write_com(0x80+0x03); //第一行起始地址
for(num=0;num<10;num++){
write_date(init_display1[num]);
delay(5);
}
write_com(0x80+0x42); //第二行起始地址
for(num=0;num<9;num++){
write_date(init_display2[num]);
delay(5);
}
}
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0)
{
write_com(0x80 + x);
}
else
{
write_com(0xC0 + x);
}
write_date( Data);
}
void write_dat_to_lcd(u8 add,u8 dat){
u8 ge,shi;
ge=dat%10;
shi=dat/10;
write_com(0x0c);
write_com(0x80+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void ds1302_write_byte(u8 dat){//1302寫一字節(jié)函數(shù)
u8 temp,num1;
temp=dat;
ds1302rst=1;
for(num1=0;num1<8;num1++){
ds1302io=temp&0x01;
ds1302clk=0;
ds1302clk=1;
temp=temp>>1;
}
}
u8 ds1302_read_byte(){//1302讀一字節(jié)函數(shù)
u8 num,temp;
ds1302rst=1;
for(num=0;num<8;num++){
if(ds1302io)
temp=temp|0x80;
else
temp=temp&0x7f;
ds1302clk=1;
ds1302clk=0;
temp=temp>>1;
}
return temp;
}
void ds1302_write_add_dat(u8 address,u8 dat){//向ds1302特定地址寫入一字節(jié)數(shù)據(jù)
ds1302rst=0;
ds1302clk=0;
ds1302rst=1;
ds1302_write_byte(address);
ds1302_write_byte(dat);
ds1302clk=1;
ds1302rst=0;
}
u8 ds1302_read_add_dat(u8 address,u8 dat){//向ds1302特定地址讀入一字節(jié)數(shù)據(jù)
u8 temp;
ds1302rst=0;
ds1302clk=0;
ds1302rst=1;
ds1302_write_byte(address);//先寫地址再讀數(shù)據(jù)
temp=ds1302_read_byte();
ds1302clk=1;
ds1302rst=0;
return temp;
}
u8 BCD_Decimal(u8 bcd){//BCD碼轉(zhuǎn)十進(jìn)制
u8 Decimal;
Decimal=bcd>>4;
return (Decimal=Decimal*10+(bcd&=0x0f));
}
void init_ds1302(){
ds1302rst=0;
ds1302clk=0;
ds1302_write_add_dat(0x8e,0x00);
}
//按鍵模塊
void keyscan(){
if(key1==0){//加速鍵
delay(5);
if(key1==0){//功能按鍵
while(!key1);
runmode=0;
key1pushflag=1;//功能按鍵按下,萬(wàn)年歷設(shè)置狀態(tài)
countkey1++;//年月日時(shí)分秒設(shè)置
if(countkey1>6)
countkey1=1;
}
}
if(key7==0){//鬧鐘模式
delay(5);
if(key7==0){
while(!key7);
naomode=1;
key6pushflag=1;
countkey2++;
if(countkey2>1)
countkey2=0;
}
}
if(key1pushflag==1||key6pushflag==1){
if(key2==0){//加鍵
delay(5);
if(key2==0){
while(!key2);
key2pushflag=1;
}
}
if(key3==0){//減鍵
delay(5);
if(key3==0){
while(!key3);
key3pushflag=1;
}
}
if(key4==0){
delay(5);
if(key4==0){
while(!key4);
key4pushflag=1;
key1pushflag=0;
key6pushflag=0;
}
}
}
if(key5==0){//12/24小時(shí)切換鍵
delay(5);
if(key5==0){
while(!key5);
key5pushflag=1;
}
}
if(key6==0){//12/24小時(shí)切換鍵
delay(5);
if(key6==0){
while(!key6);
key5pushflag=0;
}
}
}
//按鍵處理
void keyhandle(){
u8 temp;
switch(countkey1){
case 1: //功能按鍵按一次,年數(shù)據(jù)處理
write_com(0x80+0x05);//光標(biāo)處于年的位置
write_com(0x0f);//光標(biāo)閃爍
if(key2pushflag==1){//增加按鍵按下
year++;
if(year>99)
year=0;
key2pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直減少
write_dat_to_lcd(0x05,year);//顯示增加數(shù)字
write_com(0x80+0x05); //光標(biāo)回到年起始位置
}
else if(key3pushflag==1){
year--;
if(year<0)
year=99;
key3pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直增加
write_dat_to_lcd(0x05,year);//顯示減少數(shù)字
write_com(0x80+0x05); //光標(biāo)回到年起始位置
}
break;
case 2:
write_com(0x80+0x08);//光標(biāo)處于月的位置
write_com(0x0f);//光標(biāo)閃爍
if(key2pushflag==1){//增加按鍵按下
mon++;
if(mon>12)
mon=1;
key2pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直增加
write_dat_to_lcd(0x08,mon);//顯示增加數(shù)字
write_com(0x80+0x08); //光標(biāo)回到月起始位置
}
else if(key3pushflag==1){
mon--;
if(mon<0)
mon=12;
key3pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直減少
write_dat_to_lcd(0x08,mon);//顯示減少數(shù)字
write_com(0x80+0x08); //光標(biāo)回到月起始位置
}
break;
case 3:
write_com(0x80+0x0b);//光標(biāo)處于日的位置
write_com(0x0f);//光標(biāo)閃爍
if(key2pushflag==1){//增加按鍵按下
day++;
if(day>30)
day=0;
key2pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直增加
write_dat_to_lcd(0x0b,day);//顯示增加數(shù)字
write_com(0x80+0x0b); //光標(biāo)回到日起始位置
}
else if(key3pushflag==1){
day--;
if(day<1)
day=30;
key3pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直減少
write_dat_to_lcd(0x0b,day);//顯示減少數(shù)字
write_com(0x80+0x0b); //光標(biāo)回到日起始位置
}
break;
case 4:
write_com(0x80+0x42);//光標(biāo)處于時(shí)的位置
write_com(0x0f);//光標(biāo)閃爍
if(key2pushflag==1){//增加按鍵按下
hou++;
if(hou>23)
hou=0;
key2pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直增加
write_dat_to_lcd(0x42,hou);//顯示增加數(shù)字
write_com(0x80+0x42); //光標(biāo)回到時(shí)起始位置
}
else if(key3pushflag==1){
hou--;
if(hou<0)
hou=23;
key3pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直減少
write_dat_to_lcd(0x42,hou);//顯示減少數(shù)字
write_com(0x80+0x42); //光標(biāo)回到時(shí)起始位置
}
break;
case 5:
write_com(0x80+0x45);//光標(biāo)處于分的位置
write_com(0x0f);//光標(biāo)閃爍
if(key2pushflag==1){//增加按鍵按下
min++;
if(min>59)
min=0;
key2pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直增加
write_dat_to_lcd(0x45,hou);//顯示增加數(shù)字
write_com(0x80+0x45); //光標(biāo)回到分起始位置
}
else if(key3pushflag==1){
min--;
if(min<0)
min=59;
key3pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直減少
write_dat_to_lcd(0x45,min);//顯示減少數(shù)字
write_com(0x80+0x45); //光標(biāo)回到分起始位置
}
break;
case 6:
write_com(0x80+0x48);//光標(biāo)處于秒的位置
write_com(0x0f);//光標(biāo)閃爍
if(key2pushflag==1){//增加按鍵按下
sec++;
if(sec>59)
sec=0;
key2pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直增加
write_dat_to_lcd(0x48,sec);//顯示增加數(shù)字
write_com(0x80+0x48); //光標(biāo)回到秒起始位置
}
else if(key3pushflag==1){
sec--;
if(sec<0)
sec=59;
key3pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直減少
write_dat_to_lcd(0x48,sec);//顯示減少數(shù)字
write_com(0x80+0x48); //光標(biāo)回到秒起始位置
}
break;
}
if(key4pushflag==1){
temp=sec/10*16+sec%10;//秒鐘數(shù)據(jù)變成BCD碼
ds1302_write_add_dat(0x8e,0x00);//禁止DS1302寫保護(hù)
ds1302_write_add_dat(0x80,temp); //將秒鐘數(shù)據(jù)寫入1302秒鐘寄存器
temp=min/10*16+min%10;//分鐘數(shù)據(jù)變成BCD碼
ds1302_write_add_dat(0x8e,0x00);//禁止DS1302寫保護(hù)
ds1302_write_add_dat(0x82,temp); //將秒鐘數(shù)據(jù)寫入1302秒鐘寄存器
temp=hou/10*16+hou%10;//時(shí)鐘數(shù)據(jù)變成BCD碼
ds1302_write_add_dat(0x8e,0x00);//禁止DS1302寫保護(hù)
ds1302_write_add_dat(0x84,temp); //將秒鐘數(shù)據(jù)寫入1302秒鐘寄存器
temp=day/10*16+day%10;//日數(shù)據(jù)變成BCD碼
ds1302_write_add_dat(0x8e,0x00);//禁止DS1302寫保護(hù)
ds1302_write_add_dat(0x86,temp); //將秒鐘數(shù)據(jù)寫入1302秒鐘寄存器
temp=mon/10*16+mon%10;//月數(shù)據(jù)變成BCD碼
ds1302_write_add_dat(0x8e,0x00);//禁止DS1302寫保護(hù)
ds1302_write_add_dat(0x88,temp); //將秒鐘數(shù)據(jù)寫入1302秒鐘寄存器
temp=year/10*16+year%10;//年數(shù)據(jù)變成BCD碼
ds1302_write_add_dat(0x8e,0x00);//禁止DS1302寫保護(hù)
ds1302_write_add_dat(0x8c,temp); //將秒鐘數(shù)據(jù)寫入1302秒鐘寄存器
write_com(0x0c);
key4pushflag=0;
runmode=1;
}
}
void naozhongmozhi(void){
u8 temp;
switch(countkey2){
case 0:
write_com(0x80+0x42);//光標(biāo)處于時(shí)的位置
write_com(0x0f);//光標(biāo)閃爍
if(key2pushflag==1){//增加按鍵按下
naohou++;
if(naohou>23)
naohou=0;
key2pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直增加
write_dat_to_lcd(0x42,naohou);//顯示增加數(shù)字
write_com(0x80+0x42); //光標(biāo)回到時(shí)起始位置
}
else if(key3pushflag==1){
naohou--;
if(naohou<0)
naohou=23;
key3pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直減少
write_dat_to_lcd(0x42,naohou);//顯示減少數(shù)字
write_com(0x80+0x42); //光標(biāo)回到時(shí)起始位置
}
break;
case 1:
write_com(0x80+0x45);//光標(biāo)處于分的位置
write_com(0x0f);//光標(biāo)閃爍
if(key2pushflag==1){//增加按鍵按下
naomin++;
if(naomin>59)
naomin=0;
key2pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直增加
write_dat_to_lcd(0x45,naomin);//顯示增加數(shù)字
write_com(0x80+0x45); //光標(biāo)回到分起始位置
}
else if(key3pushflag==1){
naomin--;
if(naomin<0)
naomin=59;
key3pushflag=0;//清除按鍵標(biāo)志,放置按1次該鍵,數(shù)值一直減少
write_dat_to_lcd(0x45,naomin);//顯示減少數(shù)字
write_com(0x80+0x45); //光標(biāo)回到分起始位置
}
break;
}
if(key4pushflag==1){
write_com(0x0c);
key4pushflag=0;
naomode=0;
}
}
void shijianmoshiqiehuan(void){
if(key5pushflag==1){
if(hou>12){
hou=hou-12;
LCD_Write_Char(10,1,'P');
LCD_Write_Char(11,1,'M');
}
else{
hou=hou;
LCD_Write_Char(10,1,'A');
LCD_Write_Char(11,1,'M');
}
write_dat_to_lcd(0x48,sec);//把秒送入液晶
write_dat_to_lcd(0x45,min);
write_dat_to_lcd(0x42,hou);
write_dat_to_lcd(0x0b,day);
write_dat_to_lcd(0x08,mon);
write_dat_to_lcd(0x05,year);
}
else{
write_dat_to_lcd(0x48,sec);//把秒送入液晶
write_dat_to_lcd(0x45,min);
write_dat_to_lcd(0x42,hou);
write_dat_to_lcd(0x0b,day);
write_dat_to_lcd(0x08,mon);
write_dat_to_lcd(0x05,year);
LCD_Write_Char(10,1,' ');
LCD_Write_Char(11,1,' ');
}
}
void main(void)
{
init_lcd();
init_ds1302();
while (1){
keyscan();
if(runmode==1){
sec=BCD_Decimal(ds1302_read_add_dat(0x81));//讀1302秒鐘寄存器數(shù)據(jù),并轉(zhuǎn)化為十進(jìn)制
min=BCD_Decimal(ds1302_read_add_dat(0x83));
hou=BCD_Decimal(ds1302_read_add_dat(0x85));
day=BCD_Decimal(ds1302_read_add_dat(0x87));
mon=BCD_Decimal(ds1302_read_add_dat(0x89));
year=BCD_Decimal(ds1302_read_add_dat(0x8d));
write_com(0x0c);
if(naomode==0){
shijianmoshiqiehuan();
}
if(naomode==1){
write_dat_to_lcd(0x45,naomin);
write_dat_to_lcd(0x42,naohou);
naozhongmozhi();
}
if(hou==naohou&&min==naomin){
beep=0;
}
else{
beep=1;
}
}
else{//萬(wàn)年歷參數(shù)設(shè)置模式
keyhandle();
}
}
}
|
|