找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索

單片機DS1302驅(qū)動與轉(zhuǎn)換數(shù)據(jù)以及時序觀察問題

查看數(shù): 4335 | 評論數(shù): 44 | 收藏 1
關(guān)燈 | 提示:支持鍵盤翻頁<-左 右->
    組圖打開中,請稍候......
發(fā)布時間: 2022-12-23 15:06

正文摘要:

錄像只寫了讀取秒鐘

回復(fù)

ID:401564 發(fā)表于 2023-2-1 11:48
xianfajushi 發(fā)表于 2023-1-31 11:00
為了驗證程序員的價值和水平可以做到降低產(chǎn)品成本,我修改了程序拋開時鐘芯片用定時期替代秒計時,運行十幾 ...

自己回復(fù)自己的帖子有意思嗎?
一個DS1302再怎么搞,它也就那樣,并不能體現(xiàn)一個程序員的代碼水平
你搞個無刷電機FOC試一下,你就會知道,DS1302是多么的低端
再說,你整幾個月,都還沒有搞明白,DS1302的精度跟程序一點關(guān)系都沒有
"我修改了程序拋開時鐘芯片用定時期替代秒計時,運行十幾個小時結(jié)果和電腦時鐘一樣精準(zhǔn)"
自以為是找到新世界的大門,實際上是連DS1302的門都沒有找到
DS1302的精度取決晶振,如果你用的無源晶振,那就得用晶振機(或者叫石英精度測試儀之類的)不斷的調(diào)試,更改匹配電容來達到高精度的效果如果用的是有源晶振,DS1302的精度主取決有源晶振的誤差了,但這一點意義都沒有,因為一個有源晶振的價格可以買一個RX8025T了,如果你不知道什么叫RX8025T,那就先去百度一下吧
ID:213173 發(fā)表于 2023-1-31 14:42
xianfajushi 發(fā)表于 2023-1-31 11:00
為了驗證程序員的價值和水平可以做到降低產(chǎn)品成本,我修改了程序拋開時鐘芯片用定時期替代秒計時,運行十幾 ...

就單純做時鐘而言本來就是用單片機遠比1302精準(zhǔn)。理論精度達10ns級。采用計時專用芯片的好處是掉電不停止走時,做萬年歷還可省去繁瑣的大小月、潤月、閏年、世紀年的計算。如果算成本,批量定制電子鐘專用的邦定封裝芯片比單片機成本還低。
ID:332444 發(fā)表于 2023-1-31 11:14
對了有一點需要補充就是程序里面寫的定時期頻率仿真電路芯片的時鐘頻率需要保持一致否則會偏差,比如程序?qū)?1.0592Mhz那么仿真電路圖中的單片機屬性里面的時鐘頻率也要修改為11.0592Mhz保持相同,如果是12Mhz則走快了,反過來如果程序?qū)?2Mhz而仿真是11.0592Mhz則會走慢。
ID:332444 發(fā)表于 2023-1-29 15:43
突發(fā)奇想,用數(shù)碼管顯示每周的值:一二三四五六日。64,64,9,9,73,73,63,63,9,61,81,69,121,79
ID:332444 發(fā)表于 2023-1-29 08:55
wulin 發(fā)表于 2023-1-28 20:56
所謂合理是相對的,在不影響其它功能的前提下頻繁讀1302也并無不可,單片機也累不死。只能說在現(xiàn)有硬件條 ...

如果能夠把程序打造得輕便即可用計時器中斷實現(xiàn)比較精準(zhǔn)的計時拋卻時鐘芯片目標(biāo),畢竟兆赫茲的精度比千赫茲提高了一個數(shù)量級別。
ID:332444 發(fā)表于 2023-1-29 08:50
wulin 發(fā)表于 2023-1-28 20:56
所謂合理是相對的,在不影響其它功能的前提下頻繁讀1302也并無不可,單片機也累不死。只能說在現(xiàn)有硬件條 ...

只有了然于胸才能駕輕就熟
ID:332444 發(fā)表于 2023-1-29 08:29
wulin 發(fā)表于 2023-1-28 20:56
所謂合理是相對的,在不影響其它功能的前提下頻繁讀1302也并無不可,單片機也累不死。只能說在現(xiàn)有硬件條 ...

