📄 keyboardscan.c
字号:
/*! @file
********************************************************************************
模块名 : 基于MSP430F1611和CH452的键盘扫描程序
文件名 : KeyboardScan.c
相关文件 : in430.h
intrinsics.h
msp430x16x.h
stdarg.h
stdio.h
sysmac.h
实现功能 : 实现读取键值的功能
作者 : 余刚
版本 : 1.0
完成日期 : 2006 年 10 月 16 日
--------------------------------------------------------------------------------
备注 : 无
--------------------------------------------------------------------------------
修改记录 :
日 期 版本 修改人 修改内容
*********************************************************************
版权所有(c) 2006, 余刚, 保留所有权利
******************************************************************************/
/******************************************************************************************
********* DCLK <--- P5.5 **********************
********* DIN <--- P5.6 **********************
********* LOAD <--- P5.7 **********************
********* DOUT ---> P2.4 **********************
*******************************************************************************************/
#include <stdio.h>
#include <msp430x16x.h>
//定义信号常量
#define DCLK_1 {P5OUT|=BIT5;}//定义DCLK高、低电平信号
#define DCLK_0 {P5OUT&=~BIT5;}
#define DIN_1 {P5OUT|=BIT6;}//定义DIN高、低电平信号
#define DIN_0 {P5OUT&=~BIT6;}
#define LOAD_1 {P5OUT|=BIT7;}//定义LOAD高、低电平信号
#define LOAD_0 {P5OUT&=~BIT7;}
//定义键值常量
#define RModeKey 0x01 //"读取"
#define WModeKey 0x02 //"写入"
#define TModeKey 0x03 //""
#define LeftKey 0x04 //"左移"
#define RightKey 0x05 //"右移"
#define UpKey 0x06 //"上移"
#define DownKey 0x07 //"下移"
#define Key0 0x08 //"0"
#define Key1 0x09 //"1"
#define Key2 0x0a //"2"
#define Key3 0x0b //"3"
#define Key4 0x0c //"4"
#define Key5 0x0d //"5"
#define Key6 0x0e //"6"
#define Key7 0x0f //"7"
#define Key8 0x10 //"8"
#define Key9 0x11 //"9"
#define KeyDot 0x12 //"."
#define TransKey 0x13 //"传输"
#define BackKey 0x14 //"<--"
#define EnterKey 0x15 //"确认"
#define CheckKey 0x16 //"检测"
#define SpaceKey 0x17 //"空格"
#define F1Key 0x18 //"F1"
#define F2Key 0x19 //"F2"
#define F3Key 0x1a //"F3"
#define F4Key 0x1b //"F4"
#define F5Key 0x1c //"F5"
#define F6Key 0x1d //"F6"
//定义队列
#define KEY_QUEUE_SIZE 30 //队列长度
unsigned char KeyQueue[KEY_QUEUE_SIZE]; //存放按键的队列
//定义其他全局变量
int temp=-1; //队列下标
int flag=0; //队列放满标志
//定义CH452命令
#define Sys_Parameter 0x402 //系统参数,开启键盘扫描功能,关闭显示功能
#define Read_Keyboard 0x700 //读取键盘代码
#define Internal_Reset 0x201 //CH452内部复位
//延时函数
void Delay(int n)//延时,时间为 n
{
int i;
for(i=0;i<n;i++);//循环n次
}
//初始化系统时钟函数
void Init_CLK()//初始化MCU时钟
{
unsigned int i;
BCSCTL1 = 0X00; //将寄存器的内容清零
WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
BCSCTL1 &= ~XT2OFF; //选用外部晶振
do
{
IFG1 &=~OFIFG; //清OFIFG中断
for (i = 0xff; i>0; i--);
}
while ((IFG1 & OFIFG) != 0);
BCSCTL2 |= (SELM1 + SELS); // 0x80|0x08|0x02 mclk=8 MHz
}
//初始化4线工作模式函数
void Init_4lines_Mode(void)//初始化4线工作模式
{
//初始化P5端口,P5.5接CH452的DCLK引脚,P5.6接CH452的DIN引脚,P5.7接CH452的LOAD引脚
P5DIR|=BIT5+BIT6+BIT7;
P2DIR&=~BIT4;
//初始化DCLK、DIN和LOAD
DCLK_1;
DIN_1;
LOAD_1;
}
//发送一个Bit
void Send_A_Bit(unsigned n)//MSP430单片机向CH452发送一个比特
{
DCLK_0;
if(n==1)
{
DIN_1;
Delay(100);
DCLK_1;
Delay(100);
}
else
{
DIN_0;
Delay(100);
DCLK_1;
Delay(100);
}
}
//发送命令
void Send_Command(unsigned Command)//MSP430单片机向CH452发送命令,Command为12位数据
{
int i;
LOAD_0;
for(i=0;i<12;i++)
{
if((Command&0x001)) //如果最低位为1,发送1
Send_A_Bit(1);
else //如果最低位为0,发送0
Send_A_Bit(0);
Command>>=1;
}
LOAD_1;
}
//接收一个比特
unsigned char Receive_A_Bit(void)//接收一个Bit
{
unsigned char subtemp;
if(P2IN & BIT4)
{
subtemp=0x01;
}
else
{
subtemp=0x00;
}
DCLK_0;
Delay(100);
DCLK_1;
Delay(100);
return(subtemp);
}
//接收按键值
unsigned char Receive_Key_Value(void)
{
unsigned char Keyvalue = 0x00;//用于存储按键代码
int i;
unsigned char NewBit;
for(i=0;i<7;i++)
{
Keyvalue<<=1;
NewBit=Receive_A_Bit();
Keyvalue|=NewBit;
}
Keyvalue&=0x7F;
return(Keyvalue);
}
//从队列中取键值
unsigned char Get_Key_Value()
{
int i;
unsigned char Keyvalue;
Keyvalue=KeyQueue[0];
for(i=0;i<KEY_QUEUE_SIZE-1;i++)
{
KeyQueue[i]=KeyQueue[i+1];
}
KeyQueue[KEY_QUEUE_SIZE-1]=0x00;
return(Keyvalue);
}
//主函数
void main(void)
{
int i;
Init_CLK(); //设置系统时钟
Init_4lines_Mode();
Send_Command(Internal_Reset);
Send_Command(Sys_Parameter);
for(i=0;i<KEY_QUEUE_SIZE;i++)
KeyQueue[i]=0x00;
//开中断,P2.4接CH452的DOUT引脚,当有键按下时,DOUT上产生由高到低的脉冲
P2IE|=BIT4;
P2IES|=BIT4;
P2IFG&=~BIT4;
_EINT();
while(1)
{
}
}
//中断处理函数
#pragma vector = PORT2_VECTOR//中断处理程序,接收到DOUT脉冲信号时,运行之
__interrupt void Port2(void)
{
int i; //i,j循环变量
unsigned char Keyvalue;
for(i=0;i<KEY_QUEUE_SIZE;i++)
{
if(!KeyQueue[i])//若队列未放满,存储在空余位置
{
temp=i;
flag=1; //队列未满,标志置1
break;
}
else
flag=0;
}
if(flag) //若队列未满,读取键值
{
Send_Command(Read_Keyboard);
Keyvalue=Receive_Key_Value();
switch(Keyvalue)
{
case 0x4c:
{
KeyQueue[temp]=TransKey;
break;
}
case 0x4d:
{
KeyQueue[temp]=DownKey;
break;
}
case 0x4e:
{
KeyQueue[temp]=CheckKey;
break;
}
case 0x4f:
{
KeyQueue[temp]=F6Key;
break;
}
case 0x54:
{
KeyQueue[temp]=LeftKey;
break;
}
case 0x55:
{
KeyQueue[temp]=EnterKey;
break;
}
case 0x56:
{
KeyQueue[temp]=RightKey;
break;
}
case 0x57:
{
KeyQueue[temp]=F5Key;
break;
}
case 0x5c:
{
KeyQueue[temp]=RModeKey;
break;
}
case 0x5d:
{
KeyQueue[temp]=UpKey;
break;
}
case 0x5e:
{
KeyQueue[temp]=WModeKey;
break;
}
case 0x5f:
{
KeyQueue[temp]=F4Key;
break;
}
case 0x64:
{
KeyQueue[temp]=Key9;
break;
}
case 0x65:
{
KeyQueue[temp]=Key0;
break;
}
case 0x66:
{
KeyQueue[temp]=KeyDot;
break;
}
case 0x67:
{
KeyQueue[temp]=SpaceKey;
break;
}
case 0x6c:
{
KeyQueue[temp]=Key5;
break;
}
case 0x6d:
{
KeyQueue[temp]=Key6;
break;
}
case 0x6e:
{
KeyQueue[temp]=Key7;
break;
}
case 0x6f:
{
KeyQueue[temp]=Key8;
break;
}
case 0x74:
{
KeyQueue[temp]=Key1;
break;
}
case 0x75:
{
KeyQueue[temp]=Key2;
break;
}
case 0x76:
{
KeyQueue[temp]=Key3;
break;
}
case 0x77:
{
KeyQueue[temp]=Key4;
break;
}
case 0x7c:
{
KeyQueue[temp]=F1Key;
break;
}
case 0x7d:
{
KeyQueue[temp]=F2Key;
break;
}
case 0x7e:
{
KeyQueue[temp]=F3Key;
break;
}
case 0x7f:
{
KeyQueue[temp]=BackKey;
break;
}
default:break;
}
}
P2IFG&=~BIT4;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -