欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標題: 請優化你的MCU代碼 Ver2.0 [打印本頁]

作者: Similarv    時間: 2025-10-30 17:41
標題: 請優化你的MCU代碼 Ver2.0
- 前言 -
⼤家,好久不⻅。
此⽂旨在于對2019年我發表在51黑論壇的貼⼦《請⼯程化,定制化你的單⽚機代碼http://m.raoushi.com/bbs/dpj-162218-1.html 進⾏更新,升級和完善。
雖說現在回頭⼀看,那篇貼⼦在⼀些細節確實有⼀些問題,不過最⼤的問題是——它不是⼀個完整的⽂章,我匆忙的把⼀些編程要點塞進了帖⼦⾥,然后就⼀直沒有更新了。
[attach]338394[/attach]

如今⼀晃就是6年,機緣巧合下,我突然⼜找到了那篇貼⼦。在不知不覺之間,帖⼦已經被置頂,有了這么多的評論和閱讀量,這令我甚是慚愧。
感謝⼤家的⽀持。
我近期剛好有時間,那就把帖⼦重寫⼀下,并更完⽂章吧。

- 第⼀章:設計⼀個時鐘基線 -
在⼀些初級MCU編程⼊⻔書中,經常能夠⻅到類似
  1. delay1s();  //延時1秒
復制代碼
或者
  1. while(K1 == 0); //等待⽤戶釋放鍵盤上的K1按鍵
復制代碼
這樣的代碼,表⾯上看沒有什么問題,但是本質上跟下⾯的邏輯差不多:
“已知⼩明同學從教室跑去⼩賣部買糖再回來,⼤概需要1分鐘,所以,當我們需要計時12⼩時的時候,讓⼩明同學這樣來回往返個720次,應該就差不多了!
“你戳⼩明⼀下,他就會叫⼀聲但是如果你⼀直戳著不松開,他就會由于腦⼦不夠⽤,不但叫不出來,就算你跟他說話他也沒法聽進去!


在這樣的代碼中,MCU的PC指針(這東⻄代表著程序當前在哪個代碼⾥運⾏)就如同悲催的⼩明同學,被困在那兩⾏代碼中。也許是巨⼤的資源浪費,也許是⽆法對外部的信息變化做出反應,都是很糟糕的事情。
那么,要怎么樣來編寫單⽚機程序,才可以⼜實現這些邏輯功能,⼜釋放PC指針呢這就是我們接下來要討論的內容。

1.1 帶有時基的主程序架構

正如“ 每個不得不跑去⼩賣部的⼩明,其實他去年買了個表,根本不⽤跑 ”的道理()。
即使是普通的51單⽚機,他也是有定時器的。
我們需要設置⼀個定時器,讓定時器會告訴單⽚機:“好的,現在已經過了1ms了(或者10ms這都沒關系)”單⽚機⼀拍腦袋:“啊,已經到了1ms了么,那我就把⼀些事情做⼀下吧”。就像下面這樣子:


在這個框架下,我們的代碼看起來會像下⾯這個樣⼦:
  1. unsigned char flag1ms; //全局變量

  2. void main()
  3. {
  4.     flag1ms = 0;
  5.     mcuConfig(); //MCU的⼀些其他初始化,此處略過
  6.     timer0Init(); //定時器0初始化,略過,需設置1ms定時周期

  7.     while(1)
  8.     {
  9.         if(flag1ms)
  10.         {
  11.             flag1ms = 0;
  12.             doAnything(); //單片機可以做任意事情
  13.         }
  14.     }
  15. }

  16. void timer0XINT() interrupt 1 //定時器T0中斷
  17. {
  18.     flag1ms = 1;
  19. }
復制代碼
為了⽅便理解,這⾥的“⼀系列⼯作”在代碼中只⽤了⼀個doAnything()來表⽰,實際應⽤中,往往會放好⼏個⼦程序,沒什么問題。
在本程序中,單⽚機每隔1ms會將⼀系列⼯作執⾏⼀遍。從現在開始,你的⼦程序必須要摒棄那些“傻等⾏為”,重新設計你的程序邏輯。