不斷優(yōu)化就是對邏輯思維的驗證,從而實現(xiàn)賣油翁的過程.
其實不然我認為頻繁讀取對精度有所影響,就好比開定時器中斷應(yīng)該說沒什么影響,然而實踐告訴人們,輕便的程序?qū)Χ〞r器計時精度沒多大影響,而復(fù)雜的程序?qū)Χ〞r器計時精度就有影響,中斷也要獲得響應(yīng)時間的,電路也是一樣的總要撥點時間去處理其他事件.
ID:213173 發(fā)表于 2023-1-28 20:56
xianfajushi 發(fā)表于 2023-1-28 17:08
那么怎樣才合理?之上已經(jīng)說了,尋求合理的安排,目前把讀秒壓縮在每秒4次左右,在不開定時期情況下;若開定時 ...

所謂合理是相對的,在不影響其它功能的前提下頻繁讀1302也并無不可,單片機也累不死。只能說在現(xiàn)有硬件條件下,滿足所有功能預(yù)期,互相不發(fā)生沖突是需要一定的編程技巧?桃庾非笾骱瘮(shù)周期減小到十幾微秒又有多少實際意義。
ID:213173 發(fā)表于 2023-1-28 20:39
xianfajushi 發(fā)表于 2023-1-28 10:27
頻繁讀取1302全部數(shù)據(jù)是否會影響其計時精度?目前猜測而已沒什么證據(jù)。

頻繁讀取1302全部數(shù)據(jù)不會影響其計時精度,但對于你刻意精打細算主循環(huán)時間肯定有影響。比如蜂鳴器音調(diào)會不穩(wěn)。
ID:332444 發(fā)表于 2023-1-28 17:08
wulin 發(fā)表于 2023-1-28 09:13
這個限制條件不完善,在Mbcd=0的1秒時間內(nèi)會多次讀1302,如果是跨年的那1秒內(nèi),則重復(fù)多次讀全部數(shù)據(jù)。當(dāng) ...

那么怎樣才合理?之上已經(jīng)說了,尋求合理的安排,目前把讀秒壓縮在每秒4次左右,在不開定時期情況下;若開定時器按每秒讀取然而定時器未必就能精確每秒夜有不精確時候就會造成漏讀秒的情況發(fā)生.
ID:332444 發(fā)表于 2023-1-28 10:27
wulin 發(fā)表于 2023-1-28 09:13
這個限制條件不完善,在Mbcd=0的1秒時間內(nèi)會多次讀1302,如果是跨年的那1秒內(nèi),則重復(fù)多次讀全部數(shù)據(jù)。當(dāng) ...

頻繁讀取1302全部數(shù)據(jù)是否會影響其計時精度?目前猜測而已沒什么證據(jù)。
ID:213173 發(fā)表于 2023-1-28 09:13
xianfajushi 發(fā)表于 2023-1-10 17:13
限制條件的讀是最合理的時間安排
Mbcd=Du_1302(0x81);
if(Mbcd==0)Fbcd=Du_1302(0x83);

這個限制條件不完善,在Mbcd=0的1秒時間內(nèi)會多次讀1302,如果是跨年的那1秒內(nèi),則重復(fù)多次讀全部數(shù)據(jù)。當(dāng)然這屬吹毛求疵,未必影響其它程序正常運行。何況是在半夜,誰還會去計較。
ID:332444 發(fā)表于 2023-1-27 07:29
wulin 發(fā)表于 2023-1-9 17:17
用定時器的目的是控制主函數(shù)循環(huán)周期,以便輕松處理按鍵消抖和按鍵長短按計數(shù)以及數(shù)碼管動態(tài)掃描。如果在 ...

中斷+計數(shù)的1毫秒間隔或200微妙能做多少事還真的沒什么案例,本案例旨在說明詢問式計數(shù)延時相比獨占計數(shù)延時的優(yōu)越且靈活調(diào)節(jié)和設(shè)置,屬于高級分析思維模式,而非入門級別獨占計數(shù)延時一直套用引發(fā)種種疑難。
ID:332444 發(fā)表于 2023-1-18 10:14
經(jīng)過幾次試驗?zāi)壳鞍炎x秒信號壓縮到每秒4次左右基本察覺不到太大差別可以接受的程度,調(diào)整后蜂鳴器音調(diào)頻率也發(fā)生變化能聽出區(qū)別來。
ID:332444 發(fā)表于 2023-1-15 12:52
人中狼 發(fā)表于 2023-1-12 08:39
這個就是純粹的強調(diào)所謂的效率兩個字而已,但實際應(yīng)用中效率到底又指什么呢

