|
1、本人對單片機編程不在行,也是在不斷學(xué)習(xí)中,我是搞硬件工作的,對一般的硬件電路倒是很熟悉,也用單片機做個一些非常簡單的項目,比如一些試驗設(shè)備也是用單片機來控制,事半功倍啊。但那些程序相對IIC,紅外通信,1302來說都簡單得不得了。本著利用業(yè)余時間不斷學(xué)習(xí)精進(jìn)的理想,一直在努力向前輩們學(xué)習(xí)中。平日里自己的作品都不能留在自己的手上,就像看著自己的兒子被人抱走一樣,也許沒什么技術(shù)含量,但自娛自樂一下,還是能提升不少荷爾蒙,為了彌補心中之遺憾,特別做一件留給自己的作品。
我不喜歡在開發(fā)板上作東西,那是開發(fā)前期試驗程序用的,不能算是一件作品。一件作品必須是獨立的實現(xiàn)預(yù)設(shè)的功能指標(biāo),所有的相關(guān)設(shè)計都是圍繞這個功能為中心,并且作品具有一定的實用性和便利性。
該作品硬件比較簡單,但程序部分花了我不少時間(因為是新手),電波鐘解碼部分找了些網(wǎng)上的相關(guān)解決方案和電波鐘的信號編碼規(guī)則,結(jié)合到手上1的程序,試驗調(diào)試,解決各種BUG,最后完成。
2、材料清單:
1、STC12CXXXX單片機一片
2、1英寸白色數(shù)碼管和紅色小數(shù)碼管共6只
3、74HC245一塊
4、DS1302模塊(用的現(xiàn)成的)一塊
5、報時語音模塊一塊
6、電波鐘模塊一塊
7、運放一塊
8、光敏,發(fā)光二極管,PNP和NPN數(shù)只,按鍵4只,
9、連接線若干
10、透明防水外殼一個
11、杜幫線若干
12、9V線性變壓電源一只
13、7805一塊,SM1117一塊
14、電解電容,鉭電容,電阻,貼片電阻容若干
15、洞洞板一塊,銅柱4根
16、防浪涌保護(hù)TVS管一只
3、開始工作
準(zhǔn)備構(gòu)思如何用好這些材料做出一個像樣的作品,前殼為什么要全透明呢,這是為了增加電子作品的藝術(shù)性,觀賞性(手工板也可以欣賞)能看清內(nèi)部構(gòu)造,即增加了作品的透明感,又增加了電子技術(shù)的神秘感。
初步構(gòu)思
理想中,成品應(yīng)該可能也許大概是這樣的
焊接部分模塊
焊接幾個,試試效果,不斷構(gòu)思,不斷改進(jìn)中。先用的綠色LED作為時分的分隔,后來發(fā)現(xiàn)綠光不純,偏黃,后換成紅色。
再次構(gòu)思
經(jīng)過一天的焊接(業(yè)余時間),初步成型,先試試能不能動起來。嗯,不完美的地方來了,LED看起來亮與不亮的字段區(qū)分不明顯,對于我這個強迫癥來說,一定要加濾光片。不然難受,吃不下飯。
不管了,先把電波鐘模塊加上,淘寶15元。用熱熔膠粘上去。語音模塊也裝上,喇叭也在側(cè)面開了孔。電波模塊用LED試驗了一下,晚上能收到信號,白天基本不可能,電磁污染太嚴(yán)重(我就是搞EMC的 ),經(jīng)我試驗,坐標(biāo)廣州,收到商丘的電波鐘信號,要在晚上00點以后,才能在窗戶口收到正常的信號。
取個名《大笨鐘》,LED已經(jīng)加了濾光片,現(xiàn)在已經(jīng)完美了。按鍵加上了,電波的電源控制等部分也完成了。寫入程序,增加自己功能,并調(diào)試。白LED太亮,晚上就是小夜燈,所以在夜間要降低亮度,用光敏加運放自動控制。
紅色LED在電波對時成功后會關(guān)閉,綠色LED是電波鐘信號指示,會隨信號有無閃動。夜間2-3點自動開啟授時,授時失敗紅色LED亮起提示,直到第二次授時成功后,才會關(guān)閉。第4個按鍵改為強制手動授時。本來第4個鍵是手動關(guān)閉整點報時的,F(xiàn)在程序改為夜間自動關(guān)閉報時
最終完成,放在古董收音機上,不錯。為什么我的按鍵要放在里面呢,調(diào)時要開蓋,不方便??NONO,我的是電波授時,理論上,永遠(yuǎn)不用調(diào)時。所以不需要開蓋調(diào)整。我也不需要年月日周,所以只要時間就OK。
以下是程序部分,發(fā)程序出來,不注釋,別人很難看懂,隔幾個月,自己可能都看不懂了。哈哈哈。
嚴(yán)正聲明:本程序部分純屬個人技術(shù)性開發(fā)娛樂,無任何商業(yè)用途,如認(rèn)為有侵權(quán)行為,速與我聯(lián)系或與論壇管理員聯(lián)系并刪除。否則本人不承擔(dān)任何法律責(zé)任。
/**************************************************
程序名:《大笨鐘》
晶 振:24MHZ
功 能:LED數(shù)碼管顯示,按鍵可調(diào),電波自動校時,整點報時功能,夜間光感自動亮度
全局變量已達(dá)到90個,有點多,后續(xù)要完善一下,只用一個程序文件寫完。
******************************************************/
- /**************************************************
- 程序名:《大笨鐘》
- 晶 振:24MHZ
- 功 能:LED數(shù)碼管顯示,按鍵可調(diào),電波自動校時,整點報時功能,夜間光感自動亮度
- 全局變量已達(dá)到93個
- ******************************************************/
- #include<stc12c5a60s2.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar Dat_su,Dat_num,min,hour,keysetnum;
- uchar s1,m1,h1;
- uchar hourshi,hourge,minshi,minge,secshi,secge;
- sbit DSIO = P2^2; //1302信號腳
- sbit RST = P2^1; //1302復(fù)位信號腳
- sbit SCLK = P2^0; //1302時鐘信號腳
- sbit keyset = P3^7; //進(jìn)入設(shè)置
- sbit keyshi = P3^6; //時加按鍵設(shè)置
- sbit keyfen = P3^5; //分加按鍵設(shè)置
- sbit keyBPC = P3^4; //電波強制對時按鍵
- sbit Ring = P2^4; //整點報時輸出
- bit flag200ms; //200MS讀DS1302標(biāo)志位
- bit keysetflag; //進(jìn)入按鍵設(shè)置標(biāo)志位
- bit alarmflag; //報時標(biāo)志位
- /******BPC***********/
- sbit BPC = P3^3; //BPC輸入,外部輸入
- sbit BPC_EN = P2^3; //BPC 使能
- sbit BPC_FailLED = P2^5; //BPC校時失敗指示燈
- bit keyBPCflag; //強制對時標(biāo)志位
- bit BPC_add; //BPC中斷標(biāo)志位
- bit BPC_ok = 1; //對時成功標(biāo)志位,默認(rèn)為開啟才能開啟BPC
- bit Get_time,As_time; //授時標(biāo)志位
- uchar Dat_su,Dat_num,keyBPCnum;
- uchar data BPC_dat[3][19]; //BPC3列個19組數(shù)組
- uint BPC_temp,Dat_add; //BPC脈寬時間記錄變量
- uchar data Times[3]; //BPC "分,時,上/下午“數(shù)組
- uchar DisplayData[6]; //LED顯示緩存數(shù)組
- uchar code smgduan[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0x78,0x80,0x90}; //LED 0-9
- //DS1302寫入和讀取時分秒的地址命令
- //秒分時日月周年最低位讀寫位
- uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
- uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
- //存儲順序秒分時日月周年,存儲格式是用BCD碼//
- uchar TIME[7];
- /*************************************
- * 函數(shù)名: delay()
- * 按鍵延時函數(shù),按鍵使用
- ************************************/
- void delay() //100ms
- {
- unsigned char a,b,c;
- for(c=4;c>0;c--)
- for(b=212;b>0;b--)
- for(a=140;a>0;a--);
- }
- /*******************************************************************************
- * 函 數(shù) 名 : Ds1302Write
- * 函數(shù)功能 : 向DS1302命令(地址+數(shù)據(jù))
- * 輸 入 : addr,dat
- *******************************************************************************/
- void Ds1302Write(uchar addr, uchar dat)
- {
- uchar n;
- RST = 0;
- _nop_();
- SCLK = 0; //先將SCLK置低電平。
- _nop_();
- RST = 1; //然后將RST(CE)置高電平。
- _nop_();
- for (n=0; n<8; n++) //開始傳送八位地址命令
- {
- DSIO = addr & 0x01;//數(shù)據(jù)從低位開始傳送
- addr >>= 1;
- SCLK = 1; //數(shù)據(jù)在上升沿時,DS1302讀取數(shù)據(jù)
- _nop_();
- SCLK = 0;
- _nop_();
- }
- for (n=0; n<8; n++) //寫入8位數(shù)據(jù)
- {
- DSIO = dat & 0x01;
- dat >>= 1;
- SCLK = 1; //數(shù)據(jù)在上升沿時,DS1302讀取數(shù)據(jù)
- _nop_();
- SCLK = 0;
- _nop_();
- }
-
- RST = 0; //傳送數(shù)據(jù)結(jié)束
- _nop_();
- }
- /*******************************************************************************
- * 函 數(shù) 名 : Ds1302Read
- * 函數(shù)功能 : 讀取一個地址的數(shù)據(jù)
- * 輸 入 : addr
- * 輸 出 : dat
- *******************************************************************************/
- uchar Ds1302Read(uchar addr)
- {
- uchar n,dat,dat1;
- RST = 0;
- _nop_();
- SCLK = 0; //先將SCLK置低電平。
- _nop_();
- RST = 1; //然后將RST(CE)置高電平。
- _nop_();
- for(n=0; n<8; n++) //開始傳送八位地址命令
- {
- DSIO = addr & 0x01;//數(shù)據(jù)從低位開始傳送
- addr >>= 1;
- SCLK = 1; //數(shù)據(jù)在上升沿時,DS1302讀取數(shù)據(jù)
- _nop_();
- SCLK = 0; //DS1302下降沿時,放置數(shù)據(jù)
- _nop_();
- }
- _nop_();
- for(n=0; n<8; n++) //讀取8位數(shù)據(jù)
- {
- dat1 = DSIO; //從最低位開始接收
- dat = (dat>>1) | (dat1<<7);
- SCLK = 1;
- _nop_();
- SCLK = 0; //DS1302下降沿時,放置數(shù)據(jù)
- _nop_();
- }
- RST = 0;
- _nop_(); //DS1302復(fù)位的穩(wěn)定時間,必須的。
- SCLK = 1;
- _nop_();
- DSIO = 0;
- _nop_();
- DSIO = 1;
- _nop_();
- return dat;
- }
- /*******************************************************************************
- * 函 數(shù) 名 : Ds1302Init
- * 函數(shù)功能 : 初始化DS1302
- *******************************************************************************/
- void Ds1302Init()
- {
- uchar dat;
- RST = 0;
- SCLK = 0;
- dat = Ds1302Read(0x81); //讀1302最高位判斷掉電時間是否正常
- if((dat&0x80)!=0) //為0,正常運行
- {
- Ds1302Write(0x8E,0X00); //禁止寫保護(hù),就是關(guān)閉寫保護(hù)功能
- Ds1302Write(0x84,0x00); //寫入時鐘最高位為0,定義為24小時制
-
- /******
- 本程序不需要寫入年月日和初始時間
- for (n=0; n<7; n++) //寫入7個字節(jié)的時鐘信號:分秒時日月周年
- {
- Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
- }
- *******/
- Ds1302Write(0x8E,0x80); //打開寫保護(hù)功能
- }
- }
- /*******************************************************************************
- * 函 數(shù) 名 : Ds1302ReadTime
- * 函數(shù)功能 : 讀取時鐘信息
- *******************************************************************************/
- void Ds1302ReadTime()
- {
- uchar n;
- for (n=0; n<7; n++) //讀取7個字節(jié)的時鐘信號:分秒時日月周年
- {
- TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
- }
-
- }
- /*******************************************************************************
- * 函 數(shù) 名 : datapros()
- * 函數(shù)功能 : 時間讀取處理轉(zhuǎn)換函數(shù)
- *******************************************************************************/
- void datapros()
- {
- Ds1302ReadTime(); //先讀取1302的時分秒
- DisplayData[0] = smgduan[TIME[2]>>4]; //時十位
- DisplayData[1] = smgduan[TIME[2]&0x0f];
- DisplayData[2] = smgduan[TIME[1]/16]; //分十位
- DisplayData[3] = smgduan[TIME[1]&0x0f];
- DisplayData[4] = smgduan[TIME[0]/16]; //秒十位
- DisplayData[5] = smgduan[TIME[0]&0x0f];
- }
- /*******************************************************************************
- * 函 數(shù) 名 :keyscan()
- * 函數(shù)功能 :按鍵設(shè)置時間和BPC對時
- *******************************************************************************/
- void keyscan()
- {
- if(keyset == 0)
- {
- delay();
- if(keyset == 1)
- {
- keysetnum++; //按鍵記錄值
- h1 = (TIME[2]>>4)*10+(TIME[2]&0x0f)%10;//先將1302暫停時的小時值轉(zhuǎn)換成十進(jìn)制賦予變量H1時,以便在此基礎(chǔ)上累加調(diào)整改然后寫入1302
- m1 = (TIME[1]>>4)*10+(TIME[1]&0x0f)%10;//先將1302暫停的的分鐘值轉(zhuǎn)換成十進(jìn)制賦予變量M1時,以便在此基礎(chǔ)上累加調(diào)整改然后寫入1302
- }
- if(keysetnum == 1) //按一次
- {
- keysetflag = 1; //按下KEYSET標(biāo)志位,用以暫停讀1302
- }
- if(keysetnum >= 2) //按二次,恢復(fù)讀1302,不能==2,可能因按鍵因素大于2
- {
- keysetnum = 0; //清零
- keysetflag = 0; //標(biāo)志位清零,恢復(fù)讀1302
- Ds1302Write(0x8E,0X00); //關(guān)閉1302寫保護(hù)
- Ds1302Write(0x80,0); //向秒寄存器寫入0
- Ds1302Write(0x8E,0x80); //打開1302寫保護(hù)
- }
- }
- if(keyshi == 0) //“時”增加按鍵
- {
- delay();
- if((keyshi==1)&&(keysetflag==1)) //判斷KEYSET標(biāo)志位,只有KEYSET按下后才運行
- {
- h1++; //小時加1,24小時制
- if(h1>23)
- {
- h1 = 0;
- }
- DisplayData[0] = smgduan[h1/10]; //十進(jìn)制轉(zhuǎn)換送LED十位顯示
- DisplayData[1] = smgduan[h1%10]; //十進(jìn)制轉(zhuǎn)換送LED個位顯示
- hour = (h1/10*16)+(h1%10); //將H1的值轉(zhuǎn)換成BCD碼賦給HOUR
- Ds1302Write(0x8E,0X00); //關(guān)閉1302寫保護(hù)
- Ds1302Write(0x84,hour); //向1302“時”寄存器寫入小時值
- Ds1302Write(0x8E,0x80); //打開1302寫保護(hù)
- }
- }
- if(keyfen == 0) //“分”增加鍵
- {
- delay();
- if((keyfen==1)&&(keysetflag==1)) //判斷KEYSET標(biāo)志位,只有KEYSET按下后才運行
- {
- m1++;
- if(m1>59) //分,十進(jìn)制
- {
- m1 = 0;
- }
- DisplayData[2] = smgduan[m1/10]; //十進(jìn)制轉(zhuǎn)換送LED十位顯示
- DisplayData[3] = smgduan[m1%10]; //十進(jìn)制轉(zhuǎn)換送LED個位顯示
- min = (m1/10*16)+(m1%10); //將m1的值轉(zhuǎn)換成BCD碼賦給min
- Ds1302Write(0x8E,0X00); //關(guān)閉寫保護(hù)
- Ds1302Write(0x82,min); //向"分"寄存器寫入分鐘值
- Ds1302Write(0x8E,0x80); //打開寫保護(hù)
- }
- }
- if(keyBPC == 0) //按鍵強制開啟BPC
- {
- delay();
- if(keyBPC == 1)
- {
- keyBPCnum++;
- if(keyBPCnum == 1) //按下一次,開啟BPC
- {
- BPC_EN = 0;
- BPC_FailLED = 1;
- keyBPCflag = 1;
- }
- if(keyBPCnum >= 2) //按下第二次,關(guān)閉BPC
- {
- keyBPCnum = 0;
- BPC_EN = 1;
- BPC_FailLED = 0;
- keyBPCflag = 0;
- }
- }
- }
- }
- /*********************************************
- * 整點報時函數(shù) :AlarmRing()
- * 函數(shù)功能 : 整點報時
- **********************************************/
- void AlarmRing()
- {
- uchar p,q;
- p = (TIME[1]>>4)*10+(TIME[1]&0x0f)%10; //讀取1302 變?yōu)槭M(jìn)制,分鐘為00
- q = (TIME[0]>>4)*10+(TIME[0]&0x0f)%10; //秒鐘為00
- if((p|q) == 0) //分與秒相或為0時
- {
- if(alarmflag == 1) //先判斷報時標(biāo)志打開,禁止報時段標(biāo)志為0
- {
- Ring = 1; //觸發(fā)報時
- delay();
- delay();
- Ring = 0; //關(guān)閉觸發(fā)
- }
- }
- }
- /************************************************************
- * 整點報時設(shè)定函數(shù) : Closealarm()
- **函數(shù)功能 : 設(shè)置整點報時時段
- ***********************************************************/
- void Closealarm()
- {
- uchar k;
- k = (TIME[2]>>4)*10+(TIME[2]&0x0f)%10; //讀1302小時值,轉(zhuǎn)成十進(jìn)制,設(shè)定關(guān)閉鬧鐘時間段
- if((0<=k)&&(k<=5)) //小5點,大于0點時段,關(guān)閉整點報時
- {
- alarmflag = 0; //關(guān)閉報時標(biāo)志 0-6點
- //alarmLED = 0; //關(guān)閉報時指示燈
- }
- else //打開報時
- {
- alarmflag = 1; //否則打啟報時標(biāo)志位
- //alarmLED = 1;
- }
- }
- /******************************************************
- * BPC接收函數(shù) : recieveBPCtime()
- * 函數(shù)功能 : 接收BPC授時和寫入DS1302時間
- *******************************************************/
- void recieveBPCtime()
- {
- if(As_time) //正確接收19位數(shù)據(jù)標(biāo)志位
- {
- As_time=0; //清零標(biāo)志,并判斷一分鐘內(nèi)3列19組相同的數(shù)據(jù),“分時周月年”
- if(
- (BPC_dat[0][1]==BPC_dat[1][1])&&(BPC_dat[0][1]==BPC_dat[2][1])
- &&(BPC_dat[0][2]==BPC_dat[1][2])&&(BPC_dat[0][2]==BPC_dat[2][2])
- &&(BPC_dat[0][3]==BPC_dat[1][3])&&(BPC_dat[0][3]==BPC_dat[2][3])
- &&(BPC_dat[0][4]==BPC_dat[1][4])&&(BPC_dat[0][4]==BPC_dat[2][4])
- &&(BPC_dat[0][5]==BPC_dat[1][5])&&(BPC_dat[0][5]==BPC_dat[2][5])
- &&(BPC_dat[0][6]==BPC_dat[1][6])&&(BPC_dat[0][6]==BPC_dat[2][6])
- &&(BPC_dat[0][7]==BPC_dat[1][7])&&(BPC_dat[0][7]==BPC_dat[2][7])
- &&(BPC_dat[0][8]==BPC_dat[1][8])&&(BPC_dat[0][8]==BPC_dat[2][8])
- &&(BPC_dat[0][10]==BPC_dat[1][10])&&(BPC_dat[0][10]==BPC_dat[2][10])
- &&(BPC_dat[0][11]==BPC_dat[1][11])&&(BPC_dat[0][11]==BPC_dat[2][11])
- &&(BPC_dat[0][12]==BPC_dat[1][12])&&(BPC_dat[0][12]==BPC_dat[2][12])
- &&(BPC_dat[0][13]==BPC_dat[1][13])&&(BPC_dat[0][13]==BPC_dat[2][13])
- &&(BPC_dat[0][14]==BPC_dat[1][14])&&(BPC_dat[0][14]==BPC_dat[2][14])
- &&(BPC_dat[0][15]==BPC_dat[1][15])&&(BPC_dat[0][15]==BPC_dat[2][15])
- &&(BPC_dat[0][16]==BPC_dat[1][16])&&(BPC_dat[0][16]==BPC_dat[2][16])
- &&(BPC_dat[0][17]==BPC_dat[1][17])&&(BPC_dat[0][17]==BPC_dat[2][17])
- )
- Get_time=1;
- }
- if(Get_time) //收到3幀相同的數(shù)據(jù)后,對Times[]數(shù)據(jù)賦值授時
- {
- Get_time=0; //標(biāo)志位清零
- keysetflag = 1; //利用該標(biāo)志位來暫停讀DS1302
- Times[0]=((BPC_dat[0][2]*4)+(BPC_dat[0][3])); //BPC”時“,4進(jìn)制,第2、3位
- Times[1]=((BPC_dat[0][4]*16)+(BPC_dat[0][5]*4)+(BPC_dat[0][6])+1); //BPC”分“,4進(jìn)制,第4,5,6位,3幀數(shù)據(jù)相同后,分的起始點為第2分鐘00秒,要加1補償
- Times[2]=(BPC_dat[0][9]); //判斷BPC第10位識別上/下午,0,1為上午,2,3為下午
- if(Times[2]<2) //上下午判斷,如果小于2,為上午
- {
- hour = (Times[0]/10*16)+(Times[0]%10); //時轉(zhuǎn)換成BCD
- min = (Times[1]/10*16)+(Times[1]%10); //分轉(zhuǎn)換成BCD
- }
- else //上下午判斷,如果大于1,為下午
- {
- hour = ((Times[0]+12)/10*16)+((Times[0]+12)%10); //BPC下午,Times[3]要加12變?yōu)?4小時制并轉(zhuǎn)換為BCD
- min = (Times[1]/10*16)+(Times[1]%10); //分轉(zhuǎn)成BCD
- }
- Ds1302Write(0x8E,0X00); //關(guān)閉寫保護(hù)
- Ds1302Write(0x84,hour); //向時寄存器寫入小時值
- Ds1302Write(0x82,min); //向分寄存器寫入
- Ds1302Write(0x80,0); //向秒寄存器寫入0,一分鐘3幀相同信號,分加1后,秒歸0.無需判斷
- Ds1302Write(0x8E,0x80); //打開寫保護(hù)
- keysetflag = 0; //恢復(fù)讀1302
- BPC_ok = 0; //授時成功標(biāo)志清零
- BPC_EN = 1; //接收成功后,關(guān)閉BPC
- BPC_FailLED = 0; //關(guān)閉授時失敗指示燈
- keyBPCflag = 0; //取消強制對時標(biāo)志位
- }
- }
- /**************************************************
- * BPC自動接收函數(shù) : BPC_openset()
- * 函數(shù)功能 : 設(shè)置BPC開啟授時時間
- *************************************************/
- void BPC_openset()
- {
- uchar t;
- t = (TIME[2]>>4)*10+(TIME[2]&0x0f)%10; //先讀出1302的小時值,轉(zhuǎn)換成十進(jìn)制
- if(t == 2) //夜間2點,持續(xù)接收BPC。
- {
- if(BPC_ok) //先判斷BPC授時成功標(biāo)志位,授時成功一次,不再執(zhí)行該程序
- {
- BPC_EN = 0; //打開BPC授時模塊
- BPC_FailLED = 1; //打開授時失敗指示燈
- }
- }
- if(t == 3) //夜時3點,如未成功授時自動關(guān)閉BPC
- {
- if(keyBPCflag == 0) //判斷按鍵強制對時按鍵標(biāo)志位,如果有按鍵強制對時,不執(zhí)行
- {
- BPC_EN = 1; //1小時內(nèi)授時不成功,關(guān)閉BPC模塊,不關(guān)指示燈用于提示授時失敗
- BPC_ok = 1; // 開授時成功標(biāo)志位,以便下一個2點能開啟BPC模塊
- }
- }
- }
- /*******************************************************************************
- * 函 數(shù) 名 : main
- * 函數(shù)功能 : 主函數(shù)
- *******************************************************************************/
- void main()
- {
- Ring = 0; // 整點報時初始值
- BPC_EN = 1; //BPC使能初始
- BPC_FailLED = 0; //授時失敗指示燈初始
- EA = 1;
- TMOD = 0x01; //T0
- TH0 = (65536-2000)/256; //LED刷新和定時讀DS1302
- TL0 = (65536-2000)%256;
- TR0 = 1;
- ET0 = 1;
- IT1=1; //P33下降沿觸發(fā)
- EX1=1; //開啟外部中斷
- PX1=1; //外部中斷優(yōu)先
- //Ds1302Init(); //本程序無需初始化DS1302
- while(1)
- {
- Closealarm(); //整點報時關(guān)閉時段
- keyscan(); //按鍵
- AlarmRing(); //整點報時
- BPC_openset(); // BPC開啟函數(shù)
- recieveBPCtime(); //BPC接收轉(zhuǎn)換函數(shù)
-
- if(flag200ms) //讀1302時間標(biāo)志
- {
- flag200ms = 0;
- if(keysetflag == 0) //有按鍵調(diào)整時,標(biāo)志位置1,暫停讀1302
- {
- datapros(); //數(shù)據(jù)處理函數(shù)
- }
- }
- }
- }
- /*******************************************************************************
- * 函 數(shù) 名 : interruptimer()
- * 函數(shù)功能 : 中斷,刷新數(shù)碼管,BPC時間記時判斷脈寬值
- *******************************************************************************/
- void interrutptimer() interrupt 1
- {
- uchar i,ms;
- TH0 = (65536-2000)/256; //1ms
- TL0 = (65536-2000)%256;
- ms++;
- if(ms>=200)
- {
- ms = 0;
- flag200ms = 1; //讀1302間隔時間段
- }
- switch(i)
- {
- case 0: P1=0x3e;i++;P0=0x00;P0=DisplayData[5];break; // 秒
- case 1: P1=0x3d;i++;P0=0x00;P0=DisplayData[4];break;
- case 2: P1=0x3b;i++;P0=0x00;P0=DisplayData[3];break; //分
- case 3: P1=0x37;i++;P0=0x00;P0=DisplayData[2];break;
- case 4: P1=0x2f;i++;P0=0x00;P0=DisplayData[1];break; //時
- case 5: P1=0x1f;i=0;P0=0x00;P0=DisplayData[0];break;
- default: break;
- }
-
- Dat_add++; //外部中斷內(nèi)對ADD清零,1500次內(nèi),有外部中斷,重新清零
- if(Dat_add>1500) //BPC啟始信號,每1MS對DAT_add加1,如在1500個周期內(nèi)沒有進(jìn)入外部中斷被清零,1.5S后標(biāo)志找到超始信號,重新對Dat_num清零,以便重新對19個位賦值
- Dat_num=0; //對數(shù)組清零,說明已授收到超始脈沖
- if(BPC_add) //外部中斷標(biāo)志為真
- {
- if(!BPC) // 第1個脈沖負(fù)邊到來時
- BPC_temp++; //用BPC_temp累加值來判斷脈寬
- else
- {
- BPC_add=0; //當(dāng)?shù)?個脈沖跳變?yōu)檎厱r,對BPC_add標(biāo)志位清零,等待下個脈沖的中斷
- if((BPC_temp>50)&&(BPC_temp<150)) BPC_dat[Dat_su][Dat_num]=0; //判斷脈寬值,賦值給二維數(shù)組的第[0][0]
- else if((BPC_temp>150)&&(BPC_temp<250))BPC_dat[Dat_su][Dat_num]=1;
- else if((BPC_temp>250)&&(BPC_temp<350))BPC_dat[Dat_su][Dat_num]=2;
- else if((BPC_temp>350)&&(BPC_temp<450))BPC_dat[Dat_su][Dat_num]=3;
- else Dat_num=0; //如果以上有不正確的值,對Dat_num清零重來
-
- Dat_num++; //對第二維的數(shù)據(jù)的值清零
- if(Dat_num>18)
- {
- Dat_num=0;
- As_time=1; //正確接收19位數(shù)據(jù)標(biāo)志位
- Dat_su++; //對第一維的數(shù)據(jù)增加,最終共3*19組數(shù)據(jù)
- if(Dat_su>2)
- Dat_su=0;
- }
- BPC_temp=0; //脈沖累加值清零
- }
- }
- }
- /***********************************************************************
- * 電波鐘中斷檢測函數(shù) :Time_EX1()
- * 函數(shù)功能 : BPC當(dāng)外部下降沿時產(chǎn)生中斷,標(biāo)志置位,清零時間累加值
- ***************************************************************************/
- void Time_EX1(void)interrupt 2 //外部中斷,優(yōu)先級為最高,防止漏檢
- {
- BPC_add=1; //外部中斷標(biāo)志
- Dat_add=0; //1ms定時中斷內(nèi)對變量加1,用來判斷1.5S的超始脈沖
- }
復(fù)制代碼 發(fā)貼不易,敬請評論指點,特別是在程序上,希望能學(xué)習(xí)時步。
全部資料51hei下載地址:
大笨鐘.zip
(53.95 KB, 下載次數(shù): 167)
2020-6-20 16:48 上傳
點擊文件名下載附件
|
評分
-
查看全部評分
|