1.2 ⼀個按鍵程序的例⼦
我們先拿⼀個⾮常惡⼼的按鍵函數來開⼑,如果沒有時基,我們可能會寫出這樣的⼀個按鍵程序:
  1. /* 在沒有時基的時候,代碼是這樣寫的 */
  2. #define K1_PRESSING() ((P1&0x01)==0) //按鍵位于P1^0引腳
  3. void keyPress()
  4. {
  5.     unsigned int key_press_time = 0;
  6.     while(K1_PRESSING()) //等待松開
  7.     {
  8.         ++key_press_time;
  9.         if(key_press_time==300) //300*10ms = 3s
  10.         {
  11.             //⻓按3s時要做的事情
  12.         }
  13.         delay10ms(); //delay計時
  14.     }
  15.     if((key_press_time < 300) && (key_press_time >= 2))
  16.     {
  17.         //短按的處理
  18.     }
  19. }
復制代碼
這個函數兼具delay()語句和while(KEY==0)語句,可以說是⼆毒俱全了。
如果是在新的代碼架構中,它可以修改成這樣的形式
  1. /* 本程序將在每個1ms時基中被調⽤ */
  2. #define JUST_INC(x) if(++x<=0) --x //x在不能溢出的前提下++
  3. #define K1_PRESSING() ((P1&0x01)==0) //按鍵位于P1^0引腳
  4. void keyPress()
  5. {
  6.     static unsigned int key_press_time = 0;  // ……請標為靜態變量
  7.     if(K1_PRESSING())
  8.     {
  9.         JUST_INC(key_press_time);//計量按鍵時間,并避免數據溢出
  10.         if(key_press_time==3000)
  11.         {
  12.             //在此寫下按鍵⻓按3s時要做的事情
  13.         }
  14.     }
  15.     else
  16.     {
  17.         if((20<=key_press_time) && (key_press_time < 3000))
  18.         {
  19.             //20ms ~ 3s之間,視為短按,在此寫下寫短按的處理代碼
  20.         }
  21.         key_press_time=0;
  22.     }
  23. }
復制代碼
功能是⼀樣的,但實際⽤起來區別很⼤——舊程序跑1次⻓按功能,新程序已經跑了3000次,且后者不會⼀直占⽤PC指針。
新的程序有些細節,可以展開說⼀說:
①key_press_time現在是⼀個靜態變量,static關鍵字可以讓該變量在每次重新進⼊函數的時候不會重新賦值為0,⽽是保留上次退出函數時的值。
②“JUST_INC(key_press_time)”這⼀句,看起來⽤“++key_press_time”就能搞定,但是,誰也不能保證⽤戶真的不會按按鍵超過65秒的啊萬⼀他真的按了65576ms單⽚機還就真的以為⽤戶“短按”了⼀次呢(65576-65536=40ms,屬于短按范疇),下⾯那個短按程序段也會被執⾏現在這樣寫,哪怕你按100年也沒關系了,反正單⽚機就每隔1ms進來看⼀次,K1這個按鈕你想按多久就按多久,掉在范圍內就處理,超出范圍就⽆視。
③“if(key_press_time==3000)”這⾥的3000只是隨便設置的⼀個3秒⻓按時間,如果需要做按鍵⻓短按功能,這⾥就是⻓按程序所放的位置也可以不⽤3000,⽤2000、50000都沒事,別超過65534就⾏。
④“if((20<=key_press_time) && (key_press_time < 3000))”這⾥,前⾯的>=20是短按的消抖設計——再強的⼈類也不可能1秒按⼀個按鍵超過20次,也就是不可能⼩于50ms的時間——這⾥⽤了20ms相當于兼容“超級快男”來按按鍵了。后⾯<3000是不能和⻓按的時間沖突,因為3s我們已經⼈為的設置成⻓按時間節點了。
⑤這⾥的參數遵循乘法原則。舉個例⼦,如果時基是10ms,那么這⾥的if(key_press_time==3000)就會代表30秒,如果想設置⻓按3秒的話,得把3000改成300。


1.3 關于時基的進階設置
回到剛剛討論的時鐘基線處,這⾥有⼏個⼩問題。
(1)假如,1ms的周期不夠把事情做完怎么辦
——那就把時基設置⼤⼀些,⽐如5ms,10ms,20ms,還不夠就該換芯⽚了,要不就是代碼還有很⼤的其他問題,需要好好排查。
(2)我該怎么⼤致估算代碼跑完“⼀系列⼯作”需要的時間,好讓我設置更合適的時基
——好問題這⾥有⼀個簡單且準確的⽅案任意找個閑置端⼝,⽐如P0^0,在⼲活之前先把這個端⼝拉⾼,⼲完活之后⻢上把它拉低,通過外接⽰波器或者邏輯分析儀,就能直觀的測量出耗時了。



