1 設計任務
電子數字電子鐘是單片機系統的一個應用,由硬件和軟件相配合使用。硬件由主控器、時鐘電路、顯示電路、鍵盤接口4個模塊組成。主控模塊用STC89C52RC、時鐘電路用時鐘芯片DS1302、顯示模塊用 LCD1602、鍵盤接口電路用普通按鍵接上拉電阻完成;軟件利用C語言編程實現單片機程序控制。單片機通過時鐘芯片DS1302獲取時間數據,通過1602液晶顯示器進行顯示陽歷年、月、日、時、分、秒、星期。
數字電子鐘的功能要求:數字電子鐘能用1602液晶顯示屏第一行顯示年、月、日、星期,第二行顯示秒、分、時。
數字電子鐘的按鍵要求:四個獨立按鍵的功能分別為:K1對秒、分、時的選擇,K4對年、月、日的選擇,K2加,K3減。
2 系統硬件設計
2.1 器件選擇
本系統以 AT89S52 單片機為控制核心,時鐘芯片DS1302,將得到的數據通過 1602液晶顯示出來,同時通過相應的按鍵調整相應的值。51單片機的硬件資源分配:單片機最小系統模塊:STC89C52RC單片機芯片;復位電路;晶振電路。本模塊AT89C52RC系統控制核心,單片機系統復位由按鍵電平復位電路完成,并設計獨立按鍵調節時間,本次設計顯示為6位,采用兩個四位一體數碼管(共陽極)作為顯示窗口,既可以節約成本又能簡化電路。STC89C52RC單片機包含中央處理器、程序寄存器(ROM)、數據存儲器(ROM)、并行接口、串行接口和舉行鍵盤等幾大單元及數據總線、地址總線、和控制總線等三大總線。STC89C52RC共有4組8位I/O口(P0、P1、P2、P3),用于對外部數據的傳輸。
2.2 硬件原理圖
STC89C52RC芯片有40個引腳:
(1)電源及時鐘引腳(4個)
Vcc:電源接入引腳。
GND:接地引腳。
XTAL1:晶體振蕩器接入的一個引腳。
XTAL2:晶體振蕩器接入的另一個引腳。
(2)控制線引腳(4個)
ALE/PROG:地址鎖存允許信號輸出/編程脈沖引腳。
EA:內外存儲器選擇引腳。
PSEN:外部程序存儲器(ROM)選通信號輸出引腳。
(3)并行I/O引腳(32個,分成4個8位端口)
P0.0- P0.7:一般I/O端口引腳或數據/低位地址總線復用引腳。
P1.0- P1.7:一般I/O端口引腳。
P2.0- P2.7:一般I/O端口引腳或高位地址總線引腳。
P3.0- P3.7:一般I/O端口引腳或第二功能引腳。
STC89C52RC芯片,如圖2.1所示:
圖2.1 STC89C52RC芯片
1602 液晶功耗較小可直接與單片機接口相接,電源直接與電源電路相接,使用單片機的P0口和P1口與1602進行通信。1602 相應功能特性介紹 n +5V 電壓,對比度可調 n 內含復位電路n 提供各種控制命令,如:清屏、字符閃爍、光標閃爍、顯示移位等多種功能 n有80字節顯示數據存儲器 DDRAM n內建有160個 5X7 點陣的字型的字符發生器 CGROM n 8 個可由用戶自定義的5X7的字符發生器CGRAM ,如圖2.2所示:
圖2.2 1602硬件原理圖
DS1302時鐘芯片包括實時時鐘/日歷和31字節的靜態RAM。它經過一個簡單的串行接口與微處理器通信。實時時鐘/日歷提供秒、分、時、日、周、月和年等信息。對于小于31天的月和月末的日期自動調整,還包括閏年校正的功能。時鐘的運行可以采用24h或帶AM(上午)/PM(下午)的12h格式。采用三線接口與CPU進行同步通信,并可采用突發方式一次傳送多個字節的時鐘信號或RAM數據。DS1302有主電源/后備電源雙電源引腳:Vcc1在單電源與電池供電的系統中提供低電源,并提供低功率的電池備份;Vcc2在雙電源系統中提供主電源,在這種運用方式中,Vcc1連接到備份電,以便在沒有主電源的情況下能保存時間信息以及數據。DS1302由Vcc1或Vcc2中較大者供電。當Vcc2大于Vcc1+0.2V時,Vcc2給DS1302供電;當Vcc2小于Vcc時, DS13026由Vcc1供電。如圖2.3所示:
圖2.3 DS1302時鐘模塊原理圖
按鍵部分電路采用獨立式按鍵,各按鍵相互獨立,每個按鍵單獨占用一根I/O口線,每根I/O口線的按鍵工作狀態不會影響其他I/O口線上的工作狀態。因此,通過檢測輸入線的電平狀態可以很容易判斷哪個按鍵被按下了。獨立式按鍵接口電路配置靈活,軟件結構簡單。但每個按鍵需占用一根I/O口線,在按鍵數量較多時,I/O口浪費大。因此,獨立式按鍵主要用于按鍵較少或操作速度較高的場合。本次設計需要按鍵數較少,故選用獨立式按鍵。獨立式按鍵接口電路如圖2.4所示:
圖2.4 獨立式按鍵接口電路
3 系統軟件設計
3.1總體方案組成框圖
(1)主程序流程圖如圖3.1所示:
圖3.1 主程序流程圖
(2)子程序流程圖如圖3.2所示:
圖3.2 時間調整程序流程圖
3.2軟件清單
void delay()此函數為延時函數
void write_com()此函數為寫入命令函數
void write_date()此函數為寫入數據函數
void init() 此函數為初始函數
void write_sfm()此函數是時間設置地址,將數據寫入對應的地址的函數
void write_riqi()此函數是日期設置 將數據寫入對應的地址的函數
void keyscan()此函數是時間按鍵函數
void riqi_xq() 此函數是顯示星期的函數
void keys_riqi() 此函數是顯示日期的函數
void main() 此函數為主函數
下圖中為子函數
#include#define uchar unsigned char#define uint unsigned int
sbit dula=P2^6;sbit wela=P2^7;sbit lcdrs=P1^0;sbit lcdrw=P1^1;sbit lcden=P2^5;
sbit s1=P3^4;sbit s2=P3^5;sbit s3=P3^6;//sbit s4=P3^0;//sbit s8=P3^1;
//sbit s12=P3^2;sbit s4=P3^7;
uchar tt,s1num,s4num;char shi,fen,miao,shiji,nian,yue,ri,xq;
//string char code tabe2[7]={"MON","TUE","WED","THU","FRI","SAR","SUN"};
uchar code tabe[15]=" 2020_12-12_SAR";uchar code tabe1[14]=" 30:30:20 ";
void delay(uint n)
{
while(n--)
{
uchar i;for(i=113;i >0;i--);
}
}
void write_com(uchar com)
{
lcdrw=0;lcdrs=0;P0=com;
delay(5);lcden=1;delay(5);lcden=0;
}
void write_date(uchar date)
{
lcdrw=0;lcdrs=1;P0=date;delay(5);lcden=1;delay(5);lcden=0;
}
void init()
{
uchar num;dula=0;wela=0;lcden=0;shi=20;fen=30;miao=30;ri=12;yue=12;
nian=20;shiji=20;write_com(0x01);write_com(0x3c);write_com(0x0c);
write_com(0x06);write_com(0x80);for(num=0;num< 15;num++)
{
write_date(tabe[num]);delay(10);
}
write_com(0x80+0x40);for(num=0;num< 14;num++)
{
write_date(tabe1[num]);delay(10);
}
TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;
TR0=1;
}
void write_sfm(uchar add,uchar date)
{
uchar sh,ge;sh=date%100/10;ge=date%10;write_com(0x80+0x40+add);
write_date(0x30+sh);write_date(0x30+ge);
}
void write_riqi(uchar add,uint date)
{
uchar sh,ge;sh=date%100/10;ge=date%10;write_com(0x80+add);
write_date(0x30+sh);write_date(0x30+ge);
}
void keyscan()
{
if(s1==0)
{
delay(5);if(s1==0)
{
while(!s1);s1num++;if(s1num==1)
{
TR0=0;write_com(0x80+0x40+3);write_com(0x0f);
}
if(s1num==2)
{
write_com(0x80+0x40+6);
}
if(s1num==3)
{
write_com(0x80+0x40+9);
}
if(s1num==4)
{
s1num=0;TR0=1;write_com(0x0c);
}
}
}
if(s1num!=0)
{
if(s2==0)
{
delay(5);if(s2==0)
{
while(!s2);if(s1num==1)
{
miao++;if(miao==60)
miao=0;write_sfm(3,miao);write_com(0x080+0x40+3);
}
if(s1num==2)
{
fen++;if(fen==60)
fen=0;write_sfm(6,fen);write_com(0x080+0x40+6);
}
if(s1num==3)
{
shi++;if(shi==24)
shi=0;write_sfm(9,shi);write_com(0x080+0x40+9);
}
}
}if(s3==0)
{
delay(5);if(s3==0){
while(!s3);if(s1num==1
{
miao--;if(miao==-1)
miao=59;write_sfm(3,miao);write_com(0x80+0x40+3);
}
if(s1num==2)
{
fen--;if(fen==-1)
fen=59;write_sfm(6,fen);write_com(0x80+0x40+6);
}
if(s1num==3)
{
shi--;if(shi==-1)
shi=23;write_sfm(9,shi);write_com(0x80+0x40+9);
}
}
}
}
}
void riqi_xq()
{
switch(xq)
{
case 1:write_com(0x80+12);write_date(0x40+13);write_date(0x40+15);
write_date(0x40+14);write_com(0x80+12);break;
case 2:write_com(0x80+12);write_date(0x50+4);write_date(0x50+5);
write_date(0x40+5);write_com(0x80+12);break;
case 3:write_com(0x80+12);write_date(0x50+7);write_date(0x40+5);
write_date(0x40+4);write_com(0x80+12);break;
case 4:write_com(0x80+12);write_date(0x50+4);write_date(0x40+8);
write_date(0x50+5);write_com(0x80+12);break;
case 5:write_com(0x80+12);write_date(0x40+6);write_date(0x50+2);
write_date(0x40+9);write_com(0x80+12);break;
case 6:write_com(0x80+12);write_date(0x50+3);write_date(0x40+1);
write_date(0x50+2);write_com(0x80+12);break;
case 7:write_com(0x80+12);write_date(0x50+3);write_date(0x50+5);
write_date(0x40+14);write_com(0x80+12);break;
}
}
void keys_riqi()
{
if(s4==0)
{delay(10);if(s4==0)
{while(!s4);s4num++;if(s4num==1)
{TR0=0;write_com(0x80+0x0c);write_com(0x0f);
}
if(s4num==2)
{
write_com(0x80+9);
}
if(s4num==3)
{
write_com(0x80+6);
}
if(s4num==4)
{
write_com(0x80+3);
}
if(s4num==5)
{
write_com(0x80+1);
}
if(s4num==6)
{
s4num=0;TR0=1;write_com(0x0c);
}
}
}
if(s4num!=0)
{
if(s2==0)
{
delay(5);if(s2==0)
{
while(!s2);if(s4num==1)
{
xq++;if(xq==8)
xq=1;riqi_xq();
}
if(s4num==2)
{
ri++;if(ri==32)
ri=1;write_riqi(9,ri);write_com(0x80+9);
}
if(s4num==3)
{
yue++;if(yue==13)yue=1;write_riqi(6,yue);write_com(0x80+6);
}
if(s4num==4)
{
nian++;if(nian==100)
nian=0;write_riqi(3,nian);write_com(0x80+3);
}
if(s4num==5)
{
shiji++;if(shiji==100)
shiji=0;write_riqi(1,shiji);write_com(0x80+1);
}
}
}
if(s3==0)
{
delay(5);if(s3==0)
{
while(!s3);//s4num++;if(s4num==1)
{
xq--;if(xq==0)
xq=7;riqi_xq();
}
if(s4num==2)
{
ri--;if(ri==0)
ri=31;
write_riqi(9,ri);write_com(0x80+9);
}
if(s4num==3)
{
yue--;if(yue==0)
yue=12;write_riqi(6,yue);write_com(0x80+6);
}
if(s4num==4)
{
nian--;if(nian==0)
nian=99;write_riqi(3,nian);write_com(0x80+3);
}
if(s4num==5)
{shiji--;if(shiji==0)
shiji=99;write_riqi(1,shiji);write_com(0x80+1);
}
}
}
}
}
void main()
{
init();
while(1)
{
keys_riqi();keyscan();if(tt==20)
{
tt=0;miao++;if(miao==60)
{miao=0;fen++;if(fen==60)
{fen=0;shi++;if(shi==24)
{shi=0;ri++;xq++;if(ri==32)
{ri=1;yue++;if(yue==13)
{yue=1;nian++;if(nian==100)
{nian=0;shiji++;if(shiji==100)
{shiji=0;
}
write_riqi(1,shiji);
}
write_riqi(3,nian);
}
write_riqi(6,yue);
}
riqi_xq();write_riqi(9,ri);
}
write_sfm(9,shi);
}
write_sfm(6,fen);
}
write_sfm(3,miao);
}
}
}
void time0() interrupt 1
{
TH0=(65536-50000)/256;TL0=(65536-50000)%256;tt++;
}
-
發生器
+關注
關注
4文章
1368瀏覽量
61695 -
數碼管
+關注
關注
32文章
1882瀏覽量
91108 -
晶體振蕩器
+關注
關注
9文章
620瀏覽量
29122 -
數字電子鐘
+關注
關注
7文章
27瀏覽量
20605 -
STC89C52RC
+關注
關注
15文章
64瀏覽量
38639
發布評論請先 登錄
相關推薦
評論