历史上的今天
今天是:2025年04月18日(星期五)
2018年04月18日 | MSP430学习笔记7-4*4键盘的对应数码管显示
2018-04-18 来源:eefocus
这个例程也是开发板上面的一个经典例程,我对程序的框架进行了修改,更适合以后的调用。具体的4*4键盘扫描原理较为基础这里不再赘述,这里我认为比较重要的是要养成一个良好的写程序的习惯,想4*4键盘扫描这样的函数可以写成一个固定的C或者H文件,便于以后调用。先看看主程序:
/***********************************************
程序功能:扫描4X4键盘并将键值在数码管上显示
------------------------------------------------
测试说明:按动K1~K16按键,观察数码管显示
************************************************/
#include
#include "Keypad.C"
//数码管7位段码:0--f
unsigned char scandata[16] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//记录显示位数的全局变量
unsigned char cnt = 0;
//显示缓存
unsigned char Dispbuf[2];
//引用外部变量的声明
extern unsigned char key_Pressed;
extern unsigned char key_val;
extern unsigned char key_Flag;
/********************主函数********************/
void main(void)
{
/*下面六行程序关闭所有的IO口*/
P1DIR = 0XFF;P1OUT = 0XFF;
P2DIR = 0XFF;P2OUT = 0XFF;
P3DIR = 0XFF;P3OUT = 0XFF;
P4DIR = 0XFF;P4OUT = 0XFF;
P5DIR = 0XFF;P5OUT = 0XFF;
P6DIR = 0XFF;P6OUT = 0XFF;
P6DIR |= BIT2;P6OUT |= BIT2; //关闭电平转换
WDTCTL = WDT_ADLY_1_9; //设置内部看门狗工作在定时器模式,1.9ms中断一次
IE1 |= WDTIE; //使能看门狗中断
_EINT(); //打开全局中断
Init_Keypad();
while(1)
{
Key_Event();
if(key_Flag == 1)
{
key_Flag = 0;
Dispbuf[1] = key_val / 10;
Dispbuf[0] = key_val % 10;
}
}
}
/*******************************************
函数名称:watchdog_timer
功 能:看门狗中断服务函数,在这里输出数码管的
段选和位选信号
参 数:无
返回值 :无
********************************************/
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
P4OUT = 0xff;
P5OUT = scandata[Dispbuf[cnt]]; //输出段选信号
P4OUT &= ~(1 << (cnt+2)); //输出位选信号
cnt++; //位计数变量在0~1之间循环
if(cnt == 2) cnt = 0;
}
主程序较为简单,具体的原理参见上一个笔记,在主程序中与键盘扫描相关的函数被击中在Keypad.C中,需要说明的是在主函数中需要对Keypad.C的部分变量做声明,这样才能使用Keypad.C中的变量。Keypad.C代码如下:
/********************************************************
4*4键盘扫描函数
作者:孙浩
修改时间:2010.8.2
程序说明:
此程序以开发板的例程做部分修改,更方便程序调用。
在调用之前需要注意需要在主函数中对程序中使用的变量做外部变量声明
需要在主函数中声明的变量如下:
//引用外部变量的声明
extern unsigned char key_Pressed; //按键是否被按下:1--是,0--否
extern unsigned char key_val; //存放键值
extern unsigned char key_Flag; //按键是否已放开:1--是,0--否
另外对应的键值可以在本文件的全局变量中修改,只需要对应修改
数组uchar key_Map[]的对应的值即可。
调用示例如下:
Init_Keypad(); //先进行初始化
while(1)
{
Key_Event(); //在死循环中进行键值扫描
if(key_Flag == 1)//用来判断有无按键按下,从而读取键值进行操作
{
key_Flag = 0;//key_Flag需要手动清零
}
}
**********************************************************/
#include
//相应的函数声明
void Init_Keypad(void);//键盘初始化
void Check_Key(void);
void delay();
void Key_Event(void);//读取键盘函数,在使用时通过此函数进行键盘扫描
//选择对应的端口
#define KEYOUT P1OUT
#define KEYIN P1IN
#define KEYDIR P1DIR
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};
/*******************************************
函数名称:Init_Keypad
功 能:初始化扫描键盘的IO端口
参 数:无
返回值 :无
********************************************/
void Init_Keypad(void)
{
KEYDIR = 0xf0; //KEY.0~KEY.3设置为输入状态, KEY.4~KEY.7设置为输出状态
KEYOUT |= 0xf0; // KEY.4~KEY.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++) //行扫描
{
KEYOUT = 0xf0; //KEY.4~KEY.7输出全1
KEYOUT -= tmp1; //KEY.4~p1.7输出四位中有一个为0
tmp1 >>=1;
if ((KEYIN & 0x0f) < 0x0f) //是否KEYIN的KEY.0~KEY.3中有一位为0
{
tmp2 = 0x01; // tmp2用于检测出那一位为0
for(col = 0;col < 4;col++) // 列检测
{
if((KEYIN & tmp2) == 0x00) // 是否是该列,等于0为是
{
key_val = key_Map[row * 4 + col]; // 获取键值
return; // 退出循环
}
tmp2 <<= 1; // tmp2右移1位
}
}
}
}
/*******************************************
函数名称:delay
功 能:延时约15ms,完成消抖功能
参 数:无
返回值 :无
********************************************/
void delay()
{
uint tmp;
for(tmp = 12000;tmp > 0;tmp--);
}
/*******************************************
函数名称:Key_Event
功 能:检测按键,并获取键值
参 数:无
返回值 :无
********************************************/
void Key_Event(void)
{
uchar tmp;
KEYOUT &= 0x00; // 设置KEYOUT全为0,等待按键输入
tmp = KEYIN; // 获取 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();
}
}
具体的注意提防都已经在注释中做了说明,在原来的程序中这个文件是分为Keypad.C和Keypad.h两个文件,键盘扫描函数的声明单独为一个头文件,我觉得并不是特别需要。源程序中全局变量是单独列为一个头文件gdata.h的。这样在全局变量比较多的情况下可以使程序更有条理可以参考。
史海拾趣
|
汽车转向泵是一种中高档汽车的零部件,它由多种零件组成,需要借助不同的设备,按照一定的工序把它们组装起来。在整个过程中,不仅要完成基本的装配,还要对过程中诸如压力、位移、时间等参数进行实时监控,以满足工艺所提出的严格要求,保证装配质 ...… 查看全部问答> |
|
按键扫描是每个搞单片机的都会遇到的问题,也是一个开发人员必须具备的基本功。先从最基本的说起。在此声明,没有代码,也不要向我要代码,也不想穿裤子,如果你看了帖子还写不出代码,那么我只能说你太笨了。。。。。。。。还是那句话,搞开发重要 ...… 查看全部问答> |
|
我想变成程序,但不知道要多少钱,请高手个价位 仪器的功能大概如下;1,压力传感器测得压力显示在数码管上,另外可以对通过对标定对传感器进行微调 &nbs ...… 查看全部问答> |
|
各位大哥: 最近在研究用 IO 来做键盘, 有几个问题不明白, 1、很多IO键盘驱动都是使用中断来实现,比如 4X4 的要 4 个中断,首先创建一个事件,然后启动一个线程, 通 ...… 查看全部问答> |
|
我想用nGCS2作片选,LDADDR0-LDADDR7作地址线,LDDATA0-LDDATA7作数据线进行CPLD的读写数据.于是我定义了下面的结构体: #define NGCS2_BASE 0XA4000080 #define NGCS2_PHY_BASE 0x10000080 ///定义CPLD控制寄存器地 ...… 查看全部问答> |
|
大家好: 请问PRO/E野火版怎么安装?安装时要把什么来代替一下吗?本来想把安装的界面的图传上来不知道怎么搞,还是请大家帮忙看下 1. boot up your pc with windows 2. start pro/e setup 3. open ptc_licfile.dat with your fa ...… 查看全部问答> |
|
Cortex-M3和Cortex-M0的区别 ARM架构自v6开始分为A/R/M三个系列。CM0/CM3都是属于M系列的。CortexM0是基于v6架构;CortexM3是v7架构。主要区别 性能: Cortex-M0 基于32 位架构,利用一个 通过MULS 指令直接与内核相连的3 ...… 查看全部问答> |




