07第七讲 数码管显示与按键输入技术.docx

上传人:b****8 文档编号:29986253 上传时间:2023-08-04 格式:DOCX 页数:21 大小:93.11KB
下载 相关 举报
07第七讲 数码管显示与按键输入技术.docx_第1页
第1页 / 共21页
07第七讲 数码管显示与按键输入技术.docx_第2页
第2页 / 共21页
07第七讲 数码管显示与按键输入技术.docx_第3页
第3页 / 共21页
07第七讲 数码管显示与按键输入技术.docx_第4页
第4页 / 共21页
07第七讲 数码管显示与按键输入技术.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

07第七讲 数码管显示与按键输入技术.docx

《07第七讲 数码管显示与按键输入技术.docx》由会员分享,可在线阅读,更多相关《07第七讲 数码管显示与按键输入技术.docx(21页珍藏版)》请在冰豆网上搜索。

07第七讲 数码管显示与按键输入技术.docx

07第七讲数码管显示与按键输入技术

第七讲数码管显示与按键输入技术

郧阳师专电工电子实验教学中心艾庆生

单片机与个人微机(PC机)间的最大区别就是:

它追求“小而全”,只有简单的输入和输出部件。

而数码管和按键就是这样的即简单又常用又重要的部件,我们必须熟练掌握。

一、数码管的结构

LED(LightEmittingDiode)数码管

如图所示:

7只或8只发光二极管构成一位数码管,俗称“7段8”或“8段8”,我们以8段8为例来讲解:

若8只发光管的阳极接在一起引出的话,称之为共阳极数码管;反之,8只发光管的阴极接在一起引出的话,称之为共阴极数码管。

使用时,数码管各段必须接限流电阻。

数码管的各段有统一的规定,用a、b、…、g、dot定义。

二、数码管的显示代码

由于数码管各段排列的特殊性,它所显示的字符与送给它的代码是不一样的。

以共阴极数码管为例,如,送给它代码3FH,将显示字符“0”,送代码06H,将显示字符“1”,…。

下表列出了共阴和共阳数码管所显示字符的代码表。

图二则告诉了如何得到显示代码的方法。

三、数码管的显示技术

1.静态显示

在任意时刻,每位数码管都有电流流过。

如图3所示,有8位数码管,显示“07-05-12”,每位数码管都有8根引线与专门电路相连,向其提供“段选码”。

它的显示是同时的、稳定的。

其优点是原理简单、编程较易;缺点是引线太多、耗电太大。

2.动态显示

参考图4,仍是8位数码管,但它们各自的8根引线并联在一起引出,所以,无论是几位数码管显示,总共只有8根“段选码”引出线;每位数码管的公共端单独引出,构成了8根“位选码”的引出线。

其工作原理如下:

设从右往左显示,首先送2的显示代码(即段选码),然后将com0变为低电平,其它为高电平(即位选码),延时1-2ms;其次送1的显示代码,再将com1变为低电平,仍延时1-2ms;以此类推,当最左边数码管的0显示完毕后,这称为扫描了一遍,共需时8-16ms;不断地重复此过程,就叫“动态显示”技术。

可知,1秒钟能扫描50到100多遍,由于视觉暂留缘故,我们就看到了稳定的显示。

它的优点显而易见,引线数大为减少,省电(任意时刻,仅有一位数码管在显示),只是编程稍麻烦一点,但其难度仅为1课时的学习而已。

四、数码管的编程

;************************************************************

;*************数码管显示一遍子程序*********************

;************************************************************

;设数据显示区从78H-7FH,与8位数码管一一对应

;单片机P0口接数码管的段选口;P2口接数码管的位选口

smg_disp:

movdptr,#disp_tab;指向显示代码表

movr0,#78h;指向数据显示区

movr7,#0feh;显示模式(即“位选码”)

disp_loop:

mova,@r0;取一个数据

movca,@a+dptr;转换成显示代码

movp0,a;送P0口(“段选码”)

mova,r7;取显示模式

movp2,a;送P2口(“位选码”)

incr0;指向下一数据

rla;移向下一位

movr7,a;并保存

lcallys1ms

cjnea,#0feh,disp_loop;扫描一遍了吗?

Ret

;延时1ms子程序

ys1ms:

movr6,#2

ys0:

movr5,#250

djnzr5,$

djnzr6,ys0

ret

;数据区数据显示代码表

disp_tab:

db3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh

db6fh,77h,7ch,39h,5eh,79h,71h,76h,73h

db40h,80h

