logo资料库

msp430按键控制LED.docx

第1页 / 共8页
第2页 / 共8页
第3页 / 共8页
第4页 / 共8页
第5页 / 共8页
第6页 / 共8页
第7页 / 共8页
第8页 / 共8页
资料共8页,全文预览结束
按键篇
按键篇 经过一短时间的学习,下面,亲自动手编写一下程序吧。 程序的目的是:按下按键,控制 LED 的亮和灭。短按键,则小灯亮 1 秒,然后灭; 长按键,小灯常亮。 首先,完成键盘的扫描程序。 第一点:如果是扫描,就要用到定时器。我想设计定时器每隔 10ms 扫描一次按 键。 定时器,我选用定时器 A。它的定时中断函数如下: 函数名称:TimerA_ISR 功 能:定时器 A 的中断服务函数 参 数:无 返回值 :无 ********************************************/ #pragma vector = TIMERA0_VECTOR __interrupt void TimerA_ISR(void) { GetKey(); } 上面这个定时中断函数的意思就是:每当定时时间到了以后,就调用 GetKey() 函数一次。GetKey()函数就是扫描键盘按键的函数了。在 GetKey()函数中,会 根据按键类型(长按/短按)返回不同的数值。根据返回的数值,做小灯亮法的 操作。那么,返回的这个值,我们需要保存在一个变量中,在这里定义一个变量 uchar FlagLcd ; 来保存返回值。这个变量在全局变量中定义,以保证它的作用 域。 那么定时函数就变为 #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 来完成这个任务。
在主程序中定义全局变量 unsigned int TIME_1_S=0;然后再定时器中断函数中 做些改动 #pragma vector = TIMERA0_VECTOR __interrupt void TimerA_ISR(void) { FlagLcd =GetKey(); If(FlagLcd==1) TIME_1_S=1; If((TIME_1_S>0)&&( TIME_1_S<100)) TIME_1_S++; Else TIME_1_S=0; } 这样,在控制 LED 的时候,可以这样写 If(TIME_1_S>0) P2OUT = 0xfe; Else P2OUT = 0xff; 就实现了亮 1S 的效果。 那么长按键的时候呢,则需要再做一下处理。 在主程序中定义全局变量 unsigned int TIME_L_S=0;然后再定时器中断函数中 做些改动 #pragma vector = TIMERA0_VECTOR __interrupt void TimerA_ISR(void) { FlagLcd =GetKey(); If(FlagLcd==1) TIME_1_S=1; If((TIME_1_S>0)&&( TIME_1_S<100)) TIME_1_S++; Else TIME_1_S=0; If(FlagLcd==2) TIME_L_S=1; } If((TIME_1_S>0)||( TIME_L_S==1)) P2OUT = 0xfe; Else P2OUT = 0xff; 到这里,基本的实现函数都已经完成了。剩下的事情,就是把相关框架搭建一下
了 第一:是 main.c 文件 #include #include "key.h" unsigned char FlagLcd ; unsigned int TIME_L_S=0; unsigned int TIME_1_S=0; void main(void) { P1DIR = 0XFF;P1OUT = 0XFF; P2DIR = 0XFF;P2OUT = 0XFF; P3DIR = 0XFF;P3OUT = 0XFF; P4DIR = 0XFF;P4OUT = 0XFF; P5DIR = 0XFF;P5OUT = 0XFF; P6DIR = 0XFF;P6OUT = 0XFF; WDTCTL = WDTPW + WDTHOLD; //关闭看门狗 P6DIR |= BIT2;P6OUT |= BIT2; //关闭电平转换 CCTL0 = CCIE; //使能 CCR0 中断 CCR0 = 40; //设定周期 0.01S TACTL = TASSEL_1 + ID_3 + MC_1; //定时器 A 的时钟源选择 ACLK,增计数模 式 P2DIR = 0xff; //设置 P2 口方向为输出 P2OUT = 0xff; //设置 P2 口输出高电平 Init_Keypad(); _EINT();//使能全局中断 while(1) { if((TIME_1_S>0)||( TIME_L_S==1)) P2OUT = 0xfe; else P2OUT = 0xff; } } #pragma vector = TIMERA0_VECTOR
__interrupt void TimerA_ISR(void) { FlagLcd =GetKey(); if(FlagLcd==1) TIME_1_S=1; if((TIME_1_S>0)&&( TIME_1_S<100)) TIME_1_S++; else TIME_1_S=0; if(FlagLcd==2) TIME_L_S=1; } 第二:key.c 文件 #include void Init_Keypad(void) { P1DIR = 0xfe; //P1.0 设置为输入状态, P1.1~P1.7 设置为输出状态 P1OUT &= 0x7f; // P1.1~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,相当于是消抖过程 { 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; } 第三:key.h 文件 void Init_Keypad(void); unsigned char GetKey();
分享到:
收藏