|
采用stc15單片機(jī)做的主控芯片,僅供參考
制作出來(lái)的ds3132時(shí)鐘實(shí)物圖:
正面.JPG (201.1 KB, 下載次數(shù): 115)
下載附件
2017-12-18 22:21 上傳
背面.JPG (371.14 KB, 下載次數(shù): 101)
下載附件
2017-12-18 22:21 上傳
電路原理圖:
QQ圖片20171218183531.png (52.38 KB, 下載次數(shù): 115)
下載附件
2017-12-18 18:51 上傳
pcb文件:工程文件可到本帖附件中下載
QQ圖片20171218183907.png (32.14 KB, 下載次數(shù): 104)
下載附件
2017-12-18 18:51 上傳
51單片機(jī)源程序如下:
- //#include <reg52.h>
- #include "stc15f104w.h"
- #include "I2C.h"
- #include "Led_can.h"
-
- typedef unsigned int u16; //16位無(wú)符號(hào)整型數(shù)
- typedef unsigned char u8; //8位無(wú)符號(hào)整型數(shù)
- #define E2PROM_WriteAddress 0xAE //器件寫(xiě)地址
- #define DS3231_WriteAddress 0xD0 //器件寫(xiě)地址
- #define DS3231_ReadAddress 0xD1 //器件讀地址
- #define DS3231_SECOND 0x00 //秒
- #define DS3231_MINUTE 0x01 //分
- #define DS3231_HOUR 0x02 //時(shí)
- #define DS3231_WEEK 0x03 //星期
- #define DS3231_DAY 0x04 //日
- #define DS3231_MONTH 0x05 //月
- #define DS3231_YEAR 0x06 //年
- //鬧鈴1
- //#define DS3231_SALARM1ECOND 0x07 //秒
- //#define DS3231_ALARM1MINUTE 0x08 //分
- //#define DS3231_ALARM1HOUR 0x09 //時(shí)
- //#define DS3231_ALARM1WEEK 0x0A //星期/日
- //鬧鈴2
- //#define DS3231_ALARM2MINUTE 0x0b //分
- //#define DS3231_ALARM2HOUR 0x0c //時(shí)
- //#define DS3231_ALARM2WEEK 0x0d //星期/日
- #define DS3231_CONTROL 0x0e //控制寄存器
- #define DS3231_STATUS 0x0f //狀態(tài)寄存器
- #define BSY 2 //忙
- #define OSF 7 //振蕩器停止標(biāo)志
- #define DS3231_XTAL 0x10 //晶體老化寄存器
- #define DS3231_TEMPERATUREH 0x11 //溫度寄存器高字節(jié)(8位)
- #define DS3231_TEMPERATUREL 0x12 //溫度寄存器低字節(jié)(高2位)
- sbit BP = P1^5; //秒數(shù)碼管驅(qū)動(dòng)
- sbit KEY1 = P1^5; //按鍵輸入引腳
- u8 Time[18]; //時(shí)鐘數(shù)值緩沖區(qū)
- bit BiaoJi=0; //讀實(shí)時(shí)時(shí)鐘標(biāo)記
- bit BianJi_c=0; //長(zhǎng)按鍵標(biāo)記
- bit BianJi_d=0; //短按鍵標(biāo)記
- u8 BianJi=0; //編輯模式標(biāo)記
- u8 L_u[4]={2,3,4,5};//數(shù)碼管顯示第幾時(shí)鐘緩沖區(qū)
- u8 ling=0; //數(shù)碼管首位是否顯示零標(biāo)記
- bit WenDu = 0; //溫度轉(zhuǎn)換標(biāo)記
- void ConfigTimer0(u8 ms); //配置并啟動(dòng)T0,ms-T0定時(shí)時(shí)間
- void write_byte(u8 addr, u8 write_data);//DS3231_寫(xiě)一個(gè)字節(jié)數(shù)據(jù)到時(shí)鐘芯片
- u8 read_byte(u8 random_addr); //DS3231_讀一個(gè)字節(jié)數(shù)據(jù)到時(shí)鐘芯片
- void write_byte_E2( u8 write_data); //E2PROM-寫(xiě)一個(gè)字節(jié)數(shù)據(jù)到時(shí)鐘芯片
- u8 read_byte_E2(); //E2PROM-讀一個(gè)字節(jié)數(shù)據(jù)到時(shí)鐘芯片
- u8 BCD2HEX(u8 val); //BCD轉(zhuǎn)換為Byte
- u8 HEX2BCD(u8 val); //B碼轉(zhuǎn)換為BCD碼
- void anjian(); //按鈕掃描 需在定時(shí)中斷中調(diào)用
- void Anjian_d(u8 addr, u8 map); //短按鍵處理—子程序
- void main()
- {
- u8 map;
- u16 wend;
-
- EA = 1; //開(kāi)總中斷
- Led_cu(); //數(shù)碼管初始化
- ConfigTimer0(5); //配置T0定時(shí)
- ling=read_byte_E2(); //E2PROM讀出數(shù)據(jù)—數(shù)碼管首位是否顯示零標(biāo)記
- //初始化實(shí)時(shí)時(shí)鐘,小時(shí)采用24小時(shí)制
- write_byte(DS3231_CONTROL, 0x1C); //控制寄存器 DS3231_CONTROL
- write_byte(DS3231_STATUS, 0x00); //狀態(tài)寄存器 DS3231_STATUS
- //write_byte(DS3231_SECOND,HEX2BCD(30)); //修改秒
- //write_byte(DS3231_MINUTE,HEX2BCD(30)); //修改分
- //write_byte(DS3231_HOUR,HEX2BCD(16)); //修改時(shí)
- //write_byte(DS3231_DAY,HEX2BCD(1)); //修改日
- //write_byte(DS3231_MONTH,HEX2BCD(12)); //修改月
- //write_byte(DS3231_YEAR,HEX2BCD(17)); //修改年
-
- while(1)
- { //讀取時(shí)鐘芯片并寫(xiě)進(jìn)數(shù)碼管顯示緩沖區(qū)======================
- if(BiaoJi == 1)
- { BiaoJi = 0;
-
- map=read_byte(DS3231_SECOND); //讀秒
- map=BCD2HEX(map);
- Time[0]=map%10;
- Time[1]=map/10%10;
- map=read_byte(DS3231_MINUTE); //讀分
- map=BCD2HEX(map);
- Time[2]=map%10;
- Time[3]=map/10%10;
- map=read_byte(DS3231_HOUR)&0x3f; //讀小時(shí) 24小時(shí)制
- map=BCD2HEX(map);
- Time[4]=map%10 ;
- Time[5]=map/10%10 ;
-
- //map=read_byte(DS3231_WEEK ); //讀星期
- //Time[6]=map
- //map=read_byte(DS3231_DAY); //讀日
- //map=BCD2HEX(map);
- //Time[8]=map%10
- //Time[9]=map/10%10
- //map=read_byte(DS3231_MONTH); //讀月
- //map=BCD2HEX(map);
- //Time[10]=map%10
- //Time[11]=map/10%10
- //map=read_byte(DS3231_YEAR); //讀年
- //map=BCD2HEX(map);
- //Time[12]=map%10
- //Time[13]=map/10%10
-
- if((ling==0) && (Time[L_u[3]]==0)) //判斷數(shù)碼管首位零是否顯示
- Led_buff[3] = 0xff;
- else
- Led_buff[3] = Led_Char[ Time[L_u[3]]];
- Led_buff[2] = Led_Char[ Time[L_u[2]]];
- Led_buff[1] = Led_Char[ Time[L_u[1]]];
- Led_buff[0] = Led_Char[ Time[L_u[0]]];
-
- }
- //讀取溫度并寫(xiě)進(jìn)數(shù)碼管顯示緩沖區(qū)======================
- if(WenDu == 1)
- { WenDu = 0;
- //零上溫度轉(zhuǎn)換
- map=read_byte(DS3231_TEMPERATUREH); //溫度高字節(jié)—整數(shù)位
- if((map&0x80)==0) //判斷首字節(jié)為1即為 零下溫度
- { Led_buff[0] = 0xa7;
- Time[16]=map%10 ;
- Time[17]=map/10%10;
- map=read_byte(DS3231_TEMPERATUREL); //溫度低字節(jié)—小數(shù)位
- map=(map>>6)*25; //由于分辨率為0.25 所以擴(kuò)大25倍便于顯示
- Time[14]=map%10;
- Time[15]=map/10%10;
- }
- else //零下溫度轉(zhuǎn)換—零下是以2的補(bǔ)碼形式存儲(chǔ)的
- { Led_buff[0] = 0xa6;
- wend=map; //單字節(jié)轉(zhuǎn)換雙字節(jié)
- wend=wend<<2; //移出兩位放溫度的低位
- map=read_byte(DS3231_TEMPERATUREL); //讀溫度低字節(jié)
- map=map>>6; //由于2位放在頭兩位上,移到低位
- wend=wend+map; //組成10位的2進(jìn)制的溫度編碼
- wend=(~wend)+1; //負(fù)數(shù)是以2的補(bǔ)碼形式存儲(chǔ)的,轉(zhuǎn)為原碼
- wend=wend&0x03ff;//10位的2進(jìn)制的溫度編碼,截去無(wú)用位
- map= wend&0x0003;//分離低兩位,作為小數(shù)位
- map= map*25; //由于分辨率為0.25 所以擴(kuò)大25倍便于顯示
- Time[14]=map%10;
- Time[15]=map/10%10;
- wend=wend>>2; //整數(shù)位處理
- Time[16]=wend%10;
- Time[17]=wend/10%10;
- }
-
- if((ling==0) && (Time[L_u[17]]==0)) //判斷數(shù)碼管首位零是否顯示
- Led_buff[3] = 0xff;
- else
- Led_buff[3] = Led_Char[ Time[17]]; //整數(shù)位顯示兩位
- Led_buff[2] = Led_Char[ Time[16]];
- Led_buff[1] = Led_Char[ Time[15]]; //小數(shù)位顯示一位
-
- write_byte(DS3231_CONTROL, 0x3C); //溫度強(qiáng)制轉(zhuǎn)換—準(zhǔn)備下次讀取
- }
- //長(zhǎng)按鍵處理
- if(BianJi_c==1)
- { BianJi_c=0;
- KEY1=1;
- BianJi++;
- if(BianJi==1) //進(jìn)入溫度顯示
- { WenDu = 1; }
- if(BianJi==2) //進(jìn)入首位數(shù)碼管修改位
- { Led_buff[3] = Led_Char[ Time[L_u[3]]];
- Led_buff[2] = 0xbf;
- Led_buff[1] = 0xbf;
- Led_buff[0] = 0xbf;
- }
- if(BianJi==3) //進(jìn)入第二位數(shù)碼管修改位
- { Led_buff[3] = 0xbf;
- Led_buff[2] = Led_Char[ Time[L_u[2]]];
- if(Time[L_u[3]]==2 && Time[L_u[2]]>3) //若為24小時(shí)制 首位為2則壓縮次位的修改范圍
- { Time[L_u[2]]=3;
- Anjian_d(L_u[2],3);
- }
- }
- if(BianJi==4) //進(jìn)入第三位數(shù)碼管修改位
- { Led_buff[2] = 0xbf;
- Led_buff[1] = Led_Char[ Time[L_u[1]]];
- }
- if(BianJi==5) //進(jìn)入第四位數(shù)碼管修改位
- { Led_buff[1] = 0xbf;
- Led_buff[0] = Led_Char[ Time[L_u[0]]];
- }
- if(BianJi==6) //進(jìn)入數(shù)碼管首位零是否顯示,修改選項(xiàng) 顯示零:ON 不顯示零:OFF
- { if(ling==0)
- { Led_buff[3] = 0xff;
- Led_buff[2] = 0xC0;
- Led_buff[1] = 0x8E;
- Led_buff[0] = 0x8E;
- }
- else
- { Led_buff[3] = 0xff;
- Led_buff[2] = 0xff;
- Led_buff[1] = 0xC0;
- Led_buff[0] = 0xc8;
- }
- }
- if(BianJi==7) //退出編輯模式
- { BianJi=0; }
-
- }
- //短按鍵處理
- if(BianJi_d==1)
- { BianJi_d=0;
- if(BianJi==1) //退出編輯模式
- { BianJi=0; }
- if(BianJi==2) //首位數(shù)碼管修改位
- { Anjian_d(L_u[3],2);}
- if(BianJi==3) //第二位數(shù)碼管修改位
- { if(Time[L_u[3]]==2 )
- { Anjian_d(L_u[2],3); }
- else
- { Anjian_d(L_u[2],9); }
-
- }
- if(BianJi==4) //第三位數(shù)碼管修改位
- { Anjian_d(L_u[1],5); }
- if(BianJi==5) //第四位數(shù)碼管修改位
- { Anjian_d(L_u[0],9); }
- if(BianJi==6) //進(jìn)入數(shù)碼管首位零是否顯示,修改選項(xiàng) 顯示零:ON 不顯示零:OFF
- {
- if(ling==0)
- { ling = 1;
- Led_buff[3] = 0xff;
- Led_buff[2] = 0xff;
- Led_buff[1] = 0xC0;
- Led_buff[0] = 0xc8;
- write_byte_E2(ling);
- }
- else
- { ling = 0;
- Led_buff[3] = 0xff;
- Led_buff[2] = 0xC0;
- Led_buff[1] = 0x8E ;
- Led_buff[0] = 0x8E;
- write_byte_E2(ling);
- }
- }
-
- }
- }
- }
- //短按鍵處理
- void Anjian_d(u8 addr, u8 map)
- {
- u8 i;
- Time[addr]++; //時(shí)間變量
- if(Time[addr]>map) //時(shí)間變量最大值
- Time[addr]=0;
- if((addr%2)==0) //計(jì)算傳入值時(shí)十位或個(gè)位 0:各位 1:十位
- i = Time[addr+1]*10+Time[addr]; //十位個(gè)位組成數(shù)值待寫(xiě)入DS3231
- else
- i = Time[addr]*10+Time[addr-1]; //十位個(gè)位組成數(shù)值待寫(xiě)入DS3231
- Led_buff[5-BianJi] = Led_Char[ Time[addr]]; //修改的值顯示到數(shù)碼管上
- write_byte(addr/2,HEX2BCD(i)); //寫(xiě)入DS3231
-
- }
- /* 配置并啟動(dòng)T0,ms-T0定時(shí)時(shí)間 */
- void ConfigTimer0(u8 ms)
- {
- unsigned long tmp; //臨時(shí)變量
-
- tmp = 12000000 / 12; //定時(shí)器計(jì)數(shù)頻率
- tmp = (tmp * ms) / 1000; //計(jì)算所需的計(jì)數(shù)值
- tmp = 65536 - tmp; //計(jì)算定時(shí)器重載值
- TMOD &= 0xF0; //清零T0的控制位
- TH0 = (u8)(tmp>>8); //定時(shí)器重載值拆分為高低字節(jié)
- TL0 = (u8)tmp;
- ET0 = 1; //使能T0中斷
- TR0 = 1; //啟動(dòng)T0
- }
- //中斷定義為5毫秒
- void InterruptTimer0() interrupt 1
- {
- static u8 Di;
- //非編輯模式進(jìn)入
- if(BianJi==0)
- {
- Di++;
- if(Di==100)
- {BP=1;} //秒顯示賦值 0.5秒
- if(Di==200)
- {
- Di=0;
- BiaoJi=1; //一秒一次讀DS3231時(shí)間,并寫(xiě)入數(shù)碼管緩沖區(qū)的標(biāo)記
- BP=0; //秒顯示賦值 0.5秒
- }
- }
- //編輯模式(1)進(jìn)入
- if(BianJi==1)
- { Di++;
- if(Di==200)
- { Di=0; WenDu = 1;} //一秒一次讀DS3231溫度,并寫(xiě)入數(shù)碼管緩沖區(qū)的標(biāo)記
- }
-
- Led_can(); //數(shù)碼管刷新
- anjian(); //按鍵掃描
- WDT_CONTR=0x37; //看門(mén)狗刷新 8.4S
- }
- //E2PROM-寫(xiě)一個(gè)字節(jié)數(shù)據(jù)到時(shí)鐘芯片
- void write_byte_E2( u8 write_data)
- {
- I2CStart(); //產(chǎn)生總線(xiàn)起始信號(hào)
- I2CWrite(E2PROM_WriteAddress); //<<<<I2C總線(xiàn)寫(xiě)操作 E2PROM-器件碼
- I2CWrite(0); // E2PROM-存儲(chǔ)空間高八位地址
- I2CWrite(1); // E2PROM-存儲(chǔ)空間低八位地址
- I2CWrite(write_data); // 寫(xiě)數(shù)據(jù)
- I2CStop(); //產(chǎn)生總線(xiàn)停止信號(hào)
-
- }
- //E2PROM-讀一個(gè)字節(jié)數(shù)據(jù)到時(shí)鐘芯片
- u8 read_byte_E2()
- {
- char temp;
- I2CStart(); //產(chǎn)生總線(xiàn)起始信號(hào)
- I2CWrite(E2PROM_WriteAddress); //<<<<I2C總線(xiàn)寫(xiě)操作 E2PROM-器件碼
- I2CWrite(0); // E2PROM-存儲(chǔ)空間高八位地址
- I2CWrite(1); // E2PROM-存儲(chǔ)空間低八位地址
- I2CStart(); //產(chǎn)生總線(xiàn)起始信號(hào)
- I2CWrite(E2PROM_WriteAddress|1); //從寫(xiě) E2PROM-器件碼
- temp = I2CReadNAK(); // 讀數(shù)據(jù)-發(fā)送非應(yīng)答信號(hào),不讀了
- I2CStop(); //產(chǎn)生總線(xiàn)停止信號(hào)
- return(temp);
- }
- //DS3231_寫(xiě)一個(gè)字節(jié)數(shù)據(jù)到時(shí)鐘芯片
- void write_byte(u8 addr, u8 write_data)
- {
- I2CStart(); //產(chǎn)生總線(xiàn)起始信號(hào)
- I2CWrite(DS3231_WriteAddress); //<<<<I2C總線(xiàn)寫(xiě)操作
- I2CWrite(addr); //<<<<I2C總線(xiàn)寫(xiě)操作
- I2CWrite(write_data); //<<<<I2C總線(xiàn)寫(xiě)操作
- I2CStop(); //產(chǎn)生總線(xiàn)停止信號(hào)
-
- }
- //DS3231_讀一個(gè)字節(jié)數(shù)據(jù)到時(shí)鐘芯片
- u8 read_byte(u8 random_addr)
- {
- char temp;
- I2CStart(); //產(chǎn)生總線(xiàn)起始信號(hào)
- I2CWrite(DS3231_WriteAddress); //<<<<I2C總線(xiàn)寫(xiě)操作 器件碼
- I2CWrite(random_addr); //<<<<存儲(chǔ)空間地址
- I2CStart(); //產(chǎn)生總線(xiàn)起始信號(hào)
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
0.jpg (22.38 KB, 下載次數(shù): 84)
下載附件
2017-12-18 21:57 上傳
所有資料51hei提供下載:
實(shí)時(shí)時(shí)鐘.rar
(145.56 KB, 下載次數(shù): 369)
2017-12-18 18:52 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|