TACCTL0 &= ~CCIE; //停止发声 P2OUT = 0xf7; P1IFG = 0; return; } }
default:
while(keyin != 0x0f); //等待按键放开 P1IFG = 0; return; } }
P1IFG = 0; } //数码管7位段码:0--f
unsigned char scandata[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //记录显示位数的全局变量 unsigned char cnt = 0; //显示缓存
unsigned char Dispbuf[2];
//引用外部变量的声明
extern unsigned char key_Pressed; extern unsigned char key_val; extern unsigned char key_Flag;
void Init_Keypad(void); void Check_Key(void); void delay();
void Key_Event(void);
#include
typedef unsigned char uchar; typedef unsigned int uint;
/***************全局变量***************/
uchar key_Pressed; //按键是否被按下:1--是,0--否 uchar key_val; //存放键值
uchar key_Flag; //按键是否已放开:1--是,0--否 //设置键盘逻辑键值与程序计算键值的映射
uchar key_Map[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
/*******************************************
46
函数名称:Init_Keypad
功 能:初始化扫描键盘的IO端口 参 数:无 返回值 :无
********************************************/ void Init_Keypad(void)
{
P1DIR = 0xf0; //P1.0~P1.3设置为输入状态, P1.4~P1.7设置为输出状态 P1OUT |= 0xf0; // P1.4~P1.7输出高电平 key_Flag = 0; key_Pressed = 0; key_val = 0;
}
/********************************************* * Check_Key(),检查按键,确认键值
*********************************************/ /******************************************* 函数名称:Check_Key
功 能:扫描键盘的IO端口,获得键值 参 数:无 返回值 :无
********************************************/ void Check_Key(void) {
uchar row ,col,tmp1,tmp2;
tmp1 = 0x80;
for(row = 0;row < 4;row++) //行扫描
{
P1OUT = 0xf0; //P1.4~P1.7输出全1
P1OUT -= tmp1; //P1.4~p1.7输出四位中有一个为0 tmp1 >>=1;
if ((P1IN & 0x0f) < 0x0f) //是否P1IN的P1.0~P1.3中有一位为0 {
tmp2 = 0x01; // tmp2用于检测出那一位为0 for(col = 0;col < 4;col++) // 列检测
{
if((P1IN & tmp2) == 0x00) // 是否是该列,等于0为是 {
key_val = key_Map[row * 4 + col]; // 获取键值 return; // 退出循环 }
tmp2 <<= 1; // tmp2右移1位 } }
47
}
}
/******************************************* 函数名称:delay
功 能:延时约15ms,完成消抖功能 参 数:无 返回值 :无
********************************************/ void delay() {
uint tmp;
for(tmp = 12000;tmp > 0;tmp--); }
/******************************************* 函数名称:Key_Event
功 能:检测按键,并获取键值 参 数:无 返回值 :无
********************************************/ void Key_Event(void)
{
uchar tmp;
P1OUT &= 0x00; // 设置P1OUT全为0,等待按键输入 tmp = P1IN; // 获取 p1IN
if ((key_Pressed == 0x00)&&((tmp & 0x0f) < 0x0f)) //如果有键按下 {
key_Pressed = 1; // 如果有按键按下,设置key_Pressed标识 delay(); //消除抖动
Check_Key(); // 调用check_Key(),获取键值
}
else if ((key_Pressed == 1)&&((tmp & 0x0f) == 0x0f)) //如果按键已经释放 {
key_Pressed = 0; // 清除key_Pressed标识 key_Flag = 1; // 设置key_Flag标识 } else {
_NOP(); }
}
/*********************************************** 程序功能:扫描4X4键盘并将键值在数码管上显示
48
------------------------------------------------ 跳线设置:将跳线座J3上的短路帽拔下 ------------------------------------------------
测试说明:按动K1~K16按键,观察数码管显示 ************************************************/ #include
/********************主函数********************/ void main(void)
{
BoardConfig(0x88); //打开数码管,关闭流水灯和电平转换
WDTCTL = WDT_ADLY_1_9; //设置内部看门狗工作在定时器模式,1.9ms中断一次 IE1 |= WDTIE; //使能看门狗中断
P4DIR = 0xff; //设置P4,P5的IO方向为输出 P5DIR = 0xff;
P4OUT = 0x00; //设置P4,P5的输出初值 P5OUT = 0xff;
_EINT(); //打开全局中断 Init_Keypad(); while(1) {
Key_Event();
if(key_Flag == 1) {
key_Flag = 0;
Dispbuf[0] = key_val / 10; Dispbuf[1] = key_val % 10; } }
}
/******************************************* 函数名称:watchdog_timer
功 能:看门狗中断服务函数,在这里输出数码管的 段选和位选信号 参 数:无 返回值 :无
********************************************/ #pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void) {
49
P5OUT = 0xff;
P4OUT = scandata[Dispbuf[cnt]]; //输出段选信号 P5OUT &= ~(1 << (cnt+2)); //输出位选信号
cnt++; //位计数变量在0~1之间循环 if(cnt == 2) cnt = 0; } void DispStr(unsigned char x,unsigned char y,unsigned char *ptr);
void DispNChar(unsigned char x,unsigned char y, unsigned char n,unsigned char *ptr); void LocateXY(unsigned char x,unsigned char y);
void Disp1Char(unsigned char x,unsigned char y,unsigned char data); void LcdReset(void);
void LcdWriteCommand(unsigned char cmd,unsigned char chk); void LcdWriteData( unsigned char data ); void WaitForEnable(void); void Delay5ms(void);
#include
#include \
typedef unsigned char uchar; typedef unsigned int uint;
/**************宏定义***************/ #define DataDir P4DIR #define DataPort P4OUT
#define Busy 0x80 #define CtrlDir P3DIR
#define CLR_RS P3OUT&=~BIT0; //RS = P3.0 #define SET_RS P3OUT|=BIT0;
#define CLR_RW P3OUT&=~BIT1; //RW = P3.1 #define SET_RW P3OUT|=BIT1; #define CLR_EN P3OUT&=~BIT2;
//EN = P3.2
#define SET_EN P3OUT|=BIT2;
/*********************************************** 函数名称:DispStr
功 能:让液晶从某个位置起连续显示一个字符串 参 数:x--位置的列坐标 y--位置的行坐标
ptr--指向字符串存放位置的指针 返回值 :无
***********************************************/ void DispStr(uchar x,uchar y,uchar *ptr) {
uchar *temp;
50