標(biāo)題:
DS1302與1602LCD設(shè)計的可調(diào)式電子日歷與時鐘 含仿真
[打印本頁]
作者:
痘天涯
時間:
2016-6-22 23:42
標(biāo)題:
DS1302與1602LCD設(shè)計的可調(diào)式電子日歷與時鐘 含仿真
DS1302與1602LCD設(shè)計含仿真 自己做的 大家可以看看代碼
仿真原理圖
0.png
(36.07 KB, 下載次數(shù): 135)
下載附件
2016-6-25 13:57 上傳
部分程序預(yù)覽:
#include "DS1302.h"
/*---------延時程序------------------*/
void DelayMS(uint ms)
{
uchar i;
while(ms--){for(i=0;i<120;i++);}
}
//-----------讀LCD狀態(tài)------------------//
uchar Read_LCD_State()
{ uchar state;
RS=0;RW=1;EN=1; //輸出:D0~D7=狀態(tài)字
DelayMS(1);
state=P0; //從P0口讀LCD狀態(tài)
EN = 0;DelayMS(1);
return state;
}
//-----------忙等待------------------//
void LCD_Busy_Wait()
{
while((Read_LCD_State()&0x80)==0x80);
DelayMS(5);
}
//-----------向LCD寫數(shù)據(jù)------------------//
void Write_LCD_Data(uchar dat)
{
LCD_Busy_Wait();
RS=1;EN=0;RW=0; //寫數(shù)據(jù),EN為高脈沖,
P0=dat;EN=1;DelayMS(1);EN=0;
}
//-------------寫LCD指令-------------------//
void Write_LCD_Command(uchar cmd)
{
LCD_Busy_Wait();
RS=0;EN=0; RW=0; //寫指令,EN高脈沖,輸出:D0~D7=數(shù)據(jù)
P0=cmd;EN=1;DelayMS(1);EN=0;
}
//-------------LCD初始化-------------------//
void Init_LCD()
{
Write_LCD_Command(0x38); //設(shè)置16*2顯示,5*7點陣,8位數(shù)據(jù)接口
DelayMS(1);
Write_LCD_Command(0x01); //顯示清零,數(shù)據(jù)指針清零
DelayMS(1);
Write_LCD_Command(0x06); //寫一個字符后地址指針自動加1
DelayMS(1);
Write_LCD_Command(0x0c); //設(shè)置開顯示,不顯示光標(biāo)
DelayMS(1);
}
//------------------------------------------
//設(shè)置液晶顯示位置
//------------------------------------------
void Set_LCD_POS(uchar p){
Write_LCD_Command(p|0x80);//相當(dāng)于在0x80基礎(chǔ)上加入位置量
}
//----在LCD上顯示字符串---------//
void Display_LCD_String(uchar p,uchar *s)
{ uchar i;
Set_LCD_POS(p);
for(i=0;i<16;i++)
{
Write_LCD_Data(s[i]); //在固定位置顯示時間日期
DelayMS(1);
}
}
//---------日期與時間值轉(zhuǎn)換為數(shù)字字符----------------//
void Format_DateTime(uchar d,uchar *a)
{
a[0]=d/10+'0';
a[1]=d%10+'0';
}
//判斷是否為閏年
uchar isLeapYear(uint y)
{ return (y%4==0&&y%100!=0)||(y%400==0);}
//求自2000.1.1開始的任何一天是星期幾
//函數(shù)沒有通過,求出總天數(shù)后再求星期幾
//因為求總天數(shù)可能會超出uint的范圍
void RefreshWeekDay()
{ uint i,d,w=5; //已知1999.12.31是周五
for(i=2000;i<2000+DateTime[6];i++)
{
d=isLeapYear(i)?366:365;
w=(w+d)%7;
}
d=0;
for(i=1;i<DateTime[4];i++)
{ d+=MonthsDays[i]; }
d+=DateTime[3];
//保存星期,0~6表示星期日,星期一,二,...,六,為了與DS1302的星期格式匹配,返回值需要加1
DateTime[5]=(w+d)%7+1;
}
//*****年月日時分++/--********//
void DateTime_Adjust(char x)
{ switch(Adjust_Index)
{
case 6: //年00-99
if(x==1&&DateTime[6]<99) DateTime[6]++;
if(x==-1&&DateTime[6]>0) DateTime[6]--;
//獲取2月天數(shù)
MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;
//如果年份變化后當(dāng)前月份的天數(shù)大于上限則設(shè)為上限
if(DateTime[3]>MonthsDays[DateTime[4]])
{ DateTime[3]=MonthsDays[DateTime[4]];}
RefreshWeekDay(); //刷新星期
break;
case 4: //月01-12
if(x==1&&DateTime[4]<12) DateTime[4]++;
if(x==-1&&DateTime[4]>1) DateTime[4]--;
MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;
if(DateTime[3]>MonthsDays[DateTime[4]])
{ DateTime[3]=MonthsDays[DateTime[4]];}
RefreshWeekDay();
break;
case 3: //日00-28、29、30、31,調(diào)節(jié)之前首先根據(jù)年份得出該年中斷二月 天數(shù)
MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;
//根據(jù)當(dāng)前月份決定調(diào)節(jié)日期的上限
if(x==1&&DateTime[3]<MonthsDays[DateTime[4]]) DateTime[3]++;
if(x==-1&&DateTime[3]>0) DateTime[3]--;
RefreshWeekDay();
break;
case 2: //時
if(x==1&&DateTime[2]<23) DateTime[2]++;
if(x==-1&&DateTime[2]>0) DateTime[2]--;
break;
case 1: //分
if(x==1&&DateTime[1]<59) DateTime[1]++;
if(x==-1&&DateTime[1]>0) DateTime[1]--;
break;
}
}
//---定時器0每秒刷新LCD顯示----//
void T0_INT() interrupt 1
{
TH0=-50000/256;
TL0=-50000%256;
if(++tCount !=2) return;
tCount=0;
//按指定格式生成待顯示的日期時間串
Format_DateTime(DateTime[6],LCD_DSY_BUFFER1+5);
Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+8);
Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+11);
//星期
strcpy(LCD_DSY_BUFFER1+13,WEEK[DateTime[5]-1]);
//時分秒
Format_DateTime(DateTime[2],LCD_DSY_BUFFER2+5);
Format_DateTime(DateTime[1],LCD_DSY_BUFFER2+8);
Format_DateTime(DateTime[0],LCD_DSY_BUFFER2+11);
//顯示年月日,星期,時分秒
Display_LCD_String(0x00,LCD_DSY_BUFFER1);
Display_LCD_String(0x40,LCD_DSY_BUFFER2);
}
//----------鍵盤中斷(INT0)-------------//
void EX_INT0() interrupt 0
{
if(K1==0) //選擇調(diào)整對象(Y M D H M)
{
DelayMS(10);
if(K1==0){
//while(K1==0);
if(Adjust_Index==-1||Adjust_Index==1)
{
Adjust_Index=7;
}
Adjust_Index--;
if(Adjust_Index==5) Adjust_Index=4;
LCD_DSY_BUFFER2[13]='[';
LCD_DSY_BUFFER2[14]=Change_Flag[Adjust_Index]; //顯示調(diào)節(jié)對象
LCD_DSY_BUFFER2[15]=']';
}
}
else if(K2==0) //加
{ //while(K2==0);
DelayMS(10);
if(K2==0)
DateTime_Adjust(1);
}
else if(K3==0) //減
{
DelayMS(10);//while(K3==0);
if(K3==0)
DateTime_Adjust(-1);
}
else if(K4==0) //確定
{
//while(K4==0);
DelayMS(10);
if(K4==0){
SET_DS1302(); //將調(diào)整后的時間寫入DS1302
LCD_DSY_BUFFER2[13]=' ';
LCD_DSY_BUFFER2[14]=' ';
LCD_DSY_BUFFER2[15]=' ';
Adjust_Index=-1;
}
}
}
void main()
{ Init_LCD(); //液晶初始化
IE=0x83; //允許INT0,T0中斷,EA=1,,ET0=1,EX0=1
IP=0x01; //設(shè)置外部中斷0為高級中斷
IT0=0x01; //外部中斷0為電平觸發(fā),低電平有效
TMOD=0x01; //設(shè)置定時器T0工作方式為方式1,
TH0=-50000/256; //裝入初始值,定時1秒
TL0=-50000%256;
TR0=1; //啟動定時器
while(1)
{
//如果未執(zhí)行調(diào)整操作則正常讀取當(dāng)前時間
if(Adjust_Index==-1) GetTime();
}
}
復(fù)制代碼
0.png
(56.76 KB, 下載次數(shù): 130)
下載附件
2016-6-25 13:57 上傳
所有資料下載:
A3020.rar
(104.25 KB, 下載次數(shù): 228)
2016-6-22 23:42 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
陳先生212
時間:
2017-9-15 22:30
謝謝樓主
作者:
陳先生212
時間:
2017-9-15 22:31
謝謝樓主
作者:
陳先生212
時間:
2017-9-15 22:32
謝謝樓主啥啥啥
作者:
atwell
時間:
2017-12-8 23:50
謝謝分享
作者:
持勤補(bǔ)拙
時間:
2017-12-9 00:24
感謝樓主分享
作者:
123qazwsx
時間:
2017-12-28 20:00
為什么用你的主函數(shù)創(chuàng)建HEX文件仿真不出來,而用你自帶的HEX文件卻可以?
作者:
SaviorKing
時間:
2018-1-1 16:35
厲害了
作者:
qq821627057
時間:
2018-1-2 20:49
蟹蟹樓主
作者:
Honter
時間:
2018-1-5 15:14
樓主怎么才能看源代碼
作者:
果粒多12345
時間:
2018-1-8 14:44
我想問一下為什么我燒出來在LCD上怎么不能刷新時間?
作者:
果粒多12345
時間:
2018-1-8 14:50
樓主樓主,我用了你的代碼仿真能成功,但是連接到實物圖上卻不能一秒一秒的顯示,只能顯示固定的數(shù)字為什么呢
作者:
騰飛的龍
時間:
2018-2-2 17:23
感謝分享學(xué)習(xí)一下。。。。。。
作者:
tang111
時間:
2018-9-5 12:08
謝謝樓主
作者:
ASDAQ
時間:
2018-9-7 15:41
謝謝樓主了
作者:
生活不易
時間:
2018-9-7 16:06
感謝分享學(xué)習(xí)一下。。。。。!
作者:
minbox
時間:
2019-11-30 17:07
感謝樓主分享
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1