本帖最后由 jianwei2030 于 2017-9-3 21:12 編輯
自己做了一個萬年歷時鐘,利用STC15W408AS單片機,時鐘芯片采用DS1302。當前自己參考網上寫了時間讀取的程序,在實驗板走時正常,但是斷電再上電后無法保存時間,程序在首次上電后會初始化一個固定的時間,每次都得自己重新調時。看到網上有種說法是給1302寫入標志位,每次系統上電后檢測這個標志位,如果能夠檢測到就不初始化時間,直接讀取;如果檢測不到標志位就初始化。但是按照這種方法試過后仍然不見效果,請大家幫忙看看我這程序該怎么修改合適?
電路部分:
捕獲.JPG (104.12 KB, 下載次數: 109)
下載附件
電路
2017-9-2 20:52 上傳
以下是我的程序:
1302部分:
- #include<STC15W.h>
- #define uchar unsigned char
- #define uint unsigned int
- /* 宏定義寫DS1302的地址 */
- #define write_sec_add 0x80 //秒數據地址 1000 0000
- #define write_min_add 0x82 //分數據地址 1000 0010
- #define write_hr_add 0x84 //時數據地址 1000 0100
- #define write_week_add 0x86 //星期數據地址 1000 0110
- #define write_month_add 0x88 //月數據地址 1000 1000
- #define write_day_add 0x8a //日數據地址 1000 1010
- #define write_year_add 0x8c //年數據地址 1000 1100
- #define write_control_add 0x8e //控制數據地址 1000 1110
- #define write_charger_add 0x90 //可編程涓流充電地址 1001 0000
- #define write_clkburst_add 0xbe //時鐘脈沖串地址
- #define write_RAM0_add 0xc0 //RAM0寄存器寫地址 1100 0000
- /* 宏定義讀DS1302的地址 */
- #define read_sec_add 0x81 //秒數據地址 1000 0001
- #define read_min_add 0x83 //分數據地址 1000 0011
- #define read_hr_add 0x85 //時數據地址 1000 0101
- #define read_week_add 0x87 //星期數據地址 1000 0111
- #define read_month_add 0x89 //月數據地址 1000 1001
- #define read_day_add 0x8b //日數據地址 1000 1011
- #define read_year_add 0x8d //年數據地址 1000 1101
- #define read_control_add 0x8f //控制數據地址 1000 1111
- #define read_charger_add 0x91 //可編程涓流充電地址 1001 0001
- #define read_clkburst_add 0xbe //時鐘脈沖串地址
- #define read_RAM0_add 0xc1 //RAM0寄存器讀地址 1100 0001
- //#define P2M1 = 0x00; //0000 0000
- //#define P2M0 = 0x04; //0000 0100
- uchar sec,min,hr,week,mouth,day,year,ram_data;
- sbit sclk=P2^1;
- sbit io=P2^2;
- sbit ce=P2^3;
- void write1302_time(uchar address,uchar dat) //寫入數據給1302
- {
- uchar i;
- ce=0; //禁止讀寫數據
- sclk=0;
- for(i=0;i<8;i++) //寫地址
- {
- ce=1; //允許讀寫數據
- sclk=0;
- io=address&0x01;
- address>>=1;
- sclk=1;
- }
- for(i=0;i<8;i++) //寫數據
- {
- ce=1; //允許讀寫數據
- sclk=0;
- io=dat&0x01;
- dat>>=1;
- sclk=1;
- }
- ce=0;
- }
- uchar read1302_time(uchar address) //從1302讀取時間數據
- {
- uchar i,num;
- ce=0; //禁止讀寫數據
- for(i=0;i<8;i++)
- {
- ce=1;
- sclk=0;
- io=address&0x01;
- address>>=1;
- sclk=1;
- }
- for(i=0;i<8;i++)
- {
- if(io==1)
- num=num|0x80;
- else
- num=num|0x00;
- sclk=1;
- num>>=1;
- sclk=0;
- }
- ce=0;
- return num;
- }
- void init_1302() //初始化函數 設置時間
- {
- read_ram_data = read1302_time(read_RAM0_add);
- if(rread_ram_data!=0xf0)
- {
- write1302_time(0x8e,0x00); //保護取消,可以進行讀寫操作
- write1302_time(write_sec_add,0x00);//寫入初始秒時間 0101 0110
- write1302_time(write_min_add,0x35);//寫入初始分時間 0101 0110
- write1302_time(write_hr_add,0x22); //寫入初始時時間 0101 0110
- write1302_time(write_week_add,0x06); //寫入初始周時間 0101 0110
- write1302_time(write_month_add,0x08); //寫入初始月時間 0101 0110
- write1302_time(write_day_add,0x12); //寫入初始日時間 0101 0110
- write1302_time(write_year_add,0x17); //寫入初始年時間 0101 0110
- write1302_time(0x90,0xa5); //使能涓流充電, 1010 0101
- write1302_time(write_RAM0_add,0xf0); //往RAM寄存器中寫入0xf0數據,因為RAM有掉電丟失特點,所以進入初始化函數的時候首先判斷這個寄存器是否還有數據
- write1302_time(0x8e,0x80); //保護啟動,禁止對1302寫操作
- }
- }
- void xianshi_data() //將從1302讀出的二進制數據轉換為十進制
- {
- uchar read_sec, read_min, read_hr, read_week, read_mouth, read_day, read_year;
- read_sec = read1302_time(read_sec_add); //從“read1302_time”函數取得返回值num的數據
- sec = ((read_sec&0x70)>>4)*10+(read_sec&0x0f); //十進制“秒”
- read_min = read1302_time(read_min_add);
- min = ((read_min&0x70)>>4)*10+(read_min&0x0f); //十進制“分”
- read_hr = read1302_time(read_hr_add);
- hr = ((read_hr&0x70)>>4)*10+(read_hr&0x0f); //十進制“時”
- read_week = read1302_time(read_week_add);
- week = ((read_week&0x70)>>4)*10+(read_week&0x0f); //十進制“周”
- read_day = read1302_time(read_day_add);
- day = ((read_day&0x70)>>4)*10+(read_day&0x0f); //十進制“日”
- read_mouth = read1302_time(read_month_add);
- mouth = ((read_mouth&0x70)>>4)*10+(read_mouth&0x0f); //十進制“月”
- read_year = read1302_time(read_year_add);
- year = ((read_year&0x70)>>4)*10+(read_year&0x0f); //十進制“年”
- }
復制代碼
主函數部分:
- #include<STC15W.h>
- #include"1302.h"
- #include"18B20.h"
- #include"display.h"
- #include"keyboard.h"
- #define uchar unsigned char
- #define uint unsigned int
- //#define P2M1_set 0x00 //設置P2口工作模式 0000 0000
- //#define P2M0_set 0x0d //設置P2口工作模式 0000 1110
- uchar num;
- /*************************延時函數*************************/
- void delay(uint a) // 1ms延時程序(12MHz 10倍于51單片機速度時)
- {
- uint i;
- while(--a != 0)
- {
- for(i = 0;i < 600;i++);
- }
- }
- /***************************************初始化IO口狀態**************************************/
- //void IO_init(void)
- //{
- //P2M1 = P2M1_set;
- //P2M0 = P2M0_set;
- //}
- /**************************************外部中斷INT2初始化函數 **************************************/
- void INT2_init()
- {
- INT_CLKO |= 0x10;
- EA = 1;
- }
- void main()
- {
- INT2_init();
- // IO_init();
- // read_ram();
- init_1302();
- init_18b20();
- while(1)
- {
- display_service();
- display_qiehuan();
- }
- }
復制代碼
這是網上找到的別人的回答:
https://zhidao.baidu.com/question/345394758.html
|