今年大二 开学大三 玩M0有一年了 暑假无事 小弟M0写的按键扫描的 请匠人、菜农各位大侠拍砖,M0搞了一个调度器,暑假不出去游玩的话 ,应该可以完成,到时上传源码,请高手指点:D
main.c
#include "LPC11xx.h" /* LPC11xx 外设寄存器定义 */
#include "gpio.h"
#include "uart.h"
#include "key.h"
#include "systick.h"
uint8_t TMR20MS;
uint8_t TMR40MS;
uint32_t key =0 ;
void TimeEvent(void);
void DelayMS(uint32_t dly)
{
uint32_t i;
while (dly-- > 0) {
for(i = SystemFrequency / 1000; i > 0; i--); /* 延时1ms */
}
}
int main (void)
{
uint8_t datatest[] = "sunshitao" ;
SystemInit(); /* 系统初始化 */
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 6);
KeyPin_init();
UARTInit(115200);
SysTick_Config( 200000 ); //系统定时时间4mS
UARTSend(datatest, 10);
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 16);
KeyQueue.out = 0;
KeyQueue.in = 0;
while (1) {
TimeEvent();
}
}
void TimeEvent(void)
{
uint8_t KeyValue;
if(TMRInt4ms标志寄存器){
TMRInt4ms标志寄存器 = 0;
if(++TMR20MS > 5){
TMR20MS = 0;
KeyFSM();
}
if(++TMR40MS > 10){
TMR40MS = 0;
KeyValue = KeyRead();
if(KeyValue != 0xff){
UARTSend(&KeyValue,1);
}
}
}
}
/********************************************************************************************************
** End Of File
********************************************************************************************************/
key.h
#ifndef KEY_H_
#define KEY_H_
#define P0KEYMASKEDIN 0x8FE
#define P2KEYMASKEDOUT 0xFF
#define X0 ( 0xFE )
#define X1 ( 0xFD )
#define X2 ( 0xFB )
#define X3 ( 0xF7 )
#define X4 ( 0xEF )
#define X5 ( 0xDF )
#define X6 ( 0xBF )
#define X7 ( 0x7F )
#define Y0 (0x8FC)
#define Y1 (0x8FA)
#define Y2 (0x8F6)
#define Y3 (0x8EE)
#define Y4 (0x8DE)
#define Y5 (0x8BE)
#define Y6 (0x87E)
#define Y7 (0x0FE)
#define UNVALID 0xFF
#define PULL_DOWNBIT ( 1 << 3 )
#define KeyQLEN 8
typedef struct {
uint8_t KeyBuffer[KeyQLEN];
uint8_t out;
uint8_t in;
} KeyQ;
extern KeyQ KeyQueue;
extern void KeyPin_init(void);
extern uint32_t Key_scan(void);
extern uint8_t KeyFSM(void );
extern uint8_t KeyRead(void);
#endif
key.c
#include "LPC11xx.h"
#include "uart.h"
#include "gpio.h"
#include "key.h"
#define LED1 (1 << 0)
#define LED1INIT() LPC_IOCON->PIO3_0 &= ~0x07;LPC_GPIO3->DIR |= LED1
#define LED1OFF() LPC_GPIO3->MASKED_ACCESS[LED1] = LED1
#define LED1ON() LPC_GPIO3->MASKED_ACCESS[LED1] = 0
enum KeyFSM_Enum //按键状态有限状态机
{
_Key_Idle=0,
_Key1_down,
_Key1_press,
_Key1_up,
_Key_confirm,
};
KeyQ KeyQueue;
void KeyPin_init(void)
{
//PIO0_1--PIO0_7保留chip默认设置;PIO0_11设置为IO口
//PIO2_0--PIO22_7保留chip默认设置
LPC_IOCON->PIO0_1 |= PULL_DOWNBIT;
LPC_IOCON->PIO0_2 |= PULL_DOWNBIT;
LPC_IOCON->PIO0_3 |= PULL_DOWNBIT;
LPC_IOCON->PIO0_4 |= PULL_DOWNBIT;
LPC_IOCON->PIO0_5 |= PULL_DOWNBIT;
LPC_IOCON->PIO0_6 |= PULL_DOWNBIT;
LPC_IOCON->PIO0_7 |= PULL_DOWNBIT;
LPC_IOCON->R_PIO0_11 |= 0x01;//PIO0_11默认不是IO口,配置为IO口
LPC_IOCON->R_PIO0_11 |= PULL_DOWNBIT;
LPC_GPIO0->DIR &= 0x0701 ; //PIO0_1--PIO0_7、PIO0_11设置为输入
LPC_GPIO2->DIR |= 0xFF; //PIO2_0--PIO2_7 设置为输出
LPC_GPIO2->MASKED_ACCESS[0xFF] = 0xFF;
LED1INIT();
}
uint32_t Key_scan(void)
{
uint32_t Key_coordinate;
uint32_t Y_coordinate = 0x0;
Key_coordinate = UNVALID ;
LPC_GPIO2->MASKED_ACCESS[P2KEYMASKEDOUT] = X0; //p2.0输出低电平 扫描X0
Y_coordinate = LPC_GPIO0->MASKED_ACCESS[P0KEYMASKEDIN];
if( (Y_coordinate & P0KEYMASKEDIN ) != P0KEYMASKEDIN ){
switch ( Y_coordinate ) {
case Y0 : Key_coordinate = 0x00;
break;
case Y1 : Key_coordinate = 0x01;
break;
case Y2 : Key_coordinate = 0x02;
break;
case Y3 : Key_coordinate = 0x03;
break;
case Y4 : Key_coordinate = 0x04;
break;
case Y5 : Key_coordinate = 0x05;
break;
case Y6 : Key_coordinate = 0x06;
break;
case Y7 : Key_coordinate = 0x07;
break;
default : ;
break;
}
return (Key_coordinate);
}
LPC_GPIO2->MASKED_ACCESS[P2KEYMASKEDOUT] = X1 ; //p2.1输出低电平 扫描X1
Y_coordinate = LPC_GPIO0->MASKED_ACCESS[P0KEYMASKEDIN];
if( (Y_coordinate & P0KEYMASKEDIN) != P0KEYMASKEDIN ){
switch ( Y_coordinate ) {
case Y0 : Key_coordinate = 0x10;
break;
case Y1 : Key_coordinate = 0x11;
break;
case Y2 : Key_coordinate = 0x12;
break;
case Y3 : Key_coordinate = 0x13;
break;
case Y4 : Key_coordinate = 0x14;
break;
case Y5 : Key_coordinate = 0x15;
break;
case Y6 : Key_coordinate = 0x16;
break;
case Y7 : Key_coordinate = 0x17;
break;
default : ;
break;
}
return (Key_coordinate);
}
LPC_GPIO2->MASKED_ACCESS[P2KEYMASKEDOUT] = X2 ; //p2.2输出低电平 扫描X2
Y_coordinate = LPC_GPIO0->MASKED_ACCESS[P0KEYMASKEDIN];
if( (Y_coordinate & P0KEYMASKEDIN) != P0KEYMASKEDIN ){
switch ( Y_coordinate ) {
case Y0 : Key_coordinate = 0x20;
break;
case Y1 : Key_coordinate = 0x21;
break;
case Y2 : Key_coordinate = 0x22;
break;
case Y3 : Key_coordinate = 0x23;
break;
case Y4 : Key_coordinate = 0x24;
break;
case Y5 : Key_coordinate = 0x25;
break;
case Y6 : Key_coordinate = 0x26;
break;
case Y7 : Key_coordinate = 0x27;
break;
default : ;
break;
}
return (Key_coordinate);
}
LPC_GPIO2->MASKED_ACCESS[P2KEYMASKEDOUT] = X3 ; //p2.3输出低电平 扫描X3
Y_coordinate = LPC_GPIO0->MASKED_ACCESS[P0KEYMASKEDIN];
if( (Y_coordinate & P0KEYMASKEDIN) != P0KEYMASKEDIN ){
switch ( Y_coordinate ) {
case Y0 : Key_coordinate = 0x30;
break;
case Y1 : Key_coordinate = 0x31;
break;
case Y2 : Key_coordinate = 0x32;
break;
case Y3 : Key_coordinate = 0x33;
break;
case Y4 : Key_coordinate = 0x34;
break;
case Y5 : Key_coordinate = 0x35;
break;
case Y6 : Key_coordinate = 0x36;
break;
case Y7 : Key_coordinate = 0x37;
break;
default : ;
break;
}
return (Key_coordinate);
}
LPC_GPIO2->MASKED_ACCESS[P2KEYMASKEDOUT] = X4 ; //p2.4输出低电平 扫描X4
Y_coordinate = LPC_GPIO0->MASKED_ACCESS[P0KEYMASKEDIN];
if( (Y_coordinate & P0KEYMASKEDIN ) != P0KEYMASKEDIN ){
switch ( Y_coordinate ) {
case Y0 : Key_coordinate = 0x40;
break;
case Y1 : Key_coordinate = 0x41;
break;
case Y2 : Key_coordinate = 0x42;
break;
case Y3 : Key_coordinate = 0x43;
break;
case Y4 : Key_coordinate = 0x44;
break;
case Y5 : Key_coordinate = 0x45;
break;
case Y6 : Key_coordinate = 0x46;
break;
case Y7 : Key_coordinate = 0x47;
break;
default : ;
break;
}
return (Key_coordinate);
}
LPC_GPIO2->MASKED_ACCESS[P2KEYMASKEDOUT] = X5 ; //p2.4输出低电平 扫描X4
Y_coordinate = LPC_GPIO0->MASKED_ACCESS[P0KEYMASKEDIN];
if( (Y_coordinate & P0KEYMASKEDIN ) != P0KEYMASKEDIN ){
switch ( Y_coordinate ) {
case Y0 : Key_coordinate = 0x50;
break;
case Y1 : Key_coordinate = 0x51;
break;
case Y2 : Key_coordinate = 0x52;
break;
case Y3 : Key_coordinate = 0x53;
break;
case Y4 : Key_coordinate = 0x54;
break;
case Y5 : Key_coordinate = 0x55;
break;
case Y6 : Key_coordinate = 0x56;
break;
case Y7 : Key_coordinate = 0x57;
break;
default : ;
break;
}
return (Key_coordinate);
}
LPC_GPIO2->MASKED_ACCESS[P2KEYMASKEDOUT] = X6 ; //p2.4输出低电平 扫描X4
Y_coordinate = LPC_GPIO0->MASKED_ACCESS[P0KEYMASKEDIN];
if( (Y_coordinate & P0KEYMASKEDIN ) != P0KEYMASKEDIN ){
switch ( Y_coordinate ) {
case Y0 : Key_coordinate = 0x60;
break;
case Y1 : Key_coordinate = 0x61;
break;
case Y2 : Key_coordinate = 0x62;
break;
case Y3 : Key_coordinate = 0x63;
break;
case Y4 : Key_coordinate = 0x64;
break;
case Y5 : Key_coordinate = 0x65;
break;
case Y6 : Key_coordinate = 0x66;
break;
case Y7 : Key_coordinate = 0x67;
break;
default : ;
break;
}
return (Key_coordinate);
}
LPC_GPIO2->MASKED_ACCESS[P2KEYMASKEDOUT] = X7 ; //p2.4输出低电平 扫描X4
Y_coordinate = LPC_GPIO0->MASKED_ACCESS[P0KEYMASKEDIN];
if( (Y_coordinate & P0KEYMASKEDIN ) != P0KEYMASKEDIN ){
switch ( Y_coordinate ) {
case Y0 : Key_coordinate = 0x70;
break;
case Y1 : Key_coordinate = 0x71;
break;
case Y2 : Key_coordinate = 0x72;
break;
case Y3 : Key_coordinate = 0x73;
break;
case Y4 : Key_coordinate = 0x74;
break;
case Y5 : Key_coordinate = 0x75;
break;
case Y6 : Key_coordinate = 0x76;
break;
case Y7 : Key_coordinate = 0x77;
break;
default : ;
break;
}
return (Key_coordinate);
}
return ( Key_coordinate );
}
uint8_t KeyFSM(void)
{
static uint32_t KeyTemp = UNVALID;
uint32_t NewKey = UNVALID;
static uint8_t KeyState = 0;
NewKey = Key_scan();
if((NewKey == UNVALID)&&(KeyState != _Key1_press)&&(KeyState != _Key1_up)){
return 0;
}
switch(KeyState) {//状态机
case _Key_Idle:{//空闲
KeyTemp = NewKey;//保存键值
KeyState = _Key1_down;//单键按下消抖
break;
}
case _Key1_down:{//单键按下消抖
if(NewKey == KeyTemp){//键值不变
KeyState = _Key1_press;
} else {//单键按下
KeyState = _Key_Idle;//空闲
}
break;
}
case _Key1_press:{//单键按下
if(NewKey != KeyTemp)//键值改变
KeyState = _Key1_up;//单键抬起消抖
break;
}
case _Key1_up:{//单键抬起消抖
if(NewKey == KeyTemp){//键值不变
KeyState = _Key1_press;//单键按下
} else {
KeyState = _Key_confirm;//按键确认成功
}
break;
}
default:{
KeyState = _Key_Idle;//空闲
break;
}
}
if(KeyState == _Key_confirm){//按键确认成功
KeyState = _Key_Idle;//空闲
//放入键值缓冲区中
if(KeyTemp != UNVALID){//如果键值有效,则放入缓冲区中
KeyQueue.KeyBuffer[KeyQueue.in++] = KeyTemp;
if(KeyQueue.in >= KeyQLEN){//如果"写"跑到了队列尾部,则重新跳回原点
KeyQueue.in=0;
}
return 1;
}
return 0;
}
return 0;
}
uint8_t KeyRead(void)
{
uint8_t Value;
if(KeyQueue.out != KeyQueue.in){
Value=KeyQueue.KeyBuffer[KeyQueue.out ;
if(KeyQueue.out >= KeyQLEN) {
KeyQueue.out=0;
}
} else {
Value=UNVALID
}
return(Value);
}
systick.h
#ifndef SYSTICK_H_
#define SYSTICK_H_
extern volatile uint32_t TimeTick;
extern volatile uint32_t TMRInt4ms标志寄存器 ;
#endif
systick.c
#include "LPC11xx.h"
#include "systick.h"
#include "uart.h"
volatile uint32_t TimeTick = 0;
volatile uint32_t TMRInt4ms标志寄存器 = 0;
void SysTick_Handler(void)
{
TimeTick++;
TMRInt4ms标志寄存器 = 1;
} |