前言
实践是巩固知识最好的方法,在初步学习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;
}
}
}
该处为按键消抖部分,在做硬件方面的实验时会由于硬件设备本身的缘故产生误差,从而影响实验结果,这里按键触发中断时可能会因为周围的干扰或这自身的抖动,使按键多次短暂(时间非常非常短)闭合,从而多次触发中断,影响变量值,产生误差。
总结
多练多思考,不要只限于书本上的例程,通过自己思考,做自己设想出的实验,在这过程中你会收获更多。