;思考题:

1.若从左往右显示,怎样修改以上程序?

;2.若只显示两位(任意选取,如最右边两位),怎样改?

;3.若编写“跑马灯”程序,怎样修改?

;************************************************************

五、简单按键的输入法

按键作为一种简单的输入器件,其实牵涉到它的技术却是不简单的。

有这样几个问题需要解决。

即1.单片机的并行口为准双向口,故输入时是有限制的,须先向该口写“1”;2.要考虑按键的抖动问题,硬件的解决办法是另外用“触发器”;软件的解决办法是延时若干ms,待按键稳定下来;3.对按键进行处理,判断是功能键还是数字键,具体键值是多少?

是单个按键值输入还是连续按键值输入?

4.按键松开没有,是否等待按键释放?

这些问题在编程时都必须考虑!

下图,是我们的单片机最小系统里简单按键的连接图。

当把跳线JMP1上的短路帽插上时,可以做外部中断的扩展实验(见下讲)。

实验1:

4按键的识别实验1

为简单起见,我们将按键情况用P0口的发光管直接显现出来(求反后送)。

;************************************************************

;*******************四按键识别实验1*********************

;************************************************************

Org0000H

Main:

movp0,#0H;关闭P0口8只发光管

Movp3,#0ffH;为读入P3口的按键做准备

Loop:

mova,p3;读入P3口状态送A寄存器

Cpla;求反,因P0口发光管高电平点亮

Movp0,a;将按键情况送P0口显示

Sjmploop

End

;***********************************************************

实验2:

4按键的识别实验2

用上边刚学到的数码管知识,这次我们将识别后的按键引脚号直接送数码管显示,如显示“P3.5”。

;************************************************************

;******************四按键识别实验2********************

;************************************************************

;主程序

Org0000H

Main:

mov78h,#18

Mov79h,#18

Mov7ah,#18

Mov7bh,#18;没有按键按下时,首先显示“――――”

Loop:

lcallsmg_disp;调用数码管显示子程序(只显示4位)

Lcallkey_check;调用按键检查子程序

Sjmploop

;按键检查子程序

Key_check:

movp3,#0ffh;为读入P3口内容做准备

Mova,p3;读入P3口内容到A

Cpla

Jnzkey_value;有键按下跳去处理

Key_end:

Ret

Key_value:

lcallsmg_disp

lcallsmg_disp;数码管显示两遍,延时若干ms抗干扰

Mova,p3;再次读入P3口内容到A

Cpla

Jzkey_end;无键按下返回

Jbacc.4,key_p34;判是P3.4脚接的按键吗?

Jbacc.5,key_p35;判是P3.5脚接的按键吗?

Jbacc.6,key_p36;判是P3.6脚接的按键吗?

Jbacc.7,key_p37;判是P3.7脚接的按键吗?

Sjmpkey_end

Key_p34:

mov78h,#4

Mov79h,#19;送小数点的查表值

Mov7ah,#3

Mov7bh,#17;送P的查表值

Sjmpkey_wait

Key_p35:

mov78h,#5

Mov79h,#19;送小数点的查表值

Mov7ah,#3

Mov7bh,#17;送P的查表值

Sjmpkey_wait

Key_p36:

mov78h,#6

Mov79h,#19;送小数点的查表值

Mov7ah,#3

Mov7bh,#17;送P的查表值

Sjmpkey_wait

Key_p37:

mov78h,#7

Mov79h,#19;送小数点的查表值

Mov7ah,#3

Mov7bh,#17;送P的查表值

Key_wait:

lcallsmg_disp;等候按键释放并保持数码管的显示不

;断续

movp3,#0ffh

Mova,p3;再次读入P3口内容到A

Cpla

Jnzkey_wait;等候按键释放

Ret

End

;此处省略了两个子程序(即数码管显示子程序和1ms延时子程序)以及显

;示代码表,调试程序时请添加上,另外需修改数码管显示子程序为右边

;4位显示。

;请认真体会程序里是如何抗按键抖动的、如何判断键值的、如何等候按键

;释放的?

;************************************************************

六、矩阵键盘的扫描法

简单按键的连接容易,程序的编写也较容易,但它的缺点是占用引脚资源过多,若采用矩阵式键盘,则16个按键只需8根引线,或64个按键只需16根引线。

显然,它的优点就是引线少,编程复杂一些。

对于矩阵式键盘,一般分两步来处理。

第一步:

扫描键盘,判断有无按键按下;第二步:

在有按键按下的情况下,确定是何键?

