1. I/O口的簡介
特點:
(1)多種複用和設置(即可控制是否輸入、是否輸出、是否接上下拉電阻、是否可接受中斷)
(2)一般情況下,P1和P2都具有中斷能力的。從P1和P2接口的各個I/O管腳引入的中斷可以獨立的被使能並且設置爲上升沿或者下降沿觸發,對應的中斷向量表分別爲P1IV和P2IV,他們只能進行字操作,並且PAIV這個寄存器是不存在的。
(3)P1、P2可合爲PA,P3、P4可合爲PB…。所以P1爲8位BCD 0X00,PA爲16位BCD 0X0000。當進行字操作寫入PA口時,所有的16位都被寫入這個端口;當利用字節操作寫入PA口的低字節時,高字節保持不變;
(4)由於430很多I/O和外圍電路接線,所以這裏常用位操作。如事先定義(接下來也會用到,先在此聲明),BIT0=0X01、BIT1=0X02、BIT3=0X04…,那麼將
P1.1、P1.3---》1(高電平):P1OUT |=(BIT1+BIT3),
P1.1、P1.3---》0(低電平):P1OUT &=~(BIT1+BIT3),
電平翻轉即按位異(取反):P1OUT ^=(BIT1+BIT3)。
(5)沒有使用到的I/O口,統一拉低,當讀入的數據長短小於端口最大長度時,那些沒有用到的爲會被視爲0;
2. I/O口的簡單配置(一)
430 I/O的配置是用軟件來實現的,是通過相應的配置寄存器來實現的。(用到某個I/O時,一定要先配置好該I/O,否則易出錯)
2.1.1 I/O方向設定寄存器PxDIR
如設定P1.1和P1.2爲輸出狀態有以下三種設置模式:
P1DIR |=(BIT1+BIT2)
PADIR |=(BIT1+BIT2)
PADIR_L |=(BIT1+BIT2
== 拉高設定爲輸出,拉低設定爲輸入(默認)==
2.1.2 I/O輸入設定寄存器PxIN
如設定P1.1和 P1.2的輸入爲低電平:
P1IN &=~(BIT1+BIT2)。
2.1.3 I/O輸出設定寄存器PxOUT
(1)當只用爲簡單的輸出時:如設定P1.1和P1.2輸出爲高電平:
P1OUT |=(BIT1+BIT2);
(2)如果該引腳爲正常I/O功能,且當前已設定爲輸入方向,且上拉/下拉電阻寄存器是有效的,那麼PxOUT可以用來配置上拉和下拉電阻。低電平爲下拉電阻,高電平爲上拉電阻。
2.1.4 上拉/下拉電阻使能寄存器PxREN
低電平該寄存器無效狀態
高電平該寄存器有效狀態
2.1.5 輸出驅動能力設置寄存器PxDS
弱化驅動可以減弱電磁干擾EMI,全力驅動會增強電磁干擾。默認爲減弱驅動。
低電平表示減弱的驅動(默認)。
高電平表示全力的驅動。
2.1.6 功能選擇寄存器PxSEL(引腳複用)
用來聲明該端口是要應用於外圍電路的特殊功能(不決定輸入輸出方向),默認爲低電平。
低電平表示普通的I/O口(默認);如:
P1SEL |=BIT0;
高電平表示該引腳將有連接外圍電路的特殊用途。如:
P5SEL |=(BIT2+BIT3)
這句話的意思是聲明P5.2和P5.3將有特殊用途,實際上這兩個I/O接的是外部的高頻時鐘晶振(之後還是要設定爲輸入狀態纔可以)。此外需要注意的是。一旦某個I/O的PxSEL置高了,那麼該引腳將不能再被用爲中斷引腳。
外部中斷應用實例
/*實現LED的閃爍LED位於每個觸摸按鍵的下方,具體接口請查詢原理圖
#include <msp430.h>該頭文件內部包含430各個寄存器的配置情況*/
/**
* main.c
* 流水燈
*/
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
P1DIR |=(BIT2+BIT3+BIT4);//P1.2、P1.3、P1.4爲輸出方向
P1OUT &=~(BIT2+BIT3+BIT4);//置零
int i=0,j=0;
while(1){
if(i>5)
i=0;
else{
switch(i){
case 0:break;
case 1:break;
case 2:P1OUT=0X04;break;
case 3:P1OUT=0X08;break;
case 4:P1OUT=0X10;break;
}
}
i++;
for(j=20000;j>0;j--);//延時
}
}
3.通用I/O口的簡單配置(二)
外部中斷是MSP430優先級最低的中斷而且是可屏蔽中斷。
3.1.1簡單的端口中斷(外部中斷)
(1)P1、P2的所有端口都具有中斷能力,可以通過寄存器PxIFG,PxIE和PxIES來配置。其他端口則需要參照具體的引腳說明書。所有的P1中斷標誌是最優先的(相比其它引腳的外部中斷),其中P1IFG.0又最優。
(2)PxIV中斷向量寄存器:只有P1IV和P2IV。最高優先級使能中斷在P1IV寄存器中產生一個序號,這個數字會被程序計數器識別或者加入其中,然後自動的執行合適的中斷服務程序。關閉P1口中斷不會影響P1IV寄存器的值。P2口具有相同的功能。PxIV寄存器只能字訪問。
(3)PxIFGx中斷標誌寄存器:只有相應的中斷使能PxIE打開且總中斷GIE打開,該寄存器纔有效。
- 低電平表示沒有中斷請求等待響應;
- 高電平表示有中斷請求等待響應;
注意:
(1)使用端口的中斷功能期間,如果進行PxIN、PxOUT等操作可能使中斷變化。
(2)中斷標誌需要軟件清零。有一種情況例外:兩個中斷同時發生,先響應優先級高的中斷,當該中斷服務程序結束後,該位的中斷標誌會自動清零,然後去響應另外一箇中斷。
PxIE中斷使能寄存器
- 低電平表示中斷關閉;
- 高電平表示中斷允許;
PxIES中斷觸發方式選擇寄存器
- 低電平表示上升沿觸發;
- 高電平表示下降沿觸發;
#include <msp430.h>
/**
* main.c
* 採用中斷的方式,開關P2.1控制LED--》P1一個一個點亮
*/
int s=0;//s用來表示按鍵次數
int num =0;//num表示LED值
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
P1DIR=0XFF;//P1全部接輸出
P1OUT=0X00;//接LED初始化故全拉低,這樣開始燈是滅的
P2DIR=0X00;//P2全部設爲輸入,因爲要接受外部中斷
P2IFG=0X00;//清除P2口的中斷標誌
P2IE=BIT1;//P2.1開啓中斷
P2IES=0XFF;//P2爲下降沿觸發
P2IN=BIT1;//P2.1輸入拉高,因此開關閉合時會拉低產生下降沿(即中斷)
P2OUT=0XFF;
P2REN=0XFF;//作爲輸入時配置上拉電阻
__enable_interrupt();//開啓中斷
while(1){
num=s%5;
switch(num){
case 0:P1OUT=0X04;break;
case 1:P1OUT=0X08;break;
case 2:P1OUT=0X10;break;
case 3:P1OUT=0X20;break;
case 4:P1OUT=0X40;break;
}
}
}
#pragma vector=PORT2_VECTOR//固定格式,聲明中斷向量地址
__interrupt void Port_2(void)
{//中斷子程序
unsigned int temp;//局部變量
int i;
for(i=0;i<12000;i++);//延時消抖
if((P2IN & 0XFF)!=0XFF){//如果有按鍵按下
temp=P2IFG;//讀取中斷標誌
P2IFG=0X00;//標誌位清零
if(temp==0x02)//如果P2.1產生中斷
s++;
}
}