单片机驱动数码管显示设计
图6 |
现在让我们把目标文件"smg1.hex"烧写到单片机中去,看看实际的效果吧,将ISP编程器硬件连接好(见下图7)。
图7:ISP |
将产品配套光盘中的“ISP编程器驱动软件”文件夹复制到你电脑硬盘的D盘根目录下,并将其目录下的所有文件的只读属性去掉,具体操作如下:全选文件夹中的文件,鼠标右键单击出现文件属性对话框,单击“只读”属性前面复选框中的勾,使其只读属性去掉即可。然后双击文件夹中的“ISP编程器驱动软件.exe”启动编程软件,点击"文件",在打开文件的对话框中找到工程文件夹中的目标文件"smg1.hex"打开即可,然后点击“AUTORUN”将程序烧写到单片机内部(如下图8)。
图8:将程序烧写到单片机内部 |
烧写完成了,把单片机从编程器中取出,然后插到S51增强型实验板上,插上USB电源,看看显示效果是不是和上面图4显示一样,是否有一点点的成就感呀!初学者也许会问:数码管显示一个数字“6”就要15行程序,太复杂了?的确有点复杂了,在上面程序中为了显示数字“6”,数码管的段码"b"、段码"dp"输出的是高电平,其它引脚输出的是低电平,实际上从单片机的P0.0~P0.7输出的是二进制码“10000010”,转换成十六进制为82H。因此,我们只要把所有要显示的数字和字符的段码根据硬件连接编制一个字形表,显示时直接把相应的字形码送到P0口就可以了。
共阳LED数码管字形(段码)表 | ||||||||||
显示数字 | P0.7 | P0.6 | P0.5 | P0.4 | P0.3 | P0.2 | P0.1 | P0.0 | 二进制代码 | 十六进制代码 |
0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 11000000 | C0H |
1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 11111001 | F9H |
2 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 10100100 | A4H |
3 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 10110000 | B0H |
4 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 10011001 | 99H |
5 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 10010110 | 92H |
6 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 10000010 | 82H |
7 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 11111000 | F8H |
8 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10000000 | 80H |
9 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 10010000 | 90H |
A | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 10001000 | 88H |
B | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 10000011 | 83H |
C | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 11000110 | C6H |
D | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 10100001 | A1H |
E | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 10000110 | 86H |
F | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 10001110 | 8EH |
H | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 10001001 | 89H |
O | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 11000000 | A3H |
P | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 10000100 | 8CH |
N | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 11001000 | C8H |
从上面表格中可以看到,显示“6”的十六进制段码值为"82H",因此我们把刚才的程序修改一下,修改后的完整程序如下:
MAIN:MOV P0,#82H ;将数字"6"的段码输出到P0口
MOV P2,#0FEH;从P2口输出数码管选通代码,即输出二进制“11111110”
AJMPMAIN;跳转到开始重新进行
END ;程序结束
看看修改后的程序将变得更加简洁,直观了,程序代码从原来的15行减少到仅4行,一样实现了相同的功能。这也就是我们要学习的编程技巧哦!在编程中尽量用最少的代码实现相同的功能。程序第1行的功能是将要显示的数字“6”的十六进制段码"82H"送到P0口,程序第2行的功能就是将数码管的选通代码#0FEH(即二进制"11111110")送到P2口,从而控制第一位数码管显示,其它数码管熄灭。把修改过的程序编译后的目标文件写到单片机上看到显示效果是一样的。程序中用一行代码 MOVP0,#82H 就输出了字形,因此我们要显示其它字形时只要从上面的数码管段码表中查出对应的十六进制字形码,用同样的方法把段码输出到P0口就可以了。比如我们要显示一个数字“8”, 只需将程序中的 MOVP0,#82H 语句改成 MOVP0,#80H 即可,至此,我们终于可以随心所欲地控制数码管要显示的字形了,是不是很简单呀 :) 。
另外,如果想让第二位数码管DG2显示,其它熄灭怎么办呢?其实很简单,只要把对应数码管的选通端口输出低电平就可以使该位数码管显示了,如指令 CLRP2.1 就可以让第二个数码管显示。。。程序中如果使P2.0~P2.4都输出低电平,那么实验板上的5个数码管都会被选通,显示出相同的字形,即显示“66666”。下面就是5位数码管显示出“66666”的程序,初学者可以实验一下,以加深对数码管显示位选通(使能)控制的理解。
MAIN:MOV P0,#82H ;将数字"6"的段码输出到P0口
MOV P2,#0E0H;从P2口输出数码管选通代码,使5位数码管均选通,即输出二进制“11100000”
AJMPMAIN;跳转到开始重新进行
END ;程序结束
单片机驱动数码管的动态显示编程
上面我们已经学习了数码管静态显示,接下来我们就学习数码管动态显示编程,编程让实验板上的数码管显示“89C51”。从原理图中(图5)我们可以看到,5个数码管的8个显示笔划"a,b,c,d,e,f,g,dp"的同名端是2连在一起的,那么当程序从P0口输出字形码时,在同一个时间所有数码管都会接收到相同的字形码。你一定会问,这样不是5个数码管都显示相同的数字了吗?如何显示出5个不同的字符“89C51”呢?因此,就要使用动态扫描了,在程序中,首先显示一个数,然后关掉;然后显示第二个数,又关掉,显示第三个数,又关掉。。。直到所有要显示的5个数完成,再从头开始扫描。轮流点亮扫描过程中,每位显示器的点亮时间是极为短暂的(约1ms),由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位显示器并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感。
数码管显示“89C51”的具体编程思路如下:第一位数码管显示“8” → 延时1ms → 关闭所有数码管显示 → 第二位数码管显示“9” → 延时1ms → 关闭所有数码管显示 → 第三位数码管显示“C” → 延时1ms → 关闭所有数码管显示 → 第四位数码管显示“5” → 延时1ms → 关闭所有数码管显示 → 第五位数码管显示“1” → 延时1ms → 关闭所有数码管显示 → 返回到第一步重新进行新一轮扫描过程。下面就是根据该思路编出来的源程序,初学者可以把该程序粘贴到Keil工程中,编译得到目标文件,然后烧写到单片机验证一下。
; *********** 在数码管上动态显示"89C51" *************
MAIN: MOV P0,#80H;第1位数码管显示“8”
CLR P2.0 ;允许第1位数码管显示
ACALL DELAY;显示延时一段时间
MOV P0,#0FFH ;清除P0口字形码
MOV P2,#0FFH ;停止所有数码管显示选通,关闭所有显示
- FPGA的DSP性能揭秘(06-16)
- 基于单片机通用引脚的软件UART设计(10-16)
- 分时操作系统思想在单片机中的具体应用 (10-30)
- 基于AT89C51+DSP的双CPU伺服运动控制器的研究(05-26)
- 关于RTX51 TINY的分析与探讨(05-30)
- 基于MC9S12DGl28单片机的智能寻迹车设计(04-03)