|
發布時間: 2019-6-6 11:48
正文摘要:- 前言 - 時至今日,依舊看到很多小伙伴們放著單片機里的定時器不用,動輒delay1s(); delay500ms();雖然簡單粗暴,但是其實是很不妥當的。還有很多需要按鍵的程序,動不動就“while(k1==0);”的等按鍵松開,這樣 ... |
|
如果有需要,我可以把相關的主程序和架構打包上傳……不過說實話這些代碼隨便敲敲就有了,需要鍛煉的是一種“精準控制”軟件的邏輯的思維。 跑快了的東西我們把它放慢些,跑慢了的東西給它放快些。 對于一個系統來說,“平衡”是很重要的事情。 最后再說一句,while(1)大循環里面不要放“delay();”或者“while(按鍵被按下);”了…… ![]() |
很抱歉的告訴大家,之前的想法還是太樂觀,現在每天忙成狗,完全不確定啥時候能抽時間寫完,7月15日要是沒有更新的話還請大家諒解。![]() ![]() ![]() 不過我是不會就這么停筆的,只是不知道啥時候有時間寫而已。作為打工仔,真的身不由己。 為了不辜負大家的期待,下次更新時我會把文檔做成pdf,附帶源碼,流程圖,表格一并上傳。 ![]() ![]() ![]() 其實還有很多可以寫的地方,但是現在這篇帖子就寫這3點——時基,模塊化,狀態機——已經夠大家消化一陣子了。而且,如果帖子的篇幅太長了,其實不利于閱讀的。 以后如果還有別的分享,我會另開帖子的,多蹭點管理員的黑幣,哈哈。 ![]() ![]() ![]() |
ccdmcu 發表于 2019-8-2 16:22 我不是給了個keyPress()程序么,你再好好看看。 簡單來說,有鍵按下時,時間就會++; 無鍵按下時,時間就會清零。 但在清零之前會先檢查,時間是否大于0,時間值大于0(或者消抖值)說明曾經有鍵按下過,并且剛剛松開。這時候處理“這次按鍵”不就好了。 |
| 樓主這文章比那些所謂的教科書好多了,那些教科書按鍵消抖動不動就是delay(20ms),真是誤人子弟,真正出來做到大型項目才知道 DELAY是多么不實際。希望樓主繼續更新,最好轉成PDF,多點例程,尤其是一些按鍵的,短按,長按,雙擊組合鍵例程。現在絕大部份寫按鍵程序都喜歡delay消抖,while松手檢測。郭天詳的書也是這么教的,一點不實用 |
laishu12345 發表于 2019-8-9 17:08 確實不會“小于”0,但“等于”0是有可能的喔,所以這樣寫是沒問題的。 至于為什么我寫了“<=",而不是”==“呢? 理由是 —— 容錯機制: 萬一手殘了,在定義key_press_time的時候忘記加了unsigned,我們的按鍵程序照樣可以正常工作(只是計數最大值只有原來的一半了) |
本帖最后由 Similarv 于 2019-8-15 10:40 編輯 IdeaMing 發表于 2019-8-14 10:27 這個好說,把基礎時基變成10ms(或者20ms),也就是定時器中斷10ms(或者20ms)產生一次。 然后就是……
|
IdeaMing 發表于 2019-8-16 16:25 我剛剛特意去查了一下,這玩意僅僅是個溫度傳感器,而且還特么是數字的,讀一次溫度居然至少要5Ms?!(還不確定是否會更久) 這樣,如果你有示波器的話,請你做這么一個實驗,把單片機某個端口設為輸出,這個端口平時是低電平,然后用18b20讀取溫度之前拉高它,讀取結束的時候又拉低它,然后用示波器好好的看看這個端口被拉高的時間,你就知道它每次采溫需要多長時間了。再結合其他子程序的工作時長,設計你的時基。 其實,這種數字型溫度傳感器在我們實際做項目的人的眼里,只有華而不實四個字可以評價。如果我們的項目里需要測溫,我們一般會采用內部自帶adc模塊的單片機,測溫只要一個熱敏電阻就可以搞定。整個測溫的時間只需大約10us。不但更便宜,精度更好,效率還是你那個測溫模塊的500倍!具體方案這里就不贅述了。 |
本帖最后由 Similarv 于 2020-1-13 18:07 編輯 13303022280 發表于 2020-1-7 14:29 你的做法當然也沒有問題,不過我是這么做的: 按鍵就只是做按鍵檢測,并且設置相應的“按鍵已觸發”標志(bit變量);至于按鍵的功能則是在別處比如狀態機中去執行。 例子:當按鍵按下之后開/關燈 key.c 文件: bit key_flag_light; //當按鍵觸發時為1,否則為0, 此變量是給狀態機使用的 static bit key_press_light; //當按鍵按下時為1,未按下為0,此變量僅在key.c內使用。 函數1-keyScan() -- 功能:檢測按鍵是否按下,若按鍵按下則將key_press_light置一,否則清零。 函數2-keyDeal() -- 功能:使用某靜態變量統計key_press_light的時間;當key_press_light從1變為0的時候,檢查靜態變量的值是否大于消抖值,若大于消抖時間則將key_flag_light設置為1; state.c文件 函數1-StateMachine() -- 功能:當key_flag_light==1時,取反led_flag_out的值,隨后將key_flag_light設置為0. led.c文件 bit led_flag_out; //當該值==1,開燈;當該值==0;關燈 函數1-ledOutput() -- 功能:根據led_flag_out的取值開燈或者關燈 main.c文件 在10ms或者20ms的時基中依次調用 keyScan(); keyDeal(); StateMachine(); 在100ms的時基中調用 ledOutput(); /******/ 稍微修改一下,剛剛沒有認真審題,你需要做長按的判定,我這個架構是基于短按的。 修改的地方位于keyDeal()部分, 短按 —— 是等待按鍵松開時裁決靜態變量的計時值。 長按 —— 則是直接在靜態變量等于‘長按時間點’的時刻將key_flag_light置一即可。key_flag_light==1的時候,狀態機自然會處理長按事件,此后keyDeal()里的靜態變量會在按鍵繼續按著的時候繼續加,但其值已經‘大于’‘長按時間點’了,所以key_flag_light不會被重復置一,當按鍵釋放之后,此靜態變量清零,一切重新開始。 |
hubj627 發表于 2020-1-13 09:20 進階教程尚待壇友們自己修行,鄙人不才,只能帶路到這了 ![]() |
|
V2版本的新帖子鏈接: http://www.denmoz.com/bbs/dpj-241462-1.html 祝大家節日快樂 ![]() |
|
很好學 說的通俗易懂 點贊點贊 |
Similarv 發表于 2019-8-12 11:46 厲害很厲害 很有幫助 |
13327291097 發表于 2019-6-6 20:53 是的,真的很受用,感謝博主 |
| 絕世好帖! |
| 好貼,多謝樓主分享,學習了 |
kissme 發表于 2026-2-1 10:17 嚴格地說,這不是在延時,只是在“計時”。 在這里的代碼中,假如計時未到,系統會去做別的事。 如果你用了delay,系統則是卡死在delay中。 |
很不錯的文章,繼續學習中![]() |
| 只看懂了部分,具體看來還需要實踐 |
| 很好的技術文章,小白的寶藏老師 |
|
不懂就問: id keyPress(){ 02. static unsigned int key_press_time = 0; // ……請記得標為靜態變量 03. if(K1==0){ 04. if(++key_press_time <=0 ) --key_press_time;//計量按鍵時間,并避免數據溢出 05. if(key_press_time==3000){ 06. //在此寫下按鍵長按3s時要做的事情; 這不也是在延時么?那么跟DELAY(300)有啥原則上的區別?? |
goodgoodgood 發表于 2026-1-5 06:08 V2版本的新帖子鏈接: http://www.denmoz.com/bbs/dpj-241462-1.html 已經更完所有內容,謝謝支持 |
很好的文章,請繼續。感謝!![]() |
| 很好的文章,請繼續。感謝! |
| 很好的文章,請繼續。感謝! |
| 很好的文章。 |
| 贊一個! |
| 真的是好文章,對51定時器的理解更深了,原來程序還能這么寫 |
| 這個不錯啊 |
本帖最后由 Similarv 于 2025-11-11 11:35 編輯 wmt333 發表于 2025-7-3 07:19 : http://www.denmoz.com/bbs/dpj-241462-1.html本貼已經被置頂,因此無法再編輯正文了。 V2.0帖子內有pdf文檔和工程文件,感謝支持。 |
| 這個框架好 |
| 好文章,開拓新思路,奠定優秀的未來 |
|
真的是好文章,對51定時器的理解更深了,原來程序還能這么寫 |
| 學習良好的編程習慣,感謝樓主的付出!。 |
| 真的是書上看不到的技術文章~~ |
| 寫得太好了 |
| 真厲害 |
|
好文章,不知樓主能否弄成pdf格式上傳呢,想保存起來!!! |
|
不錯學習了 |
| good! |
| 絕世好貼! |
|
很好 |
| 感謝分享 |
| 這是教的程序整體架構,對于裸機(沒有操作系統)開發是堪稱經典的教程。 |
|
學會了,謝謝樓主 |
| 我是白菜,這個思路一下子就打開了我的思維,大多教程都是老的那一套,感謝大神的分享!! |
秒啊,好文![]() |
必須收藏了好吧![]() |
真不錯,有耳目一新的感覺。![]() |
幾年前的貼子怎么沒有留意到呢,點了好幾年的燈,看來有望進階八級點燈大師啦![]() |