即键值判断。

图6是矩阵式键盘的示意图,为简单起见,我们假定P1口和P3口作为矩阵式键盘的行线和列线的连接口。

可见,它们的交叉点共有64个,可接64个按键。

判断有无按键按下,采用扫描法,其基本方法是:

将行线(或列线)置为低电平,然后读回列线(或行线)的值,显然,若无按键按下,读回的值应全部为高电平,否则,就一定会有低电平(被按键拉低的缘故)。

;************************************************************

;****************矩阵键盘扫描子程序*****************

;************************************************************

Key_scan:

Movp1,#0;将行线置为低电平

Movp3,#0ffh;为读入列线的值做准备

Nop

Mova,p3;读入列线的值到A寄存器

Cpla;目的以A是否为0来作判断,

Ret;便于使用指令JZ或JNZ。

;返回值在A寄存器里,若不为0则一定有按键按下。

;思考题:

为什么要将A取反?

好处在哪里?

;************************************************************

上图为实际的按键接线图。

上边的扫描子程序同样适用于此接线图。

七、矩阵键盘的键值识别法(以图7为例)

1.传统识别法(逐行扫描法):

行线输出,列线输入。

行线逐行输出0,将列线读回。

若该行有按键按下,则列线输入有0;若无按键按下,列线输入全部为1。

程序流程图如下:

参考程序如下,需说明的是这样编程较复杂。

Key_Value:

 Lcallsmg_disp

Lcallsmg_disp;延时16ms以抗抖动

Lcallkey_scan;再次检查按键情况

jnzkey_H;有键按下则跳转处理

LjmpKey_ret;无键按下返回

Key_H:

movp1,#0feh;第1排行线置0

movp3,#0ffh;为读入P3列线情况先置“1”

mova,p3

cpla

jnzvalue_0;是第一排按键吗?

是跳转至Value_0

movp1,#0fdh

mova,p3

cpla

jnzvalue_4;是第二排按键吗?

是跳转至Value_4

movp1,#0fbh

mova,p3

cpla

jnzvalue_8;是第三排按键吗?

是跳转至Value_8

movp1,#0f7h

mova,p3

cpla

jnzvalue_C;是第四排按键吗?

是跳转至Value_C

LjmpKey_ret

Value_0:

movr4,#00h;赋行首键值0

ajmpKey_V

Value_4:

movr4,#04h;赋行首键值4

ajmpKey_V

Value_8:

movr4,#08h;赋行首键值8

ajmpKey_V

Value_C:

movr4,#0Ch;赋行首键值C

Key_V:

jbacc.0,V_0;是第一列按键吗?

是跳至V_0

jbacc.1,V_1;是第二列按键吗?

是跳至V_1

jbacc.2,V_2;是第三列按键吗?

是跳至V_2

jbacc.3,V_3;是第四列按键吗?

是跳至V_3

LjmpKey_ret

V_0:

mova,#0;赋列号0

ajmpkey_add

V_1:

mova,#1;赋列号1

ajmpkey_add

V_2:

mova,#2;赋列号2

ajmpkey_add

V_3:

mova,#3;赋列号3

Key_add:

adda,r4;“行首键值+列号值”送A

movr0,#78h

Exchange:

xcha,@r0;键值送显示区,整个显示区数据前移

;一字节

incr0

cjner0,#80h,exchange

Wait:

acallsmg_disp

acallkey_scan

jnzwait;等候按键释放

Key_ret:

ret

2.行列反转法

可用行、列交换法结合查表法迅速获得键值。

行列线交换输入、输出,两步获取按键键值。

;************************************************************

