9.1.1 扫描法LED显示编程原理


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”中的工程。




