各位好,最近在除錯iic的時候遇到了sda波形有半高電平的狀態,下面分享一下解決的方法。
1.測試方法
通過iic將資料0xef寫入eeprom中的0x01位址。整個操作過程如下且通過示波器測試波形 通訊引數:起始訊號+寫0xa0+從機回ack+寫0x01+從機回ack+寫0xef+從機回ack+stop
2.問題描述
測試發現寫入過程中,從機每次的ack應答都會產生乙個半高波形,如下圖紅框所示。
猜想:sda在從機產生ack應答時主機和從機發生了電平衝突。
關於ack訊號:主機寫入過程中,當8bit寫入完成後,在隨後的第九個時鐘上如果sda為低,則主機收到ack,若是sda為高,則主機收到noack。
如下是有問題的程式關鍵部分:
從ack的介紹和有問題的程式上看,當第八個bit完成時,scl會拉低,然後在拉高。在scl拉低的時候從機立即會進行資料變化,產生低電平(ack訊號),但是此時主機的sda還是輸出高狀態,所以電平衝突,造成了半高電平的產生。
3.解決辦法
從問題上看,說明是在從機傳送ack時兩端產生了sda控制權的衝突,導致了這個問題。因為sda本身帶有上拉,所以第一刪除無用的sda輸出高語句,第二當需要主機傳送高電平時,主機設定sda為輸入狀態,通過外部的上拉將sda穩定在高點平。程式和實際結果如下所示,可以看到ack時的半高狀態消除:
4.結論:
4-1.模擬iic情況下,如果mcu支援開漏輸出,則用開漏輸出,因為開漏只能拉低不能拉高,這樣不會造成電平衝突等問題。
4-2.如果用推挽輸出的話,那麼mcu在控制sda引腳時,
a) 輸出高電平,則mcu設定sda為輸入狀態,靠外部上拉將sda穩定在高點平;
b) 輸出低電平,則mcu這只sda為輸出狀態,且輸出低電平。
c) 輸入狀態,mcu設定sda為輸入狀態。
for迴圈寫三個練習 增強for迴圈
重要 雖然所有迴圈結構都可以用while或者do.while表示,但j a提供了另一種語句 for迴圈,使一些迴圈結構變得更加簡單。for迴圈語句是支援迭代的一種通用結構,是最有效 最靈活的迴圈結構。for迴圈執行的次數是在執行前就確定的。語法格式如下 for 初始化 布林表示式 更新 練習之前 p...
獲取使用者IP位址的三個屬性
一 沒有使用 伺服器的情況 remote addr 您的 ip http via 沒數值或不顯示 http x forwarded for 沒數值或不顯示 二 使用透明 伺服器的情況 transparent proxies remote addr 最後乙個 伺服器 ip http via 伺服器 i...
如何獲取客戶端MAC位址 三個方法
方法一 public static string getmacaddress br.close return address.trim catch ioexception e return address we can replace the ipconfig to ping x.x.x.x and...