|
實(shí)現(xiàn)功能:1、以AT89C51/52為設(shè)計(jì)核心,采用LCD屏幕顯示。
2、可以顯示公歷日期、時(shí)間、星期(可調(diào))
3、平年和潤年區(qū)分
4、鬧鐘設(shè)置
5、包含原理圖、源碼、仿真
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
Altium Designer畫的原理圖如下:(51hei附件中可下載工程文件)
調(diào)試及性能分析
6.1 軟件測試
軟件測試為利用Keil4軟件的編譯功能,講程序?qū)雓eil編譯運(yùn)行,無錯(cuò)誤顯示,故通過軟件測試,如圖6-1所示:
6.2 proteus電路仿真
為了測試電路在下載程序后是否能夠按設(shè)計(jì)運(yùn)行,有兩種測試方法,最初為制作硬件電路板測試,這種測試方法在有錯(cuò)誤后常常需要重新制作電路板故后來漸漸被其它方法取代,另一種方法為在計(jì)算機(jī)上進(jìn)行模擬電路仿真,這種方法簡便并易差錯(cuò),在此次設(shè)計(jì)電路初次測試即為利用proteus進(jìn)行仿真測試,如圖6-2所示:
圖6-2 proteus電路仿真
DS1302模塊的電路圖如圖4-3所示,第1腳和第4腳分別接到了電路的VCC和GND,這2個(gè)腳是芯片工作的電源輸入腳。第8腳接了一個(gè)3V的紐扣電池作為時(shí)鐘芯片的后備電池,可以保證斷掉主電源后時(shí)鐘繼續(xù)行走。第2和第3腳接了一個(gè)32.768K的晶振給芯片提供時(shí)鐘脈沖,最后,第5、6、7依次連接到單片機(jī)的IO口,進(jìn)行數(shù)據(jù)的傳輸。
本設(shè)計(jì)中由于采用的按鍵數(shù)量較少,只有4個(gè)按鍵,分別是“時(shí)鐘設(shè)置”、“鬧鐘設(shè)置”、“減”、“加”,故采用了獨(dú)立鍵盤的方式。按鍵的連接圖4-4所示:
程序設(shè)計(jì)
5.1 液晶程序算法
(1)1602液晶寫數(shù)據(jù)函數(shù),dat就是要寫入的命令
void LcdWriteData(uchar dat)
{
LcdRs_P = 1;
LcdRw_P = 0;
LcdEn_P = 0;
P0=dat;
DelayMs(2);
LcdEn_P = 1;
DelayMs(2);
LcdEn_P = 0;
}
(2)1602液晶初始化函數(shù)
void LcdInit()
{
LcdWriteCmd(0x38); // 16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)口
LcdWriteCmd(0x0C); // 開顯示,不顯示光標(biāo)
LcdWriteCmd(0x06); // 地址加1,當(dāng)寫入數(shù)據(jù)后光標(biāo)右移
LcdWriteCmd(0x01); // 清屏
}
(3)液晶光標(biāo)定位函數(shù)
void LcdGotoXY(uchar line,uchar column)
{
// 第一行
if(line==0)
LcdWriteCmd(0x80+column);
// 第二行
if(line==1)
LcdWriteCmd(0x80+0x40+column);
}
(4)液晶顯示內(nèi)容的初始化
void LcdShowInit()
{
LcdGotoXY(0,0);
LcdPrintStr("20 - - ");
LcdGotoXY(1,0);
LcdPrintStr(" : : ");
}
(5)液晶輸出數(shù)字
void LcdPrintNum(uchar num)
{
LcdWriteData(num/10+48); // 十位
LcdWriteData(num%10+48); // 個(gè)位
}
(6)液晶顯示星期
void LcdPrintWeek(uchar week)
{
switch(week)
{
case 1: LcdPrintStr(" Sun"); break;
case 2: LcdPrintStr(" Mon"); break;
case 3: LcdPrintStr("Tues"); break;
case 4: LcdPrintStr(" Wed"); break;
case 5: LcdPrintStr("Thur"); break;
case 6: LcdPrintStr(" Fri"); break;
case 7: LcdPrintStr(" Sat"); break;
default: break;
}
}
(7)液晶顯示平潤年
void LcdPrintYearType(uchar type)
{
switch(type)
{
case 0: LcdPrintStr(" RUN"); break;
case 1: LcdPrintStr(" PING"); break;
default: break;
}
}
(8)刷新時(shí)間顯示
void FlashTime()
{
LcdGotoXY(0,2); // 年份
LcdPrintNum(TimeBuff[0]);
LcdGotoXY(0,5); // 月份
LcdPrintNum(TimeBuff[1]);
LcdGotoXY(0,8); // 日期
LcdPrintNum(TimeBuff[2]);
LcdGotoXY(1,0); // 小時(shí)
LcdPrintNum(TimeBuff[4]);
LcdGotoXY(1,3); // 分鐘
LcdPrintNum(TimeBuff[5]);
LcdGotoXY(1,6); // 秒鐘
LcdPrintNum(TimeBuff[6]);
LcdGotoXY(0,11); // 星期
LcdPrintWeek(TimeBuff[3]);
LcdGotoXY(1,11); // 平潤年
LcdPrintYearType(nian_type);
}
5.2 時(shí)鐘程序算法
(1)初始化DS1302
void DS1302_Init(void)
{
RST_P=0; // RST腳置低
SCK_P=0; // SCK腳置低
SDA_P=0; // SDA腳置低
}
(2)從DS1302讀出一字節(jié)數(shù)據(jù)
uchar DS1302_Read_Byte(uchar addr)
{
uchar i;
uchar temp;
RST_P=1;
for(i=0;i<8;i++)
{
if(addr&0x01)
SDA_P=1;
else
SDA_P=0;
SCK_P=1;
_nop_();
SCK_P=0;
_nop_();
addr=addr>> 1;
}
for(i=0;i<8;i++)
{
temp=temp>>1;
if(SDA_P)
temp|= 0x80;
else
temp&=0x7F;
SCK_P=1;
_nop_();
SCK_P=0;
_nop_();
}
RST_P=0;
return temp;
}
(3)向DS1302寫入時(shí)間數(shù)據(jù)
void DS1302_Write_Time()
{
uchar i;
uchar temp1;
uchar temp2;
for(i=0;i<7;i++) // 十進(jìn)制轉(zhuǎn)BCD碼
{
temp1=(TimeBuff[ i]/10)<<4;
temp2=TimeBuff[ i]%10;
TimeBuff[ i]=temp1+temp2;
}
DS1302_Write_Byte(0x8E,0x00); // 關(guān)閉寫保護(hù)
DS1302_Write_Byte(0x80,0x80); // 暫停時(shí)鐘
DS1302_Write_Byte(0x8C,TimeBuff[0]); // 年
DS1302_Write_Byte(0x88,TimeBuff[1]); // 月
DS1302_Write_Byte(0x86,TimeBuff[2]); // 日
DS1302_Write_Byte(0x8A,TimeBuff[3]); // 星期
DS1302_Write_Byte(0x84,TimeBuff[4]); // 時(shí)
DS1302_Write_Byte(0x82,TimeBuff[5]); // 分
DS1302_Write_Byte(0x80,TimeBuff[6]); // 秒
DS1302_Write_Byte(0x80,TimeBuff[6]&0x7F); // 運(yùn)行時(shí)鐘
DS1302_Write_Byte(0x8E,0x80); // 打開寫保護(hù)
}
(4)從DS1302讀出時(shí)間數(shù)據(jù)
void DS1302_Read_Time()
{
uchar i;
uint nian_temp;
TimeBuff[0]=DS1302_Read_Byte(0x8D); // 年
TimeBuff[1]=DS1302_Read_Byte(0x89); // 月
TimeBuff[2]=DS1302_Read_Byte(0x87); // 日
TimeBuff[3]=DS1302_Read_Byte(0x8B); //星期
TimeBuff[4]=DS1302_Read_Byte(0x85); // 時(shí)
TimeBuff[5]=DS1302_Read_Byte(0x83); // 分
TimeBuff[6]=(DS1302_Read_Byte(0x81))&0x7F; // 秒
for(i=0;i<7;i++) // BCD轉(zhuǎn)十進(jìn)制
{
TimeBuff[ i]=(TimeBuff[ i]/16)*10+TimeBuff[ i]%16;
}
nian_temp=2000+TimeBuff[0];
//計(jì)算平潤年
if((nian_temp%4==0&&nian_temp%100!=0)||(nian_temp%400==0))
{
nian_type=0;
}
else
{
nian_type=1;
}
}
下載:
基于51單片機(jī)LCD萬年歷.7z
(359.96 KB, 下載次數(shù): 219)
2022-4-14 17:49 上傳
點(diǎn)擊文件名下載附件
|
評分
-
查看全部評分
|