(3)只有1個時基不⽅便,我的按鍵只需要10ms采集1次,但是LCD顯⽰我需要100ms才刷新⼀次。
——時基是可以擴展的!在1個時基的基礎上,只要你有需要,完全可以擴展出N多個時基匹配你的N個⼦程序。
⽐如下⾯的代碼,就在1ms的時基上分別擴展出了10ms和100ms的時基:
(4)我的各個函數應該放在哪個時基⾥⾯呢
——這要求我們要對⾃⼰的程序要有清楚的把握,以及⼀定的產品思維,以下是⼀⼰之⻅。
①⾸先,所有的函數都要寫得簡潔⼲凈,不要有任何模塊的delay()加起來超過0.2ms,⼦程序⾥⾯放⼏個nop倒是⽆傷⼤雅。
按鍵,檢測,通信這類的⼦程序放到10ms時基⾥。輸出,顯⽰這類的放100ms時基就OK了。
③1ms時基⾥⾯應該放什么呢可以什么也別放,空著就好;蛘甙阎鞒绦虻幕A時基換成10ms也可以,其實很少有東⻄需要刷新得這么快的。如果基礎時基打算⽤10ms的話,可以將定時器的中斷設置為每10ms觸發(這樣可以刪掉flag1ms變量,此處不展開)也可以偷個懶,原本的程序框架改成這樣即可


④如果有特別需要關照的部分,⽐如說步進電機的驅動啥的,請放到另⼀個定時器中斷⾥(單⽚機基本都⾄少有倆定時器的,不⽤⽩不⽤),按你需要的來設置。
⑤定時器的中斷觸發時間建議不要少于0.5ms,不然進中斷就太頻繁了。
現在,我們的代碼已經初具雛形,⼤家可以⾃⼰搭⼀下這個框架來體驗⼀下。
(當當當,現在是中場休息時間,喝杯⽔吧)







- 第⼆章: 程序之間的解耦 -
通俗點說,耦合度就是表⽰兩個東⻄“你中有我,我中有你”的程度,代碼間的耦合度越⾼,修改代碼就會越費勁。
去耦合,或者說解耦,就是把各個功能從代碼層⾯盡可能的分隔開,當代碼邏輯因為各種原因需要變化的時候,就可以簡單的修改⼀⼩部分,⽽不需要⼤改動。

2.1 從⼀個⻛扇的案例說起
為了⽅便說明,這⾥舉⼀個例⼦,假設我們有個⻛扇項⽬,MCU有這些IO端⼝要連接:
輸入 輸出 顯示
K1開關鍵 風扇電機的開關 1個LED,開機時打開
K2擺頭鍵 擺頭電機 1個LED,擺頭時打開
K3檔位鍵 風扇電機的強弱切換 1個LED,高檔風速時打開

項⽬需求:
產品具有開機和關機2個狀態,關機時所有負載和LED關閉,開機時恢復上⼀次的⼯作狀態,第⼀次開機時默認為低轉速,不開擺頭。斷電后⽆記憶。以下為按鍵功能
開關鍵——切換產品的開關機狀態
擺頭鍵——開機狀態下,可切換擺頭電機開關
檔位鍵——開機狀態下,可切換⻛扇電機的輸出⻛⼒強弱。
基于此需求,我們如果沒有去耦合的概念,可能就會寫出這樣的代碼——






Tip⽆需逐⾏去理解這些代碼,很快它就會被推翻重寫,但請體會⼀下代碼⾼耦合的感覺。
這樣的代碼雖然實現了功能,但耦合度很⾼,它的按鍵、顯⽰、負載程序像蜜糖⼀樣黏糊糊的。呈現這樣的狀態

不過,反正我們都實現了項⽬的功能,測試也統統Pass,如果功能不再改來改去,作為研發你當然可以到點下班,回家打⿇將去。

2.2 完了,需求要改啦
實際上到了⼯作上,你就會發現,功能的改動是很平常且頻繁的事情