其它都不用說,有好的程序拿來看看。
我家一臺旭日紅外熱水器無線控制器每周都快1小時多,比如時間是6點看它屏幕走時已經(jīng)是7點多了,每次都要去調(diào)整時間,否則計算峰谷的時間就不準(zhǔn)確了!非常麻煩,是很差勁的產(chǎn)品質(zhì)量,可以斷定是很差勁的程序代碼,所以莫要小看簡單的程序提高效率問題,所謂見微知著,簡單的功能都不能注重效率的話,可知復(fù)雜功能是很有問題的。
ID:384109 發(fā)表于 2023-1-12 08:39
這個就是純粹的強調(diào)所謂的效率兩個字而已,但實際應(yīng)用中效率到底又指什么呢
ID:401564 發(fā)表于 2023-1-11 13:22
188610329 發(fā)表于 2023-1-11 00:20
ds1302來說,你真要節(jié)約寶貴的系統(tǒng)資源,就用硬件讀寫。不管用spi讀寫,還是串口1讀寫,都比你IO讀寫,占 ...

從主程序中看到,這就是一個1302時鐘,其它什么事都沒干,壓根就不需要節(jié)約什么時間,效率什么的都是沒有什么意義的
1秒鐘讀取一次,延時直接用delay();
按鍵一樣的直接延時去抖動,沒必要折騰那么多東西
或者是說用讀取的時間來作為數(shù)碼管的延時,都比樓主折騰這個好
我也不知道,把單片機時間節(jié)約成這樣子,是為了什么?
是怕單片機累壞了?還是怕單片機長時間延時會鬧情緒
我看了半天,都不知道“獨占時間”是個什么玩意
ID:624769 發(fā)表于 2023-1-11 00:20
xianfajushi 發(fā)表于 2023-1-10 16:50
優(yōu)化的讀取是秒=0則讀分,分=0則讀時,不需要頻繁讀分和時信息,這樣就可以節(jié)省很多寶貴的時間資源.

ds1302來說,你真要節(jié)約寶貴的系統(tǒng)資源,就用硬件讀寫。不管用spi讀寫,還是串口1讀寫,都比你IO讀寫,占用系統(tǒng)時鐘少。
ID:332444 發(fā)表于 2023-1-10 23:01
在不開定時器情況下也可以比較精準(zhǔn)控制只讀一次秒信息精度控制在毫秒以下,因為上述說過了的6毫秒和40毫秒周期,因此可以比較精準(zhǔn)控制去讀秒信息一次足夠,而不需要無謂的多次讀取,同樣道理讀天月年也可以按條件讀取,只是不開定時器情況下按我的思路是實現(xiàn)所有功能代碼后再進行比較精準(zhǔn)的控制讀秒信息,因為不同功能的程序周期也不同,就比如6毫秒和40毫秒周期一般道理。
ID:332444 發(fā)表于 2023-1-10 17:13
wulin 發(fā)表于 2023-1-9 17:17
用定時器的目的是控制主函數(shù)循環(huán)周期,以便輕松處理按鍵消抖和按鍵長短按計數(shù)以及數(shù)碼管動態(tài)掃描。如果在 ...

限制條件的讀是最合理的時間安排
Mbcd=Du_1302(0x81);
if(Mbcd==0)Fbcd=Du_1302(0x83);
if(Mbcd==0&&Fbcd==0)Sbcd=Du_1302(0x85);
ID:332444 發(fā)表于 2023-1-10 16:59
wulin 發(fā)表于 2023-1-9 17:17
用定時器的目的是控制主函數(shù)循環(huán)周期,以便輕松處理按鍵消抖和按鍵長短按計數(shù)以及數(shù)碼管動態(tài)掃描。如果在 ...

