基於51微控制器液晶萬年曆設計
電子萬年曆是一種非常廣泛日常計時工具,給人們的帶來了很大的方便,在社會上越來越流行。 它可以對年、月、日、時、分、秒進行計時,採用直觀的數字顯示,可以同時顯示年月日時分秒和溫度等資訊,還有時間校準、鬧鐘等功能。該電子萬年曆主要採用STC89C52微控制器作為主控核心,用DS1302時鐘晶片作為時鐘、液晶12864螢幕顯示。STC89C52微控制器是由巨集晶公司推出的,功耗小,電壓可選用4~6V電壓供電;DS1302時鐘晶片是美國DALLAS公司推出的具有細電流充電功能的低功耗實時時鐘晶片,它可以對年、月、日、星期、時、分、秒進行計時,還具有閏年補償等多種功能,而且DS1302的使用壽命長,誤差小;數字顯示是採用的12864液晶螢幕來顯示,可以同時顯示年、月、日、星期、時、分、秒和溫度等資訊。此外,該電子萬年曆還具有時間校準等功能。
1. 系統總體功能
本設計採用的是巨集晶公司的STC89C52微控制器為核心,通過微控制器與時鐘晶片DS1302通訊來對時間的讀寫,保證時鐘時間的穩定性,並帶有內部電源模組,使系統斷電時時鐘資料不會丟失,以DS18B20溫度感應晶片作為溫度電路的核心,向微控制器發出獲取到的溫度資料,並通過LCD1602將時間、顯示出來,並可以通過按鍵調整時間日期和鬧鐘時間。
2. 總體電路圖
電路組成:
- 微控制器最小系統
- LCD602液晶螢幕電路
- 四路獨立按鍵
- DS1302時鐘電路
- DS18B20溫度感測器
- 系統電源
3. 程式設計
(1) LCD1602驅動程式
sbit rs = P2^0;
sbit rw = P2^1;
sbit e = P2^2;
#define lcddata P0
sbit busy=P0^7; //lcd busy bit
void wr_d_lcd(uchar content);
void wr_i_lcd(uchar content);
void clrram_lcd (void);
void init_lcd(void);
void busy_lcd(void);
void rev_row_lcd(uchar row);
void rev_co_lcd(uchar row,uchar col,uchar mode);
void clr_lcd(void);
void wr_co_lcd(uchar row,uchar col,uchar lcddata1,uchar lcddtta2);
void wr_row_lcd(uchar row,char *p);
//**********************************
//液晶初始化
//**********************************
void init_lcd(void)
{
wr_i_lcd(0x06); /*游標的移動方向*/
wr_i_lcd(0x0c); /*開顯示,關遊標*/
}
//***********************************
//填充液晶DDRAM全為空格
//**********************************
void clrram_lcd (void)
{
wr_i_lcd(0x30);
wr_i_lcd(0x01);
}
//***********************************
//對液晶寫資料
//content為要寫入的資料
//***********************************
void wr_d_lcd(uchar content)
{
busy_lcd();
rs=1;
rw=0;
lcddata=content;
e=1;
;
e=0;
}
//********************************
//對液晶寫指令
//content為要寫入的指令程式碼
//*****************************
void wr_i_lcd(uchar content)
{
busy_lcd();
rs=0;
rw=0;
lcddata=content;
e=1;
;
e=0;
}
//********************************
//液晶檢測忙狀態
//在寫入之前必須執行
//********************************
void busy_lcd(void)
{
lcddata=0xff;
rs=0;
rw=1;
e =1;
while(busy==1);
e =0;
}
//********************************
//指定要顯示字元的座標
//*******************************
void gotoxy(unsigned char y, unsigned char x)
{
if(y==1)
wr_i_lcd(0x80|x);
if(y==2)
wr_i_lcd(0x90|x);
if(y==3)
wr_i_lcd((0x80|x)+8);
if(y==4)
wr_i_lcd((0x90|x)+8);
}
//**********************************
//液晶顯示字串程式
//**********************************
void print(uchar *str)
{
while(*str!='\0')
{
wr_d_lcd(*str);
str++;
}
}
//***************************************
//液晶顯示主程式模組
//***************************************
void show_time()
{
DS1302_GetTime(&CurrentTime); //獲取時鐘晶片的時間資料
TimeToStr(&CurrentTime); //時間資料轉換液晶字元
DateToStr(&CurrentTime); //日期資料轉換液晶字元
ReadTemp(); //開啟溫度採集程式
temp_to_str(); //溫度資料轉換成液晶字元
gotoxy(4,0);
print("溫度");
gotoxy(4,2); //液晶字元顯示位置
print(TempBuffer); //顯示溫度
gotoxy(4,6);
print("℃");
gotoxy(3,0);
print("時間:");
gotoxy(3,3);
print(CurrentTime.TimeString); //顯示時間
gotoxy(2,3);
print(CurrentTime.DateString); //顯示日期
gotoxy(2,0);
print("星期");
gotoxy(2,2);
print(week_value); //顯示星期
gotoxy(1,1);
print("【萬年曆】");
mdelay(500); //掃描延時
}
(2) DS1302驅動程式
//***********************************
//DS1302時鐘部分子程式模組
//***********************************
typedef struct __SYSTEMTIME__
{
uchar Second;
uchar Minute;
uchar Hour;
uchar Week;
uchar Day;
uchar Month;
uchar Year;
uchar DateString[11];
uchar TimeString[9];
}SYSTEMTIME; //定義的時間型別
SYSTEMTIME CurrentTime;
#define AM(X) X
#define PM(X) (X+12) // 轉成24小時制
#define DS1302_SECOND 0x80 //時鐘晶片的暫存器位置,存放時間
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
//**********************************
//實時時鐘寫入一位元組(內部函式)
//**********************************
void DS1302InputByte(uchar d)
{
uchar i;
ACC = d;
for(i=8; i>0; i--)
{
DS1302_IO = ACC0; //相當於彙編中的 RRC
DS1302_CLK = 1;
DS1302_CLK = 0;
ACC = ACC >> 1;
}
}
//*************************************
//實時時鐘讀取一位元組(內部函式)
//*************************************
uchar DS1302OutputByte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相當於彙編中的 RRC
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0;
}
return(ACC);
}
//**************************************
//ucAddr: DS1302地址, ucData: 要寫的資料
//**************************************
void Write1302(uchar ucAddr, uchar ucDa)
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr); // 地址,命令
DS1302InputByte(ucDa); // 寫1Byte資料
DS1302_CLK = 1;
DS1302_RST = 0;
}
//**************************************
//讀取DS1302某地址的資料
//**************************************
uchar Read1302(uchar ucAddr)
{
uchar ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr|0x01); // 地址,命令
ucData = DS1302OutputByte(); // 讀1Byte資料
DS1302_CLK = 1;
DS1302_RST = 0;
return(ucData);
}
//******************************************
//獲取時鐘晶片的時鐘資料到自定義的結構型陣列
//******************************************
void DS1302_GetTime(SYSTEMTIME *Time)
{
uchar ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//轉換為相應的10進位制數
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_DAY);
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_WEEK);
Time->Week = ((ReadValue&0x10)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_MONTH);
Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_YEAR);
Time->Year = ((ReadValue&0xf0)>>4)*10 + (ReadValue&0x0F);
}
//******************************************
//將時間年,月,日,星期資料轉換成液
//晶顯示字串,放到陣列裡DateString[]
//******************************************
void DateToStr(SYSTEMTIME *Time)
{
uchar tab[ ]={0XD2,0XBB,0XB6,0XFE,0XC8,0XFD,0XCB,0XC4,0XCE,0XE5,0XC1,0XF9,0XC8,0XD5};
if(hide_year<2) //這裡的if,else語句都是判斷位閃爍,<2顯示資料,>2就不顯示,輸出字串為 2007/07/22
{
Time->DateString[0] = '2';
Time->DateString[1] = '0';
Time->DateString[2] = Time->Year/10 + '0';
Time->DateString[3] = Time->Year%10 + '0';
}
else
{
Time->DateString[0] = ' ';
Time->DateString[1] = ' ';
Time->DateString[2] = ' ';
Time->DateString[3] = ' ';
}
Time->DateString[4]='-';
if(hide_month<2)
{
Time->DateString[5] = Time->Month/10 + '0';
Time->DateString[6] = Time->Month%10 + '0';
}
else
{
Time->DateString[5] = ' ';
Time->DateString[6] = ' ';
}
Time->DateString[7]='-';
if(hide_day<2)
{
Time->DateString[8] = Time->Day/10 + '0';
Time->DateString[9] = Time->Day%10 + '0';
}
else
{
Time->DateString[8] = ' ';
Time->DateString[9] = ' ';
}
if(hide_week<2)
{
week_value[0] =tab[2*(Time->Week%10)-2]; //星期的資料另外放到 week_value[]陣列裡,跟年,月,日的分開存放,因為等一下要在最後顯示
week_value[1] =tab[2*(Time->Week%10)-1];
}
else
{
week_value[0] = ' ';
week_value[1]=' ';
}
week_value[2] = '\0';
Time->DateString[10] = '\0'; //字串末尾加 '\0' ,判斷結束字元
}
//******************************************
//將時,分,秒資料轉換成液晶
//顯示字元放到陣列 TimeString[]
//*****************************************
void TimeToStr(SYSTEMTIME *Time)
{ if(hide_hour<2)
{
Time->TimeString[0] = Time->Hour/10 + '0';
Time->TimeString[1] = Time->Hour%10 + '0';
}
else
{
Time->TimeString[0] = ' ';
Time->TimeString[1] = ' ';
}
Time->TimeString[2] = ':';
if(hide_min<2)
{
Time->TimeString[3] = Time->Minute/10 + '0';
Time->TimeString[4] = Time->Minute%10 + '0';
}
else
{
Time->TimeString[3] = ' ';
Time->TimeString[4] = ' ';
}
Time->TimeString[5] = ':';
if(hide_sec<2)
{
Time->TimeString[6] = Time->Second/10 + '0';
Time->TimeString[7] = Time->Second%10 + '0';
}
else
{
Time->TimeString[6] = ' ';
Time->TimeString[7] = ' ';
}
Time->TimeString[8] = '\0';
}
//******************************
//時鐘晶片初始化
//******************************
void Initial_DS1302(void)
{
uchar Second=Read1302(DS1302_SECOND);
if(Second&0x80) //判斷時鐘晶片是否關閉
{
Write1302(0x8e,0x00); //寫入允許
Write1302(0x8c,0x07); //以下寫入初始化時間 日期:07/07/25.星期: 3. 時間: 23:59:55
Write1302(0x88,0x07);
Write1302(0x86,0x25);
Write1302(0x8a,0x07);
Write1302(0x84,0x23);
Write1302(0x82,0x59);
Write1302(0x80,0x55);
Write1302(0x8e,0x80); //禁止寫入
}
}
(3)DS18B20驅動程式
/***********ds18b20子程式*************************/
/***********ds18b20延遲子函式(晶振12MHz )*******/
void delay_18B20(unsigned int i)
{
while(i--);
}
/**********ds18b20初始化函式**********************/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ復位
delay_18B20(8); //稍做延時
DQ = 0; //微控制器將DQ拉低
delay_18B20(40); //精確延時 大於 480us
DQ = 1; //拉高匯流排
delay_18B20(7);
x=DQ; //稍做延時後 如果x=0則初始化成功 x=1則初始化失敗
delay_18B20(10);
}
/***********ds18b20讀一個位元組**************/
uchar ReadOneChar(void)
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 給脈衝訊號
dat>>=1;
DQ = 1; // 給脈衝訊號
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
/*************ds18b20寫一個位元組****************/
void WriteOneChar(uchar dat)
{
uchar i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay_18B20(5);
DQ = 1;
dat>>=1;
}
}
/**************讀取ds18b20當前溫度************/
void ReadTemp(void)
{
uchar a=0;
uchar b=0;
uchar t;
Init_DS18B20();
WriteOneChar(0xCC); // 跳過讀序號列號的操作
WriteOneChar(0x44); // 啟動溫度轉換
delay_18B20(100); // this message is wery important
Init_DS18B20();
WriteOneChar(0xCC); //跳過讀序號列號的操作
WriteOneChar(0xBE); //讀取溫度暫存器等(共可讀9個暫存器) 前兩個就是溫度
delay_18B20(50);
a=ReadOneChar(); //讀取溫度值低位
b=ReadOneChar(); //讀取溫度值高位
t=b&0xf8;
if(t)
{
TempBuffer[0]=':';
TempBuffer[1]='-';
temp_value=b<<4;
temp_value+=(a&0xf0)>>4;
temp_value=~temp_value+1;
temp1_value=~a&0x0f;
}
else
{
temp_value=b<<4;
temp_value+=(a&0xf0)>>4;
temp1_value=a&0x0f;
TempBuffer[0]=':';
TempBuffer[1]=temp_value/100+'0'; //百位
if(TempBuffer[1]=='1')
{
TempBuffer[1]='1';
}
else
{
TempBuffer[1]=' ';
}
}
}
void temp_to_str() //溫度資料轉換成液晶字元顯示
{
TempBuffer[2]=temp_value%100/10+'0'; //十位
TempBuffer[3]=temp_value%10+'0'; //個位
TempBuffer[4]='.';
TempBuffer[5]=temp1_value*625/1000%10+'0';
TempBuffer[6]=temp1_value*625/100%10+'0';
TempBuffer[7]=temp1_value*625/10%10+'0';
//TempBuffer[8]=temp1_value*625%10+'0';
TempBuffer[8]='\0';
}
//**********************************************
//延時子程式模組
//**********************************************
void mdelay(uint delay)
{ uint i;
for(;delay>0;delay--)
{for(i=0;i<80;i++) //1ms延時.
{;}
}
}
(4) 按鍵驅動程式
//************************************
//跳出調整模式,返回預設顯示
//************************************
void outkey()
{ uchar Second;
if(out==0)
{ mdelay(5);
count=0;
hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_month=0,hide_year=0;
Second=Read1302(DS1302_SECOND);
Write1302(0x8e,0x00); //寫入允許
Write1302(0x80,Second&0x7f);
Write1302(0x8E,0x80); //禁止寫入
done=0;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//*************************
//升序按鍵
//*************************
void Upkey()
{
Up=1;
if(Up==0)
{
mdelay(5);
switch(count)
{case 1:
temp=Read1302(DS1302_SECOND); //讀取秒數
temp=((temp&0x70)>>4)*10 + (temp&0x0F);
temp=temp+1; //秒數加1
up_flag=1; //資料調整後更新標誌
if((temp)>59) //超過59秒,清零
temp=0;
temp=temp/10*16+temp%10;
break;
case 2:
temp=Read1302(DS1302_MINUTE); //讀取分數
temp=((temp&0x70)>>4)*10 + (temp&0x0F);
temp=temp+1; //分數加1
up_flag=1;
if(temp>59) //超過59分,清零
temp=0;
temp=temp/10*16+temp%10;
break;
case 3:
temp=Read1302(DS1302_HOUR); //讀取小時數
temp=((temp&0x70)>>4)*10 + (temp&0x0F);
temp=temp+1; //小時數加1
up_flag=1;
if(temp>23) //超過23小時,清零
temp=0;
temp=temp/10*16+temp%10;
break;
case 4:
temp=Read1302(DS1302_WEEK); //讀取星期數
temp=((temp&0x70)>>4)*10 + (temp&0x0F);
temp=temp+1; //星期數加1
up_flag=1;
if(temp>7)
temp=1;
temp=temp/10*16+temp%10;
break;
case 5:
temp=Read1302(DS1302_DAY); //讀取日數
temp=((temp&0x70)>>4)*10 + (temp&0x0F);
temp=temp+1; //日數加1
up_flag=1;
if(temp>31)
temp=1;
temp=temp/10*16+temp%10;
break;
case 6:
temp=Read1302(DS1302_MONTH); //讀取月數
temp=((temp&0x70)>>4)*10 + (temp&0x0F);
temp=temp+1; //月數加1
up_flag=1;
if(temp>12)
temp=1;
temp=temp/10*16+temp%10;
break;
case 7:
temp=Read1302(DS1302_YEAR); //讀取年數
temp=((temp&0xf0)>>4)*10 + (temp&0x0F);
temp=temp+1; //年數加1
up_flag=1;
if(temp>99)
temp=0;
temp=temp/10*16+temp%10;
break;
default:break;
}
// while(Up==0);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//************************
//降序按鍵
//************************
void Downkey()
{
Down=1;
if(Down==0)
{
mdelay(5);
switch(count)
{case 1:
temp=Read1302(DS1302_SECOND); //讀取秒數
temp=((temp&0x70)>>4)*10 + (temp&0x0F);
temp=temp-1; //秒數減1
down_flag=1; //資料調整後更新標誌
if(temp==-1) //小於0秒,返回59秒
temp=59;
temp=temp/10*16+temp%10;
break;
case 2:
temp=Read1302(DS1302_MINUTE); //讀取分數
temp=((temp&0x70)>>4)*10 + (temp&0x0F);
temp=temp-1; //分數減1
down_flag=1;
if(temp==-1)
temp=59; //小於0秒,返回59秒
temp=temp/10*16+temp%10;
break;
case 3:
temp=Read1302(DS1302_HOUR); //讀取小時數
temp=((temp&0x70)>>4)*10 + (temp&0x0F);
temp=temp-1; //小時數減1
down_flag=1;
if(temp==-1)
temp=23;
temp=temp/10*16+temp%10;
break;
case 4:
temp=Read1302(DS1302_WEEK); //讀取星期數;
temp=((temp&0x70)>>4)*10 + (temp&0x0F);
temp=temp-1; //星期數減1
down_flag=1;
if(temp==0)
temp=7;
temp=temp/10*16+temp%10;
break;
case 5:
temp=Read1302(DS1302_DAY); //讀取日數
temp=((temp&0x70)>>4)*10 + (temp&0x0F);
temp=temp-1; //日數減1
down_flag=1;
if(temp==0)
temp=31;
temp=temp/10*16+temp%10;
break;
case 6:
temp=Read1302(DS1302_MONTH); //讀取月數
temp=((temp&0x70)>>4)*10 + (temp&0x0F);
temp=temp-1; //月數減1
down_flag=1;
if(temp==0)
temp=12;
temp=temp/10*16+temp%10;
break;
case 7:
temp=Read1302(DS1302_YEAR); //讀取年數
temp=((temp&0xf0)>>4)*10 + (temp&0x0F);
temp=temp-1; //年數減1
down_flag=1;
if(temp==-1)
temp=99;
temp=temp/10*16+temp%10;
break;
default:break;
}
// while(Down==0);
}
}
//**************************
//模式選擇按鍵
//**************************
void Setkey()
{
Set=1;
if(Set==0)
{
mdelay(5);
count=count+1; //Setkey按一次,count就加1
done=1; //進入調整模式
while(Set==0);
}
}
//*************************
//按鍵功能執行
//*************************
void keydone()
{
uchar Second;
/* if(flag==0) //關閉時鐘,停止計時
{ Write1302(0x8e,0x00); //寫入允許
temp=Read1302(0x80);
Write1302(0x80,temp|0x80);
Write1302(0x8e,0x80); //禁止寫入
flag=1;
}*/
Setkey(); //掃描模式切換按鍵
switch(count)
{
case 1:do //count=1,調整秒
{
outkey(); //掃描跳出按鈕
Upkey(); //掃描加按鈕
Downkey(); //掃描減按鈕
if(up_flag==1||down_flag==1) //資料更新,重新寫入新的資料
{
Write1302(0x8e,0x00); //寫入允許
Write1302(0x80,temp); //寫入新的秒數
Write1302(0x8e,0x80); //禁止寫入
up_flag=0;
down_flag=0;
}
if(Down!=0&&Up!=0)
{
hide_sec++;
if(hide_sec>3)
hide_sec=0;
}
else hide_sec=0;
show_time(); //液晶顯示資料
}while(count==2);break;
case 2:do //count=2,調整分
{
hide_sec=0;
outkey();
Upkey();
Downkey();
if(temp>0x60)
temp=0;
if(up_flag==1||down_flag==1)
{
Write1302(0x8e,0x00); //寫入允許
Write1302(0x82,temp); //寫入新的分數
Write1302(0x8e,0x80); //禁止寫入
up_flag=0;
down_flag=0;
}
if(Down!=0&&Up!=0)
{
hide_min++;
if(hide_min>3)
hide_min=0;
}
else hide_min=0;
show_time();
}while(count==3);break;
case 3:do //count=3,調整小時
{
hide_min=0;
outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{
Write1302(0x8e,0x00); //寫入允許
Write1302(0x84,temp); //寫入新的小時數
Write1302(0x8e,0x80); //禁止寫入
up_flag=0;
down_flag=0;
}
if(Down!=0&&Up!=0)
{
hide_hour++;
if(hide_hour>3)
hide_hour=0;
}
else hide_hour=0;
show_time();
}while(count==4);break;
case 4:do //count=4,調整星期
{
hide_hour=0;
outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{
Write1302(0x8e,0x00); //寫入允許
Write1302(0x8a,temp); //寫入新的星期數
Write1302(0x8e,0x80); //禁止寫入
up_flag=0;
down_flag=0;
}
if(Down!=0&&Up!=0)
{
hide_week++;
if(hide_week>3)
hide_week=0;
}
else hide_week=0;
show_time();
}while(count==5);break;
case 5:do //count=5,調整日
{
hide_week=0;
outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{
Write1302(0x8e,0x00); //寫入允許
Write1302(0x86,temp); //寫入新的日數
Write1302(0x8e,0x80); //禁止寫入
up_flag=0;
down_flag=0;
}
if(Down!=0&&Up!=0)
{
hide_day++;
if(hide_day>3)
hide_day=0;
}
else hide_day=0;
show_time();
}while(count==6);break;
case 6:do //count=6,調整月
{
hide_day=0;
outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{
Write1302(0x8e,0x00); //寫入允許
Write1302(0x88,temp); //寫入新的月數
Write1302(0x8e,0x80); //禁止寫入
up_flag=0;
down_flag=0;
}
if(Down!=0&&Up!=0)
{
hide_month++;
if(hide_month>3)
hide_month=0;
}
else hide_month=0;
show_time();
}while(count==7);break;
case 7:do //count=7,調整年
{
hide_month=0;
outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{
Write1302(0x8e,0x00); //寫入允許
Write1302(0x8c,temp); //寫入新的年數
Write1302(0x8e,0x80); //禁止寫入
up_flag=0;
down_flag=0;
}
if(Down!=0&&Up!=0)
{
hide_year++;
if(hide_year>3)
hide_year=0;
}
else hide_year=0;
show_time();
}while(count==8);break;
case 8: count=0;hide_year=0; //count8, 跳出調整模式,返回預設顯示狀態
Second=Read1302(DS1302_SECOND);
Write1302(0x8e,0x00); //寫入允許
Write1302(0x80,Second&0x7f);
Write1302(0x8E,0x80); //禁止寫入
done=0;
break; //count=7,開啟中斷,標誌位置0並退出
default:break;
}
}
(5) 主程式
main()
{
// flag=1; //時鐘停止標誌
init_lcd();
clrram_lcd();
Init_DS18B20( ) ; //DS18B20初始化
Initial_DS1302(); //時鐘晶片初始化
up_flag=0;
down_flag=0;
done=0; //進入預設液晶顯示
while(1)
{
while(done==1)
keydone(); //進入調整模式
while(done==0)
{
show_time(); //液晶顯示資料
// flag=0;
Setkey(); //掃描各功能鍵
}
}
}
原始碼+AD電路圖 下載:關注公眾號,首頁回覆“萬年曆”獲取資料
相關文章
- 基於51微控制器的交通燈Proteus模擬設計
- (畢業設計資料)基於微控制器51微控制器智慧藥盒控制系統設計
- 【微控制器彙編實戰】基於51微控制器的搶答器設計
- 244【畢設課設】基於51微控制器智慧語音控制窗簾設計
- 307【畢設課設】基於51微控制器虛擬按鍵電子琴設計
- 736【畢設課設】基於51微控制器的計程車計價器打表儀器設計
- 基於51微控制器的定時器定時器
- 基於STC51微控制器的霓虹燈
- 基於51微控制器的矩陣按鍵矩陣
- 基於51微控制器的智慧溫控風扇
- (畢業設計資料)基於51微控制器無線水塔水箱液水位監控報警系統
- 51微控制器系列(三)51 微控制器遊戲設計 —— 雙人對戰小遊戲(石頭剪刀布)遊戲設計
- 基於組合語言微控制器的時鐘設計組合語言
- 585【畢設課設】基於微控制器計程車計價器模擬系統設計
- 51微控制器學習歷程(二)快速入門51微控制器
- 51微控制器競賽設計44例全部帶proteus模擬+程式
- 160【畢設課設】基於51微控制器的家庭安全安防報警系統設計-紅外-火焰-甲烷-GSM(電路圖+程式+論文)
- 基於微控制器的無線語音遙控智慧車設計
- 基於51微控制器的小車避障電路實現-PCB下載站
- 51微控制器紅外接收
- 快速入門51微控制器
- 51微控制器彙編教程
- 基於微控制器的紅外電子密碼鎖程式設計思路密碼程式設計
- 新編MCS-51微控制器應用設計-電子芯Z138
- 課設 - 基於微控制器的多功能密碼鎖設計(電路+流程+論文)密碼
- 241【畢設課設】基於STM32微控制器數控調頻發射器設計
- 308【畢設課設】基於微控制器的自動皁液機原理圖論文設計圖論
- 51微控制器 16X16點陣迴圈滾動顯示漢字(基於proteus)
- 51微控制器實現流水燈
- 51微控制器學習跳轉
- 51微控制器序列通訊原理
- 基於微控制器的光控路燈設計含程式和模擬圖
- 139【畢設課設】基於微控制器音訊放大器聲控燈控制電路設計音訊
- 51微控制器內部定時器/計數器實驗定時器
- 基於8266WIFI模組實現智慧手機與51微控制器的通訊入門WiFi
- 650【畢設課設】基於微控制器大氣壓監測報警系統電路方案設計
- 簡單的51微控制器多工作業系統(C51)作業系統
- 基於UDP程式設計UDP程式設計