msp430 按键控制LED 最基本程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
按键篇
经过一短时间的学习,下面,亲自动手编写一下程序吧。
程序的目的是:按下按键,控制LED的亮和灭。短按键,则小灯亮1秒,然后灭;长按键,小灯常亮。
首先,完成键盘的扫描程序。
第一点:如果是扫描,就要用到定时器。我想设计定时器每隔10ms扫描一次按键。
定时器,我选用定时器A。它的定时中断函数如下:
函数名称:TimerA_ISR
功能:定时器A的中断服务函数
参数:无
返回值:无
********************************************/
#pragma vector = TIMERA0_VECTOR
__interrupt void TimerA_ISR(void)
{
GetKey();
}
上面这个定时中断函数的意思就是:每当定时时间到了以后,就调用GetKey()函数一次。GetKey()函数就是扫描键盘按键的函数了。在GetKey()函数中,会根据按键类型(长按/短按)返回不同的数值。根据返回的数值,做小灯亮法的操作。那么,返回的这个值,我们需要保存在一个变量中,在这里定义一个变量ucharFlagLcd ; 来保存返回值。这个变量在全局变量中定义,以保证它的作用域。
那么定时函数就变为
#pragma vector = TIMERA0_VECTOR
__interrupt void TimerA_ISR(void)
{
FlagLcd =GetKey();
}
定时器中断的时间间隔,我在主函数中定义。
这样写:
CCTL0 = CCIE; //使能CCR0中断
CCR0 = 40; //设定周期0.01S
TACTL = TASSEL_1 + ID_3 + MC_1; //定时器A的时钟源选择ACLK,增计数模式
这样,定时器这块就算完工了。那么,下面进行按键扫描程序。
按键的定义是这样的,根据我板子的按键原理图如下
这是一个矩阵键盘。其中KEY就是外部高电平3.3V。我只想用其中的P1.0作为这次试验的按键。那么,做些设置就可以了。将P1.7方向设置为输出,并输出电平为低。这样,才能实现当K1按下时,P1.0输入为低;当K1抬起时,P1.0输入为高的效果。
对P1口进行初始化:
void Init_Keypad(void)
{
P1DIR = 0xfe; //P1.0设置为输入状态, P1.1~P1.7设置为输出状态
P1OUT &= 0x7f; // P1.0~P1.6输出高电平,P1.7输出低电平
}
下面是键盘扫描函数:
unsigned char GetKey()
{
unsigned char keyRetu=0; //返回的按键值
static unsigned char s_keyState=0,keyTime=0; //按键状态,按键按下的时间
计数器
switch (s_keyState)
{
case 0:
if((P1IN&0x01)==0) //检测到有按键,转到状态1,相当于是消抖过程。((P1IN&0x01)==0判断P1.0口输
入是高还是低电平
{
s_keyState=1;
}
break;
case 1:
if((P1IN&0x01)==0) //再次检测到有按键,转到状态2
{
s_keyState=2;
keyTime=0; //清零按键时间计数器
}
else
{
s_keyState=0; //没有检测到按键,说明状态0检测到是一个抖动,重新转到状态0
}
break;
case 2:
if((P1IN&0x01)==1) //检测到按键松开
{
s_keyState=0; //状态转到状态0
keyRetu=1; //输出1
}
else
{
if(++keyTime>=50) //按下时间>1s
{
s_keyState=3; //转到状态3
keyTime=0; //清零按键时间计数器
keyRetu=2; // 输出2
}
}
break;
case 3:
if((P1IN&0x01)==1) //检测到按键松开
{
s_keyState=0; //状态转到状态0
}
else
{
s_keyState=3; //转到状态3
}
break;
}
return keyRetu;
}
上面这个扫描函数,根据按键K1是长按还是短按,返回不同的值:长按,返回2;短按,返回1。
获得了返回值以后,就要对LED进行操作了。
我的板子的LED如下图
LED是LED供电高电平,这里我只想用其中的D1作为实验灯。初始化P2.0口:P2DIR = 0xff; //设置P2口方向为输出
P2OUT = 0xff; //设置P2口输出高电平
那么P2OUT = 0xfe,则LED亮;P2OUT = 0xff,则LED灭。这个很好实现。但是,怎么样才能持续亮1s呢?这个问题还需要定时器来解决。我在这里还利用定时器A来完成这个任务。