第1节 码管编程实例
推荐给好友
打印
加入收藏
更新于2008-07-25 19:40:55

本节在简要介绍8段数码管基本知识的基础上,阐述了扫描法LED显示编程原理,并提供一个接口编程实例。

9.1.1 扫描法LED显示编程原理

8段数码管一般由8个发光二极管(Light-emitting diode,LED)组成,每一个位段就是一个发光二极管。一个8段数码管分别由a、b、c、d、e、f、g位段,外加上一个小数点的位段h(或记为dp)组成。根据公共端所接电平的高低,可分为共阳极和共阴极两种,如图9-1所示。实物外型见图9-2。有时数码管不需要小数点,只有7个位段,称7段数码管。共阴极8段数码管的信号端高电平有效,只要在各个位段上加上相应的信号即可使相应的位段发光,比如:要使a段发光,则在a段加上高电平即可。共阳极的8段数码管则相反,在相应的位段加上低电平即可使该位段发光。因而,一个8段数码管就必须有8位(即1个字节)数据来控制各个位段的亮灭。比如:对共阳极8段数码管,PTA0~7分别接a~g、dp,即PTA = 0b011111111时,dp段亮;当PTA=0b10000000时,除dp位段外,其他位段均亮。如此推算,有几个8段数码管,就必须有几个字节的数据来控制各个数码管的亮灭。这样控制虽然简单,却不切实际,MCU也不可能提供这么多的端口用来控制数码管,为此,往往是将几个8段数码管合在一起使用,通过一个称为数据口的8位数据端口来控制段位。而一个8段数码管的公共端,原来接到固定的电平(对共阴极是GND,对共阳极是Vcc),现在接MCU的一个输出引脚,由MCU来控制,通常叫“位选信号”,而把这些由n个数码管合在一起的数码管组称为n连排数码管。这样,MCU的两个8位端口就可以控制一个8连排的数码管。若是要控制更多的数码管,则可以考虑外加一个译码芯片。例如:一个4连排的共阴极数码管,它们的位段信号端(称为数据端)接在一起,可以由MCU的一个8位端口控制,同时还有4个位选信号(称为控制端),用于分别选中要显示数据的数码管,可用MCU另一个端口的4个引脚来控制。如图9-3所示。对于图9-3所示的4连排数码管,利用CS3 、CS2、CS1、CS0控制各个数码管的位选信号,每个时刻只能让一个数码管有效,即CS3 、CS2、CS1、CS0只能有一个为0,例如令CS3=0,CS2、CS1、CS0=111,则数据线上的数据体现在第一个数码管上,其他则不受影响。要让各个数据管均显示需要的数字,则必须逐个使相应位选信号为0,其他位选信号为1,并将要显示的一位数字送到数据线上。这种方法叫“位选线扫描法”。虽然每个时刻只有一个数码管有效,但只要延时适当,由于人眼的“视觉暂留效应”(约100ms左右),看起来则是同时显示的。

9.1.2 接口实例

图9-4给出了一个4连排共阴极8段数码管的编程实例。在硬件连接上,利用MCU的B口控制8个位段(数据),用C口的低四位控制数码管的位选信号。图中,PTB7~0分别接h~a位段,PTC3~0分别通过1K电阻与CS3~0位选端相接,这样PTC3就控制最左边一个数码管的显示,PTC0则控制最右边一个数码管的显示。接在位选线上的1K电阻是限流电阻,避免电流过大烧坏数码管。

9.1.3 数码管汇编语言实例

以下给出GP32对上述4位一体LED的汇编编程实例,表9-1列出了该例程的所有程序文件,下面逐一介绍这些程序。

 (1) LED汇编编程主函数
//------------------------------------------------------*
//工 程 名:LED.prj *
//硬件连接: *
// (1)LED的8个位段(数据)和位选引脚与MCU的通用I/O口 *
// 引脚连接(见"LED.s"文件) *
// (2)MCU的串口与PC方的串口相连 *
//工程描述:在4连排数码管上从左至右显示从串口接收来的4位 *
// 十进制数 *
//目 的:实现数码管的显示 *
//注 意:LED及键盘的可能影响 *
//--------清华2007版《嵌入式技术基础与实践》实例--------*

//总头文件
.include "Includes.h"
//主程序
.area flash(abs)
.org FlashStartAddr
MainInit:: //复位后从此处执行(见Vectors08.s文件末尾处)
SEI //关总中断
//1. 堆栈初始化为RAM最高端
LDHX #RAMendAddr + 1 //HX = #RAMEndAddr + 1
TXS //HX - 1 -> SP
//2. 芯片初始化
JSR MCUinit //初学时跳过此处
//3. 模块初始化
JSR SCIinit //(1) 串行口初始化
JSR LEDinit //(2) LED控制引脚初始化
//4. 全局变量初始化
//(1) LED缓存初始存入0000
MOV #'0',*LEDbuf4
MOV #'0',*LEDbuf4+1
MOV #'0',*LEDbuf4+2
MOV #'0',*LEDbuf4+3
//(2) 标志初始化 = &FF
MOV #$FF,ReFlag
//5. 开放各模块中断
JSR EnableSCIreInt //允许SCI接收中断
//6. 开总中断
CLI
//LED初始显示0000
LDHX #LEDbuf4
JSR LEDshow
//程序总循环入口
MainLoop:
LDA ReFlag //当接收并正确接收数据时,ReFlag = 0
CMP #$0
BNE Main_Show
//数据从ReBuf-->LEDbuf
MOV *ReBuf4, *LEDbuf4
MOV *ReBuf4+1,*LEDbuf4+1
MOV *ReBuf4+2,*LEDbuf4+2
MOV *ReBuf4+3,*LEDbuf4+3
MOV #$FF,ReFlag
Main_Show:
//把LEDbuf4为首址4个数字送LED显示
LDHX #LEDbuf4
JSR LEDshow
BRA MainLoop
//包含本工程的其他文件-----------------------------------
.include "EnDisInt.s" //允许/禁止MCU各模块中断
.include "MCUinit.s" //芯片初始化
.include "GeneralFun.s" //该文件包含延时子程序
.include "SCI.s" //串行通信
.include "LED.s" //LED驱动

