前言
實踐是鞏固知識最好的方法,在初步學習MSP430F5529時,我們最容易做的實驗,便是“點燈”,下面分享的是我自己設計的一個綜合性“點燈實驗”
實驗內容:通過P1.1控制P1.0,P4.7的LED燈亮滅,用P2.1切換燈亮滅的樣式,
MSP430F5529按鍵點燈與切換
代碼如下:
#include <msp430.h>
/**
* main.c
*/
//實作效果:P1.1按鍵控制燈的亮滅,P2.1按鍵按下產生中斷,在中斷程式中改變全域變數I,再次按下P1.1,進入中斷程式,通過判斷I的值,切換不同的燈光效果
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
P1DIR |= BIT0;
P4DIR |= BIT7; //P1.0,P4.7口設定為輸出
P1OUT &= ~BIT0;
P4OUT &= ~BIT7; //初始化P1.0,P4.7輸出低電平(初始化LED燈為滅)
P1DIR &= ~BIT1;
P2DIR &= ~BIT1; //設定P1.1,P2.1口為輸入
P1REN |= BIT1;
P2REN |= BIT1;
P1OUT |= BIT1;
P2OUT |= BIT1; //配置P1.1,P2.1上拉電阻
P1IES |= BIT1;
P2IES |= BIT1; //P1.1,P2.1下降沿觸發中斷
P1IE |= BIT1;
P2IE |= BIT1; //P1.1,P2.1中斷使能
P1IFG &= ~BIT1;
P2IFG &= ~BIT1; //清除中斷標志位
_EINT(); //打開全域中斷允許中斷嵌套
}
int led1,led2,led3,led4,led5,led6,led7,led8;
int I; //在定時中斷中判斷小燈的組合方式
//P1口中斷服務程式
#pragma vector = PORT1_VECTOR
__interrupt void P1_ISR()
{
if(P1IFG&BIT1)
{
while((P1IN&BIT1)==0) //P1.1為按下狀態
{
TA0CCTL0 = CCIE; //CCR0中斷使能
TA0CCR0 = 327; //10MS一次中斷
TA0CTL = TASSEL_1 + MC_1 + TACLR; //ACLK, upmode, clear TAR
}
}
P1IFG &= ~BIT1; //清楚中斷標志
}
//定時器中斷程式
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR(void)
{
//*********model 1******************
led1=(led1+1)%50;
if((led1<25)&&(I==0))
{
P1OUT |= BIT0;
}
else if((led1>=25)&&(I==0))
{
P1OUT &= ~BIT0;
}
led2=(led2+1)%100;
if((led2<75)&&(I==0))
{
P4OUT |= BIT7;
}
else if((led2>=75)&&(I==0))
{
P4OUT &= ~BIT7;
}
//*********model 2******************
led3=(led3+1)%100;
if((led3<75)&&(I==1))
{
P1OUT |= BIT0;
}
else if((led3>=75)&&(I==1))
{
P1OUT &= ~BIT0;
}
led4=(led4+1)%50;
if((led4<25)&&(I==1))
{
P4OUT |= BIT7;
}
else if((led4>=25)&&(I==1))
{
P4OUT &= ~BIT7;
}
//*********model 3******************
led5=(led5+1)%20;
if((led5<10)&&(I==2))
{
P4OUT |= BIT7;
}
else if((led5>=10)&&(I==2))
{
P4OUT &= ~BIT7;
}
led6=(led6+1)%50;
if((led6<35)&&(I==2))
{
P1OUT |= BIT0;
}
else if((led6>=35)&&(I==2))
{
P1OUT &= ~BIT0;
}
//*********model 4******************
led7=(led7+1)%100;
if((led7<90)&&(I==3))
{
P1OUT |= BIT0;
}
else if((led7>=90)&&(I==3))
{
P1OUT &= ~BIT0;
}
led8=(led8+1)%100;
if((led8<30)&&(I==3))
{
P4OUT |= BIT7;
}
else if((led8>=30)&&(I==3))
{
P4OUT &= ~BIT7;
}
}
//P2口中斷服務程式
#pragma vector = PORT2_VECTOR
__interrupt void P2_ISR()
{
int n,a;
TA0CCTL0 = 0 ; //退出由P1.1觸發的定時器中斷
if((P2IN&BIT1)==0)
{
for(a=0;a<=1000;a++) //按鍵的消抖功能:檢測1000次,將<900的過濾掉(由于按鍵抖動產生的毛刺干擾)
{
if((P2IN&BIT1)==0)
n++;
}
if(n>=900)
{
I=I+1;
if(I==4) //控制I,使現象可回圈
{
I=0;
}
}
}
P2IFG &= ~BIT1;
}
容易忽略的地方
代碼如下:
if((P2IN&BIT1)==0)
{
for(a=0;a<=1000;a++) //按鍵的消抖功能:檢測1000次,將<900的過濾掉(由于按鍵抖動產生的毛刺干擾)
{
if((P2IN&BIT1)==0)
n++;
}
if(n>=900)
{
I=I+1;
if(I==4) //控制I,使現象可回圈
{
I=0;
}
}
}
該處為按鍵消抖部分,在做硬體方面的實驗時會由于硬體設備本身的緣故產生誤差,從而影響實驗結果,這里按鍵觸發中斷時可能會因為周圍的干擾或這自身的抖動,使按鍵多次短暫(時間非常非常短)閉合,從而多次觸發中斷,影響變數值,產生誤差,
總結
多練多思考,不要只限于書本上的例程,通過自己思考,做自己設想出的實驗,在這程序中你會識訓更多,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/280969.html
標籤:其他
上一篇:C#的Socket案例
下一篇:瘋狂跳動的測量結果
