對STM32硬體IIC的深入探討

STM32的硬件IIC一直是廣大STM32開發者的心病,或許軟件模擬IIC大家用的都挺嗨,網上資料一抓一大把,應用於項目貌似也很穩定,而且移植性比較好。不過相信大多開發人員都是作為主設備去應用,一旦要將STM32作為IIC從設備恐怕就不那麼愉快了!因為項目需求,本人就遇到了這個難題,發現百度瞬間變得不那麼強大了,幸好沒有選擇放棄,使用STM32硬件開發了從機,應用於項目至今沒出現任何異常狀況。而對於STM32主設備硬件IIC問題雖然官方有例程貌似可以解決,但是本人從未考慮使用。

IIC是PHILIPS公司推出的一種具備多主機系統所需的包括總線裁決和高低速器件同步功能的一種高性能串行總線。後來ATMEL又出了一種TWI總線,其實兩者並沒有本質區別。本人在做AVR和STM32通信時(AVR作主設備,STM32作從設備),確實也遇到一個插曲,貌似是TWI總線的停止信號比較IIC的停止信號時序要來的嚴格,數據發送完成拉高SCL、SDA總線時需要加簡短的延時才能解決。

相對於個體而言,IIC其實有四種工作模式,主模式發、從模式發、主模式收、從模式收。當然,由於SCL線是由主設備控制的,所以所有的通信過程都是由主設備發起的。其實對於主從間的設備通信大都類似如此。

在這裡,我不想過多的介紹IIC的協議格式,我只想細說一下STM32的從設備是如何開發的,以下均以STM32F103C8T6這款芯片為例。

首先,開啟相關外設時鐘,配置IO端口複用到IIC功能,設置IIC從機地址,並且設置為7位地址(因為標準的IIC地址就是7位,不必考慮其他擴展情況)。至於IIC速度是主設備考慮的事情,低速模式100K,高速模式400K,這裡配不配置都不影響。然後最重要的一點就是開啟IIC事件中斷並設置中斷優先級,儘量設高一點。我們後面從設備要做的所有事情都在這個中斷服務函數里面去處理。

好了,是時候貼張圖了!

對STM32硬件IIC的深入探討

注意,我這裡做了IO管腳重映射,另外IIC錯誤中斷我實際沒有使用。

接下來庫函數可能不太夠用了,我們需要打入STM32芯片內部,這樣操作起來更方便。我們需要不斷地讀IIC的一些狀態來判斷協議進行到哪裡,該作何處理,基本就是判斷IIC狀態寄存器SR的值。STM32的每個IIC外設有兩個狀態寄存器,如IIC1_SR1(寄存器地址為0x40005414),IIC1_SR2(寄存器地址為0x40005418).STM32中文參考手冊中對寄存器的各個標誌位都有詳細說明,如

對STM32硬件IIC的深入探討

對STM32硬件IIC的深入探討

然後再具體聊聊STM32從機接收數據的具體過程,對於從機發送數據由於還未用到,暫且不提,等哪天用到了再來調試,過程也基本類似。

首先,開一個緩存用來存儲接收到的數據,定義一個狀態變量用來標識接收完成狀態,再定義一個變量用來作為緩存索引,即接收數據計數。當主機啟動總線併發送來對應的從機地址,索引清零,復位接收完成標誌,同時清狀態標誌寄存器(即SR1、SR2),準備接收數據。單字節數據接收完成後填入緩衝區,索引加1,同時清狀態寄存器。直到檢測到停止信號後,重新啟動IIC外設,即將控制寄存器CR1第0位寫1,同時清狀態寄存器,然後置位接收完成標誌。此時,我們就可以讀出緩存中接收到的數據進行解析處理了。當然,若真的通信過程出現異常,發生接收超時,我們也可以重啟一次IIC外設,清狀態寄存器,實際應用中並未遇到過這種現象。至此,基於STM32的IIC從機接收數據的過程就圓滿結束了。下面貼出關鍵代碼:

對STM32硬件IIC的深入探討


分享到:


相關文章: