碼管時(shí)鐘項(xiàng)目教程:從Arduino圖形化編程到實(shí)時(shí)時(shí)鐘開發(fā))
最近有不少人在后臺(tái)問想帶學(xué)生或者自己入門硬件第一個(gè)項(xiàng)目做什么好。我通常給的答案是Mixly 數(shù)碼管時(shí)鐘。原因很簡(jiǎn)單這個(gè)項(xiàng)目把三樣特別關(guān)鍵的東西一次性串起來了——圖形化編程工具 Mixly、常見的顯示器件數(shù)碼管、以及嵌入式里繞不開的時(shí)間處理。無論你是想給小學(xué)生上創(chuàng)客課、給學(xué)生做電子設(shè)計(jì)入門訓(xùn)練還是自己在家里折騰一塊 Arduino 開發(fā)板這個(gè)項(xiàng)目都能讓你在兩三個(gè)小時(shí)內(nèi)看到實(shí)實(shí)在在的成果同時(shí)又把底層的原理吃透。很多教程喜歡一上來就甩代碼但用 Mixly 做時(shí)鐘核心價(jià)值不在于把 DS1302 的時(shí)間讀出來顯示在數(shù)碼管上而在于讓你理解一個(gè)完整的小系統(tǒng)是怎么運(yùn)轉(zhuǎn)的硬件怎么連、信號(hào)怎么走、數(shù)據(jù)怎么從傳感器到處理器再到顯示器件、程序邏輯怎么安排才能保證顯示不閃爍、時(shí)間不走錯(cuò)。這篇文章我把整個(gè)項(xiàng)目從設(shè)計(jì)思路、硬件選型到 Mixly 積木搭建、常見踩坑點(diǎn)全部拆開講一步步帶著做保證你看完之后不只是會(huì)抄一個(gè)作業(yè)而是真正能根據(jù)需求改出自己的時(shí)鐘。1. 項(xiàng)目設(shè)計(jì)與思路拆解1.1 數(shù)碼管時(shí)鐘的三層架構(gòu)任何一個(gè)數(shù)碼管時(shí)鐘項(xiàng)目不管用什么主控、什么屏本質(zhì)上都是三層結(jié)構(gòu)顯示層、驅(qū)動(dòng)層、計(jì)時(shí)層。顯示層決定了你用什么器件把數(shù)字呈現(xiàn)出來驅(qū)動(dòng)層負(fù)責(zé)把主控的 IO 信號(hào)轉(zhuǎn)成數(shù)碼管能識(shí)別的電平組合計(jì)時(shí)層則負(fù)責(zé)回答一個(gè)核心問題——現(xiàn)在到底是幾點(diǎn)幾分幾秒。這三層是相互獨(dú)立的理解這一點(diǎn)特別重要。很多人做項(xiàng)目失敗就是因?yàn)榘堰@三種問題混在一起想。比如數(shù)碼管顯示亂碼你以為是代碼問題其實(shí)可能是驅(qū)動(dòng)層的限流電阻沒加對(duì)時(shí)間莫名其妙跳到 2000 年大概率是計(jì)時(shí)層的備用電池沒接好或者時(shí)序初始化出錯(cuò)。把問題拆成三層之后每個(gè)現(xiàn)象都能快速定位到對(duì)應(yīng)的模塊排查起來就非常有條理。這個(gè)項(xiàng)目里顯示層我選的是 6 位共陰極數(shù)碼管因?yàn)闀r(shí)鐘至少需要顯示時(shí)分秒6 位正好夠用。驅(qū)動(dòng)層用 Arduino Uno 的 IO 口直接驅(qū)動(dòng)配合動(dòng)態(tài)掃描算法不需要額外的驅(qū)動(dòng)芯片。計(jì)時(shí)層選擇 DS1302 實(shí)時(shí)時(shí)鐘模塊因?yàn)樗诮虒W(xué)場(chǎng)景里最經(jīng)典、資料最全、成本最低而且?guī)Ъ~扣電池備份主控?cái)嚯娭髸r(shí)間不丟。這三個(gè)選擇搭配起來是新手體驗(yàn)最平滑、容錯(cuò)率最高的組合。1.2 為什么選擇 Mixly 而不是直接敲代碼Mixly 是北京師范大學(xué)團(tuán)隊(duì)開發(fā)的圖形化編程工具它的定位是降低嵌入式開發(fā)的學(xué)習(xí)門檻讓編程的注意力從語法轉(zhuǎn)移到邏輯上。做時(shí)鐘這個(gè)項(xiàng)目如果你直接用 Arduino IDE 寫 C 語言新手很可能卡在 DS1302 的時(shí)序通信、數(shù)組下標(biāo)操作、函數(shù)封裝這些點(diǎn)上兩個(gè)小時(shí)過去還在跟語法較勁而邏輯層面的東西反而沒學(xué)到。用 Mixly 就不一樣讀取時(shí)間、數(shù)據(jù)轉(zhuǎn)換、動(dòng)態(tài)掃描這些都可以用積木塊拖拽完成。積木塊之間沒有語法錯(cuò)誤的可能你能把精力全部放在流程控制上。比如“先讀取時(shí)間再把時(shí)間拆成時(shí)分秒最后一位一位地顯示到數(shù)碼管上”這個(gè)思路用積木搭一遍比看十遍代碼都管用。但這里要明確一個(gè)邊界Mixly 只是降低了編程的起步門檻不是讓你永遠(yuǎn)不碰底層。Mixly 會(huì)把積木自動(dòng)轉(zhuǎn)換成 Arduino C 代碼你在軟件右上角可以隨時(shí)看到生成的代碼。我的建議是每搭完一個(gè)模塊就切到代碼視圖看一眼理解這個(gè)積木背后實(shí)際執(zhí)行了什么。這樣學(xué)完這個(gè)項(xiàng)目你既有圖形化編程的直覺也順便把 C 語言的底子打了。1.3 時(shí)鐘源選型為什么 DS1302 是教學(xué)首選項(xiàng)目剛開始的時(shí)候很多人會(huì)糾結(jié)是直接用 Arduino 的 millis() 數(shù)毫秒來計(jì)時(shí)還是外接一個(gè) RTC實(shí)時(shí)時(shí)鐘模塊。這個(gè)問題確實(shí)值得聊透。用 millis() 計(jì)時(shí)最大的好處是零成本、不額外占 IO 口。但致命缺陷是一旦主控?cái)嚯娀蛘咧貑⒂?jì)時(shí)立刻歸零所有的日期時(shí)間都要重新設(shè)置。而 clock 芯片有一個(gè)獨(dú)立的晶振和備用電源即使主控?cái)嚯娭灰~扣電池還有電時(shí)間照樣走。對(duì)時(shí)鐘項(xiàng)目來說這個(gè)“斷電不丟時(shí)間”是剛需。DS1302、DS3231 這倆是市面上最常見的 RTC 芯片。DS3231 精度更高自帶溫度補(bǔ)償走一年誤差通常在幾秒以內(nèi)價(jià)格在十塊錢上下其實(shí)也不貴。DS1302 是老前輩走時(shí)精度比 DS3231 稍差但勝在便宜、資料海量、通信協(xié)議簡(jiǎn)單是新手的完美入門選擇。而且 DS1302 的通信協(xié)議是類似 SPI 的三線接口學(xué)習(xí)價(jià)值很高——你把這個(gè)搞明白了以后看任何傳感器的手冊(cè)都能舉一反三。所以我這個(gè)項(xiàng)目直接用 DS1302核心目的是先跑通流程。等你有經(jīng)驗(yàn)了再換 DS3231 就是改幾行代碼的事硬件連接幾乎一模一樣。2. 硬件準(zhǔn)備與電路連接2.1 元器件清單與采購建議先列一個(gè)完整的清單這東西我建議直接照抄避免在淘寶上買錯(cuò)器件型號(hào)/規(guī)格數(shù)量備注主控板Arduino Uno R3兼容版即可1用 Nano 也行接線思路一樣數(shù)碼管6 位共陰數(shù)碼管或 2 個(gè) 4 位共陰數(shù)碼管組合1-2最好選帶冒號(hào)分隔的款式顯示時(shí)間更直觀RTC 模塊DS1302 模塊帶紐扣電池座1電池一般是 CR2032跳線杜邦線公對(duì)公、公對(duì)母、母對(duì)母各一捆—顏色分好方便排查電阻220Ω 或 330Ω 直插電阻8 個(gè)段選限流用8 段含小數(shù)點(diǎn)正好 8 個(gè)面包板400 孔或 830 孔面包板1方便插拔不用焊接按鍵可選輕觸按鍵 2 個(gè)2用于調(diào)時(shí)分秒后期擴(kuò)展用采購的時(shí)候特別注意數(shù)碼管有共陰和共陽之分接法和代碼段碼都不一樣。買的時(shí)候問清楚或者看商家標(biāo)注如果已經(jīng)買錯(cuò)了也沒關(guān)系后面代碼部分我兩種都會(huì)給段碼表你對(duì)著自己的硬件調(diào)整即可。2.2 數(shù)碼管的接法共陰、共陽和限流電阻怎么算數(shù)碼管本質(zhì)上就是一堆 LED 的組合。七段數(shù)碼管有 7 個(gè)段a-g加 1 個(gè)小數(shù)點(diǎn)dp每個(gè)段就是一個(gè)發(fā)光二極管。共陰極的意思是所有 LED 的陰極連在一起接到 GND用高電平點(diǎn)亮某個(gè)段共陽極則相反公共端接 VCC低電平點(diǎn)亮。同一個(gè)數(shù)字共陰和共陽的段碼是正好取反的。比如顯示數(shù)字 1共陰數(shù)碼管需要點(diǎn)亮 b、c 兩段段碼是 0x06共陽數(shù)碼管的段碼則是所有位全部取反變成 0xF9也就是把 b 和 c 置低電平。很多新手就在這一步被坑了亮出來的數(shù)字完全不是自己想的那樣。限流電阻的選擇有明確的計(jì)算邏輯。普通紅色 LED 的正向壓降大約 1.8-2.0V工作電流選 5-10mA 比較合適。Arduino 輸出高電平是 5V所以限流電阻 R (5 - 2) / 0.01 ≈ 300Ω這就是為什么 220Ω 到 330Ω 都是合理范圍。如果你用的是 3.3V 的單片機(jī)比如 ESP32計(jì)算方式一樣R (3.3 - 2) / 0.01 ≈ 130Ω200Ω-220Ω 就合適。電阻選太大顯示亮度會(huì)明顯變暗選太小容易縮短 LED 壽命長(zhǎng)時(shí)間滿電流驅(qū)動(dòng)甚至可能燒段。2.3 DS1302 模塊接線與注意事項(xiàng)DS1302 是三線接口CE片選也叫 RST、SCLK時(shí)鐘線、IO數(shù)據(jù)線。以 Arduino Uno 為例推薦接到 Pin 7CE、Pin 6IO、Pin 5SCLK。這個(gè)不是固定死的代碼里改了就行但最好固定在 5/6/7 這組相鄰的 IO 口方便后續(xù)維護(hù)和排線。電源方面DS1302 模塊有兩種接法。模塊上一般有一個(gè) VCC 引腳和 GND 引腳接 Arduino 的 5V 和 GND。另外模塊背面有紐扣電池座裝上 CR2032 電池就行。要注意的是如果你用的模塊沒有電池掉電后時(shí)間會(huì)復(fù)位到初始值每次上電都要重新設(shè)時(shí)間。這不是代碼的 bug就是缺電池。還有一個(gè)特別多人忽略的細(xì)節(jié)DS1302 的 VCC 上最好并聯(lián)一個(gè) 0.1uF 的陶瓷電容做去耦如果模塊本身帶了電容就不用管。這個(gè)電容的作用是濾掉電源線上的高頻噪聲避免干擾 DS1302 的通信時(shí)序。另外喂入 DS1302 的電源紋波如果太大可能會(huì)讓時(shí)間走不準(zhǔn)這在用劣質(zhì) USB 供電時(shí)會(huì)偶然出現(xiàn)排查方向就記著往電源上靠。3. Mixly 圖形化編程實(shí)現(xiàn)核心邏輯3.1 程序設(shè)計(jì)的第一原則顯示刷新與時(shí)間讀取解耦這個(gè)項(xiàng)目的程序邏輯安排直接決定了最終效果是“穩(wěn)定顯示時(shí)鐘”還是“一亮一閃的災(zāi)難現(xiàn)場(chǎng)”。很多人第一版代碼是這樣寫的在一個(gè) while 循環(huán)里先讀 DS1302 拿時(shí)間再逐位刷新數(shù)碼管然后再讀一次時(shí)間再刷新。這種寫法跑起來之后數(shù)碼管看起來會(huì)閃爍得很厲害。原因在于 DS1302 的串行通信本身要花時(shí)間幾個(gè)字節(jié)的讀寫要翻轉(zhuǎn)幾十次 SCLK 時(shí)鐘線單次讀時(shí)間耗時(shí)大約幾百微秒到 1 毫秒。如果讀時(shí)間和刷新顯示串在一起顯示刷新的頻率就會(huì)忽高忽低人眼能明顯感知到亮度的跳變。正確的設(shè)計(jì)思路是把“讀時(shí)間”和“刷新顯示”拆成兩個(gè)獨(dú)立的部分。主循環(huán)只做一件事把全局變量里的時(shí)分秒顯示到數(shù)碼管上。讀時(shí)間放到定時(shí)中斷里或者放到主循環(huán)中每隔 200ms 才執(zhí)行一次讀取結(jié)果存入全局變量比如 hour 14; minute 30; second 12。這樣顯示刷新是恒定頻率不會(huì)因?yàn)橥ㄐ挪僮鞅豢D。這是嵌入式開發(fā)里非常經(jīng)典的思想——“耗時(shí)操作與實(shí)時(shí)操作分離”別以為這是臨時(shí)方案很多商業(yè)產(chǎn)品也是這么干的。3.2 逐塊搭積木初始化、讀取、拆解、掃描顯示我用 Mixly 0.998 版本的操作流程來說明其他版本界面略有差異但積木邏輯是一致的。第一步程序初始化。從“模塊”分類里拖出 DS1302 初始化積木填入 CE7、IO6、SCLK5 這三個(gè)引腳號(hào)。然后調(diào)用“寫時(shí)間”這個(gè)初始化函數(shù)把開發(fā)時(shí)的當(dāng)前時(shí)間寫進(jìn) DS1302。注意這個(gè)寫時(shí)間積木只在第一次燒錄時(shí)調(diào)用一次即可否則每次上電都會(huì)把時(shí)間重置成你寫死的值。第二步建立全局變量。在“變量”分類里新建三個(gè)變量分別叫 H、M、S用來存放時(shí)分秒值。還需要一個(gè)數(shù)組存放數(shù)碼管的段碼Mixly 里可以在“數(shù)組”分類中用積木初始化這個(gè)數(shù)組。共陰數(shù)碼管 0-9 的段碼是{0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}。排好序之后數(shù)字 n 對(duì)應(yīng)的段碼就是 seg[n]非常直白。第三步主循環(huán)里做兩件事。先判斷是否需要讀時(shí)間比如用“如果 S 當(dāng)前秒條件為真”則調(diào)一次讀時(shí)間積木或者更簡(jiǎn)單地每次循環(huán)先讀時(shí)間但只讀秒如果秒值變了再觸發(fā)一次完整的時(shí)間讀取和顯示刷新。Mixly 的 DS1302 積木提供了“讀取小時(shí)”“讀取分鐘”“讀取秒”三個(gè)函數(shù)在“電子模塊 - 實(shí)時(shí)時(shí)鐘”分類里能找到。讀取到的結(jié)果分別賦值給 H、M、S。比較繁瑣的是六位動(dòng)態(tài)掃描這一步。動(dòng)態(tài)掃描的原理參考人眼的視覺暫留效應(yīng)把一個(gè)數(shù)碼管點(diǎn)亮立刻熄滅然后點(diǎn)亮下一位循環(huán)往復(fù)。只要循環(huán)頻率高于每秒 25 次人眼看起來就像是六位數(shù)同時(shí)在亮。時(shí)間上每一位停留 2-4ms整輪六位大概 12-24ms刷新率大約 40-80Hz效果穩(wěn)定不閃爍。掃描的具體流程用積木寫是第一步全部位選關(guān)閉防止上一位的殘影串?dāng)_第二步選中第 1 位把第 1 位的位選引腳設(shè)為有效電平第三步把 seg[H/10] 的值送到段選引腳第四步延時(shí) 2ms第五步關(guān)閉第 1 位。然后按同樣步驟處理第 2 位顯示 H%10第 3、4 位顯示分鐘第 5、6 位顯示秒。中間如果數(shù)碼管帶冒號(hào)可以把冒號(hào)引腳同時(shí)點(diǎn)亮。3.3 看看生成的底層 C 代碼理解積木背后的邏輯Mixly 每一步積木都會(huì)生成 C 代碼切到代碼視圖能看到全貌。閱讀這段代碼非常有價(jià)值因?yàn)槟銜?huì)發(fā)現(xiàn)積木里拖出來的邏輯落到代碼里無非就是賦值語句、if 判斷、for 循環(huán)。核心的掃描函數(shù)生成的代碼大概是這樣的void scanDisplay() { // 第1位顯示十位小時(shí) digitalWrite(COM1, LOW); // 位選 digitalWrite(A, H / 10); // A 是數(shù)碼管 a 段引腳 digitalWrite(B, H / 10); // ... 其他段依此類推 delay(2); digitalWrite(COM1, HIGH); // 關(guān)閉本位 // 第2位顯示個(gè)位小時(shí) // 代碼邏輯同上只是換了 COM2 和數(shù)據(jù) }這里有個(gè)新手很容易犯的錯(cuò)誤如果直接用 digitalWrite 給每個(gè)段引腳送 H/10而不是查表那顯示出來的會(huì)是黑乎乎的一片。因?yàn)樵诠碴帞?shù)碼管里數(shù)字 1 不是直接把 H/10 的高電平輸出到引腳而是要把 b、c 段點(diǎn)亮。正確的做法永遠(yuǎn)是用段碼表 seg[H/10]然后按位拆出 a-g 這七段的電平再分別寫引腳??梢赃@么說段碼表是整個(gè)數(shù)碼管項(xiàng)目的靈魂。把它理解透了無論換成 74HC595 驅(qū)動(dòng)、換成 FPGA 驅(qū)動(dòng)還是換到 STM32 上做思路都是一模一樣的。只是換了一個(gè)送數(shù)據(jù)的方式而已。而這正是 Mixly 這類圖形化工具最核心的價(jià)值把底層通信細(xì)節(jié)包裝成積木把需要?jiǎng)幽X子的邏輯暴露給你讓你在搭建的過程中自然地形成工程思維。4. 常見問題與排查技巧實(shí)錄4.1 顯示亂碼、缺段、亮度不均勻這個(gè)現(xiàn)象出現(xiàn)的概率極高差不多我見過的項(xiàng)目十個(gè)里有八個(gè)第一版都會(huì)遇到。先說缺段。某個(gè)數(shù)字缺了一筆比如“8”顯示成了“0”那基本可以判定是段選引腳接錯(cuò)了或者對(duì)應(yīng)的段碼寫錯(cuò)了。你用 Mixly 的話先單獨(dú)測(cè)試一個(gè)數(shù)字讓某個(gè)段常亮逐個(gè)檢查硬件連線然后再測(cè)試段碼。測(cè)試代碼用 Mixly 搭非??鞄酌腌娋湍芗右粋€(gè)循環(huán)掃描段位的程序。再說亂碼。如果數(shù)字跳起來完全不是你輸進(jìn)去的值像“4”變成“g”這種大概率是段碼表搞錯(cuò)了共陰共陽方向。共陽的段碼是共陰的按位取反用十六進(jìn)制表示的話就是把 0x00 變成 0xFF 再減掉原值比如 0x3F 取反是 0xC0。網(wǎng)上下載的段碼表一定先確認(rèn)你的硬件是共陰還是共陽這個(gè)和數(shù)據(jù)手冊(cè)對(duì)不上必出問題。亮度不均勻是最容易忽略的。動(dòng)態(tài)掃描的時(shí)候如果你是一位一位點(diǎn)亮每一位延時(shí)固定 2ms那么顯示六位數(shù)其實(shí)也能做到均勻。但如果你用了小數(shù)的延時(shí)或者中間夾雜了別的耗時(shí)操作某一位停留時(shí)間長(zhǎng)那一位就會(huì)明顯偏亮。另一個(gè)坑是電流分配不均公共端走線太細(xì)或者面包板接觸電阻不一致也會(huì)造成亮度差異。這時(shí)先換短一點(diǎn)的杜邦線再檢查面包板插孔往往能解決。4.2 時(shí)間不走、復(fù)位后從初始值重新跑先判斷問題出在哪一層。你把 DS1302 的讀時(shí)間積木放到 setup 里串口打印讀出的值如果讀出來全部是 0或者一直不變那說明通信沒建立起來。這時(shí)候檢查三根線有沒有接反。CE/IO/SCLK 三根線接錯(cuò)了任意兩根都會(huì)導(dǎo)致讀出的數(shù)據(jù)為 0 或者亂碼。還有一種奇葩情況DS1302 的 IO 和 SCLK 引腳順序調(diào)換了但你可能恰好用了同一組 GPIO 口結(jié)果數(shù)據(jù)反而不穩(wěn)定。建議嚴(yán)格按照 datasheet 的推薦引腳連接不要自己發(fā)揮。如果時(shí)間一開始能走斷一下電再上電又變成初始值那就是后備電池的問題。確認(rèn)電池座里有沒有裝 CR2032測(cè)量一下電池電壓是否在 3V 左右。有些模塊出廠時(shí)電池接觸彈片氧化嚴(yán)重轉(zhuǎn)一下角度可能就有電了。查完硬件如果問題還在那就看看代碼里是不是每次 setup 都執(zhí)行了“寫時(shí)間”初始化——如果是把這段代碼刪掉只在首次寫入或者需要校準(zhǔn)時(shí)間時(shí)保留。4.3 想加按鍵調(diào)時(shí)間但你未必需要自己寫消抖很多同學(xué)做完基本顯示之后會(huì)立刻想到要加兩個(gè)按鍵做時(shí)間校準(zhǔn)。方向是對(duì)的而且實(shí)際上比想象的簡(jiǎn)單。調(diào)用按鍵掃描的話不要直接在代碼里判斷 if (digitalRead(KEY) HIGH) 就響應(yīng)。機(jī)械按鍵按下和松開時(shí)內(nèi)部彈簧片會(huì)抖動(dòng)幾百微秒到幾毫秒直接讀肯定會(huì)誤觸發(fā)。最土的消抖方法是延時(shí) 50ms 再讀一次如果你用的是 Mixly拖一個(gè)“延時(shí)”積木就能實(shí)現(xiàn)檢測(cè)到按鍵為高電平延時(shí) 50ms再檢測(cè)一次按鍵如果仍然為高電平則確認(rèn)按下等待按鍵松開再退出。不過我一直想做點(diǎn)不一樣的。與其自己寫消抖不如用 Mixly 里的“按鈕”擴(kuò)展模塊它封裝了狀態(tài)檢測(cè)的邏輯能夠區(qū)分按下、松開、長(zhǎng)按三種事件底層幫你把抖動(dòng)處理了。設(shè)置時(shí)間時(shí)一個(gè)按鍵切到秒/分/小時(shí)的選擇另一個(gè)按鍵對(duì)選中項(xiàng)進(jìn)行加 1改完按住不動(dòng)快速進(jìn)位。這樣做做題體驗(yàn)很好代碼量也少。有個(gè)細(xì)節(jié)要專門說清楚設(shè)置模式的時(shí)候要把數(shù)碼管的冒號(hào)閃爍作為提示不然用戶根本分不清當(dāng)前處于顯示還是設(shè)置狀態(tài)。這個(gè)邏輯在做按鍵調(diào)時(shí)的時(shí)候是必須加的。4.4 走時(shí)不準(zhǔn)到底該怪電路還是怪芯片最后聊一個(gè)玄學(xué)問題誤差。DS1302 在常溫下走一年誤差大概在正負(fù) 1-2 分鐘這個(gè)精度對(duì)日常時(shí)鐘來說是可以接受的。如果誤差大到離譜比如一天慢幾分鐘那不是芯片本身的問題大概率是你的晶振沒接對(duì)。DS1302 模塊的晶振一般都是 32.768kHz焊接或者布局不規(guī)范會(huì)引入寄生電容直接影響振蕩頻率。如果你用的不是模塊而是裸芯片晶振到芯片引腳的連線要盡可能短不能超過 5mm并且兩個(gè)負(fù)載電容一般是 6pF要盡可能靠近晶振兩端。如果連線太長(zhǎng)頻率就可能偏到 32.7k 甚至更高走時(shí)自然不準(zhǔn)。電源噪聲也會(huì)影響走時(shí)精度。DS1302 的 VCC 如果直接接在電壓波動(dòng)很大的電源上比如和舵機(jī)、電機(jī)共用一個(gè) 5V誤差會(huì)明顯變大。給模塊的電源做一點(diǎn)簡(jiǎn)單處理在 VCC 和 GND 之間加一個(gè) 10uF 電解電容和一個(gè) 0.1uF 陶瓷電容能大幅濾除低頻和高頻干擾。這一點(diǎn)在“ADC/DAC 電路設(shè)計(jì)的 PCB 布局”里是一個(gè)重點(diǎn)話題放在時(shí)鐘芯片上一樣適用。說到底調(diào)試時(shí)鐘項(xiàng)目最忌諱的就是上來一頓亂改代碼。先把問題歸類再逐層定位這是我在帶學(xué)生做這個(gè)項(xiàng)目時(shí)反復(fù)強(qiáng)調(diào)的思路也是嵌入式開發(fā)真正的核心競(jìng)爭(zhēng)力。這個(gè)項(xiàng)目做到這一步你已經(jīng)能穩(wěn)定顯示時(shí)間、斷電時(shí)間不丟失了。如果再往下走可以往這些方向擴(kuò)展接一個(gè) DHT11 溫濕度傳感器每次按下按鍵切換顯示溫度/濕度/時(shí)間把數(shù)碼管換成 I2C 接口的 TM1650 模塊省掉大量 IO 口或者嘗試把主控?fù)Q成 ESP32用 Mixly 的 IoT 積木獲取網(wǎng)絡(luò)時(shí)間徹底告別手動(dòng)校準(zhǔn)的煩惱。我自己的經(jīng)驗(yàn)是數(shù)碼管時(shí)鐘永遠(yuǎn)是教室里最能激發(fā)熱情的一個(gè)作品因?yàn)樗銐蛑庇^、足夠有用而它背后藏著的工程思維足夠你用很久。