在陽光燦爛的⼀個上午,產品經理向你提出了新的需求,并且改動的理由⼗分的充分
①開機之后如果不按開關機鍵,就會⼀直開機,這太危險了——所以,現在我們要把開機分成⽆限⼯作和限時
⼯作兩種模式限時⼯作模式下,LED1是0.5s亮0.5s滅的閃爍狀態,連續⼯作8⼩時都⽆新按鍵按下的話,就⾃
動關機,如果有新按鍵就重新計時⽆限⼯作模式下,LED1是常亮狀態,這個模式下不會⾃動關機,只能⼿動
關機。
②開關機鍵現在修改為兼容⻓短按的功能,1s之內的按鍵視為短按,3s以上視為⻓按。開機時,短按為關機
關機時,短按則進⼊限時⼯作模式,⻓按則進⼊⽆限⼯作模式,兩⼯作模式之間⽆法直接切換。其他按鍵功能
不變。
雖然你還想反問他,⻛扇⼀直開著怎么就危險了,連續⼯作8⼩時怎么就安全了但根據⽃爭經驗,這樣的爭辯
之后,往往會因你⼝技不如⼈⽽失敗(業內常態),還不如省下吵架的功夫來考慮軟件怎么改。
那么,該怎么下⼿呢

2.3 按各個功能來劃分程序
舊代碼太臃腫且耦合了,光是LED閃爍這個功能都夠我們頭疼的,重寫吧。
⾸先,把粘連的模塊分開,按鍵歸按鍵,顯⽰歸顯⽰,輸出歸輸出,就像這樣⼦:

這樣的話,keyPress( ),display( )和output( )三個函數各做各的事情,互不⼲擾,需要共享的信息通過關鍵的變量來傳遞。這⾥我們設置了3個全局變量system_status, swing, speed; 在keyPress( )函數和timeCount( )⾥可以修改這3個變量的值,然后在display( )和output( )函數⾥查詢這3個變量的值來控制顯⽰和輸出。
這時候的代碼結構,就是這樣⼦的——各個模塊分開,⽤關鍵參數傳遞信息

所謂的“解耦”⼤致就是這種感覺,現在你需要在哪⾥改動,就單獨改動哪個部分的,不⾄于瞻前顧后、束⼿束腳了。
現在的display( )和output( )程序彼此之間已經沒有關聯,⼏乎可以不費吹灰之⼒寫出來




剩下的⼯作也簡單,只需要將在keyPress( )和timeCount( )程序⾥,正確的設置好3個關鍵變量的值,我們就
成功的完成了代碼的變動,準點下班也不再是幻想。
⼤家不妨⾃⼰試著寫⼀下(你或許會需要⼀個新的全局變量)。
希望通過這樣⼀個例⼦,⼤家能夠對程序解耦的好處能有清晰直觀的認識。
(當當當,現在是中場休息時間,起來伸個懶腰吧)






- 第三章:⽤狀態機管理系統 -
其實,輕量級的⼩項⽬都可以不上狀態機,直接⼀⼝⽓擼完代碼流程也OK。
不過,這并不代表狀態機不好⽤,只是顯得有點⼤材⼩⽤了,這篇⽂章既然是個教程,所以⽤上狀態機也并⽆不可,那咱們現在就端上⼲貨。



3.1 狀態機是什么
狀態機,其實就是若⼲個“舊狀態 + 觸發條件 = 新狀態 + 額外動作”的公式,⽐如針對我們的新⻛扇需求,我們就可以寫出這些公式
① 關機狀態 + 開關機鍵短按 = 限時⼯作模式 (⽆額外動作,下略)
② 關機狀態 + 開關機鍵⻓按 = 不限時⼯作模式
③ 限時⼯作模式 + 開關機鍵短按 = 關機狀態
……
狀態機就是這些公式的集合。
我個⼈并不喜歡寫公式,更喜歡作圖,如下,是不是更⼀⽬了然⼀些

這個圖直觀展⽰了系統的各個狀態之間是如何跳轉的,各個觸發條件⼜是如何對系統狀態產⽣影響的。
圖⾥畫了多少箭頭,你就能寫出多少個公式。
《狀態遷移》雖然在梳理邏輯的時候很好⽤,但是寫代碼需要參考時,《狀態遷移》⼜更勝⼀籌,如下所
⽰(⽤ - 表⽰⽆作⽤)

