日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

单片机sleep函数的头文件_单片机代码模块化设计思想浅谈

發布時間:2023/12/2 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单片机sleep函数的头文件_单片机代码模块化设计思想浅谈 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:前段時間分享的文章【單片機裸機代碼框架設計思路】,很多讀者給我留言,覺得很不錯,對于初學者而言,這是一個進階的技巧,對于我而言,這是對自己總結和表達能力的一個提升。

本文章我們再談談單片機代碼的模塊化設計思想是如何設計的。之前的【單片機裸機代碼框架設計思路】文章為了盡量簡潔的表達,我幾乎所有代碼都放在了main.c中,這個在實際項目中,或者說當任務比較多的時候,幾乎是不太現實的。

模塊化設計的目的是讓代碼高內聚,低耦合,是為了降低程序復雜度,使程序設計、調試和維護等操作簡單化

第一點:單獨的功能模塊各自獨立建立xxx.c和xxx.h文件

這一點相信大家可能都知道,因為51單片機的書都有講,如果您已經知道了,請跳過第一點。

下面以之前的文章單片機裸機代碼為例進行說明:如下圖所示

我把功能代碼分成了4大塊:

  • 定時器功能代碼:timer0.c、timer0.h
  • Task裸機框架功能代碼:task.c、task.h
  • 中斷函數功能代碼:interrupt.c、interrupt.h(任務很少,也可以不分出來,看具體情況)
  • 公共函數功能代碼:public.c、public.h(存放一些公共的函數和全局變量)

(1)定時器功能代碼:timer0.c、timer0.h

可以看出:timer0.c包含了3個常用函數,和1個定時器結構體變量,定時器中斷是放在interrupt.c里面

timer0.h包含一些常用的宏定義,和結構體變量類型定義,對于常用的2ms/5ms/10ms定義初始值,可以使用宏定義,修改起來就會很方便,如下所示,這是一個小技巧

為什么使用TIMER_VALUE來代替T5ms時,是因為如果不使用這個宏,那么定時器初始化的時候要給TL0/TH0賦值T5ms,在定時器中斷函數中還要賦值一次,我需要改動兩個地方,中斷賦值很容易被忽略掉,所以使用TIMER_VALUE宏定義代碼,我就可以只需要改T5ms就可以一次性更改定時器中斷的時間。

(2)Task裸機框架功能代碼:task.c、task.h

task.c包含裸機代碼框架中功能所有代碼,心跳函數,初始化任務,啟動任務,停止任務還有任務處理函數

task.h代碼如下:包含任務的數組定義等等

(3)中斷函數功能代碼:interrupt.c、interrupt.h

這個范例代碼比較簡單,只有1個定時器的中斷函數,如下所示

(4)公共函數功能代碼:public.c、public.h

存放公共函數,比如禁止總中斷,使能總中斷,軟件延時函數等等

要特別提到的一點,這是一個小技巧:public.h包含所有外設的頭文件和常用的C語言庫頭文件,這樣做的好處是,只需要修改這一個地方,其余.c文件只需要包含一條include "public.h"就可以了。

第二點:結構化封裝外設

這個才是本文章我想提到的重點,對于一般初學者而言,可能寫的最多的就是Timer0_Init(); 然后和Timer0_ISR() 函數,然后main.c調用就完事了。這種寫法的確簡單,也好理解,但是如果你的外設特別多,如果還有ADC,傳感器,等等,你需要定義全局變量傳遞參數時,外設越多,那么全局變量就越多,后續修改起來,你就會發現太痛苦了,能把功能實現就不錯了。

我們現在把定時器0就當做一個外設,

[1]、在外設對應頭文件中,比如timer0.h中,聲明一個結構體變量類型,如下圖圖所示,里面包含了3個函數指針,也可以在結構體中定義變量,比如浮點數,比如數組等等。不過定時器用不著。這里就只有函數指針了。

[2]、在外設對應的源文件中,比如timer0.c中,定義一個Timer0_t類型的結構體變量,并同時賦值,注意順序不能錯,因為前面定義的是函數指針,所以我們只需要用對應的函數名稱賦值就好,這種做法,也可以稱呼為注冊回調函數.這些回調函數因為是通過結構體變量來調用,所以前面請加static修飾,表示只能在本文件中使用,如果是其他文件要使用,請直接通過結構體變量來調用,這就達到了封裝的目的。

很多人不明白回調函數,這里簡單提一下,將函數名稱作為參數傳遞給函數指針,通過函數指針來調用該函數的功能,賦值的過程,就是注冊回調函數.如果不注冊,那么函數指針為null,指向空地址,就會出問題,我們定義的這個函數就是回調函數。

[3]、在外設對應頭文件中,請一定寫上 externTimer0_t timer0,表示外部文件可以調用 timer0結構體。

[4]、如果需要調用定時器的這些函數,只需要通過timer0結構來調用,如下所示,timer0.Init(TIMER_VALUE),

另外,VS Code的智能補全非常棒,你只需要輸入結構體變量timer0.里面的函數或變量全部都出來了,如果這樣封裝,那么編輯代碼體驗也很棒。

根據結構體封裝的思想,我再多舉兩個例子,假如對DHT11溫濕度傳感器進行封裝,封裝哪些會比較合理呢?如下所示

計算的濕度和溫度浮點數,必不可少。

單總線40bits源數據,根據實際需求,如果你是和上位機通信,也必須發送這個源數據,那么就封裝在這里,如果不需要,可以不封裝。

讀取濕度和溫度的函數必須要封裝.

調用的時候,就可以通過如下方式,通過串口打印出源數據和計算后的溫濕度數據

喜歡這篇文章,幫忙點個“關注 + 收藏”哦,謝謝

本文章的例子是基于STC89C52單片機來調試的,想獲取源碼,請“”關注 + 收藏“后,私信給我,發送文字 [單片機代碼模塊化設計思想淺談]。

總結

以上是生活随笔為你收集整理的单片机sleep函数的头文件_单片机代码模块化设计思想浅谈的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。