寒假裏作了一個燈帶控制器:html
理想狀況下我應該在一個星期內完成這個項目,但實際上它耗費了我幾乎一整個寒假,由於涉及到不少不曾嘗試的方案。在這種不是很趕時間的、能夠自定目標、自由發揮的項目中,我喜歡這麼作。編程
簡要介紹一下這個項目。硬件部分:異步
12V直流電源供電,開關降壓到4V,LDO降壓到3.3V,三路供電;學習
使用STM32G030KBT6單片機,基於Cortex-M0+;測試
12V燈帶用異步降壓驅動;優化
WS2812B燈帶的數據用SPI信號加上必定的邏輯運算生成;編碼
OLED屏經過I²C鏈接單片機;加密
無定位旋轉編碼器鏈接定時器的兩個通道。設計
軟件部分:調試
用多項式擬合把ADC讀到的值轉換成溫度;
指令與數據調度、兩級流水線式OLED更新策略;
徹底自主設計的簡單GUI,包括繪圖與控制邏輯。
大約一半時間花在兩種燈帶的方案驗證上,我製做了兩塊PCB才最終肯定以上硬件方案;另有一部分時間花在STM32和HAL的調試上,但這原本就在個人STM32學習計劃中;剩下的主要是OLED和GUI,以及寫不出來時的摸魚行爲。
我趕在去學校當天的上午完成了項目,在砍掉一點完成度的前提下。有那麼幾個小時,我很後悔把整個寒假都花在了這個項目上,沒有學該學的數學、寫該寫的博客。可是如今回想起來,這個項目讓我對單片機開發有了新的認識。
曾經AVR單片機教程惟一的讀者要開始獨立作項目了,這是對我文章質量的一次考驗。從咱們之間的交流來看,我沒有經過此次考驗——
我說從供電開始思考:一般USB能夠提供5V1A,若是須要5V2A,就應該考慮從12V1A轉換。她問如何轉換,因而我給她介紹了降壓轉換器。那麼如何肯定電流呢?主要耗電器件是32個LED。按個人思路,也能夠說是絕大多數業內人士的思路,每一個燈不會超過20mA,加起來640mA,其他器件耗電忽略,1A確定是夠的。而她的思路是,算出每一個LED的等效電阻,並聯起來,再計算電流。她又問,若是電源是5V2A,但負載只有5V1A,會燒壞嗎?
而後決定用什麼燈。兩年半之前我送給她一個禮物,用32個LED組成一顆心,燈是紅藍交錯的。她想作得比這個高級一點,用32個RGB燈,但這麼多燈的鏈接是個問題,以及RGB三種顏色之間的亮度匹配。又想到WS2812B,它在功能上很強,可是控制稍微麻煩一點。我提示她能夠用PWM來生成控制信號,她又搞不清這裏的PWM和PWM呼吸燈的區別。
多是由於在第二期裏學過OLED屏和u8g2,在電賽中又用過一遍,又收到了帶OLED屏的禮物,她以爲OLED屏很簡單,想在項目中也放一塊。
暫時不做評價,繼續說事。後來又有兩人從博客園後臺聯繫我,以成本價拿到了開發板,成爲了教程的讀者(至此我已經沒有多餘的開發板了)。一位讀者剛開始學C,他經常問我兩類我不但願他問的問題(請這位讀者不要生氣):一類是與單片機無關的純C語言問題,另外一類是與教程進度不符的、我想隱藏的實現細節問題。
他們讓我開始反思教程的內容是否充足、順序編排是否合理。
他們問個人這些問題,不少也是我曾經困惑的。
預初的那個暑假,我正式學習了C語言。此後,我想寫一個C程序來加密文件,把若干字節做爲一組處理一下,寫進新的文件,就算是加密了。文件長度不必定是整組的,最後一組可能要加入幾個空的字節,這種如今看來很基礎的控制邏輯,我當時想了好久都寫不出來。
我也長期以來不知道電池充電的電流是如何控制的,在我看來把5V電壓加到3.7V鋰電池上根本不可控啊!後來才知道降壓、參考電流、反饋控制之類的。某些營銷號還說5V2A充電器給5V1A手機充電會形成損壞,也難怪非專業人士容易受誤導了。
高一的那個暑假,我完成了第一個像樣的項目,就是前面提到的那顆心。32個LED分別串聯470Ω排阻,接到4片級聯的74HC595上,用GPIO驅動。放到如今,若是不改變設計目標,我會選擇8*4動態掃描的鏈接方式,還可能用上一片TM16xx來驅動這個陣列。
按下按鍵切換模式,這個很簡單的功能在當時實現得很是亂:先定義一個宏,每次若是按下按鍵就return
,而後在循環中屢次調用它。如今我會在定時器中斷裏處理按鍵,具體來說還有多種方法。
這些不懂的問題、很差的實現,都是經驗。有些很差的實現,好比上面這個按鍵,不值得嘗試,因此我會在回答相關問題時提供我認爲合理的方法。相似的有不少,因此我一直盡力回答每一個問題,幫人避雷,也好讓我審視一下本身的方法。
AVR單片機教程的一期介紹了簡單外設的用法。我假設讀者有良好的C語言基礎,因此沒有把基礎單片機和基礎C語言結合起來說,而是在前幾講的做業題中對讀者的C功底提出了較高的要求。針對當時讀者的問題,我專門寫了一篇元教程,強調了要普遍地瞭解相關知識。
從按鍵開始我加快了節奏,不然按照一個LED都能寫4篇的速度我如今大概剛剛講到LCD1602。原計劃一期結束後還有大量內容,可是我當時已經不大想寫了,因此挑了點必要的組成了第二期的6講。
如今有讀者反映第二期太難,其實不是太難而是兩期之間有明顯斷層。在與讀者交流的過程當中,我還發現有不少我強調過的點還強調得不夠:有些是我沒講清楚,有些是讀者真的作不到,好比完成做業——我把不少關鍵的、實際應用中須要的問題放在了做業中,它們容易被忽略,至少沒有被足夠嚴肅地對待。
這些問題,以及上面帶有責怪情感的讀者提問,都是個人失職。
我決定開始寫AVR單片機教程第三期。
首先是查漏補缺,這還得再細分幾類:
外設。I²C和定時器輸入在前兩期的正文中沒有涉及到,會在第三期補上。
語言。我不該假設讀者有良好的C基礎,但我真的無法面對完徹底全的新手,因此我將補充一些非單片機編程中不經常使用的特性,以及高級但實用的用法。
第三期的不少內容用C++講起來會更加方便,因此我會簡單介紹那些須要用的C++語法,它們也是我在本身項目中經常使用的C++功能子集。
做業。如前所述,不少重要的內容都在做業裏,我將提供解題思路和優化建議。
而後是結構:
與C++綁定起來的對象的概念,包括基於對象與面向對象;
第二期最後提到的事件驅動範式,本來是單獨的一期,將成爲第三期的一部分;
有些硬件結構能夠啓發設計(有的可能最初來自軟件),包括雙緩衝、FIFO、狀態機、流水線等;
大型程序和庫的結構。
此外,單片機項目的共同問題,好比供電、制板、測試等,也會集中講解一下。
因而可知,這一期「AVR單片機教程」實際上能夠把前三個字去掉,儘管咱們仍是基於AVR平臺講解。
我設計了新的開發板,與初版相比縮小了尺寸,去掉了部分擴展資源,使它更加核心。擴展資源被移動到了單獨的模塊上,多個模塊提供不一樣方向的器件。
原來的開發板仍然提供支持。新開發板有開放小批量訂購的計劃,目前還在原型設計階段。所以,我將從不依賴於AVR的C和C++開始。
但願第三期能爲讀者創建完善的概念,能讓讀者學會必要的單片機編程方法,在例子中積累經驗,獨立設計並製做出與文首項目難度至關的單片機系統。