狀態0:關機 狀態1:限時工作狀態2:不限時工作
⽆操作 - 計時8⼩時后,轉⼊狀態0 -
K1短按 轉⼊狀態1 轉⼊狀態0   轉⼊狀態0
K1長按 轉⼊狀態2 - -
K2短按 - 切換擺頭開關,且重新計時 切換擺頭開關
K3短按 - 切換檔位⾼低,且重新計時 切換檔位⾼低
左邊第⼀列,表⽰觸發條件;上⾯第⼀⾏,表⽰當前狀態。
⾏與列的交叉點,則表⽰“這個狀態下,假如有這個觸發動作,則會發⽣什么事情”。


3.2 對狀態機需要使⽤的變量進⾏⾃定義
狀態——建議⽤枚舉量表⽰,這是你⾃定義的⼀個變量
觸發條件——建議⽤布爾變量,觸發就是True,沒有觸發就是False
動作——則可以⾃由的根據你的項⽬來設置。
在本項⽬中,狀態機的所使⽤到的變量可以這樣定義

3.3 撰寫狀態機程序
完成了變量定義,接下來就可以寫出真正的狀態機程序。
⾸先,將系統狀態填⼊程序中


然后,根據《狀態遷移表》,⼀點點的填⼊你的狀態遷移公式,最終程序如下



這樣的話,我們的狀態機程序就寫完了。
附帶⼀提,狀態機還有第⼆種寫法,這⾥也展⽰⼀下


第⼀種寫法給⼈的感覺是——“當前正在關機,由于按了開關機鍵,所以現在要開機”。
⽽第⼆種寫法給⼈的感覺就是——“開關機鍵被按下了該怎么辦,查⼀查,嗯現在是關機狀態,所以得開機”。
我個⼈是⽐較喜歡第⼀種寫法的,因為⽐較符合⼈的常規思維當然也有⼀些⼯程師更喜歡后⾯那種,它有時可以節省代碼量。各有所好嘛,這⾥沒必要爭個⾼低了,反正功能都是⼀樣的



3.4 編寫系統⼯作程序的⼀些要點
確定了系統的狀態,就到了系統該真正處理⼯作流程的時候了,不過有些要點。需要提前說明。
(1)建議各位將功能定義與具體的功能實現區分開來。
——這句話是什么意思呢還是舉個例⼦,我們都知道LED燈要么亮,要么滅。也就是在“功能實現”上,它其實只有“亮”和“滅”,兩個值。但是,我們其實在設計⼯作流程的時候,卻可以⾃由設計出常亮,常滅,0.5秒亮1秒滅,2秒亮0.5秒滅,甚⾄是5秒周期的呼吸燈這樣的⼯作流程。后者就屬于⼀個“功能定義”,是可以多種多樣的。
我們的狀態機,只需要關注功能定義就好,具體的⼯作實現,則“外包”給負載的驅動,讓他⾃⼰去控制輸出邏輯變化就好。
也就是說,狀態機不關⼼驅動模塊的⼯作細節,但他需要知道這些模塊有哪些能耐。
基于這樣的思維,程序會出呈現這樣的框架


(2)模塊的變量和狀態機⾃⼰的變量不宜混⽤
⽐如說,b_swing這個變量,是狀態機⾃⼰⽤來記住擺頭的開關狀態的,output()程序最好另外有個屬于他⾃⼰的輸出變量,⽐如這⾥定義⼀個b_out_swing;
為什么因為項⽬需求要我們對開機的狀態進⾏記憶,只有b_swing的情況下,關機的時候到底是清空還是不清空有了b_out_swing,那就簡單得多關機時,b_out_swing為關,開機時,b_out_swing = b_swing,完美。
(3)有關計時的程序可以放進對應的⼦狀態中,⾃⼰慢慢跑。
在《狀態遷移表》中還有⼀⾏“⽆操作”時也要切換狀態的邏輯,屬于計時邏輯,這個邏輯可以放進這個程序中。
關于要點的提⽰就到這⾥,以下是程序。


最后,把systemStateSet()程序和systemStateWork()合并⼀下,就是完整的狀態機模塊了




