|
完整的設(shè)計文檔下載:
基于STC12C5A60S2系列單片機萬年歷時鐘.doc
(4.54 MB, 下載次數(shù): 26)
2017-1-4 19:42 上傳
點擊文件名下載附件
- /**************************************************/
- /*基于STC12C5A60S2系列單片機+595驅(qū)動五個數(shù)碼管+165按鍵輸入
- +1302實時時鐘+18B20溫度傳感器的萬年歷時鐘
- 功能鍵:0xfe:實現(xiàn)溫度,時間,年月日,周的轉(zhuǎn)換顯示
- 0xdf:實現(xiàn)每按一次可以一次更改小時,分,年,月,日,周的閃爍,而
- 實現(xiàn)加減按鍵對其改變數(shù)值
- 0xfb:加功能鍵,在0xdf有效的情況下才能生效
- 0xfd:減功能鍵,在0xdf有效的情況下才能生效
- 數(shù)碼管亮度有點不一致,還希望高手能幫忙解決,其他功能都是正常的,也可以給各位愛好單片機的新人們一個互相交流的一段小程序,后面付有圖片
- */
- #include < 12C5A60S2.h > //頭文件
- #include < intrins.h >
- #define uchar unsigned char //宏定義
- #define uint unsigned int
- uchar time_tuf[]={0x14,0x04,0x10,0x12,0x30,0x00,0x5}; //年月日時分秒周
- uchar code weima[]={0x20,0x10,0x08,0x04,0x02,0x01}; //數(shù)碼管位選
- uchar code duan_ma[]={0xee,0x88,0xd6,0xdc,0xb8,0x7c,0x7e,0xc8,0xfe,0xfc}; //數(shù)碼管段選信號
- uchar sec,min,hour,day,month,year,week,num,flag,flag1,flag2,flag3,Flicker,di,x,h;
- //時間變量及標志位變量
- uint tt,tvalue; //變量
- void yueri_work(void); //月日顯示程序
- void nian_work(void); //年顯示程序
- void Show_pass(uchar dss); //不顯示程序
- void zhou_work(void); //周顯示程序
- void delay_18B20(uint i); //溫度延時顯示程序
- void wendu_work(void); //溫度顯示程序
- void show_work(void); //顯示程序
- void KEY(void); //按鍵顯示程序
- sbit RCLK=P0^2; //595輸出存儲器鎖存時鐘線 /165裝載移位控制鎖存信號
- sbit SRCLK=P0^0; //595數(shù)據(jù)輸入時鐘線
- sbit SER=P0^3; //595數(shù)據(jù)線
- sbit SO=P0^4; //165數(shù)據(jù)輸出數(shù)據(jù)線
- sbit CLK=P0^1; //165時鐘信號
- sbit RST=P0^5; //1302復(fù)位引腳,高電平有效
- sbit IO=P0^6; //1302數(shù)據(jù)輸入輸出引腳
- sbit SCL=P0^7; //1302串行時鐘輸入,控制數(shù)據(jù)線的輸入輸出
- sbit DQ=P1^0; //18B20數(shù)字溫度傳感器,輸入輸出口
- void Delayms(uint z) //1毫秒 1T時鐘模式下
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=848;y>0;y--);
- }
- /********************595驅(qū)動程序*********************/
- void wr595(uchar date) //595寫入一個字節(jié)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- SRCLK=1;
- SER=date&0x80;
- date<<=1;
- SRCLK=0;
- }
- }
- void send2baty(uchar date1,uchar date2) //寫入雙字節(jié)程序
- {
- wr595(date1);
- wr595(date2);
- }
- void out595(void) //595輸出鎖存程序
- {
- RCLK=0;
- RCLK=1;
- }
- /****************************************************/
- /**************165移位寄存器并轉(zhuǎn)串驅(qū)動***************/
- uchar series_165()
- {
- uchar i;
- uchar BYTE=1; //最終接收到得字符
- RCLK=0; //將165外部端口數(shù)據(jù)裝入內(nèi)部寄存器
- RCLK=1; //抬高為移位準備
- for(i=0;i<8;i++)
- {
- BYTE<<=1; // 1
- CLK=1; //時鐘低
- BYTE=BYTE|SO; //先接收高位
- CLK=0; //時鐘高,上升沿下一個數(shù)據(jù)移出
- // 5
- }
- return BYTE; //返回接收字符
- }
- /****************************************************/
- /***************18B20數(shù)字傳感器驅(qū)動程序**************/
- void delay_18B20(uint i) //延時1微秒
- {
- i=i*12; //由于我用的是1T 51單片機 如果用普通51請 把這句話屏蔽
- while(i--);
- }
- void ds1820rst(void) //ds1820初始化
- {
- uchar x=0;
- DQ = 1; //DQ復(fù)位
- delay_18B20(4); //延時
- DQ = 0; //DQ拉低
- delay_18B20(100); //精確延時大于480us
- DQ = 1; //拉高
- delay_18B20(40);
- }
- uchar ds1820rd(void) //讀數(shù)據(jù)
- {
- uchar i=0;
- uchar dat = 0;
- for(i=8;i>0;i--)
- {
- DQ = 0; //給脈沖信號
- dat>>=1;
- DQ = 1; //給脈沖信號
- if(DQ) //如果DQ==1,執(zhí)行下面語句
- {
- dat|=0x80;
- }
- delay_18B20(10);
- }
- return(dat);
- }
- void ds1820wr(uchar wdata) //寫數(shù)據(jù)
- {
- uchar i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = wdata&0x01;
- delay_18B20(10);
- DQ = 1;
- wdata>>=1;
- }
- }
- read_temp(void) //讀取溫度值并轉(zhuǎn)換
- {
- uchar a,b;
- ds1820rst();
- ds1820wr(0xcc); //跳過讀序列號
- ds1820wr(0x44); //啟動溫度轉(zhuǎn)換
- ds1820rst();
- ds1820wr(0xcc); //跳過讀序列號
- ds1820wr(0xbe); //讀取溫度
- a=ds1820rd();
- b=ds1820rd();
- tvalue=b*16+a/16; //轉(zhuǎn)換為十進制數(shù)
-
- return tvalue;
- }
- /****************1302實時時鐘驅(qū)動程序****************/
- void write_baty(uchar dat) //1302寫入一個字節(jié)
- {
- uchar i;
- SCL=0;
- for(i=0;i<8;i++)
- {
- IO=dat&0x01; //先寫入低位
- SCL=1;
- SCL=0;
- dat>>=1;
- }
- }
- void write_addbaty(uchar address,uchar dat) //向1302地址寫入一個字節(jié)的數(shù)據(jù)
- {
- RST=0;
- SCL=0;
- RST=1;
- write_baty(address);
- write_baty(dat);
- SCL=1;
- RST=0;
- }
- uchar read_baty(void) //1302讀取一個字節(jié)
- {
- uchar i,temp;
- for(i=0;i<8;i++)
- {
- temp>>=1;
- if(IO)
- {
- temp=temp|0x80;
- }
- else
- {
- temp=temp&0x7f;
- }
- SCL=1;
- SCL=0;
- }
- return temp;
- }
- uchar read_adddaty(uchar address) //向1302地址讀取一個字節(jié)的數(shù)據(jù)
- {
- uchar temp;
- RST=0;
- SCL=0;
- RST=1;
- write_baty(address);
- temp=read_baty();
- SCL=1;
- RST=0;
- return temp;
- }
- void Init_1302time(void) //1302初始化
- {
- write_addbaty(0x8e,0x00);
- write_addbaty(0x80,time_tuf[5]);
- write_addbaty(0x82,time_tuf[4]);
- write_addbaty(0x84,time_tuf[3]);
- write_addbaty(0x86,time_tuf[2]);
- write_addbaty(0x88,time_tuf[1]);
- write_addbaty(0x8a,time_tuf[6]);
- write_addbaty(0x8c,time_tuf[0]);
- write_addbaty(0x8e,0x80);
- }
- void read_1302time(void) //讀1302時間
- {
- sec=read_adddaty(0x81);
- min=read_adddaty(0x83);
- hour=read_adddaty(0x85);
- day=read_adddaty(0x87);
- month=read_adddaty(0x89);
- week=read_adddaty(0x8b);
- year=read_adddaty(0x8d);
- }
- /****************************************************/
- /********************定時器0程序*********************/
- void Timer0Init(void) //2毫秒@11.0592MHz 1T時鐘模式下
- {
- AUXR |= 0x80; //定時器時鐘1T模式
- TMOD |= 0x01; //設(shè)置定時器模式
- TL0 = 0x9A; //設(shè)置定時初值
- TH0 = 0xA9; //設(shè)置定時初值
- TR0 = 1; //定時器0開始計時
- ET0 = 1; //定時器0中斷打開
- EA = 1; //總中斷打開
- }
- void timer0() interrupt 1 using 1
- {
- TL0 = 0x9A; //設(shè)置定時初值
- TH0 = 0xA9; //設(shè)置定時初值
- tt++;
- if(tt==500)
- {
- tt=0;
- x++;
- if(x==10) //20毫秒自動跳會無按鍵時顯示
- {
- x=0;
- di=0;
- }
- }
- if(tt<250)
- {
- Flicker=0;
- }
- else
- {
- Flicker=1;
- }
- }
- /********************時間調(diào)整程序********************/
- void set(uchar sel,uchar sal)
- {
- uchar address,time;
- uchar max,min;
- if(sel==7) {address=0x80; max=59;min=0;} //秒
- if(sel==6) {address=0x8a; max=7; min=1;} //星期
- if(sel==2) {address=0x82; max=59;min=0;} //分鐘
- if(sel==1) {address=0x84; max=23;min=0;} //小時
- if(sel==5) {address=0x86; max=31;min=1;} //日
- if(sel==4) {address=0x88; max=12;min=1;} //月
- if(sel==3) {address=0x8c; max=99;min=0;} //年
-
- time=read_adddaty(address+1)/16*10+read_adddaty(address+1)%16; //時間BCD轉(zhuǎn)換
- if (sal==0) time++; else time--;
- if(time>max) time=min;
- if(time<min) time=max;
-
- write_addbaty(0x8e,0x00);
- write_addbaty(address,time/10*16+time%10);
- write_addbaty(0x8e,0x80);
- }
- /**********************顯示程序**********************/
- void wendu_work(void)
- {
- send2baty(0x10,0x00);
- out595();
- Delayms(2);
- send2baty(0x08,0x00);
- out595();
- Delayms(2);
- if(tvalue/10==0x00)
- {
- Show_pass(0x04);
- }
- else
- {
- send2baty(0x04,duan_ma[tvalue/10]);
- out595();
- Delayms(2);
-
- send2baty(0x02,duan_ma[tvalue%10]);
- out595();
- Delayms(2);
- }
- send2baty(0x01,0x66);
- out595();
- Delayms(2);
- }
- void nian_work(void)
- {
- send2baty(0x10,duan_ma[2]);
- out595();
- Delayms(2);
- send2baty(0x08,duan_ma[0]);
- out595();
- Delayms(2);
- if((Flicker==1)&&(di==3))
- {
- Show_pass(0x04);
- Show_pass(0x02);
- }
- else
- {
- send2baty(0x04,duan_ma[year/16]);
- out595();
- Delayms(2);
- send2baty(0x02,duan_ma[year%16]);
- out595();
- Delayms(2);
- }
- send2baty(0x01,0x10);
- out595();
- Delayms(2);
- }
- void yueri_work(void)
- {
- if((Flicker==1)&&(di==4))
- {
- Show_pass(0x10);
- Show_pass(0x08);
- }
- else
- {
- send2baty(0x10,duan_ma[month/16]);
- out595();
- Delayms(2);
- send2baty(0x08,duan_ma[month%16]);
- out595();
- Delayms(2);
- }
- send2baty(0x04,0x10);
- out595();
- Delayms(2);
- if((Flicker==1)&&(di==5))
- {
- Show_pass(0x02);
- Show_pass(0x01);
- }
- else
- {
- send2baty(0x02,duan_ma[day/16]);
- out595();
- Delayms(2);
- send2baty(0x01,duan_ma[day%16]);
- out595();
- Delayms(2);
- }
- }
- void zhou_work(void)
- {
- send2baty(0x10,0x10);
- out595();
- Delayms(2);
- send2baty(0x08,0x10);
- out595();
- Delayms(2);
- if((Flicker==1)&&(di==6))
- {
- Show_pass(0x04);
- }
- else
- {
- send2baty(0x04,duan_ma[week%16]);
- out595();
- Delayms(2);
- }
- send2baty(0x02,0x10);
- out595();
- Delayms(2);
- send2baty(0x01,0x10);
- out595();
- Delayms(2);
- }
- void show_work(void)
- {
- if((num==0)&&(di==0))
- {
- wendu_work();
- }
- if((num==1)&&(di==0)||(di>=1)&&(di<=2))
- {
- if((Flicker==1)&&(di==1))
- {
- Show_pass(0x10);
- Show_pass(0x08);
- }
- else
- {
- send2baty(0x08,duan_ma[hour%16]);
- out595();
- Delayms(2);
-
- send2baty(0x10,duan_ma[hour/16]);
- out595();
- Delayms(2);
- }
- if((Flicker==1)&&(di==2))
- {
- Show_pass(0x02);
- Show_pass(0x01);
- }
- else
- {
- send2baty(0x02,duan_ma[min/16]);
- out595();
- Delayms(2);
-
- send2baty(0x01,duan_ma[min%16]);
- out595();
- Delayms(2);
- }
-
- send2baty(0x04,0x10);
- out595();
- Delayms(2);
- }
- if((num==2)&&(di==0)||(di==3))
- {
- nian_work();
- }
- if((num==3)&&(di==0)||(di>=4)&&(di<=5))
- {
- yueri_work();
- }
- if((num==4)&&(di==0)||(di==6))
- {
- zhou_work();
- }
- }
- /****************************************************/
- /**********************不顯示程序********************/
- void Show_pass(uchar dss)
- {
- send2baty(dss,0x00);
- out595();
- Delayms(1);
- }
- /********************按鍵處理程序********************/
- void KEY(void)
- {
- uchar key;
- key=series_165();
- if(key==0xdf)
- {
- Delayms(1);
- if(key==0xdf)
- {
- flag1=1;
- }
- }
- else
- {
- if(flag1==1)
- {
- flag1=0;
- di++;
- if(di==7)
- {
- di=0;
- }
- }
- }
- if(di!=0)
- {
- if(key==0xfb)
- {
- Delayms(1);
- if(key==0xfb)
- {
- flag2=1;
- }
- }
- else
- {
- if(flag2==1)
- {
- flag2=0;
- set(di,0);
- }
- }
- if(key==0xfd)
- {
- Delayms(1);
- if(key==0xfd)
- {
- flag3=1;
- }
- }
- else
- {
- if(flag3==1)
- {
- flag3=0;
- set(di,1);
- }
- }
- }
- else
- {
- if(key==0xfe)
- {
- Delayms(1);
- if(key==0xfe)
- {
- flag=1;
- }
- }
- else
- {
- if(flag==1)
- {
- flag=0;
- num++;
- if(num==5)
- {
- num=0;
- }
- }
- }
- }
- }
- /**********************主程序************************/
- void main(void) //主函數(shù)
- {
- Timer0Init();
- ds1820rst();
- Init_1302time();
- while(1)
- {
- read_1302time();
- read_temp();
- KEY();
- show_work();
- }
- }
-
-
-
復(fù)制代碼
|
評分
-
查看全部評分
|