IO 口是處理器系統對外溝通的最基本部件,從基本的鍵盤、LED 到復雜的外設芯片等,都是通過IO 口的輸入、輸出操作來進行讀取或控制的。
MSP430系列中,不同單片機的IO 口數量不同。體積最小的MSP430F20xx系列只有10 個IO,適合在超小型設備中應用;功能最豐富的MSP430FG46xx系列多達80 個IO 口,足夠應付外部設備繁多的復雜應用。在MSP430FE425 單片機中,共有14 個IO 口,屬于IO 口較少的系列。但由于需要大量引腳的設備,如LCD、多通道模擬量輸入等都有專用引腳,不占用IO 口。因此在大部分設計中IO 數量還是夠用的。
l IO 口寄存器
和大部分單片機類似,MSP430 單片機也將8 個IO 口編為一組。例如P1.0~P1.7都屬于P1 口。每組IO 口都有4 個控制寄存器,其中P1 和P2 口還額外具有3 個中斷寄存器。
表2.1.1 IO 口寄存器列表。
寄存器名 寄存器功能 讀寫類型 復位初始值
PxIN Px 口輸入寄存器 只讀 無
PxOUT Px 口輸出寄存器 可讀可寫 保持不變
PxDIR Px 口方向寄存器 可讀可寫 0(全部輸入)
PxSEL Px 口第二功能選擇 可讀可寫 0(全部為IO 口)
PxIE Px口中斷允許 可讀可寫 0(全部不允許中斷)
PxIES Px口中斷沿選擇 可讀可寫 保持不變
PxIFG Px口中斷標志位 可讀可寫 0(全部未發生中斷)
這是本書第一次出現寄存器列表,有必要說明一下MSP430單片機的寄存器以及標志位全部是大寫的。若出現的小寫的“x”,表示該設備不止一個,因此寄存器也不止一個。為了縮短列表長度,不用全部列出,用字母x 表示序號。例如對于表中的PxOUT,當x取1、2、3 時,就變成了P1OUT、P2OUT、P3OUT。
n PxDIR寄存器用于設置每一位IO口方向: 0=輸入 1=輸出MSP430 單片機的IO 口屬于雙向IO 口,因此在使用IO 口時首先要用方向選擇寄存器來設置每個IO 口的方向。例如P1.5、P1.6、P1.7 接有按鍵,P1.1、P1.3、P1.4接有LED,那么P1.5、P1.6、P1.7 要設為輸入,P1.1、P1.3、P1.4 要設為輸出:
P1DIR|=BIT1+BIT3+BIT4; // P1.1、P1.3、P1.4設為輸出
P1DIR &=~ (BIT5+BIT6+BIT7); // P1.5、P1.6、P1.7設為輸入(可省略)
由于PxDIR 寄存器在復位過程中會被清0,沒有被設置的IO 口方向均為輸入狀態,因此第二句可以被省略。
對于所有已經設成輸出狀態的IO口,可以通過PxOUT寄存器設置其輸出電平;對于所有已經被設成輸入狀態的IO 口,可以通過PxIN 寄存器讀回其輸入電平。例如讀回P1.5口上的開關狀態,并判斷若處于按下狀態(低電平)則從P1.1 口輸出高電平點亮LED:
if((P1IN & BIT5)==0) P1OUT|=BIT1; //若P1.5為低電平則P1.1輸出高電平
n PxSEL寄存器用于設置每一位IO的功能: 0=普通IO口 1=第二功能
在MSP430單片機中,很多內部功能模塊也需要和外界進行數據交流,為了不增加芯片引腳數量,大部分都和IO 口復用管腳。因此大多數IO 引腳都具有第二功能。通過寄存器PxSEL 可以指定某些IO 引腳作為第二功能使用。例如從附錄中管腳排布圖中查到MSP430x42x 系列單片機的P2.4、P2.5 口和串口的TXD、RXD 公用引腳。若需要將這兩個引腳配置為串口收發腳,則須將P2SEL的4、5位置高:
P2SEL |= BIT4 + BIT5; // P2.4,5 設為串口收發引腳
l IO 口中斷
在MSP430 所有的單片機中,P1 口、P2 口總共16 個IO 口均能作引發中斷。在MSP430x42x系列中,14 個IO 均屬于P1 或P2 口,因此每個IO 都能作為中斷源使用。通過下列2 個寄存器配置IO 口作為中斷使用:
n PxIE寄存器用于設置每一位IO的中斷允許: 0=不允許 1=允許
n PxIES寄存器用于選擇每一位IO的中斷觸發沿: 0=上升沿 1=下降沿
在使用IO 口中斷之前,需要先將IO 口設為輸入狀態,并允許該位IO 的中斷,再通過PxIES寄存器選擇觸發方式為上升沿觸發或者下降沿觸發。例如將P1.5、P1.6、P1.7 口設為中斷源,下降沿觸發:
P1DIR &=~(BIT5 + BIT6 + BIT7); // P1.5、P1.6、P1.7設為輸入(可省略)
P1IES |= BIT5 + BIT6 + BIT7; // P1.5、P1.6、P1.7設為下降沿中斷
P1IE |= BIT5 + BIT6 + BIT7; // 允許P1.5、P1.6、P1.7中斷
EINT(); // 總中斷允許
n PxIFG寄存器是IO中斷標志寄存器:0=中斷條件不成立 1=中斷條件曾經成立過無論中斷是否被允許,也不論是否正在執行中斷服務程序,只要對應IO 滿足了中斷條件(例如一個下降沿的到來),PxIFG 中的相應位都會立即置1 并保持,只能通過軟件人工清除。這種機制的目的在于最大可能的保證不會漏掉每一次中斷。在MSP430系列單片機中,P1 口的8個中斷和P2 口8個中斷各公用了一個中斷入口,因此該寄存器另一重要作用在于中斷服務程序中用于判斷哪一位IO 產生的中斷。下面的中斷服務程序示范P1.5、P1.6、P1.7 發生中斷后執行不同的代碼:
#pragma vector = PORT1_VECTOR //P1口中斷源
__interrupt void P1_ISR(void) //聲明一個中斷服務程序,名為P1_ISR()
{
if(P1IFG & BIT5) //判斷P1中斷標志第5位(P1.5)
{
... ... //在這里寫P1.5中斷處理程序
}
if(P1IFG & BIT6) //判斷P1中斷標志第6位(P1.6)
{
... ... //在這里寫P1.6中斷處理程序
}
if(P1IFG & BIT7) //判斷P1中斷標志第7位(P1.7)
{
... ... //在這里寫P1.7中斷處理程序
}
P1IFG=0; //清除P1所有中斷標志位
}
注意在退出中斷前一定要人工清除中斷標志,否則該中斷會不停發生。類似的原理,即使IO 口沒有出現中斷條件,人工向寫PxIFG 寄存器相應位寫“1”,也會引發中斷。更改中斷沿選擇寄存器也相當于跳變,也會引發中斷。所以更改PxIES寄存器應該在關閉中斷后進行,并在打開中斷之前及時清除中斷標志。MSP430單片機大量的IO 中斷非常適合做鍵盤輸入用,但要注意鍵盤存在機械結構,在閉合或松開的過程中,機械結構的碰撞和反彈會造成信號上數毫秒的“毛刺”。