之前代碼是秒分時頻繁都去讀取,其實沒必要,因此修改后的代碼就是按條件限制的讀取
Mbcd=Du_1302(0x81);
if(Mbcd==0)Fbcd=Du_1302(0x83);
if(Fbcd==0)Sbcd=Du_1302(0x85);
ID:332444 發(fā)表于 2023-1-10 16:50
wulin 發(fā)表于 2023-1-9 17:17
用定時器的目的是控制主函數(shù)循環(huán)周期,以便輕松處理按鍵消抖和按鍵長短按計數(shù)以及數(shù)碼管動態(tài)掃描。如果在 ...

優(yōu)化的讀取是秒=0則讀分,分=0則讀時,不需要頻繁讀分和時信息,這樣就可以節(jié)省很多寶貴的時間資源.
ID:213173 發(fā)表于 2023-1-9 17:17
xianfajushi 發(fā)表于 2023-1-5 07:29
今早想起來要補充說明不開定時器的情況下,就用簡單的功能來測試,蜂鳴器一定要的,若要其它功能不是不會 ...

用定時器的目的是控制主函數(shù)循環(huán)周期,以便輕松處理按鍵消抖和按鍵長短按計數(shù)以及數(shù)碼管動態(tài)掃描。如果在主函數(shù)中加無源蜂鳴器驅(qū)動就得縮短定時周期也就是主函數(shù)循環(huán)周期。大約200us。因為無源蜂鳴器有特定的驅(qū)動頻率要求,常見的廉價無源蜂鳴器約2KHz聲壓最大。若主函數(shù)循環(huán)周期不穩(wěn)定蜂鳴器音量聲調(diào)也不會穩(wěn)定。這不是仿真就可以搞定的。通常情況下200us可以干很多很多事。對于某些在一個主循環(huán)周期內(nèi)做不完的事可以拆分。單片機玩的就是時間和邏輯。說白了就是在什么時間點干什么事。
ID:332444 發(fā)表于 2023-1-9 16:05
通過我提供的測試圖片一看就知道單片機的時間都到哪去了,也就知道優(yōu)化該從何處下手了,我之所以說我的程序還能進一步優(yōu)化,指的是讀取芯片的頻次可以進一步減少而不會明顯影響顯示精度,按目前圖片的時間約50毫秒的頻次顯然有很多次去讀取是不必要的,因此是可以繼續(xù)優(yōu)化的,至于多少次或說多少時間去讀取一次合理,就值得探討了,各位高手不妨?xí)逞愿哒摗?/td>
ID:332444 發(fā)表于 2023-1-5 07:29
wulin 發(fā)表于 2023-1-4 20:42
這種要求的程序很簡單,也用不著138、573,給你一個示例參考,另加鬧鐘也是輕而易舉的事。黑幣你就自己留 ...

今早想起來要補充說明不開定時器的情況下,就用簡單的功能來測試,蜂鳴器一定要的,若要其它功能不是不會提出來,我自己代碼也是不開定時器,不使用額外循環(huán)計數(shù)延時,我的測試周期還可以優(yōu)化再減小。
ID:332444 發(fā)表于 2023-1-5 07:05
wulin 發(fā)表于 2023-1-4 20:42
這種要求的程序很簡單,也用不著138、573,給你一個示例參考,另加鬧鐘也是輕而易舉的事。黑幣你就自己留 ...

不錯,通篇沒用到計數(shù)延時。
ID:332444 發(fā)表于 2023-1-5 07:02
wulin 發(fā)表于 2023-1-4 20:42
這種要求的程序很簡單,也用不著138、573,給你一個示例參考,另加鬧鐘也是輕而易舉的事。黑幣你就自己留 ...

實在是抱歉,我忘記了說明是不開定時器的情況下,就用簡單的功能做測試,不要看表面功能簡單,練就的是功夫。
ID:213173 發(fā)表于 2023-1-4 20:42
xianfajushi 發(fā)表于 2023-1-4 07:12
可以這樣說,以貼出來的電路和只讀取1302的時分秒送8位數(shù)碼管顯示,并有整點4響半點2響為功能,并在主函數(shù)w ...

