用汇编语言编程使51单片机实现6位共阳数码管一位循环显示0-9

用汇编语言编程使51单片机实现6位共阳数码管一位循环显示0-9,第1张

以下程序实现6位数码管,每一位依次循环显示0--9

ORG 0000H

LJMP MAIN

ORG 0030H

MAIN:

MOV P2,#0FEH

MOV A,#00H

MOV DPTR,#TAB

LOOP:

MOVC A,@A+DPTR

MOV P0,A

LCALL DELAY

INC A

CJNE A,#0AH,LOOP

MOV A,P2

RL A

MOV P2,A

JB ACC.6,SS1

MOV P2,#0FEH

SS1:

CLR A

SJMP LOOP

DELAY:

MOV R1,#2

L1: MOV R2,#200

L2: MOV R3,#200

L3: DJNZ R3,L1

DJNZ R2,L2

DJNZ R1,L3

RET SJMP $

ORG 0080H

TAB:

DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H

END

#include <reg51.h>

#include <intrins.h>

void delay(unsigned int i) //函数声名

char DelayCNT//定义变量

//此表为 LED 的字模, 共阴数码管 0-9 -

unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40} //段码控制

//此表为8个数码管位选控制, 共阴数码管 1-8个 -

unsigned char code dispbit[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdF,0xbF,0x7F} //位选控制 查表的方法控制

/************主函数**********************/

main()

{

unsigned int i,LedNumVal=1 //变量定义

unsigned int LedOut[10] //变量定义

DelayCNT=0

while(1)

{

if(++DelayCNT>=20) //控制数字变化速度

{

DelayCNT=0 //20个扫描周期清零一次

++LedNumVal //每隔20个扫描周期加一次

}

LedOut[0]=Disp_Tab[LedNumVal%10000/1000]

LedOut[1]=Disp_Tab[LedNumVal%1000/100]|0x80

LedOut[2]=Disp_Tab[LedNumVal%100/10]

LedOut[3]=Disp_Tab[LedNumVal%10]

LedOut[4]=Disp_Tab[LedNumVal%10000/1000] //千位

LedOut[5]=Disp_Tab[LedNumVal%1000/100]|0x80 //百位带小数点

LedOut[6]=Disp_Tab[LedNumVal%100/10] //十位

LedOut[7]=Disp_Tab[LedNumVal%10]//个位

for( i=0i<9i++)

{

P0 = LedOut[i]

P1 = dispbit[i] //使用查表法进行位选

/* switch(i) //使用switch 语句控制位选

{

case 0:P1 = 0x7F break

case 1:P1 = 0xbF break

case 2:P1 = 0xdF break

case 3:P1 = 0xeF break

case 4:P1 = 0xf7 break

case 5:P1 = 0xfb break

case 6:P1 = 0xfd break

case 7:P1 = 0xfe break

} */

delay(150) //扫描间隔时间 太长会数码管会有闪烁感

}

}

}

void delay(unsigned int i)

{

char j

for(ii >0i--)

for(j = 200j >0j--)

}

这个程序的基本流程是:

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


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/11680675.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-17
下一篇2023-05-17

发表评论

登录后才能评论

评论列表(0条)

    保存