摘要:本節我們介紹總線,并使用的總線來訪問加速度傳感器。主循環內添加循環讀取的代碼編譯下載運行,可以看到數據輸出變換傳感器方向,可以看到測出的重力加速度的數值變化。
本節我們介紹I2C總線,并使用stm32的I2C總線來訪問加速度傳感器ADXL345。
I2C總線通信比較適合設備內部各芯片間的通信,它只需要兩根信號線。
I2C可以掛載多個主機和從機,通信總是由主機發起。每個從機都有唯一的地址,主機通過地址決定訪問哪個從機。
I2C總線的兩根線,SCL為時鐘線,SDA為數據線;所有的器件對這兩根線的輸出操作只能拉低,當釋放總線時,由總線上的上拉電阻將電平拉高。所以硬件連接上,上拉電阻是必須的,否則不能通信。
I2C空閑時,所有器件釋放總線,SCL和SDA都被上拉電阻拉到高電平;
I2C的起始條件:SCL為高電平時,SDA由高電平向低電平切換;表示開始傳送數據;一般是需要通信的主機發起,起始條件的圖示如下:
I2C的停止條件:SCL為高電平時,SDA由低電平向高電平跳變;表示結束傳送數據;一般也是主機最后結束通信,停止條件的圖示如下:
傳輸數據時,在SCL時鐘線為高電平時,SDA數據線上的電平不允許被修改;SCL時鐘線為低電平時,SDA數據線上的電平可變為高/低,如下圖所示:
I2C的ACK和NACK,都是回應,ACK是將SDA線拉低,NACK是將SDA總線釋放(拉高);ACK和NACK都是回應,可以是主機回應從機、也可以是從機回應主機。具體來說(以ADXL345芯片為例):
主機發起通信后,如果要向從機寫入數據,則每傳輸一個字節都需要等待從機回應ACK,如下圖所示;具體到實際的操作,就是主機每發完一個字節的數據,會釋放總線,等待從機回應ACK(即等待從機把SDA線拉低)。最后通信完成后,主機發送停止條件:
主機發起通信后,如果要從從機處讀取數據,則發送地址時,需要等待從機回應ACK;在從機向主機回復數據時,主機要回應ACK,當主機讀完最后一個字節不再讀取時,就回應NACK;寫入數據的過程如下圖:
上面的例子是以加速度傳感器ADXL345芯片為例,其他芯片在使用I2C通信時,可能有細微的不同,但基本上都是這幾種狀態組合起來的。
Stm32帶了硬件I2C,下面我們就使用stm32的硬件i2c讀取加速度傳感器ADXL345的數值。
我們仍然以串口的工程為基礎,在它上面添加設置,如下圖,選擇I2C接口,其他都默認:
選擇之后可以發現引腳PB6和PB7被占用為I2C的引腳,其中PB6是SCL、PB7是SDA。
在硬件連接上,我們也需要將ADXL345芯片的SCL和SDA連接到PB6和PB7,并且SDA和SCL都要用電阻上拉到電源:
生成工程代碼,在keil中打開。Stm32的hal庫已經將i2c的初始化、i2c的讀寫操作封裝成了函數,我們直接調用即可。
這里先需要修改一個bug,如下圖:
__HAL_RCC_I2C1_CLK_ENABLE();這一句使能i2c時鐘的語句,cubemx生成的代碼在GPIO初始化之后,這樣不能設置成功,需要把它提前到GPIO初始化之前:
Main函數中添加初始化ADXL345的代碼:
簡單說明一下,前面寫入的4個值是設置芯片的工作模式,最后寫入的三個值是x、y、z三個方向的校準參數。由于ADXL345傳感器有初始誤差(網上有說法是X、Y方向誤差不大,Z軸可能誤差達到幾個g;我的這個芯片X、Y、軸基本正常,Z軸有大約0.6g左右的誤差),可以寫入一組測好的參數,讓它輸出時自動減掉這個值,達到去除初始誤差的目的,我這里在Z軸寫入了f0,校準后基本正常。
主循環內添加循環讀取ADXL345的代碼:
編譯下載運行,可以看到數據輸出:
變換傳感器方向,可以看到測出的重力加速度的數值變化。
在使用stm32的硬件i2c時,查得很多資料都說stm32的硬件i2c有問題,我用的不多,但是匯總了一些網上的討論,以作為備忘,萬一哪天必須用硬件i2c時也好排查:
a) cubemx生成的代碼,初始化i2c的時鐘要提到GPIO初始化之前;
b) I2c的速率不能過高,有說法是50k以下基本無問題,100k以上運行時間久了會出問題;
c) 某些帶FSMC模塊的stm32 型號,和I2C1模塊共用了PB7引腳,會使得I2C1不能正常啟動;即使你沒有用到FSMC只是打開了FSMC的時鐘也會影響,解決辦法是改用I2C2或者重定義I2C的時鐘線和數據線到PB8、9引腳;或者關掉FSMC的時鐘;
d)硬件i2c不能被中斷打斷,否則會出問題;如果使用中斷,建議i2c的中斷設置為最高優先級。
鑒于有些問題確實不好驗證,本人后面都盡量用軟件i2c了,效率低一些但可靠性高,并且移植到其他芯片上也方便很多。
好了,這一節就講到這里了。
歡迎關注我的公眾號,可留言“資料”獲取相關資料和軟件:
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/123686.html
摘要:使用庫讀寫環境光照度傳感器本文將教大家如何快速使用庫讀取光照度數據。五實驗樣機測試展示通過之前配置好的面板,通過涂鴉智能進行配網實時采集光照度傳感器的數據。 使用STM32 HAL庫讀寫環境光照度傳感器(BH1750) 本文將教大家如何快速使用STM32HAL庫讀取光照度數據。 實現功能:通...
摘要:總線掛載的外設有等。外設地址映射片上外設區分為三條總線,根據外設速度的不同,不同總線掛載著不同的外設,掛載低速外設,和掛載高速外設。 第二章 STM32資源介紹 2...
摘要:利用可視化界面來進行的相關配置,所以時鐘滴答定時器串口等就不用根據數據手冊去操作標準庫甚至是寄存器了,可以通過軟件直接生成。 使用STM32CubeMX初始化ST...
摘要:配置三的輸入輸出建立工程并進行核心配置根據文章使用配置二核心配置進行如下配置新建工程圖形配置調試時鐘信號圖形配置時鐘樹圖形配置調試接口檢查配置配置詳解配置選擇輸入輸出比如就要配置輸出,按鍵就要配置輸入配置為輸出時配置詳 ...
摘要:異步通信與同步通信異步通信異步通信是指通信的發送與接收設備使用各自的時鐘控制數據的發送和接收過程。同步通信同步通信時要建立發送方時鐘對接收方時鐘的直接控制,使雙方達到完全同步。配置串口設置為異步通信基礎參數波特率為。 ...
閱讀 2406·2021-11-18 10:02
閱讀 1922·2021-10-13 09:40
閱讀 2999·2021-09-07 10:07
閱讀 2106·2021-09-04 16:48
閱讀 1005·2019-08-30 13:18
閱讀 2451·2019-08-29 14:03
閱讀 2921·2019-08-29 12:54
閱讀 3155·2019-08-26 11:41