控制器MCU的IO介面不夠用需要擴展出來更多的IO介面
IO擴充套件的作用
最近一個產品中主控制器MCU的IO介面不夠用,需要擴展出來更多的IO介面,那麼擴充套件IO介面的方式有兩種,(1)通過74HC595晶片可以擴充套件輸出IO介面,價格較低,需要4個IO來連線74HC595,擴展出來8個IO,擴展出來的IO不多,(2)選擇專用的IO擴充套件晶片,通過IIC介面來擴充套件成8路IO,16路IO,在一個IIC總線上連線多片IO擴充套件晶片可以擴展出來32路,64路等更多的IO介面。我這個產品中通過I2C介面來擴充套件IO口,晶片選擇的是TI公司的TCA9535, 擴展出來16路IO介面,8路IO用於連線LED指示燈,8路IO用於連線輸入按鍵。 TCA9535的電路比較簡單,I2C介面INT腳外拉上接電阻就可以,電源處增加濾波電容即可,我的應用中P0埠驅動3mm紅色發光二極體,P1埠用於連線按鍵輸入,具體請看下圖。
TCA9535的原理說明
TCA9535晶片內部一共8個暫存器,具體功能如下:
暫存器0,暫存器1 輸入暫存器:用於讀取P0,P1埠的輸入值,
job.sddp.net/wap/index.php?c=job&a=view&id=906 job.sddp.net/wap/index.php?c=job&a=view&id=905 job.sddp.net/wap/index.php?c=job&a=view&id=904 job.sddp.net/wap/index.php?c=job&a=view&id=909 job.sddp.net/wap/index.php?c=job&a=view&id=908
暫存器2,暫存器3 輸出暫存器 :用於設定P0,P1埠的輸出值,
暫存器4,暫存器5 極性反轉暫存器:用於當P0,P1埠做為輸入時,對輸入的電平進行反轉處理,即管腳為高電平時,設定這個暫存器中相應的位為1時,讀取到的輸入暫存器0,1的值就是低電平0了。
暫存器6,7 配置暫存器:用於配置P0,P1埠的做為輸入或是輸出。
job.sddp.net/wap/index.php?c=job&a=view&id=907 job.sddp.net/wap/index.php?c=job&a=view&id=912 job.sddp.net/wap/index.php?c=job&a=view&id=911 job.sddp.net/wap/index.php?c=job&a=view&id=910 job.sddp.net/wap/index.php?c=job&a=view&id=915
根據上面的原理圖可知,TCA9535需要設定P0埠為輸出, P1埠為輸入,在中斷程式中讀取P1埠的值,在程式的應用邏輯中呼叫寫P0埠來點亮不同的指示燈。
4、TCA9535的驅動程式
函式tca9535_init()實現初始化,主要設定P0口為輸出,P1口為輸入,設定MCU的中斷,還有一些其他的初始化程式是根據產品的實際需求增加上去的,從TC9535的輸出暫存器中讀取一下LED的狀態,做為返回值返回。
函式tca9535_read_key(),實現讀取P1埠的8個按鍵值。
函式tca9535_write_led(),控制P0埠的8個LED指示燈點亮或熄滅。
到這裡你直接複製我的程式,如果I2C驅動正確的話,相信你的TCA9535已經可以正常的工作了。實際這個晶片是有一點中斷的bug的,你如果不用中斷或是隻用來擴充套件輸出IO的話是不會遇到問題,可以正常使用,但你像我這樣用就有問題了(我上面的程式碼已經解決了這個中斷的bug)?
5、中斷異常的問題
TCA9535按上面的電路使用,一上電後中斷引腳就會一直輸出低電平。這是什麼原因呢?這麼明顯的bug,這樣的晶片怎麼才能使用呀。我懷疑買到了假晶片,或是使用PCA9535(型號就是PCA9535,這裡可沒有寫錯呀,TI先出的PCA9535這個晶片,晶片上電有問題,升級版本的晶片是TCA9535)這個晶片,這個晶片的上電時有問題,可能會引起中斷異常。這其間經過N次思考問題可能的原因,N次的測試,調整電路電阻,電容還是沒有找到問題的原因,懷疑為晶片本身的問題。
三天過去了,問題沒有解決,還得繼續找,突發奇想,是不是外圍電路的問題呢?但是外圍電路和手冊上面畫一樣了,怎麼可能有問題呢。死馬當做活馬醫,把晶片外面連線的按鍵,LED全部去掉,一上電,中斷訊號正常了,為高電平。把按鍵接上,上電中斷訊號正常,把LED燈接上,上電,中斷訊號異常,為低電平,測試連線LED的管腳電壓為1.6V,1.6V也是屬於高電平,接到P0埠上引起了上電中斷異常,按鍵埠的3.3.V上拉電平就不會引起晶片中斷,還是晶片設計的不合理,晶片還得用,從軟體上看看能解決不?
6、中斷異常的解決
上面問題的原因已經查到,P0埠接LED燈時,晶片上電此埠預設為輸入,讀取到了LED燈上拉產生的電平,產生了中斷。那麼試著在晶片上電後,讀取一下P0埠的輸入暫存器,來清除一箇中斷。修改tca9535_init()函式,在上電後,讀取一個P0,P1兩個埠的輸入暫存器,中斷訊號在上電後恢復為高電平,正常了。解決這個問題的關鍵程式碼如下:
覆蓋與交換技術是在多道程式環境下用來擴充記憶體的兩種方法。
記憶體覆蓋
早期的計算機系統中,主存容量很小,雖然主存中僅存放一道使用者程式,但是儲存空間放不下使用者程序的現象也經常發生,這一矛盾可以用覆蓋技術來解決。
覆蓋的基本思想是:由於程式執行時並非任何時候都要訪問程式及資料的各個部分(尤其是大程式),因此可以把使用者空間分成一個固定區和若干個覆蓋區。將經常活躍的部分放在固定區,其餘部分按呼叫關係分段。首先將那些即將要訪問的段放入覆蓋區,其他段放在外存中,在需要呼叫前,系統再將其調入覆蓋區,替換覆蓋區中原有的段。
覆蓋技術的特點是打破了必須將一個程序的全部資訊裝入主存後才能執行的限制,但當同時執行程式的程式碼量大於主存時仍不能執行。
記憶體交換
交換(對換)的基本思想是,把處於等待狀態(或在CPU排程原則下被剝奪執行權利) 的程式從記憶體移到輔存,把記憶體空間騰出來,這一過程又叫換出;把準備好競爭CPU執行的程式從輔存移到記憶體,這一過程又稱為換入。第2章介紹的中級排程就是釆用交換技術。
例如,有一個CPU釆用時間片輪轉排程演算法的多道程式環境。時間片到,記憶體管理器將剛剛執行過的程序換出,將另一程序換入到剛剛釋放的記憶體空間中。同時,CPU排程器可以將時間片分配給其他已在記憶體中的程序。每個程序用完時間片都與另一程序交換。理想情況下,記憶體管理器的交換過程速度足夠快,總有程序在記憶體中可以執行。
有關交換需要注意以下幾個問題:
交換需要備份儲存,通常是快速磁碟。它必須足夠大,並且提供對這些記憶體映像的直接訪問。 為了有效使用CPU,需要每個程序的執行時間比交換時間長,而影響交換時間的主要是轉移時間。轉移時間與所交換的記憶體空間成正比。 如果換出程序,必須確保該程序是完全處於空閒狀態。 交換空間通常作為磁碟的一整塊,且獨立於檔案系統,因此使用就可能很快。 交換通常在有許多程序執行且記憶體空間吃緊時開始啟動,而系統負荷降低就暫停。 普通的交換使用不多,但交換策略的某些變種在許多系統中(如UNIX系統)仍發揮作用。