单片机大作业---16*16点阵显示step1

github传送门https://github.com/hao297531173/8051BigAssignment

这篇文章我们先来看最简单的情况:闪烁显示汉字。

part1 中断向量表

;===========
;中断向量表
;===========
ORG   0000H
    SJMP MAIN   ;跳转到主程序
ORG   0003H     ;外中断0
    RETI    
ORG   000BH     ;定时器0
    RETI
ORG   0013H     ;外中断1
    RETI
ORG   001BH     ;定时器1
    RETI
ORG   0023H     ;串行口中断
    RETI

这一部分记录了中断程序的入口地址,如果不需要中断的话直接填RETI中断返回指令就行了,我觉得写中断向量表是一个好习惯。

part2 初始化程序

;==========
;初始化程序
;==========
MAIN:   MOV SP, #5FH    ;初始化堆栈指针
        MOV IE, #82H    ;1000 0010B,表示开总中断和EX1外部中断1
M1:     MOV DPTR, #TAB  ;将字形码其实地址送给DPTR,之后只要一直自增即可
        MOV R7, #4H     ;****这里控制要显示的字数****
M2:     ACALL DISPLAY
        DJNZ R7, M2
        SJMP M1

初始化程序需要初始化SP,因为我们要用到子程序的调用,还有堆栈,然后初始化DPTR从程序计数器取数,这里面R7控制你需要显示几个字。

part3 显示主程序

;===============================
;显示主程序
;显存为30H开始的32个内存单元
;P0口控制低8位字形码
;P1口控制高8位字形码
;P2口控制字位码
;P2.7口为高电平的时候不选通任何一列
;先送字形码,后送字位码
;然后调用延时子程序后再显示下一列
;显示完一个字后
;================================
DISPLAY:    ACALL GET       ;先将下一帧送入显存
            PUSH 00H
            PUSH 01H
            PUSH 02H
            PUSH 03H
            PUSH 04H
            MOV R4, #20H   ;****这里控制循环次数****
            ;初始化部分
D1:         MOV R0, #30H    ;用作上半部分显示内容指针
            MOV R1, #30H+10H;用作下半部分显示内容指针
            MOV R2, #10H    ;进行显示内容控制
            MOV R3, #00H    ;用作字位码
            CLR A
            MOV P0, A
            MOV P1, A
            SETB P2.7
            ;显示部分
D2:         MOV P0, @R0     ;将低8位字形码送入P0口
            MOV P1, @R1     ;将高8位字形码送入P1口
            MOV P2, R3      ;将字位码送入P2口
            CLR P2.7        ;将P2.7口置0表示可以显示
            ACALL DELAY5    ;延时0.5ms
            SETB P2.7       ;关闭显示
            INC R0
            INC R1
            INC R3
            DJNZ R2, D2
            DJNZ R4, D1
            POP 04H
            POP 03H
            POP 02H
            POP 01H
            POP 00H
            RET

先来看一下电路图

我使用的是P0口和P1口来控制灯的亮灭,使用P2口控制显示的是哪一列。LED电路一共有16*2个接口,左边16个接口控制灯亮还是灭(P1,P2口),高电平亮,低电平灭;右边16个输出口的控制选通哪一列有效,低电平有效。

这样一来显示主程序就分为两个步骤了:

1)送显示数据到P0口和P1口

2)送列选通信号到P2口

3)延时一段时间

扫描二维码关注公众号,回复: 9828089 查看本文章

4)继续显示下一列

如此循环16次就显示完一遍了,然后我们重复这个过程,就可以让汉字在屏幕上停留一段时间了。

有一个小细节要注意一下,能够用作寄存器间接寻址的寄存器(就是用寄存器当指针在数据储存器中取数)只有R0和R1,所以我们用他们两个来当指针,他们相距10H,R0指向的是上半LED显示的内容,R1指向的是下半LED显示的内容。用R3来控制显示哪一列,这个比较简单,直接赋初值为0,然后加一加一就行了,R2来进行次数控制,一共刷新16行,所以R2赋初值10H,每刷新完一行就减一,R4用来控制一个字显示的遍数,也就是R4可以控制一个字显示多久,刷新完一遍大概需要600条指令,也就是0.6ms,据此就能分析出显示一个字的时间了。

part4 送数程序

;================================
;子程序名:送数子程序
;将字形码送入30H开始的32个内存单元
;用到R1 R2 A DPTR
;================================
GET:    PUSH 01H    ;将R1的值入栈
        PUSH 02H    ;将R2的值入栈
        MOV R1, #30H ;指向显存的起始地址
        MOV R2, #20H ;控制送数个数
G1:     CLR A
        MOVC A, @A+DPTR
        MOV @R1, A
        INC DPTR
        INC R1
        DJNZ R2, G1
        POP 02H
        POP 01H
        RET