3.5 使⽤狀態機后,其他函數需要做些調整
如果要⽤狀態機,那么先前在2.3中編寫的display()和output()程序需要重寫keyPress( )函數則是需要刪除⼀些處理邏輯,只保留對b_key1_short, b_key2這類的觸發變量的改值。
為什么因為先前的代碼,是從底層追朔到頂層的編寫模式
這些驅動要需要怎么樣來控制這些LED和負載呢——取決于系統有哪些狀態,所以display()和output()做了什么事情呢他去訪問了system_status這個變量
⼀個驅動,居然去訪問系統狀態


這相當于⼀個⽼板的專屬司機,⽆時⽆刻追著⽼板問領導要不要出⻔,要出⻔他就去準備⻋,不出⻔司機就balabala……
正確的邏輯,應該是這個司機等⽼板給他發命令。他⾃⼰知道⾃⼰能做那些事,⽼板也知道。但是司機不能去打探⽼板在⼲嘛,畢竟他只是個driver。
既然決定了要⽤狀態機,要讓程序變得進⼀步的層次分明,就得快⼑斬亂⿇的放棄原本為了偷懶⽽⾛的捷徑。
output程序現在要這樣寫:


類似的,display( )程序


經過調整之后,我們的軟件代碼變得主次分明。未來如果再有其他的變動,我們都可以輕松的劃分責任,來僅對有必要的部分進⾏修改。

(當當當,正⽂已經結束了,起來上個廁所吧)


附文:從零使用STM32F103C8T6,構建文章中的風扇項目
帖子寫不下了,大家自己下載文檔來看這個附文吧。

感謝你的閱讀。
祝⼤家萬圣節快樂。
—— 【51黑】 Similarv ,Oct 30. 2025
(全⽂完。如需轉載,請標明出處。)




1.截至2025年10月的點擊量.png (39.4 KB, 下載次數: 0)

1

1

請優化你的代碼-附件程序F103.7z

684.3 KB, 下載次數: 0, 下載積分: 黑幣 -5

請優化你的單片機代碼.pdf

3.22 MB, 下載次數: 0, 下載積分: 黑幣 -5


作者: Similarv    時間: 2025-10-30 20:43
本帖最后由 Similarv 于 2025-11-3 08:57 編輯

全文共有3頁,請手動翻頁。
另外,附件的排版應該比網頁的排版干凈。
由于不可抗力,從第5個代碼塊開始,網頁端po出的代碼就開始出現亂碼,我重復編輯了很多次,都無法解決。因此后面很多代碼塊都變成了圖片格式,影響了大家的閱讀,望諒解。

作者: Similarv    時間: 2025-10-30 20:47
終于整完了,這次特意在換工作的空窗期,抽出時間完成了這個主題。大家萬圣節快樂。


祝我明天面試順利,嘻嘻。

