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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

前言:前段時(shí)間分享的文章【單片機(jī)裸機(jī)代碼框架設(shè)計(jì)思路】,很多讀者給我留言,覺得很不錯(cuò),對(duì)于初學(xué)者而言,這是一個(gè)進(jìn)階的技巧,對(duì)于我而言,這是對(duì)自己總結(jié)和表達(dá)能力的一個(gè)提升。

本文章我們再談?wù)剢纹瑱C(jī)代碼的模塊化設(shè)計(jì)思想是如何設(shè)計(jì)的。之前的【單片機(jī)裸機(jī)代碼框架設(shè)計(jì)思路】文章為了盡量簡潔的表達(dá),我?guī)缀跛写a都放在了main.c中,這個(gè)在實(shí)際項(xiàng)目中,或者說當(dāng)任務(wù)比較多的時(shí)候,幾乎是不太現(xiàn)實(shí)的。

模塊化設(shè)計(jì)的目的是讓代碼高內(nèi)聚,低耦合,是為了降低程序復(fù)雜度,使程序設(shè)計(jì)、調(diào)試和維護(hù)等操作簡單化

第一點(diǎn):單獨(dú)的功能模塊各自獨(dú)立建立xxx.c和xxx.h文件

這一點(diǎn)相信大家可能都知道,因?yàn)?1單片機(jī)的書都有講,如果您已經(jīng)知道了,請(qǐng)?zhí)^第一點(diǎn)。

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

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

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

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

可以看出:timer0.c包含了3個(gè)常用函數(shù),和1個(gè)定時(shí)器結(jié)構(gòu)體變量,定時(shí)器中斷是放在interrupt.c里面

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

為什么使用TIMER_VALUE來代替T5ms時(shí),是因?yàn)槿绻皇褂眠@個(gè)宏,那么定時(shí)器初始化的時(shí)候要給TL0/TH0賦值T5ms,在定時(shí)器中斷函數(shù)中還要賦值一次,我需要改動(dòng)兩個(gè)地方,中斷賦值很容易被忽略掉,所以使用TIMER_VALUE宏定義代碼,我就可以只需要改T5ms就可以一次性更改定時(shí)器中斷的時(shí)間。

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

task.c包含裸機(jī)代碼框架中功能所有代碼,心跳函數(shù),初始化任務(wù),啟動(dòng)任務(wù),停止任務(wù)還有任務(wù)處理函數(shù)

task.h代碼如下:包含任務(wù)的數(shù)組定義等等

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

這個(gè)范例代碼比較簡單,只有1個(gè)定時(shí)器的中斷函數(shù),如下所示

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

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

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

第二點(diǎn):結(jié)構(gòu)化封裝外設(shè)

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

我們現(xiàn)在把定時(shí)器0就當(dāng)做一個(gè)外設(shè),

[1]、在外設(shè)對(duì)應(yīng)頭文件中,比如timer0.h中,聲明一個(gè)結(jié)構(gòu)體變量類型,如下圖圖所示,里面包含了3個(gè)函數(shù)指針,也可以在結(jié)構(gòu)體中定義變量,比如浮點(diǎn)數(shù),比如數(shù)組等等。不過定時(shí)器用不著。這里就只有函數(shù)指針了。

[2]、在外設(shè)對(duì)應(yīng)的源文件中,比如timer0.c中,定義一個(gè)Timer0_t類型的結(jié)構(gòu)體變量,并同時(shí)賦值,注意順序不能錯(cuò),因?yàn)榍懊娑x的是函數(shù)指針,所以我們只需要用對(duì)應(yīng)的函數(shù)名稱賦值就好,這種做法,也可以稱呼為注冊回調(diào)函數(shù).這些回調(diào)函數(shù)因?yàn)槭峭ㄟ^結(jié)構(gòu)體變量來調(diào)用,所以前面請(qǐng)加static修飾,表示只能在本文件中使用,如果是其他文件要使用,請(qǐng)直接通過結(jié)構(gòu)體變量來調(diào)用,這就達(dá)到了封裝的目的。

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

[3]、在外設(shè)對(duì)應(yīng)頭文件中,請(qǐng)一定寫上 externTimer0_t timer0,表示外部文件可以調(diào)用 timer0結(jié)構(gòu)體。

[4]、如果需要調(diào)用定時(shí)器的這些函數(shù),只需要通過timer0結(jié)構(gòu)來調(diào)用,如下所示,timer0.Init(TIMER_VALUE),

另外,VS Code的智能補(bǔ)全非常棒,你只需要輸入結(jié)構(gòu)體變量timer0.里面的函數(shù)或變量全部都出來了,如果這樣封裝,那么編輯代碼體驗(yàn)也很棒。

根據(jù)結(jié)構(gòu)體封裝的思想,我再多舉兩個(gè)例子,假如對(duì)DHT11溫濕度傳感器進(jìn)行封裝,封裝哪些會(huì)比較合理呢?如下所示

計(jì)算的濕度和溫度浮點(diǎn)數(shù),必不可少。

單總線40bits源數(shù)據(jù),根據(jù)實(shí)際需求,如果你是和上位機(jī)通信,也必須發(fā)送這個(gè)源數(shù)據(jù),那么就封裝在這里,如果不需要,可以不封裝。

讀取濕度和溫度的函數(shù)必須要封裝.

調(diào)用的時(shí)候,就可以通過如下方式,通過串口打印出源數(shù)據(jù)和計(jì)算后的溫濕度數(shù)據(jù)

喜歡這篇文章,幫忙點(diǎn)個(gè)“關(guān)注 + 收藏”哦,謝謝

本文章的例子是基于STC89C52單片機(jī)來調(diào)試的,想獲取源碼,請(qǐng)“”關(guān)注 + 收藏“后,私信給我,發(fā)送文字 [單片機(jī)代碼模塊化設(shè)計(jì)思想淺談]。

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。