久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
單片機電子時鐘仿真程序
[打印本頁]
作者:
鬼天氣
時間:
2018-12-21 11:38
標題:
單片機電子時鐘仿真程序
智能電子時鐘仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png
(14.64 KB, 下載次數: 12)
下載附件
2018-12-22 00:40 上傳
0.png
(12.58 KB, 下載次數: 14)
下載附件
2018-12-22 00:40 上傳
單片機源程序如下:
#include <reg51.h>
#include <string.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit SDA=P1^0; //DS1302數據線
sbit CLK=P1^1; //DS1302時鐘線
sbit RST=P1^2; // DS1302 復位線
sbit k1=P3^4; // 選擇按鍵
sbit k2=P3^5; // 加
sbit k3=P3^6; // 減
sbit k4=P3^7; // 確定
sbit RS=P2^0; // LCD寄存器選擇
sbit RW=P2^1; // LCD讀寫控制
sbit EN=P2^2; // LCD啟動
uchar tcount=0;
uchar MonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31}; // 一年中每個月的天數,二月的天數由年份決定
uchar *Week[]={"SUN","MON","TUS","WEN","THU","FRI","SAT"}; //周日,周一到周六
// LCD顯示緩沖
uchar LCD_DSY_BUFFER1[]={"DATE 00-00-00 "} ;
uchar LCD_DSY_BUFFER2[]={"TIME 00:00:00 "} ;
uchar DateTime[7]; //所讀取的日期時間
char Adjust_Index=-1; //當前調節的時間對象:秒,分,時,日,月,年(0,1,2,3,4,6)
uchar Change_Flag[]="-MHDM-Y"; //(分,時,日,月,年)不調節秒和周
//函數聲明
void Initialize_LCD1602(); //液晶初始化函數
void LCD_Display(uchar p,uchar *str);
void Write_Byte_TO_DS1302(uchar X); // 向DS1302寫入一個字節
uchar Read_Byte_FROM_DS1302(); //從DS1302中讀取一個字節
uchar Read_Data_FROM_DS1302(uchar addr); //從DS1302指定位置讀取數據, 讀數據
void Write_Data_TO_DS1302(uchar addr,uchar dat); // 向DS1302指定位置寫入數據, 寫數據
void SET_DS1302(); // 設置時間
void GetTime(); // 讀取當前時間
void Initialization(); //初始化函數
void main()
{
Initialization();
while(1)
{
if(Adjust_Index==-1)
GetTime();
}
}
/*********************************************************************************************************************/
void DelayMS(uint K)
{
uchar i;
while(K--)
{
for(i=0;i<120;i++);
}
}
//----------讀取LCD的狀態-------*/
uchar Read_LCD_State()
{
uchar state;
RS=0;
RW=1;
EN=1;
DelayMS(2);
state=P0;
EN=0;
DelayMS(2);
return state;
}
void LCD_Busy_Wait()
{
while((Read_LCD_State()&0x80)==0x80);
DelayMS(5);
}
void Write_LCD_Command(uchar cmd)
{
LCD_Busy_Wait();
RS=0;
RW=0;
EN=0;
P0=cmd;
EN=1;
DelayMS(2);
EN=0;
}
void Write_LCD_Data(uchar dat)
{
LCD_Busy_Wait();
RS=1;
RW=0;
EN=0;
P0=dat;
EN=1;
DelayMS(2);
EN=0;
}
void Initialize_LCD1602() //液晶初始化函數
{
Write_LCD_Command(0x38);DelayMS(2); //功能設置,數據長度為8位,雙行顯示,5×7點陣字體
Write_LCD_Command(0x01);DelayMS(2); //清屏
Write_LCD_Command(0x06);DelayMS(2); //字符進入模式:屏幕不動,字符后移
Write_LCD_Command(0x0c);DelayMS(2); // 顯示開,關光標
}
void Set_LCD_Position(uchar pos)
{
Write_LCD_Command(pos|0x80); //設置7位的DDRAM地址值
}
void LCD_Display(uchar p,uchar *str)
{
uchar i;
Set_LCD_Position(p);
for(i=0;i<16;i++)
{
Write_LCD_Data(str[i]);
DelayMS(2);
}
}
/****************************************************************************************************************/
void Initialization()
{
Initialize_LCD1602(); //調用液晶初始化函數
IE=0x83; //允許中斷 外部0中斷和T0中斷
IP=0x01; //設置中斷優先級
IT0=0x01; //設置外部中斷的脈沖觸發方式
TMOD=0x01; //設置定時器的工作方式,為方式1
TH0=-50000/256; //寫入初值
TL0=-50000%256; //寫入初值
TR0=1; //啟動定時器
}
void Write_Byte_TO_DS1302(uchar X) // 向DS1302寫入一個字節
{
uchar i;
for(i=0;i<8;i++)
{
SDA=X&1;
CLK=1;
CLK=0;
X>>=1;
}
}
uchar Read_Byte_FROM_DS1302() //從DS1302中讀取一個字節
{
uchar i,byte,t;
for(i=0;i<8;i++)
{
byte>>=1;
t=SDA;
byte|=t<<7;
CLK=1;
CLK=0;
}
//BCD碼轉換
return byte/16*10+byte%16;
}
uchar Read_Data_FROM_DS1302(uchar addr) //從DS1302指定位置讀取數據 , 讀數據
{
uchar dat;
RST=0;
CLK=0;
RST=1;
Write_Byte_TO_DS1302(addr); //向DS1302寫入一個地址
dat=Read_Byte_FROM_DS1302(); //在上面寫入的地址中讀取數據
CLK=1;
RST=0;
return dat;
}
void Write_Data_TO_DS1302(uchar addr,uchar dat) //向DS1302指定位置寫入數據, 寫數據
{
CLK=0;
RST=1;
Write_Byte_TO_DS1302(addr);
Write_Byte_TO_DS1302(dat);
CLK=1;
RST=0;
}
void SET_DS1302() //設置時間
{
uchar i;
Write_Data_TO_DS1302(0x8E,0x00); //寫控制字,取消寫保護
// 分,時,日,月,年依次寫入
for(i=1;i<7;i++)
{
// 分的起始地址是10000010(0x82),后面依次是時,日,月,周,年,寫入地址每次遞增2
Write_Data_TO_DS1302(0x80+2*i,(DateTime[i]/10<<4)|(DateTime[i]%10));
}
Write_Data_TO_DS1302(0x8E,0x80); //寫控制字,加寫保護
}
//--------------------------------------------------------
// 讀取當前時間
//-------------------------------------------------------
void GetTime() // 讀取當前時間
{
uchar i;
for(i=0;i<7;i++)
{
DateTime[i]=Read_Data_FROM_DS1302(0x81+2*i);
}
}
void Format_DateTime(uchar d,uchar *a)
{
a[0]=d/10+'0';
a[1]=d%10+'0';
}
uchar Is_Leapyear(uint year)
{
return (year%4==0&&year%100!=0)||(year%400==0) ;
}
void Refresh_Week_Day()
{
uint i,d,w=5; //已知1999年12.31是星期五
for(i=2000;i<2000+DateTime[6];i++)
{
d=Is_Leapyear(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月天數
MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28;
//如果年份變化后當前月份的天數大于上限則設為上限
if(DateTime[3]>MonthsDays[DateTime[4]])
{
DateTime[3]=MonthsDays[DateTime[4]];
}
Refresh_Week_Day(); //刷新星期
break;
case 4: //月調整 01-12
if(X==1&&DateTime[4]<12)
{
DateTime[4]++;
}
if(X==-1&&DateTime[4]>1)
{
DateTime[4]--;
}
//獲取2月天數
MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28;
//如果年份變化后當前月份的天數大于上限則設為上限
if(DateTime[3]>MonthsDays[DateTime[4]])
{
DateTime[3]=MonthsDays[DateTime[4]];
}
Refresh_Week_Day(); //刷新星期
break;
case 3: //日調整00-28或00-29或00-30或00-31
//調節之前首先根據當前年份得出該年中2月的天數
MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28;
//根據當前月份決定調節日期的上限
if(X==1&&DateTime[3]<MonthsDays[DateTime[4]])
{
DateTime[3]++;
}
if(X==-1&&DateTime[3]>0)
{
DateTime[3]--;
}
Refresh_Week_Day(); //刷新星期
break;
case 2: // 時調整
if(X==1&&DateTime[2]<23)
{
DateTime[2]++;
}
if(X==-1&&DateTime[4]>0)
{
DateTime[2]--;
}
break;
case 1: // 分調整
if(X==1&&DateTime[1]<59)
{
DateTime[1]++;
}
if(X==-1&&DateTime[4]>0)
{
DateTime[1]--;
}
break;
}
}
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);
// 顯示年、月、日、星期、時、分、秒
LCD_Display(0x00,LCD_DSY_BUFFER1);
LCD_Display(0x40,LCD_DSY_BUFFER2);
}
void EX_INT0()interrupt 0
{
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];
LCD_DSY_BUFFER2[15]=']';
}
else if(k2==0) // 加
{
while(k2==0);
Datetime_Adjust(1);
}
else if(k3==0) // 減
{
while(k3==0);
Datetime_Adjust(-1);
}
else if(k4==0)
{
while(k4==0);
SET_DS1302();
LCD_DSY_BUFFER2[13]=' ';
LCD_DSY_BUFFER2[14]=' ';
LCD_DSY_BUFFER2[15]=' ';
Adjust_Index=-1; //操作索引重設為-1,時間繼續正常顯示
}
}
復制代碼
所有資料51hei提供下載:
智能電子時鐘2.zip
(79.1 KB, 下載次數: 34)
2018-12-21 11:37 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
歡迎光臨 (http://www.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
爱爱视频在线观看
|
九色在线观看
|
久久亚洲一区二区
|
福利久久
|
aaa一区
|
美女在线观看国产
|
91精品国产91久久久久久吃药
|
成人在线视频看看
|
黄网站免费观看
|
中文字幕在线视频免费观看
|
欧美久久一区二区三区
|
av先锋资源
|
国产综合第一页
|
欧美一区二区免费
|
黄色小视频大全
|
韩国av网站在线观看
|
九九九视频在线
|
国产极品粉嫩美女呻吟在线看人
|
欧美色专区
|
a免费在线
|
欧美色综合
|
国产精品日韩欧美一区二区三区
|
免费影视在线观看
|
91视在线国内在线播放酒店
|
国产一区二区三区在线看
|
国产精品a级
|
成人免费视频
|
免费黄色大片
|
麻豆久久久9性大片
|
久久久九九
|
欧美一区二区三区四区五区无卡码
|
黑人中文字幕一区二区三区
|
波霸ol一区二区
|
男女污污动态图
|
不卡视频一区二区三区
|
91中文在线观看
|
日韩精品影院
|
亚洲第一福利视频
|
91国内外精品自在线播放
|
欧美综合在线观看
|
二区中文
|