LPC1768的按键输入 按键是常用的输入设备,在实际应用中得到广泛应用!其中用的比较多的是独立按键和矩阵键盘,独立按键适合按键数量较少,矩阵键盘时候按键较多的情况。独立按键的读取是比较容易的。由原理图可知,我们的按键外部有上拉电阻,在没有按键按下的时候,读取端口是高电平,在有按键按下的时候,按键所在端口是低电平。这样我们的IO 口就可以读出是否有按键按下了。然而按键是机械装置,在按下和弹起时都有抖动。一般的防抖方法有硬件防抖和软件防抖,硬件防抖是在按键输入IO 口中加入施密特触发器,会引入硬件成本。而为了节约成本一般采用软件防抖,软件防抖的一般方法是2 次读取中间加一个ms 级延时,若2 次读取都是低电平,则说明有键按下。在按键的操作过程中我们一般还要求按键按下依次只读出一个按下状态,一般的做法是:在按下键盘后就在程序中使用一个while 循环等待按键的松开,在低速8 位单片机上这样做没什么不好,但是如果在32 位ARM上这样做将是浪费了宝贵的时间片资源。本程序采用一种状态存储的方法将上一次按键的状态存储,若这次检测到按键按下上一次也检测到按键按下,那么我们认为按键没有被松开!不作处理。若这次按下时读上一次保存的状态是没有被按下,那么这是一个新的按键信息,应当被处理! 下面是按键实验的主函数: #include "lpc17xx.h" // 包含头文件,头文件内保护系统初始化头文件 #include "uart.h" //包含串口所使用的头文件 //***************************************************** uint32_t msTicks,sign=0; //变量定义 extern volatile uint32_t UART0Count; //串口接收数据计数 extern volatile uint8_t UART0Buffer[BUFSIZE]; //串口数据接受缓存 //extern volatile uint32_t UART1Count; //extern volatile uint8_t UART1Buffer[BUFSIZE]; unsigned char table[]={"key 0 down!\n"}; uint32_t key_old=0,LED=0x0000000f; //key_Old 保存按键上一次按下的值 LED LED 灯的状态 //***************************************************** /****************** 函数声明区 *************************/ void key(void); /******** main **********************************/ int main(void) { SystemInit(); //系统初始化函数 UARTInit(0,9600); //UART 初始化,第一个参数是端口,第二个参数是波特率 LPC_SC->PCONP|=(1<<15); //功耗控制,此处可以注释掉,因为复位后GPIO 默认开启 LPC_GPIO2->FIODIR=0x0000000f; //只将P2口的低4 位设置成输出模式 LPC_GPIO2->FIOSET=0x0000000F; //GPIO 置位,当某位为1 则置位,为0不变 UARTSend(0,table,15); while(1) { key(); if ( UART0Count != 0 ) //判断是否有数据接受到 { LPC_UART0->IER = IER_THRE | IER_RLS; /* Disable RBR */ UARTSend( 0, (uint8_t *)UART0Buffer, UART0Count ); //将接受的数据返回去 UART0Count = 0; LPC_UART0->IER = IER_THRE | IER_RLS | IER_RBR; /* Re-enable RBR */ } } } /************************************************************/ void key(void) { uint32_t key=0,i=0; key=LPC_GPIO2->FIOPIN; //读是否有按键按下 key=key&0x00001c00; //只观测三个按键的值,屏蔽其他位 if(key!=0x00001c00) //如果有按键按下 { for(i=0;i<5000;i++); //延时一小段时间 防止按键抖动 key=LPC_GPIO2->FIOPIN; //再次读取端口状态 key=key&0x00001c00; //屏蔽其他位 if(key!=0x00001c00) //是否有按键按下 { switch(key) //判断是那一个按键 { case 0x00001800: //第一个按键(P2.10)按下 if(1!=(key_old&1)) //查看上一次这个按键是否按下 如果上次也是按下的 { //说明按键没有松开 不做处理 否则键按下 if((LED&1)==1) //LED 灯取反 LED&=~1; else LED|=1; key_old|=1; //将这一次按键的状态存储起来 table[4]=1+0x30; //修改字符串 UARTSend(0,table,15); //串口发送 } break; case 0x00001400: //第二个按键(P2.11)按下 if(2!=(key_old&2)) { if((LED&2)==2) LED&=~2; else LED|=2; key_old|=2; table[4]=2+0x30; UARTSend(0,table,15); } break; case 0x00000c00: // 第三个按键(P2.12)按下 if(4!=(key_old&4)) { if((LED&4)==4) LED&=~4; else LED|=4; key_old|=4; table[4]=3+0x30; UARTSend(0,table,15); } break; } LPC_GPIO2->FIOPIN=LED; //更新LED状态 } } else { key_old=0; //没有键按下 更新上次按键“均没有被按 下”! } } /***********************************************************/
|