我们将30H开始32个内存单元当做显存。这就是我们之前做过的程序,将程序储存器中的字形表送入数据储存器中30H开始的32个内存单元,注意,取数的时候要用MOVC A, @A+DPTR,这是从程序储存器取数的指令,送完数之后就可以开始显示啦。PS:PUSH和POP指令分别是推入堆栈和出栈的指令,后面要跟直接地址,00H就代表的是R0,01H就代表的是R1一次类推,如果要将累加器ACC入栈,那么应该写成PUSH ACC;还有,出栈和入栈的顺序要相反。

part5 延时程序

;=============================
;子程序名:延时约0.5ms
;51单片机频率为12MHz
;时钟周期为1/12M s
;一个机器周期等于12个时钟周期
;所以一个机器周期为1us
;想要延时5ms就需要执行500条指令
;需要修改延时时间只要修改R7和R6即可
;=============================
DELAY5: PUSH 07H
        PUSH 06H
        MOV R6, #2
LAB1:   MOV R7, #250
LAB2:   DJNZ R7, LAB2
        DJNZ R6, LAB1
        POP 06H
        POP 07H
        RET             ;子程序返回

关于延时程序的计算问题,可以用1us 乘以指令条数就是延时的时间,实际上不需要特别精确,大致差不多就行了。

part6 字形码表

;=============
;这里储存字形码
;=============
ORG 1000H
TAB: db  08h, 28h, 48h, 88h, 68h, 18h, 00h,0FCh     ;"鸡"
	 db	 06h, 15h, 44h, 84h, 7Eh, 04h, 00h, 00h
	 db	 10h, 08h, 06h, 01h, 02h, 14h, 10h, 13h
	 db	 12h, 12h, 1Ah, 52h, 82h, 7Fh, 02h, 00h

	db   40h, 20h,0F8h, 07h, 40h, 20h, 18h, 0Fh     ;"你"
	db	 08h,0C8h, 08h, 08h, 28h, 18h, 00h, 00h
	db	 00h, 00h,0FFh, 00h, 00h, 08h, 04h, 43h
	db	 80h, 7Fh, 00h, 01h, 06h, 0Ch, 00h, 00h

	db   20h, 20h, 20h, 20h, 20h, 20h, 20h,0FFh     ;"太"
	db	 20h, 20h, 20h, 20h, 20h, 30h, 20h, 00h
	db	 40h, 40h, 20h, 20h, 10h, 0Ch, 0Bh, 30h
	db	 03h, 0Ch, 10h, 10h, 20h, 60h, 20h, 00h

	db   80h, 88h,0A8h,0A8h,0A9h,0AAh,0AEh,0F8h     ;"美"
	db	 0ACh,0AAh,0ABh,0A8h,0ACh, 88h, 80h, 00h
	db	 80h, 84h, 84h, 44h, 44h, 24h, 14h, 0Fh
	db	 14h, 24h, 24h, 44h, 46h,0C4h, 40h, 00h

这里就是用来存储你要显示的汉字的字形码。

part7 怎么使用

只需要修改MAIN函数里R7的数值(你要显示几个汉字),然后将你想要显示汉字字形码复制到TAB开始的地方就行了。

part8 完整代码

;==================================
;程序名:51单片机控制16*16LED点阵显示
;作者:  呼啦啦
;完成时间:  2019-6-9
;step 1
;完成功能:闪烁显示字符
;==================================

;============================================
;基本功能介绍:
;使用74HC154进行列选通,p2.0-p2.3作为地址输入口
;一共有16个输出位,分别控制16列
;p0口作为上8行字形码输出口
;p1口作为下8行字形码输出口
;============================================

;==========
;常量表
;常量表报错
;不知道为什么
;==========
;NUMBER   EQU  #4    ;要显示的字数
;控制每个字循环显示的次数
;每显示一个字大约需要600条指令,也就是0.6ms
;TIME     EQU  #255 


;===========
;中断向量表
;===========
ORG   0000H
    SJMP MAIN   ;跳转到主程序
ORG   0003H     ;外中断0
    RETI    
ORG   000BH     ;定时器0
    RETI
ORG   0013H     ;外中断1
    RETI
ORG   001BH     ;定时器1
    RETI
ORG   0023H     ;串行口中断
    RETI

;==========
;初始化程序
;==========
MAIN:   MOV SP, #5FH    ;初始化堆栈指针
        MOV IE, #82H    ;1000 0010B,表示开总中断和EX1外部中断1
M1:     MOV DPTR, #TAB  ;将字形码其实地址送给DPTR,之后只要一直自增即可
        MOV R7, #4H     ;****这里控制要显示的字数****
