<track id="x7t9b"></track><delect id="x7t9b"><ins id="x7t9b"></ins></delect><noframes id="x7t9b">

    <form id="x7t9b"></form>

        <track id="x7t9b"><del id="x7t9b"><ins id="x7t9b"></ins></del></track>

        <form id="x7t9b"><i id="x7t9b"><b id="x7t9b"></b></i></form>
        <output id="x7t9b"><ruby id="x7t9b"></ruby></output>

        新聞中心

        誠邀各行業優秀的合作伙伴與博安通一起共建生態

        【外設移植】使用M61開發板驅動AHT20溫濕度傳感器

        2024-02-20

        15
        分享

        本作品由安信可社區用戶

        1084504793制作

        在智能家居和工業控制等多個場景下都會需要一款體積小巧且可以通過電信號快速獲取指定地方溫濕度、光照強度和磁場強度等的模塊。常見的溫度模塊有DS18B20和DHT11等。這些模塊大多數是通過單總線的通信方式進行通信,單總線通信方式的優點是占用MCU的I/O口資源非常少,只需要一根數據線便可進行通信,而且總線下可以掛載多個器件獲取不同的數據。但是其最大的缺點是通信速率不能太高,一般是16.3Kbps,最大可達142Kbps,通常是在100Kbps下進行通信。這樣就會限制總線下的從設備的數量。

        1980年飛利浦發明了集成電路總線,即IIC。IIC相對于單總線通信來說增加了時鐘線(SCL)。在通信速率上IIC的速率可以達到3.4Mbps,但是一般都是使用快速模式的400Kbps先進行通信,因為在該速率下擁有相對較遠的通信距離。IIC的最遠通信距離可以達到15M,當然通信速率也是要用更小的模塊確保數據傳輸的有效性。IIC因其占用引腳資源少,邏輯電平也與MCU的邏輯電平一致,通信速率范圍也比較廣,代碼移植簡單等優點,一直是MCU必備的外設通信模塊。因IIC的控制電路簡單且成本低,所以有很多的小數據量的模塊都是采用IIC進行通信。如本文要介紹的AHT20溫濕度傳感器。

        01

        AHT20參數介紹

        AHT20模塊如下圖所示:

        AHT20溫濕度傳感器是AHT10的升級款。相對于AHT10來說,AHT20主要在芯片體積和供電電壓寬度做了提升。AHT20芯片的體積更小,供電電壓寬度更大,供電電壓支持2.2-5.5 VDC。

        AHT20的電氣特性如下:

        電氣特性表中最重要的一點是其供電電壓。因為有些模塊的供電電壓最大值小于5V,而我們會因慣性思維而直接給模塊的VCC接5V,這樣會燒毀模塊芯片。因AHT20的供電電壓最大值為5.5V,所以可以用5V進行供電。

        AHT20的溫度特性如下表所示:

        上圖中顯示精度誤差典型值為±0.3,可見其精度值可以滿足一些常見的開發需求的。工作范圍-40至80℃也是和MCU(一般是-40至85℃)基本一致的。

        溫度典型誤差和最大誤差如下:

        從圖中可以看出當溫度處于極限值(-40或80℃)時,誤差值最大,但是最大不會超過2℃。

        濕度特性表如下:

        從表中可以看出其工作范圍為0至100%,完全滿足研發需求。誤差典型值也是±2,相對于人而言誤差影響基本感覺不到。

        25℃時相對濕度的誤差如下圖:

        同樣是在極值的情況下,誤差值會比較大。

        02

        AHT20接線方式

        AHT20與MCU的通信方式為標準的IIC通信。官方給的接線方式如下:

        這里用的是已將SCL、SDA、VCC和GND引腳引出來的開發模塊,所以只需要用杜邦線將M61開發板與模塊連接好就行,連接示意圖如下:

        若是需要重新畫PCB板,芯片的各個引腳說明如下:

        03

        AHT20驅動編寫

        需要注意的是,手冊上也寫明在芯片上電后的5ms之后才可以設置SCL和SDA為高電平。這個在后續的代碼驗證中,個人認為M61上電后經過board_init初始化后再初始化IIC引腳是可以的。若大家在使用的時候發現有問題,可以在初始化board_init后延時5ms再初始化IIC的引腳。

        若大家用自己寫IIC驅動的時候,記得一定要注意一下AHT20支持的IIC速率,因為在IIC通信過程中,若SDA的電平保持時間過短則會出現AHT20不能收到正確的指令,從而導致無法讀取到數據。IIC通信的一些參數如下所示:

        但是本文檔會用博流SDK的IIC驅動介紹如何與AHT20進行通信獲取溫濕度數據。

        AHT20的IIC設備地址用的是八位即一個字節來表示。由于AHT20沒有硬件地址(通過芯片引腳說明中可以看出沒有地址引腳A[0:2]),所以在給AHT20發送地址時固定值為0x38(忽略讀寫位)。也說明同一個IIC總線下只能接一個AHT20模塊或者說不能接其他設備地址為0x38的模塊,否則訪問0x38設備時接收到的數據會異常。官方給的IIC地址字節解析如下圖所示。

        設備地址的最低字節表示對設備進行讀還是寫的操作,一般最后一位為低電平(邏輯為0)時為寫指令,為高電平(邏輯為1)時為寫指令。在用官方給的IIC發送讀寫指令時,我認為結構體中bflb_i2c_msg_s的元素addr為包含讀寫指令的地址,所以在賦值時把讀寫指令的位也包含在內。但是官方的用意是只需要告訴設備的高七位的地址值就可以了,在發送設備地址時會自動在地址的最后一位加一位讀寫控制位。所以addr需要賦值為0x38。

        AHT20的驅動代碼文件主要是AHT20.c和AHT20.h。AHT20.c主要定義的是有關AHT20控制函數的定義;AHT20.h主要是指令的宏定義,狀態的枚舉和函數的聲明等。

        數據傳輸是有發送和接收數據的,一般將發送數據和接收數據封包成兩個函數來實現,所以我也封成兩個讀寫函數。

        首先是發送數據函數,函數定義代碼如下:

        其中參數有指令內容_Cmd,發送數據指針*Sendbuf和發送長度_length。改函數可以滿足任意長度的數據發送。當長度為0時,只發送設備地址和命令字;若長度不為0,則發送完設備地址和指令后也會發送數據內容,且中間沒有任何的停止信號。自己在調試過程中也發現,官方IIC的發送數據是有握手的判斷。在發送地址后,若沒有收到握手信號,則不會繼續發送數據。結構體中的flags元素決定著這些數據發送完成后是否會發送一個終止信號。若賦值為0(.h文件是沒有定義的,但是論壇教程都有說明的),則在發送完數據后產生一個停止位;若賦值為I2C_M_NOSTOP,則發送完數據后不會產生一個停止位。其他的參數賦值都是比較簡單的,在此不做過多的介紹。

        接下來是接收數據函數,函數定義代碼如下:

        函數比較簡單,參數為接收數據保存的指針*Recbuf和接收長度_length。

        AHT20的各個命令及解釋說明如下,我們在控制AHT20也是通過發送這些指令進行控制。

        針對這些指令我在ATH20.h進行一些宏定義,宏定義如下:

        官方也給了芯片正常工作的整個流程,官方給的流程如下:

        在看完如何驅動AHT20的官方流程后可以先不要著急寫驅動函數,因為這個描述比較片面,還無法寫。

        設備返回值的說明如下

        其中表中說明接收的數據為一個字節,bit[3]為校準使能位,該位說明AHT20芯片是否校準過,一般在出廠后都是進行校準過的,校準后該位便一直為1;bit[7]為AHT20狀態位,這位比較重要,說明數據是否采集成功,只有數據采集成功后,設備處于空閑狀態,該位為0,表明可以讀取數據。在這里可以先寫一個返回值判斷的函數,函數代碼如下:

        函數返回值是一個枚舉值,在AHT20.h文件中有定義,定義如下:

        該函數首先是讀取一個字節的數據,然后與0x68做相與計算,最后判斷是否與0x08相等。其實是判斷bit[7]是否為0,bit[3]是否為1。在自測的時候發現AHT20返回的空閑且已校準的狀態值不是0x08,而是其他位也是有1的,所以與0x68做與運算,濾掉其他位的影響。

        官方給的溫濕度讀取流程如下所示:

        在這里就可以寫AHT20的驅動函數了,也可以結合那些指令分裝成不同功能的函數。首先是AHT20初始化的代碼,代碼定義如下:

        發送初始化指令0x8E,發送數據為0x08和0x00。

        AHT20開始測量溫濕度指令代碼定義如下:

        同樣是發送指令0XAC和數據0x33,0x00。

        AHT20軟復位函數定義如下:

        軟初始化函數只發送指令0XBA。AHT20溫濕度數據獲取和處理指令函數定義如下:

        函數返回的枚舉值為讀取是否正常的結果,枚舉定義如下:

        需要注意的是讀取到的數據的第四個字節為溫濕度共用的字節。

        根據轉換公式,將讀取到的數據轉換為溫濕度。轉換后的溫濕度都是放大10,即保留了一個小數。溫濕度轉換公式如下:

        在調用AHT20讀取溫濕度前一定要對IIC進行初始化,否則程序會崩潰。IIC初始化函數定義如下:

        用的是芯片IIC0外設,也可以換成IIC1外設,但是一定要記住接線方式是否正確。

        AHT20上電后也要做一些初始化操作,主要是發送初始化指令和判斷AHT20的狀態。AHT20的初始化函數定義如下:

        函數返回的枚舉定義如下:

        需要注意的是,初始化失敗后需要查一下問題,如何排查問題在文末會有總結。

        04

        AHT20讀取溫濕度的調用方法(移植方法)

        AHT20的調用在main.c的main函數中有示例,main函數定義如下:

        main函數的主要功能是1S通過AHT20讀取一下溫濕度值,若讀取成功則通過打印輸出溫濕度值。通過綠燈頻率為1S的閃爍告知MCU正常運行。

        調用AHT20讀取溫濕度的步驟

        1、初始化AHT20(包括IIC初始化)AHT20_Init()

        2、在初始化成功后讀取AHT20的狀態AHT20_ReadSta()

        3、在狀態為空閑時讀取溫濕度數據AHT20_RecTempAndHumiVal()

        4、讀取成功后就可以進行其他操作,示例代碼是將溫濕度數據打印出來,需要注意的是第一個數據為濕度,第二個為溫度,且都放大10倍

        在移植過程中需要注意的是在CMakeLists.txt文件要加入AHT20的.c/h文件,添加語句為:

        05

        AHT20示例代碼驗證

        在下載好驅動代碼后首先是修改Makefile文件SDK的路徑,修改如下的值

        然后通過終端編譯和下載程序。

        通過串口軟件可以查看MCU的運行狀態和讀取到的溫濕度值。MCU正常運行和正常讀取到溫濕度值的打印狀態如下圖所示:

        :6

        常見問題解答

        1、程序編譯和燒寫都正常,但是示例程序跑起來綠燈沒有閃爍,打印如下圖所示

        這個有可能是IIC初始化失敗或沒有進行初始化,這也是我在自測的時候發現的

        2、在終端輸入make或make clean后出現如下圖所示

        這個可能是因為SDK的路徑不對,需要修改Makefile文件的變量值BL_SDK_BASE ?=

        在每個函數中都有打印信息,在示例代碼中將其注釋掉,在調試過程中可以將這些打印信息打開,這樣就可以方便定位到問題的所在。我這里總結的是我在調試過程中遇到的問題,并且給出問題的原因。還有一些其他的問題可以在評論中發表出來。我也發了問題總結帖子,其他問題可以先在這個帖子里查找,以后也會不斷補充。

        原貼地址:【外設移植】AHT20溫濕度傳感器M61開發板驅動https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=43970&highlight=%E3%80%90%E5%A4%96%E8%AE%BE%E7%A7%BB%E6%A4%8D%E3%80%91AHT20%E6%B8%A9%E6%B9%BF%E5%BA%A6%E4%BC%A0%E6%84%9F%E5%99%A8M61%E5%BC%80%E5%8F%91%E6%9D%BF%E9%A9%B1%E5%8A%A8&_dsign=93260e0f


        安信可更多產品信息可點擊以下鏈接查閱:

        ?開發資料:https://docs.ai-thinker.com/

        ?官方教程:https://blog.csdn.net/Boantong_

        ?安信可官網:https://www.ai-thinker.com

        ?安信可社區:http://bbs.ai-thinker.com/

        ?業務咨詢請聯系:18022036575






        亚洲欧美日本久久综合网站点击|丁香五月天亚洲综合4438网|亚洲欧美中文日韩在|人人操人人爱人人看
        <track id="x7t9b"></track><delect id="x7t9b"><ins id="x7t9b"></ins></delect><noframes id="x7t9b">

          <form id="x7t9b"></form>

              <track id="x7t9b"><del id="x7t9b"><ins id="x7t9b"></ins></del></track>

              <form id="x7t9b"><i id="x7t9b"><b id="x7t9b"></b></i></form>
              <output id="x7t9b"><ruby id="x7t9b"></ruby></output>