
1.把content中的数字对应的断码找出,并依次存放到LEDBuf中
2.依次送LEDBuf中的断码到LED上,LED显示对应字符
OUTBIT equ 08002h 将位码送至此地址,位码表示显示哪一位LED管
OUTSEG equ 08004h 将断码送至此地址,断码表示在指定的LED管上显示什么字符
data segment
Content db 1,2,3,0dh,0eh,0fh 要显示的数字
LEDBuf db 6 dup(?) 要显示的数字对应的断码
LEDMAP给出的是断码表,表示16进制数到断码的映射。总共16个,分别表示0-f。
比如第一个3fh就是0的断码,断码送到LED中,LED会自动显示0。
LEDMAP:
db 3fh,06h,5bh,4fh,66h,6dh,7dh,,07h
db 7fh,6fh,77h,7ch,39h,5eh, 79h,71h
data ends
code segment
assume cs:code, ds:data
Delay的目的就是为了让LED灯上的内容停留,以便看清
Delay proc
push cx
mov cx,100h
loop $ 这里的循环目的是暂停一段时间,让LED上的数字停留,以便人看清
pop cx
ret
Delay endp
DisplayLED做的事:把LEDbuf中内容全部显示到LED灯上。LEDbuf中6个断码,对应6个LED灯。
DisplayLED proc near
mov bx, offset LEDBuf
mov cx, 6 总共显示6个断码
mov ah, 00100000b 位码,00100000b中1的位置指示了要显示的数位,当前是1在左起第六个,也就是显示6号LED灯
后面有shr指令会将这个00100000b右移,这样变成00010000,显示5号LED,以此类推。
DLoop: mov dx, OUTBIT
mov al, 0
out dx,al 将0送端位码端口,表示当前不选中任何LED,即关闭LED
mov al, [bx] 将LEDbuf中的一个断码,送入al
mov dx, OUTSEG
out dx,al 送断码,表示要在LED中显示这个字符
mov dx, OUTBIT
mov al, ah
out dx, al 送位码,表示要显示哪一个LED灯
call Delay 上面送完断码,位码后,在相应的LED上就显示相应的字符,Delay可以让这个字符停留一段时间,视觉滞留。
shr ah, 1 位码右移,显示下一个LED
inc bx bx加1,那么[bx]就指向LEDbuf中的下一个断码
loop Dloop 这个Dloop循环把LEDbuf中的六个断码依次全部送到对应LED上显示
ret
DisplayLED endp
Start:程序的入口,从这里开始运行程序
Start proc near
mov ax, data
mov ds, ax
mov cx,6 显示六个字符
mov ah,0 ah是content中的偏移量,从0->5,分别找出content中各个字节内容
mov si,offset ledbuf
redo: mov bx,offset content
mov al,ah 后面的xlat指令要使用al
xlat xlat的作用al<-[bx+al],也就是将bx这个地址(content)起的第al个字节内容送到al中
mov bx,offset ledmap
xlat 将此时al中的数字对应的断码找出,并放到al中。(数字a对应的断码就是ledmap起第a个字节的数据)
mov [si],al 将找到的断码放到LEDbuf中
inc si LEDbuf地址加1,存放下一个断码
inc ah 找content中下一个数字的断码
loop redo 整个redo循环做的事:把content中数字对应的断码放到LEDbuf中,循环最后结果是LEDbuf变成:06h,5bh,4fh,5eh,79h,71h
show: call displayled
jmp show 在LED上一直显示这6个字符
start endp
code ends
end start
DELAY5MS PROC ;延时子程序开始MOV DX,0B000H ;所选计数器对应的端口地址送DX
MOV AX,5000 ;8253计数初值送AX
OUT DX,AL ;低8位送入计数器端口
MOV AL,AH ;把高八位先给AL,输入输出指令的必须格式
OUT DX,AL ;高8位计数器送入端口
HH:MOV DX,0F002H ;标号,把端口号给DX
IN AL,DX ;读地址端口值
AND AL,01H ;屏蔽端口值的D7~D1位,目的是保持AL中D0位不变,检测其值是否为0
JNZ HH ;若不为0,跳转到HH,否则顺序执行
LL:IN AL,DX ;读地址端口值
AND AL,01H ;功能与之前的相同
JZ LL ;检测是否低位为0 ,为0则跳转到LL,否则顺序执行
RET ;返回值
DELAY5MS ENDP ;子程序结束命令
这段8253的程序少了一段控制字送控制端口的命令,没有控制字送控制端口是不行的。
5000并不是5000ms 按你题目所给,应当是5ms 至于5000要根据CLK是多少MHZ来计算。
你想知道是如何实现5ms延时的,这个我懂得不多,没有控制字,我的知道范围内说不出来它的工作方式,8253一共6种工作方式,很复杂,我建议你不要那么深究,除非你将来确定要搞这方面的,否则只会8253的初始化编程就够了,我也是学生,对于我们用的教材和一些资料来说,都没有哪个书会去很深刻的剖析它,我觉得微型计算机原理这门课,你要选择性的学习一些东西。
先汗一个!
你要知道无论是8253,8255A,还是8259A,想对它们初始化编程都需要控制字,我想你如果学了8253就应该能知道什么是控制字。控制字的格式如下:
SC1, SC0———通道选择位.为00, 01, 10分别表示选择0, 1, 2通道.RL1, RL0———读/写 *** 作位.00 表示锁存数据,可随时读取计数器中的计数值01 表示只读/写低8位,高8位自动置为010表示只读/写高8位,低8位自动置为011表示读/写16位数据,先低8位,后高8位.M2,M1,M0———工作方式选择位。
根据控制字可以具体判断是选择哪一种工作方式,现在没有我就大体上说一说。
首先,计数初值=定时时间÷CLK周期 你算一算呵呵 对吧。
再说一下大体原理:
8253内部包括3个功能完全相同和 *** 作完全独立的计数通道,每个计数通道由16位减法计数器、16位计数初值寄存器和16位计数值锁存器组成。初始化时,向计数通道装入的计数初值,先送到计数初值寄存器中保存,然后送到减法计数器。计数器启动后,减法计数器对CLK的下降沿进行减1计数,在未锁定时把结果送入16位计数值锁存器中。当计数值减到0时,输出OUT信号,一次计数结束。计数初值寄存器的内容,在计数过程中保持不变。计数初值寄存器和计数值锁存器占用一个端口地址(即该计数通道口地址),CPU读取计数通道的当前计数值来自计数值锁存器。
不知道你懂不懂锁存,所存命令是在读取计数值时先用所存命令将其锁定,防止它改变,否则如果计数值有可能正处于变化中,这样得到的就是不确定的结果了。当cpu用读取所存命令后,锁存器就失效了,计数器将恢复工作。
没有控制字 但是你这个是一个延时程序那么就应该是将通道工作在定时器方式,此时确定频率的时钟脉冲从CLK输入,这正好与上面我说的频率,以及初值的计算吻合吧。
然后各通道的启动、禁止、允许计数与门控信号GATE有关,GATE的作用OUT的输出波形随各通道工作方式不同而不同。
没有控制字没法确定工作方式,也许有办法,但是我的知识有限,能知道的就这么多了,希望对你有所帮助。
PS:你算是把我榨干了!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)