作者: hange_v    時間: 2025-10-30 22:40
這樣不好嗎void ledTask(void)
{
    static u32 usBck = 0, usNow = 0;
    static u8 sta = 0;

    usNow = mSysTimerGetUs();
    if((usNow - usBck) > 250000)
    {
      usBck = usNow;
      sta = (sta == 0) ? 1 : 0;
      if(sta == 0)
      {
        LED_RUN_OFF; LED_STOP_OFF;
      }
      else
      {
        LED_RUN_ON; LED_STOP_ON;
      }
}

作者: Similarv    時間: 2025-10-30 22:59
hange_v 發表于 2025-10-30 22:40
這樣不好嗎void ledTask(void)
{
    static u3 ...

你好,請問這是在?
作者: MCU2023    時間: 2025-10-31 04:49
非常不錯,謝謝小豬豬的指導:D,收藏了!
作者: hange_v    時間: 2025-10-31 09:15
發表于 2025-10-30 22:59
你好,請問這是在?

閃爍LED  250ms
作者: Similarv    時間: 2025-10-31 16:48
hange_v 發表于 2025-10-31 09:15
閃爍LED  250ms

我推測,這段代碼只能保證“LED不會在250ms以內就翻轉電平”,并不能確保剛好總是250ms的時候就立馬翻轉。
作者: hange_v    時間: 2025-10-31 20:46
Similarv 發表于 2025-10-31 16:48
我推測,這段代碼只能保證“LED不會在250ms以內就翻轉電平”,并不能確保剛好總是250ms的時候就立馬翻轉 ...

那得做到定時器中斷,且優先級最高
作者: 莫燁    時間: 2025-10-31 22:16
感謝大師分享
作者: wbwcf13e    時間: 2025-11-1 07:21
這得好好學習一下!
作者: suixilpc    時間: 2025-11-1 15:24
謝謝分享
作者: suixilpc    時間: 2025-11-1 15:28
真的學到很多知識,再次謝謝
作者: lxh0508    時間: 2025-11-2 14:57
寫的真好
作者: lipen2008    時間: 2025-11-2 18:07
大神終于有更新了,受教了。
作者: jiangweich    時間: 2025-11-2 20:45
寫得很好
作者: jjwangxu2008    時間: 2025-11-2 23:33
[em05]
作者: maqykk    時間: 2025-11-3 07:44
好貼,學習了!
作者: dcc60    時間: 2025-11-3 09:51
樓主說的全部中招
作者: xuer0921    時間: 2025-11-3 18:53
感謝大佬的教程,已保存,慢慢研究!
作者: pxhxkij    時間: 2025-11-6 16:45
非常感謝樓主的付出。雖然我是小小小小白,只會復制別人的代碼
作者: mashuiyou    時間: 2025-11-7 08:19
非常不錯,謝謝指導!
作者: mashuiyou    時間: 2025-11-7 08:20
非常不錯,謝謝指導!
作者: zxq9781    時間: 2025-11-8 22:27
真的學到很多知識,再次謝謝
作者: zenghl    時間: 2025-11-9 20:24
大神終于有更新了,受教了。
作者: ldc2000    時間: 2025-11-13 02:22
菜鳥一枚,現在的能寫出的都是讓大神惡心的代碼
作者: hyzqq    時間: 2025-11-13 23:06

非常感謝樓主的付出。
作者: dyx811    時間: 2025-11-13 23:42
學習了大師的編程思維!真的受益良多!非常感謝!
作者: Similarv    時間: 2025-11-14 14:06
dyx811 發表于 2025-11-13 23:42
學習了大師的編程思維!真的受益良多!非常感謝!

大師不至于,這是一個面向新手的教程,目的是讓大伙起步的時候少走一些彎路。
至于怎么成為大師,我自己也在摸索前進。
作者: dcc60    時間: 2025-11-17 10:27
新手表示看不懂啊。
如果要設計一個短按與長按的函數,是直接讓定時器計時嗎?
作者: Similarv    時間: 2025-11-17 11:46
dcc60 發表于 2025-11-17 10:27
新手表示看不懂啊。
如果要設計一個短按與長按的函數,是直接讓定時器計時嗎?

你的主程序是每10ms才跑一次的,靜態變量的計數值就是計時值
作者: SHANWAZI    時間: 2025-11-17 11:49
又學習了
作者: kkfy888    時間: 2025-11-17 14:07
謝謝分享,學習優化
作者: wdgao    時間: 2025-11-17 22:47
有個問題想請教:文中提到“不要有任何模塊的delay()加起來超過0.2ms”,但對于數碼管動態掃描如何控制每個數碼管點亮2ms?
作者: Similarv    時間: 2025-11-17 23:13
wdgao 發表于 2025-11-17 22:47
有個問題想請教:文中提到“不要有任何模塊的delay()加起來超過0.2ms”,但對于數碼管動態掃描如何控制每 ...

個人建議你用低優先級的定時器中斷,2ms周期掃一下
作者: libin1009    時間: 2025-11-18 10:01
非常不錯,值得學習一下!
作者: wdgao    時間: 2025-11-19 07:07
發表于 2025-11-17 23:13
個人建議你用低優先級的定時器中斷,2ms周期掃一下

謝謝指導,是個好辦法。
作者: 亙古飛揚    時間: 2025-11-29 08:21
很好的編程思維,值得學習。
作者: 3wjkdhus    時間: 2025-11-30 12:13
能不用阻塞延時就不用
作者: ly_zhy    時間: 2025-12-2 18:43
真不錯,學習了!
作者: 三極管一樣的人    時間: 2025-12-3 14:13
想不到九年后還能看到更新版,上網這么多年,難得少見了。
作者: 手機刷機菜鳥    時間: 2025-12-9 12:15
這個真是厲害,又學習了

作者: xhbert    時間: 2025-12-16 09:52
只有我一個人看到的是方框嗎
作者: cqycqy666    時間: 2025-12-17 15:48

非常不錯,值得學習一下!




歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1