這種要求的程序很簡單,也用不著138、573,給你一個示例參考,另加鬧鐘也是輕而易舉的事。黑幣你就自己留著吧。


  1. #include <reg51.H>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5. #define key_S 8                                        //宏定義短按(約20ms)
  6. #define key_L key_S*30                        //宏定義長按(約600ms)
  7. #define key_I key_S*20                        //宏定義長按連+間隔(約200ms)
  8. //DS1302引腳連接定義
  9. sbit DSIO = P3^2;
  10. sbit REST = P3^0;
  11. sbit SCLK = P3^1;
  12. sbit key1 = P3^3;
  13. uchar code table[]={//共陰數(shù)碼管段碼"0~f-."
  14. 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x80};
  15. uchar dis_buf[8]={0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00};                //數(shù)碼管顯示緩存數(shù)組
  16. //DS1302讀取和寫入時分秒日月周年的地址
  17. uchar code READ_RTC_ADDR[7]=  {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; //讀出地址
  18. uchar code WRITE_RTC_ADDR[7]= {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c}; //寫入地址
  19. //              秒    分    時    日    月    周    年
  20. uchar TIME[7]={0x00, 0x00, 0x12, 0x04, 0x01, 0x03, 0x23};//讀取Ds1302 存儲順序是秒分時日月周年
  21. //---全局變量聲明---
  22. uint  Cnt2ms;                //2.5ms計數(shù)變量
  23. uint  num;                    //計數(shù)變量
  24. uchar KeySec;                 //鍵值變量
  25. bit   flashing;               //閃爍標(biāo)志
  26. //---本地函數(shù)聲明---//
  27. void Ds1302Init();            //DS1302初始化
  28. void Ds1302Write(uchar addr, uchar dat);//向1302芯片寫入地址和數(shù)據(jù)
  29. uchar Ds1302Read(uchar addr); //從1302讀數(shù)據(jù)
  30. void Ds1302ReadTime();        //讀取秒分時日月周年信息
  31. uchar BCD_D(uchar bcd);       //BCD碼轉(zhuǎn)十進制函數(shù)
  32. uchar D_BCD(uchar Dec);       //十進制轉(zhuǎn)BCD碼函數(shù)
  33. void Timer0Init(void);        //定時器T0初始化
  34. //==============DS1302驅(qū)動部分=====================
  35. //寫1302時鐘數(shù)據(jù)
  36. void Ds1302Write(uchar addr, uchar dat)
  37. {
  38.         uchar i;
  39.         REST= 0;
  40.         SCLK= 0;
  41.         REST= 1;
  42.         for(i=0;i<8;i++)       // 寫地址
  43.         {
  44.                 DSIO=addr & 0x01;  //數(shù)據(jù)從低位開始傳送
  45.                 addr>>=1;
  46.                 SCLK = 1;          //數(shù)據(jù)在上升沿時,DS1302讀取數(shù)據(jù)
  47.                 SCLK = 0;
  48.         }
  49.         for(i=0;i<8;i++)       //寫數(shù)據(jù)
  50.         {
  51.                 DSIO=dat & 0x01;
  52.                 dat>>= 1;
  53.                 SCLK = 1;           // 數(shù)據(jù)在上升沿時,DS1302讀取數(shù)據(jù)
  54.                 SCLK = 0;       
  55.         }                 
  56.         REST = 0;                // 傳送數(shù)據(jù)結(jié)束       
  57. }
  58. //讀1302時鐘數(shù)據(jù)
  59. uchar Ds1302Read(uchar addr)
  60. {
  61.         uchar i,dat,dat1;
  62.         REST = 0;
  63.         SCLK = 0;
  64.         REST = 1;
  65.         for(i=0; i<8; i++)      // 開始傳送八位地址命令
  66.         {
  67.                 DSIO = addr & 0x01; // 數(shù)據(jù)從低位開始傳送
  68.                 addr >>= 1;
  69.                 SCLK = 1;           // 上升沿有效,DS1302讀取數(shù)據(jù)
  70.                 SCLK = 0;
  71.         }
  72.         for(i=0;i<8;i++)        // 讀取8位數(shù)據(jù)
  73.         {
  74.                 dat1 = DSIO;        // 從最低位開始接收
  75.                 dat=(dat>>1)|(dat1<<7);
  76.                 SCLK = 1;           // 上升沿有效,DS1302讀取數(shù)據(jù)
  77.                 SCLK = 0;
  78.         }
  79.         REST = 0;               // 以下為DS1302復(fù)位的穩(wěn)定時間,必須的。                   
  80.         SCLK = 1;
  81.         DSIO = 0;
  82.         DSIO = 1;
  83.         return dat;       
  84. }
  85. //初始化DS1302
  86. void Ds1302Init()
  87. {
  88.         uchar i;
  89.         Ds1302Write(0x8E,0x00);   // 禁止寫保護功能
  90.         for(i=0;i<3;i++)          // 寫入3個字節(jié)的時鐘信號:分秒時       
  91.                 Ds1302Write(WRITE_RTC_ADDR[i],TIME[i]);
  92.         Ds1302Write(0x8E,0x80);   // 打開寫保護功能
  93. }
  94. //BCD碼轉(zhuǎn)十進制函數(shù)
  95. uchar BCD_D(uchar bcd)
  96. {
  97.         return ((bcd>>4)*10)+(bcd & 0x0f);
  98. }
  99. //十進制轉(zhuǎn)BCD碼函數(shù),返回BCD碼
  100. uchar D_BCD(uchar Dec)
  101. {
  102.         return (Dec/10*16+Dec%10);
  103. }

  104. //讀取時鐘信息
  105. void Ds1302ReadTime()
  106. {
  107.         uchar i;
  108.         for(i=0;i<3;i++)         //讀取3個字節(jié)的時鐘信號:秒分時
  109.                 TIME[i]=BCD_D(Ds1302Read(READ_RTC_ADDR[i]));//BCD轉(zhuǎn)換成十進制保存
  110. }

  111. //按鍵服務(wù)函數(shù)
  112. void key_scan()
  113. {
  114.         static uint time=0;  //計數(shù)變量

  115.         if(!key1)       //按鍵按下
  116.         {
  117.                 time++;
  118.                 if(time>=key_L)  //長按
  119.                 {
  120.                         switch(KeySec)
  121.                         {
  122.                                 case 1: TIME[2]++;if(TIME[2]>23)TIME[2]=0;break;
  123.                                 case 2: TIME[1]++;if(TIME[1]>59)TIME[1]=0;TIME[0]=0;break;
  124.                         }
  125.                         time=key_I;  //連+間隔
  126.                         num=2000;     //自復(fù)位變量賦值(5秒)
  127.                 }
  128.         }
  129.         else                                //松手
  130.         {
  131.                 if(time>key_S && time<key_I)//短按
  132.                 {
  133.                         num=2000;    //自復(fù)位變量賦值(5秒)
  134.                         KeySec++;
  135.                         if(KeySec>2)
  136.                         {
  137. //                                KeySec=0;
  138.                                 num=1;
  139.                         }
  140.                 }
  141.                 time=0;
  142.         }
  143. }

  144. // 數(shù)碼管顯示函數(shù)
  145. void display()
  146. {
  147.         uchar i;
  148.         if(KeySec==0)           //常態(tài)顯示
  149.         {
  150.                 dis_buf[0]=table[TIME[2]/10];
  151.                 dis_buf[1]=table[TIME[2]%10];
  152.                 dis_buf[3]=table[TIME[1]/10];
  153.                 dis_buf[4]=table[TIME[1]%10];
  154.                 dis_buf[6]=table[TIME[0]/10];
  155.                 dis_buf[7]=table[TIME[0]%10];
  156.         }
  157.         if(KeySec==1)           //調(diào)整時
  158.         {
  159.                 if(!key1)//持續(xù)不變表示鍵長按連加,時不閃爍
  160.                 {
  161.                         dis_buf[0]=table[TIME[2]/10];
  162.                         dis_buf[1]=table[TIME[2]%10];
  163.                 }
  164.                 else                //松手 時閃爍
  165.                 {
  166.                         if(flashing)
  167.                         {
  168.                                 dis_buf[0]=table[TIME[2]/10];
  169.                                 dis_buf[1]=table[TIME[2]%10];
  170.                         }
  171.                         else
  172.                         {
  173.                                 dis_buf[0]=0x00;
  174.                                 dis_buf[1]=0x00;
  175.                         }
  176.                 }
  177.                 dis_buf[3]=table[TIME[1]/10];
  178.                 dis_buf[4]=table[TIME[1]%10];
  179.                 dis_buf[6]=table[TIME[0]/10];
  180.                 dis_buf[7]=table[TIME[0]%10];

  181.         }
  182.         if(KeySec==2)           //調(diào)整分
  183.         {
  184.                 dis_buf[0]=table[TIME[2]/10];
  185.                 dis_buf[1]=table[TIME[2]%10];
  186.                 if(!key1)//持續(xù)不變表示鍵長按連加,分不閃爍
  187.                 {
  188.                         dis_buf[3]=table[TIME[1]/10];
  189.                         dis_buf[4]=table[TIME[1]%10];
  190.                 }
  191.                 else                //松手 分閃爍
  192.                 {
  193.                         if(flashing)
  194.                         {
  195.                                 dis_buf[3]=table[TIME[1]/10];
  196.                                 dis_buf[4]=table[TIME[1]%10];
  197.                         }
  198.                         else
  199.                         {
  200.                                 dis_buf[3]=0x00;
  201.                                 dis_buf[4]=0x00;
  202.                         }
  203.                 }
  204.                 dis_buf[6]=table[TIME[0]/10];
  205.                 dis_buf[7]=table[TIME[0]%10];
  206.         }
  207.         P2=0xff;
  208.         P0=dis_buf[i];
  209.         P2=~(0x01<<i);
  210.         i=++i%8;
  211. }
  212. //初始化定時器
  213. void Timer0Init(void)                //2500微秒@12.000MHz
  214. {
  215.         TMOD |= 0x01;                //設(shè)置定時器模式
  216.         TL0 = 0x3C;                //設(shè)置定時初始值
  217.         TH0 = 0xF6;                //設(shè)置定時初始值
  218.         TF0 = 0;                //清除TF0標(biāo)志
  219.         TR0 = 1;                //定時器0開始計時
  220. }
  221. //主函數(shù)
  222. void main()
  223. {
  224.         uchar t;
  225.         Ds1302Init();
  226.         Timer0Init();   //初始化定時器
  227.         while(1)
  228.         {
  229.                 if(TF0)    //周期2.5ms
  230.                 {
  231.                         TF0=0;
  232.                         TL0 = 0x3C;                //設(shè)置定時初始值
  233.                         TH0 = 0xF6;                //設(shè)置定時初始值
  234.                         if(++Cnt2ms==400)Cnt2ms=0;
  235.                         key_scan();//按鍵掃描
  236.                         if(num!=0)
  237.                         {
  238.                                 if(Cnt2ms%80==0)//0.2s 設(shè)置狀態(tài)時、分快閃
  239.                                         flashing=~flashing;
  240.                                 num--;
  241.                                 if(num==0)//按鍵停止操作5秒自動恢復(fù)正常顯示
  242.                                 {
  243.                                         for(t=1;t<3;t++)//數(shù)據(jù)轉(zhuǎn)碼導(dǎo)入寫入緩存
  244.                                                 TIME[t]=D_BCD(TIME[t]);//十進制轉(zhuǎn)BCD碼
  245.                                         Ds1302Init();//寫入實時時間
  246.                                         KeySec=0;//鍵值清0
  247.                                 }
  248.                         }
  249.                         else //設(shè)置時間時 不讀取DS1302實時時間
  250.                         {
  251.                                 Ds1302ReadTime();//讀DS1302實時時間
  252.                         }
  253.                         display();// 數(shù)碼管顯示函數(shù)
  254.                 }
  255.         }
  256. }

復(fù)制代碼



ID:401564 發(fā)表于 2023-1-4 20:03
xianfajushi 發(fā)表于 2023-1-4 07:12
可以這樣說,以貼出來的電路和只讀取1302的時分秒送8位數(shù)碼管顯示,并有整點4響半點2響為功能,并在主函數(shù)w ...

我這幾年編程白學(xué)了?我怎么看了幾次都看不明白這段文字表達了什么...........
ID:996773 發(fā)表于 2023-1-4 13:31
沒看懂樓主的目的,樓主用的是138解碼逐個點亮數(shù)碼管的掃描方式,讀取1302數(shù)據(jù)和bcd轉(zhuǎn)換十進制再查表只需要在點亮一個數(shù)碼管周期內(nèi)完成,其余時間只能等待延時,不延時還能干嘛呢,還有啊,這程序太簡單了,很多功能都沒實現(xiàn),操作不用按鈕,使用旋轉(zhuǎn)編碼器,年月日和鬧鐘都沒實現(xiàn)呢,這些都實現(xiàn)了,再找優(yōu)化方案和程序精簡

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表