M2:     ACALL DISPLAY
        DJNZ R7, M2
        SJMP M1




;===============================
;显示主程序
;显存为30H开始的32个内存单元
;P0口控制低8位字形码
;P1口控制高8位字形码
;P2口控制字位码
;P2.7口为高电平的时候不选通任何一列
;先送字形码,后送字位码
;然后调用延时子程序后再显示下一列
;显示完一个字后
;================================
DISPLAY:    ACALL GET       ;先将下一帧送入显存
            PUSH 00H
            PUSH 01H
            PUSH 02H
            PUSH 03H
            PUSH 04H
            MOV R4, #20H   ;****这里控制循环次数****
            ;初始化部分
D1:         MOV R0, #30H    ;用作上半部分显示内容指针
            MOV R1, #30H+10H;用作下半部分显示内容指针
            MOV R2, #10H    ;进行显示内容控制
            MOV R3, #00H    ;用作字位码
            CLR A
            MOV P0, A
            MOV P1, A
            SETB P2.7
            ;显示部分
D2:         MOV P0, @R0     ;将低8位字形码送入P0口
            MOV P1, @R1     ;将高8位字形码送入P1口
            MOV P2, R3      ;将字位码送入P2口
            CLR P2.7        ;将P2.7口置0表示可以显示
            ACALL DELAY5    ;延时0.5ms
            SETB P2.7       ;关闭显示
            INC R0
            INC R1
            INC R3
            DJNZ R2, D2
            DJNZ R4, D1
            POP 04H
            POP 03H
            POP 02H
            POP 01H
            POP 00H
            RET








;================================
;子程序名:送数子程序
;将字形码送入30H开始的32个内存单元
;用到R1 R2 A DPTR
;================================
GET:    PUSH 01H    ;将R1的值入栈
        PUSH 02H    ;将R2的值入栈
        MOV R1, #30H ;指向显存的起始地址
        MOV R2, #20H ;控制送数个数
G1:     CLR A
        MOVC A, @A+DPTR
        MOV @R1, A
        INC DPTR
        INC R1
        DJNZ R2, G1
        POP 02H
        POP 01H
        RET



;=============================
;子程序名:延时约0.5ms
;51单片机频率为12MHz
;时钟周期为1/12M s
;一个机器周期等于12个时钟周期
;所以一个机器周期为1us
;想要延时5ms就需要执行500条指令
;需要修改延时时间只要修改R7和R6即可
;=============================
DELAY5: PUSH 07H
        PUSH 06H
        MOV R6, #2
LAB1:   MOV R7, #250
LAB2:   DJNZ R7, LAB2
        DJNZ R6, LAB1
        POP 06H
        POP 07H
        RET             ;子程序返回


;================================
;字位码表,用于控制列选通
;只有选通的那一列是低电平
;其他列都是高电平
;这些数值都要送入P2口进行字位选通信号
;=================================
;字位码一直是从0-16,所以不用存了


;=============
;这里储存字形码
;=============
ORG 1000H
TAB: db  08h, 28h, 48h, 88h, 68h, 18h, 00h,0FCh     ;"鸡"
	 db	 06h, 15h, 44h, 84h, 7Eh, 04h, 00h, 00h
	 db	 10h, 08h, 06h, 01h, 02h, 14h, 10h, 13h
	 db	 12h, 12h, 1Ah, 52h, 82h, 7Fh, 02h, 00h

	db   40h, 20h,0F8h, 07h, 40h, 20h, 18h, 0Fh     ;"你"
	db	 08h,0C8h, 08h, 08h, 28h, 18h, 00h, 00h
	db	 00h, 00h,0FFh, 00h, 00h, 08h, 04h, 43h
	db	 80h, 7Fh, 00h, 01h, 06h, 0Ch, 00h, 00h

	db   20h, 20h, 20h, 20h, 20h, 20h, 20h,0FFh     ;"太"
	db	 20h, 20h, 20h, 20h, 20h, 30h, 20h, 00h
	db	 40h, 40h, 20h, 20h, 10h, 0Ch, 0Bh, 30h
	db	 03h, 0Ch, 10h, 10h, 20h, 60h, 20h, 00h

	db   80h, 88h,0A8h,0A8h,0A9h,0AAh,0AEh,0F8h     ;"美"
	db	 0ACh,0AAh,0ABh,0A8h,0ACh, 88h, 80h, 00h
	db	 80h, 84h, 84h, 44h, 44h, 24h, 14h, 0Fh
	db	 14h, 24h, 24h, 44h, 46h,0C4h, 40h, 00h

END

part9 显示效果

发布了130 篇原创文章 · 获赞 151 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/haohulala/article/details/91372488
今日推荐