//包含中断处理子程序与中断向量表文件"Vectors08.s"--------
//注意:这个包含语句的存放位置必须放在最后
.include "Vectors08.s" //中断处理子程序与中断向量表

(2) LED驱动子程序LED.s
//[LED.s]LED驱动----------------------------------------*
//本文件包含: *
// (1)LEDinit:4连排LED初始化 *
// (2)LEDshow:在4连排LED上显示4个十进制数 *
// (3)LEDshow1:在1个LED上显示数字 *
//硬件连接: *
// (1)PTB 7-0 分别接LED的数据线 h g f e d c b a *
// (2)PTC 3-0 分别接各LED的位选线(从右到左) *
//------------------------------------------------------*
.include "LED.h" //该头文件包含LED驱动相关寄存器宏定义

//LEDinit:4连排LED初始化--------------------------------*
//功能:定义LED控制引脚的数据口和位选口为输出 *
//入口:无 *
//出口:无 *
//堆栈深度:2 + 1 = 3 *
//------------------------------------------------------*
LEDinit::
PSHA //保护A
//数据口为输出到LED
LDA #%11111111
STA LEDdata_D
//位选口为输出到LED
LDA LEDcs_D
ORA #%00001111
STA LEDcs_D
PULA //恢复A
RTS

//LEDshow: 在4连排LED上显示4个十进制数------------------*
//功能:在4连排LED上显示HX所指向的4个数据 *
//入口:HX = 待显示数据缓冲的首地址 *
//出口:无 *
//说明:HX所指向的缓冲区中的数据是数值的ASCII值 *
//堆栈深度:2 + 4 + 4 = 10 *
//内部调用:LEDshow1,DelayHX *
//------------------------------------------------------*
LEDshow::
PSHA //保护A
LDA #4 //循环显示4个LED
LEDshow_1:
PSHH //暂存显示缓冲首地址
PSHX
PSHA //暂存循环计数器
//取要显示的1个数字
LDA ,X
//把这个数字的ASCII码转换成数值-->A
SUB #'0'
//设置要显示的LED位号(从左到右为3-0)-->X
PULX
PSHX
DECX
//显示这个数字
JSR LEDshow1
//延时
LDHX #$FF
JSR DelayHX
PULA //恢复计数器
PULX //恢复显示缓冲首地址
PULH
//指向下一个要显示的数字
AIX #1
//循环显示4个数字
DBNZA LEDshow_1
PULA //恢复A
RTS

//LEDshow1:在1个LED上显示数字---------------------------*
//功能:在第X个LED上显示数字A(要查表转码) *
//入口: *
// (1)X:要显示的LED位号(从右到左0-3) *
// (2)A:要显示的数字(0-9) *
//出口:无 *
//堆栈深度:2 + 1 + 1 = 4 *
//------------------------------------------------------*
LEDshow1:
PSHH //保护H
PSHA //保护A
CLRH
LDA CStable,X //查表取位选信号
STA LEDcs //送位选信号
PULA //恢复A
TAX
LDA Dtable,X //查表取显示码
STA LEDdata //送到LED数据线
PULH //恢复H
RTS

//片选表 0 1 2 3
CStable:: .byte $F7,$FB,$FD,$FE
//显示码表 0 1 2 3 4 5 6 7 8 9
Dtable:: .byte $3F,$06,$5B,$4F,$66,$6D,$7D,$07,$7F,$6F
(3) LED驱动头文件LED.h
//[LED.h]LED驱动头文件-----------------------------------

//LED驱动相关寄存器宏定义
LEDdata = PTB //LED数据口
LEDdata_D = DDRB //数据口相应方向寄存器
LEDcs = PTC //LED位选口
LEDcs_D = DDRC //位选口相应方向寄存器

9.1.4 数码管08C语言实例

以下给出GP32对上述4位一体LED的08C编程实例,表9-2列出了该例程的所有程序文件,具体内容不做介绍,读者参阅附带教学资料“MC08Ex2007\ GP32\GP32C\C05_数码管LED”中的工程。



<<上一节 下一节>>

相关链接


 
关于我们 | 诚邀加盟 | 客户服务 | 相关法律 | 网站地图 | 友情链接 | 服务信箱:service@eefocus.com
© 2006 与非门科技信息咨询(北京)有限公司 All Rights Reserved.