;键值判断子程序(要克服按键抖动、要使数码管显示无闪烁、

;要正确读出键值、要等候按键松开。

Key_Value:

lcallsmg_disp

lcallsmg_disp;延时16ms抗按键抖动

lcallkey_scan;再次判断是否按键按下?

jnzrd_value;有则去读值

ljmpkey_ret

;以下采用两次交叉键盘扫描方法,通过查表唯一确定键值

rd_value:

movp1,#0ffh

movp3,#0f0h;首先将列线置0,读回行线值

nop

mova,p1

cpla

movdptr,#H_tab

movca,@a+dptr;查表获得“行首键值”

movb,a;暂存第一次扫描的“行首键值”

movp3,#0ffh

movp1,#0f0h;其次将行线置0,读回列线值

nop

mova,p3

cpla

movdptr,#V_tab

movca,@a+dptr;查表得到第二次扫描的“列线号值”

adda,b;“行首键值+列线号值”=键值

movr0,#78h

xch_data:

xcha,@r0;保存键值到显示数据区

incr0

cjner0,#80h,xch_data;将数据区字节逐字节上移movp1,#0ffh

wait:

lcallsmg_disp

lcallkey_scan

jnzwait;等待按键释放

Key_ret:

ret

思考题:

1.“行首键值”转换表是如何得到的?

2.“列线号值”转换表是如何得到的?

3.转换表里的16是何含义?

可否用别的数据?

;************************************************************

;“行首键值”转换表

H_tab:

db16,0,4,16,8,16,16,16,12,16,16,16,16,16,16,16

;************************************************************

;“列线号值”转换表

V_tab:

db16,0,1,16,2,16,16,16,3,16,16,16,16,16,16,16

;************************************************************

;数据区数据显示代码表

disp_tab:

db3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh

db6fh,77h,7ch,39h,5eh,79h,71h,40h,40h

db40h,40h,40h,40h,40h,40h,40h,40h,40h

db40h,40h,40h,40h,40h,40h,40h,40h,40h

;************************************************************

八、数码管和键盘的联合实验

该实验的任务是:

1.数码管动态扫描显示;

2.对矩阵式按键进行扫描,判断有无按键按下。

若有按键按下,则判断键值并送显示区,实现“计算器式”输入显示。

无输入位数限制。

;************************************************************

;这是数码管显示与键盘输入程序

;主程序

org0000h

main:

movr0,#30h

mova,#0

ram_0:

mov@r0,a

incr0

cjner0,#80h,ram_0;数据区30H-7FH清0

main_loop:

lcallsmg_disp;调数码管显示一遍子程序

lcallkey_scan;调键盘扫描一遍子程序

jzmain_loop;无键按下返回

lcallkey_value;调键值判断子程序

ljmpmain_loop

;************************************************************

;数码管显示一遍子程序

smg_disp:

movdptr,#disp_tab;指向显示代码表

movr0,#78h;指向数据显示区

movr7,#0feh;显示模式(即“位选码”)

disp_loop:

mova,@r0;取一个数据

movca,@a+dptr;转换成显示代码

movp0,a;送P0口(“段选码”)

mova,r7;取显示模式

movp2,a;送P2口(“位选码”)

lcallys1ms

incr0;指向下一数据

rla;移向下一位

movr7,a;并保存

cjnea,#0feh,disp_loop;扫描一遍了吗?

ret

;思考题:

1.若从左往右显示,怎样修改以上程序?

;2.若只显示两位(任意选取,如最右边两位),怎样改?

;3.若编写“跑马灯”程序,怎样修改?

;************************************************************

;键盘扫描一遍子程序(仅仅判断有无按键按下!

key_scan:

movp1,#0f0h;将键盘的4根行线变低电平

movp3,#0ffh

nop

mova,p3;读回P3口的值送a

cpla;取反返回

movp1,#0ffh

ret

;************************************************************

;键值判断子程序(要克服按键抖动、要使数码管显示无闪烁、

;要正确读出键值、要等候按键松开。

key_value:

lcallsmg_disp

lcallsmg_disp;延时16ms抗按键抖动

lcallkey_scan;再次判断是否按键按下?

jnzrd_value;有则去读值

ljmpkey_ret

;以下采用两次交叉键盘扫描方法,通过查表唯一确定键值

rd_value:

movp1,#0ffh

movp3,#0f0h;首先将列线置0,读回行线值

nop

mova,p1

cpla

movdptr,#H_tab

movca,@a+dptr;查表获得“行首键值”

movb,a;暂存第一次扫描的“行首键值”

movp3,#0ffh

movp1,#0f0h;再将行线置0,读回列线值

nop

mova,p3

cpla

movdptr,#V_tab

movca,@a+dptr;得到第二次扫描的“列线号值”

adda,b;“行首键值+列线号值”=键值

movr0,#78h

xch_data:

xcha,@r0;保存键值到显示数据区

incr0

cjner0,#80h,xch_data;将数据区字节逐字节上移

movp1,#0ffh

wait:

lcallsmg_disp

lcallkey_scan

jnzwait;等待按键松开

Key_ret:

ret

;************************************************************

;延时1ms子程序

ys1ms:

movr6,#2

ys0:

movr5,#250

djnzr5,$

djnzr6,ys0

ret

;************************************************************

;“行首键值”转换表

H_tab:

db16,0,4,16,8,16,16,16,12,16,16

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 经济学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1