MSP430按键输入和led点阵显示解读.docx
- 文档编号:9872766
- 上传时间:2023-05-21
- 格式:DOCX
- 页数:48
- 大小:709.98KB
MSP430按键输入和led点阵显示解读.docx
《MSP430按键输入和led点阵显示解读.docx》由会员分享,可在线阅读,更多相关《MSP430按键输入和led点阵显示解读.docx(48页珍藏版)》请在冰点文库上搜索。
MSP430按键输入和led点阵显示解读
第4章键盘和显示器的应用
在单片机应用系统中,键盘和显示器是非常重要的人机接口。
人机接口是指人与计算机系统进行信息交互的接口,包括信息的输入和输出。
常用输入设备主要是键盘,常用输出设备包括发光二极管、数码管和液晶显示器等。
4.1键盘输入
键盘用于实现单片机应用系统中的数据信息和控制命令的输入,按结构可分为编码键盘和非编码键盘。
编码键盘上闭合键的识别由专用的硬件编码器实现,并产生相应的键码值,如计算机键盘。
非编码键盘是通过软件的方法产生键码,不需要专用的硬件电路。
为了减少电路的复杂程度,节省单片机的I/O口,在单片机应用系统中广泛使用非编码键盘,主要对象是各种按键或开关。
这些按键或开关可以独立使用(称之为独立键盘),也可以组合使用(称之为矩阵式键盘)。
4.1.1按键电路与按键抖动处理
按键电路连接方法非常简单,如图4.1所示。
此电路用于通过外力使按键瞬时接通开关的场合,如单片机的RESET电路中,通过按键产生一个瞬时的低电压,CPU感知这个低电压后重启。
图4.1按键复位电路
由于按键的闭合与断开都是利用其机械弹性实现的,当机械触点断开、闭合时,会产生抖动,这种抖动操作用户感觉不到,但对CPU来说,其输出波形则明显发生变化,如图4.2所示。
图4.2按键开、闭时的电压抖动波形
按键按下和释放时的抖动时间一般为10~20ms,按键的稳定闭合期由操作用户的按键动作决定,一般为几百毫秒到几秒,而单片机CPU的处理速度在微秒极,因此,按键的一次闭合,有可能导致CPU的多次响应。
为了避免这种错误操作,必须对按键电路进行去抖动处理。
常用的去抖动方法有硬件方式和软件方式两种。
使用硬件去抖动的方式,需要在按键连接的硬件设计上增加硬件去抖电路,比如将按键输出信号经过R-S触发器或RC积分电路后再送入单片机,就可以保证按一次键只发出一个脉冲。
软件方式去抖动的基本原理是在软件中采用时间延迟,对按键进行两次测试确认,即在第一次检测到按键按下后,间隔10ms左右,再次检测该按键是否按下,只有在两次都测到按键按下时才最终确认有键按下,这样就可以避开抖动时间段,消除抖动影响。
同样,在按键释放时也采用相同方法。
由于人的按键速度比单片机的运行速度要慢很多,所以,软件延时方法从技术上完全可行,而且经济上更加实惠,因此被广泛采用。
4.1.2独立键盘检测
独立键盘是一种最简单的键盘,前面章节已经介绍过使用独立键盘的实例。
独立按键的每个键单独占用一根I/O口线,每根I/O口线上的按键工作状态不会影响其他I/O线的工作状态。
实例4-1独立按键编号显示
任务要求:
单片机端口连接3个按键,从1~3进行编号,如果其中一个按键按下时,则在LED数码管上显示相应的按键编号。
1)硬件电路设计
选取MSP430F249单片机的P1口连接数码管显示按键编号,P3口的P3.0、P3.1、P3.2端口分别和3个按键连接。
硬件电路如图4.3所示。
图4.3独立键盘检测电路图
3个I/O口P3.0、P3.1、P3.2作为输入口(输入方式),分别与K1、K2、K3三个按键连接。
当按键断开时,I/O口的输入为高电平,按键闭合时,I/O口的输入为低电平。
此3个引脚上接了上拉电阻,是为了保证按键断开时逻辑电平为高。
2)程序设计
按键闭合时,与该键相连的I/O引脚为低电平;按键断开时,与该键相连的I/O引脚为高电平。
所以在程序中通过P3IN寄存器读取P3.0、P3.1、P3.2这3个I/O口的电平状态,便可检测按键是否按下。
另外,在有按键按下时,要有一定的延时,以防止由于键盘抖动而引起误操作。
当确认某按键按下后,就让数码管显示其按键编号。
#include"MSP430f249.h"
unsignedcharconsttable[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴数码管段选码表,无小数点
voiddelayus(unsignedintt)
{
unsignedinti;
while(t--)
for(i=1330;i>0;i--);
}
unsignedcharReadKey(void)
{
unsignedchartemp;
temp=P3IN&0x07;
if(temp!
=0x07)
{
delayus(10);//等待按键抖动时间
if(temp==(P3IN&0x07))
{
returntemp;
}
else
return0xFF;
}
else
return0xFF;
}
voidmain(void)
{
unsignedcharkey,i;
WDTCTL=WDTPW+WDTHOLD;//关闭看门狗
P1DIR=0xFF;//设置方向
P1OUT=0x00;
P3DIR=0x00;//P3口作为键盘输入
while
(1)
{
key=ReadKey();
switch(key)
{
case0x06:
P1OUT=table[1];
break;
case0x05:
P1OUT=table[2];
break;
case0x03:
P1OUT=table[3];
break;
}
}
}
程序说明:
当按键按下时,P3口的低三位将不全为高电平。
在ReadKey函数中,当判断到P3的低三位不全为1,即0x07时,则认为有按键按下,然后延迟20ms,再次判断P3的低三位,如果低三位依旧不全为1,可以确定是有键按下,并获取键值后显示在数码管上。
3)仿真结果与分析
双击msp430F249单片机,装载可执行文件。
运行时,LED最初没有显示。
当按下某键时,将显示相应的数值。
图4.4为编号为“3”的按键被按下时的仿真效果图。
图4.4独立键盘检测的仿真效果图
4.1.3矩阵式键盘检测
独立键盘与单片机连接时,每一个按键开关占用一个I/O口线,若单片机系统中需要较多按键时,独立按键的方式便会占用过多的I/O口资源。
此时,为了节省I/O口线,采用矩阵式键盘(也称为行列式键盘)。
下面以4×4矩阵式键盘为例讲解其工作原理和检测方法。
将16个按键排成4行4列,第一行每个按键的一端连接在一起构成行线,第一列将每个按键的另一端连接在一起构成列线,这样便一共有4行4列共8根线,如图4-5所示。
将这8根线连接到单片机的8个I/O口上,即可通过程序扫描键盘检测到是哪个按键被按下,具体方法见实例4-2。
图4.54×4矩阵式键盘
实例4-2矩阵键盘编号显示
任务要求:
将4×4矩阵式键盘编号,如果其中一个按键按下时,则在LED数码管上显示相应的按键编号。
分析说明:
4×4矩阵式键盘只需要占用一个8位的端口,硬件设计较为简洁,重点在于如何在程序中判断矩阵键盘的按键位置。
1)硬件电路设计
选取MSP430F249单片机的P1口连接数码管,P3口的8个引脚分别和矩阵式键盘的行线和列线连接。
硬件电路如图4.6所示。
图4.6矩阵式键盘电路原理图
图4.6中列线P3.4~P3.7通过上拉电阻接电源,处于输入状态,行线P3.0~P3.3为输出状态。
键盘上没有按键闭合时,所有列线P3.4~P3.7输入全部为高电平。
当键盘上某个按键闭合时,则对应的行线和列线短接。
例如10号键被按下时,行线P3.1和列线P3.5短接,此时P3.5输入电平由P3.2的输出电平决定。
在检测是否有键按下时,先使4条行线全部输出低电平,然后读取4条列线的状态。
如果全部为高电平则表示没有任何键被按下;如果有任一键被按下,由于列线是上拉至VCC则行线上读到的将是一个非全“1”的值。
2)程序设计
确定矩阵式键盘上哪个键被按下通常采用行扫描法,又称为逐行(或列)扫描查询法,其软件主要基于扫描方式完成。
关于键盘扫描查询的程序大致可分为以下几个步骤:
(1)检测当前是否有键被按下。
首先看输入的列线,假设4条行线都输出低电平,4条列线都是上拉至VCC的,在没有任何按键按下时4条列线输入都为“1”。
但当与某一条行线相连的4个按键中的任何一个被按下时,这条列线将输入低电平,即当某条列线输入低电平时,必定是连接在这条列线上的某个按键被按下了。
(2)去除键抖动。
当检测到有键被按下后,延时一段时间再作下一步的检测判断。
(3)若有键被按下,检测出是哪一个键被按下。
逐行扫描方式:
在4条行线上分别输出“0”信号,也就是说,第一次,在P3.0上输出低电平,其他的行线(P3.1、P3.2、P3.3)上输出高电平;接着第二次,在P3.1上输出低电平,其他的行线(P3.0、P3.2、P3.3)上输出高电平;第三次,在P3.2上输出低电平,其他的行线(P3.0、P3.1、P3.3)上输出高电平;第四次,在P3.3上输出低电平,其他的行线(P3.0、P3.1、P3.2)上输出高电平。
当某一行线上输出低电平时,如果此行上有键被按下,那么相应按键的列线上则会读取到“0”,于是可以惟一的确定是哪一按键被按下了。
假设图4.6中的编号“6”的按键被按下,当第一次扫描时,P3.0口输出“0”,P3.1、P3.2、P3.3输出“1”,则P3.4~P3.7所读到的电平全为“1”;当第二次扫描时,P3.1口输出“0”,P3.0、P3.2、P3.3输出“1”,此时,P3.4、P3.5、P3.6、P3.7读到的电平分别为“1”、“1”、“0”、“1”。
因此,即能确定P3.1行线和P3.6列线交叉的编号“6”按键的具体位置。
矩阵式键盘的按键检测过程如图4.8所示。
图4.8矩阵键盘识别流程图
此实例的源程序如下:
#include
unsignedcharconsttable[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴数码管段选码表,无小数点
staticcharkey;
voiddelayus(unsignedintt)
{
unsignedinti;
while(t--)
for(i=1330;i>0;i--);
}
charkeyscan(void)
{
charsccode,recode;
P3OUT=0x00;
if((P3IN&0xF0)!
=0xF0)//判断是否有有键按下
{
delayus(20);
if((P3IN&0xF0)!
=0xF0)//再次判断按键是否有抖动,如果是返回
{
sccode=0xFE;//逐行扫描初值,先扫描第1行P3.0
while((sccode&0x0F)!
=0x0F)//行扫描完成
{
P3OUT=sccode;//输出行扫描码
if((P3IN&0xF0)!
=0xF0)//当前行有键按下
{
recode=(P3IN&0xF0)|0x0F;//读取高四位列值,低四位置1
key=(sccode&recode);//行和列组合得到键盘编码
returnkey;
}
else//所扫描没有键按下,则扫描下一行
{
sccode=(sccode<<1)|0x01;//行扫描码左移一位
}
}
}
return0xFF;//无键按下
}
return0xFF;//无键按下
}
chargetkeyval(charkeycode)
{
charkeyval;
switch(keycode)
{
case0x77:
//0b01110111:
keyval=0;
break;
case0x7B:
//0b01111011:
keyval=1;
break;
case0x7D:
//0b01111101:
keyval=2;
break;
case0x7E:
//0b01111110:
keyval=3;
break;
case0xB7:
//0b10110111:
keyval=4;
break;
case0xBB:
//0b10111011:
keyval=5;
break;
case0xBD:
//0b10111101:
keyval=6;
break;
case0xBE:
//0b11011110:
keyval=7;
break;
case0xD7:
//0b11010111:
keyval=8;
break;
case0xDB:
//0b11011011:
keyval=9;
break;
case0xDD:
//0b11011101:
keyval=10;
break;
case0xDE:
//0b11011110:
keyval=11;
break;
case0xE7:
//0b11100111:
keyval=12;
break;
case0xEB:
//0b11101011:
keyval=13;
break;
case0xED:
//0b11101101:
keyval=14;
break;
case0xEE:
//0b11101110:
keyval=15;
break;
default:
keyval=255;
}
returnkeyval;
}
voidmain(void)
{
unsignedcharkey,i;
WDTCTL=WDTPW+WDTHOLD;//关闭看门狗
P1DIR=0xFF;//设置方向
P1SEL=0;//设置为普通I/O口
P1OUT=0x00;
P3DIR=0x0F;//P3.4~P3.7口作为键盘输入,P3.0~P3.3口作为键盘扫描信号输出
while
(1)
{
key=getkeyval(keyscan());
if(key!
=255)
{
P1OUT=table[key];
}
}
}
程序说明:
主程序通过调用键盘扫描程序获取键值,并通过数码管显示出键盘编号。
键盘扫描首先通过读取列线输入,如果不是全为1,则延迟20ms后再次判断列线是否全为1,如果依旧不是全为1,可以确定是稳定的按键动作;通过逐行扫描的方式得到按键的位置。
从程序上来看还存在两个问题:
一是按键扫描中延迟去抖需要20ms的时间,浪费的单片机的运算资源。
二是在扫描到按键后如果按键按下不动,主程序会得到多个相同的键值,即重复按键,这种情况可以通过判断按键弹起的动作予以解决。
3)仿真结果与分析
装载可执行文件,运行后的仿真结果图如图4.9所示。
图4.9矩阵式键盘仿真电路图
4.2LED点阵显示
LED点阵显示器由发光二极管LED按矩阵的方式排成一个n×m的点阵,每个发光二极管构成点阵中的一个点。
这种点阵显示器不仅可以静态的显示信息,而且可以通过动态滚动,增加信息显示的容量和效果,因此应用十分广泛。
4.2.1LED点阵显示原理
LED点阵显示器的分类有多种方法:
按阵列点数可分为5×7、5×8、6×8、8×8这4种,按发光颜色可分为单色、双色、三色;按极性排列方式可分为共阳极型和共阴极型。
图4.10为常见的8×8LED点阵显示器,它由64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上。
当对应的某一行置1电平,某一列置0电平,则相应的二极管就亮。
如要将第一个点亮,则将第9脚接高电平第13脚接低电平;如果要将第一行点亮,则将第9脚要接高电平,而第13、3、4、10、6、11、15、16这些引脚接低电平;如要将第一列点亮,则第13脚接低电平,而第9、14、8、12、1、7、2、5引脚接高电平。
从原理上来说,模块没有共阳或共阴之分,共阳的翻转90度就是共阴的了,共阴的翻转90度就是共阳的了。
但电路会有行扫描接阴或行扫描接阳之分。
图4.108×8LED点阵管脚图
显示单个字母、数字时,只需要一个5×7的LED点阵显示器即可,显示汉字时,需要使用多个LED点阵显示器组合,最常见的组合方式有15×14、16×15、16×16、32×32等。
例如一个16×16的点阵由4个8×8点阵组合而成,即每一个汉字在纵、横各16点的区域内显示,需要笔画经过地方的发光二极管都为点亮状态(即“1”),没有笔画地方的发光二极管都为熄灭状态(即“0”),这样就可以表示不同的汉字。
LED点阵显示器与LED数码管类似,常用的工作方式有静态显示和动态显示两种方式。
所谓静态显示,就是当显示器显示一个字符时,相应的发光二极管始终保持导通或截止,在显示的这个过程中,其状态是静止不变的,直到一个字符显示完毕,将要显示下一个字符时其状态才改变。
而动态显示方式则不同,它在显示每一个字符的过程中,都是按列(或行)不停扫描,一位一位地轮流点亮要显示的各个位,如此反复循环。
动态显示方式利用了人眼的视觉暂留性质,当扫描的速度足够快时,可以得到静态的显示效果。
由于LED点阵引脚设计的特殊性,一般采用动态扫描显示方式。
下面介绍用动态扫描方式在8×8共阳极LED点阵显示器上显示字符“B”的过程(如图4.11所示),由此简要说明动态扫描的原理。
图4.11用动态扫描方式显示字符“B”的过程
假设X、Y为两个8位的字节型数据,X的每位对应LED点阵的8条列线X7~X0,同样Y的每位对应LED点阵的8条行线Y7~Y0。
Y叫行扫描线,在每个时刻只有一条为“1”,即有效行选通电平;X叫列数据线,其内容就是点阵化的字模数据的体现。
①Y=0x01,X=0xFF,如图4-11中的第一帧;
②Y=0x02,X=0x87,如图4-11中的第二帧;
③Y=0x04,X=0xBB,如图4-11中的第三帧;
④Y=0x08,X=0xBB,如图4-11中的第四帧;
⑤Y=0x10,X=0x87,如图4-11中的第五帧;
⑥Y=0x20,X=0xBB,如图4-11中的第六帧;
⑦Y=0x40,X=0xBB,如图4-11中的第七帧;
⑧Y=0x80,X=0x87,如图4-11中的第八帧;
⑨跳到第①步循环。
如果高速地进行①~⑨的循环,且两个步骤的间隔时间小于1/24s,则由于视觉暂留,LED显示屏上将呈现出一个完整的“B”字符。
4.2.28×8LED点阵显示实例
实例4-38×8LED点阵数字显示
任务要求:
利用MSP430F249单片机控制一个8×8LED点阵显示器,使其循环显示数字0~9。
1)硬件电路设计
选用MSP430F249单片机的P2口控制LED点阵的行扫描信号,P1口控制点阵的列显示数据,硬件原理图如图4.12所示。
图4.12点阵显示数字字符硬件原理图
2)程序设计
#include"msp430f249.h"
#defineucharunsignedchar
#defineuintunsignedint
//数字0~9的8*8点阵编码
constucharTable_OF_Digits[]=
{
0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00,//0
0x00,0x08,0x38,0x08,0x08,0x08,0x3E,0x00,//1
0x00,0x3C,0x42,0x04,0x08,0x32,0x7E,0x00,//2
0x00,0x3C,0x42,0x1C,0x02,0x42,0x3C,0x00,//3
0x00,0x0C,0x14,0x24,0x44,0x3C,0x0C,0x00,//4
0x00,0x7E,0x40,0x7C,0x02,0x42,0x3C,0x00,//5
0x00,0x3C,0x40,0x7C,0x42,0x42,0x3C,0x00,//6
0x00,0x7E,0x44,0x08,0x10,0x10,0x10,0x00,//7
0x00,0x3C,0x42,0x24,0x5C,0x42,0x3C,0x00,//8
0x00,0x38,0x46,0x42,0x3E,0x06,0x3C,0x00//9
};
constucharscan_tab[]={0x01,0x02,0x04,0x08,0x010,0x20,0x40,0x80};//扫描代码
voiddelayus(uintt)
{
uinti;
while(t--)
for(i=1300;i>0;i--);//仿真时,取值130
}
voidmain(void)
{
chari,j,t=0;
WDTCTL=WDTPW+WDTHOLD;
P1DIR=0xFF;
P2DIR=0xFF;
while
(1)
{
P1OUT=0xFF;//关闭显示,防止切换数字时产生拖影
P2OUT=0xFF;
for(i=0;i<10;i++)//循环显示0~9
{
for(j=0;j<255;j++)//每个字符显示稳定
{
P2OUT=scan_tab[t];//送行扫描信号
P1OUT=~Table_OF_Digits[t+8*i];//送列显示数据
delayus
(2);
if(++t==8)
t=0;
}
}
}
}
程序说明:
在主循环中对0~9这10个数字进行循环显示,每个数字扫描次数为255,是为了让每个数字显示时间足够长,得到稳定的显示效果。
P2口送出行扫描信号后,P1口给出列显示数据,注意此例中8×8点阵为共阴极接法,显示数据是经过取反后送出的。
3)仿真结果
加载程序后,运行得到仿真图如图4.13所示。
图4.13点阵显示数字字符仿真图
4.2.316×16汉字点阵显示
与字母和数字显示原理一样,16×16汉字点阵的显示也是采用动态逐行(或逐列)扫描的方式完成,只是列扫描需要16位,而每列数据需要2×8位(2字节),一个完整的汉字则需要32字节。
1、点阵驱动电路
实例4-3中,单片机控制一个8×8LED点阵显示器,需要两组I/O口,其中一组实现点阵的行扫描,另一组输出列数据。
按照这种硬件连接方式,如果利用单片机控制一个16×16汉字点阵实现显示功能,则需要8组I/O口;如果控制多个汉字点阵显示,则需要更多的I/O口。
显然,这种连接方式是难以实现的。
因此,在多个点阵驱动电路设计中,一般采用移位寄存器的方法来减少对单片机I/O口的需求。
寄存器是存放二进制数的电路,由D触发器构成,如图4.14所示。
在CP时钟信号的上升沿,将输入的数字DI存入到D触发器中,Q端的输出就与DI相同,即无论触发器Q原来的值是什么,只要时钟脉冲C
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MSP430 按键 输入 led 点阵 显示 解读