这里使用的是AT89S51,利用定时器方式1实现跑马灯可以以5种速度变换(速度可以增加,只需要修改一点点的代码),并实现4种花样(用K1-K4键进行控制),也使用到了点阵。
实现过程
由于之前有做过按下按键使数码管显示的数字加一或减一的实验,本次的课程设计就使用此框架进行改造。
首先是控制速度,我使用的方法是将速度储存在R0中,然后每次按下按键使R0加一,再调用数码管显示程序;接着控制花样,这个就让不同按键对应使不同的值存入R2中,最后在跑马灯花样控制时进行判断。
关于点阵
点阵是我们一直想实现的内容,但是由于对74HC595的不熟悉,我们就利用P0口进行控制(还要向大佬学习),想要实现的是按下K4键点阵按照当前的速度进行移动,这里就遇到了一点点的挫折,因为忘记了延时程序还有使用到数码管显示程序,所以就造成了一些困惑,不管怎样,结果还是可以吧。
代码
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP TIMER0
ORG 1000H
;=========进行初始化==========================
MAIN:
CLR A ;把A清零
MOV R0,#0 ;赋初值,用于记录当前的数值
MOV R1,#0
MOV R2,#0 ;R2用于选择第几中变换方式
MOV P2,#0FEH ;跑马灯的初值
MOV 50H,#00H
LOOP: LCALL DIS ;等待按键按下
LCALL KEY1
;LCALL TIME_S
SJMP LOOP
KEY1:
;=========判断按键是否按下====================
;LCALL DIS ;用于显示当前的数值(即使按键没有按下)
MOV P3,#0FFH ;将初值赋给P3,写入全一
MOV A,P3 ;P3的值赋给A
CPL A ;累加器A中的内容取反
ANL A,#0FH ;检查是否有按键按下(只有四个按键)
JZ KEY1 ;累加器为0,即如果没有按键按下就跳转回到KEY1
LCALL DELAY ;延时程序去抖动
MOV P3,#0FFH ;重新判断是否有按键按下
MOV A,P3
CPL A
ANL A,#0FH
JZ KEY1 ;若无按键按下,则继续循环
JB ACC.0, PK1 ;检查按键按下的情况
JB ACC.1, PK2
JB ACC.2, PK3
JB ACC.3, PK4
PK1: LCALL PKAY2
LJMP PK
PK2: LCALL PKAY1
LJMP PK
PK3: LCALL PKAY3
LJMP PK
PK4: LCALL PKAY4
LJMP PK
PK: RET
;=========对按键按下进行处理====================
;处理K1按下的情况
PKAY1: CJNE R0,#5,ADD_OP ;判断是否等于5,即是否溢出,若无溢出,则跳转到加法运算
MOV R0,#0 ;如果等于5的话,就让R0回到0
ADD_OP: ;加法运算
INC R0 ;R0加一
LCALL DIS ;调用数码管显示程序
LIGHT:
MOV R2,#01H ;表示选择第一种花样
SJMP DIS_2
RET
;处理K2按下的情况
PKAY2: CJNE R0,#5,ADD_OP_2 ;和K1的处理方式相似
MOV R0,#0
ADD_OP_2: ;加法运算
INC R0 ;R0加一
LCALL DIS ;调用数码管显示程序
LIGHT_2:
MOV R2,#02H ;表示选择第二种花样
SJMP DIS_2
RET
;处理K3按下的情况
PKAY3: CJNE R0,#5,ADD_OP_3 ;和K1的处理方式相似
MOV R0,#0
ADD_OP_3: ;加法运算
INC R0 ;R0加一
LCALL DIS ;调用数码管显示程序
LIGHT_3:
MOV R2,#03H ;表示选择第三种花样
SJMP DIS_2
RET
;处理K4按下的情况
PKAY4: CJNE R0,#5,ADD_OP_4 ;和K1的处理方式相似
MOV R0,#0
ADD_OP_4: ;加法运算
INC R0 ;R0加一
LCALL TIME_S ;调用数码管显示程序
LCALL TIME_S
;LCALL DIS
LIGHT_4:
MOV R2,#04H ;表示选择第四种花样
MOV P0,#00H
SJMP DIS_2
RET
DIS_2:
MOV R6,#0
MOV DPTR,#NUM_CLOCK ;这里根据R0表示取出跑马灯的不同速度,
MOV A,R0 ;不同速度储存在NUM_CLOCK中,进行片选
MOVC A,@A+DPTR
MOV R3,A ;利用不同的初值可以选择不同的速度
MOV 41H,A
SJMP DIS_3 ;跳转到跑马灯程序
KRET:
RET
;=========将结果展示在数码管上=================
DIS: PUSH ACC
MOV A,R0
MOV R1,A ;A的值用R1暂存
MOV DPTR ,#NUM ;取表值
MOV A,R1
MOVC A,@A+DPTR ;选择不同的字形码
MOV P0,A ;输送到P0口
LCALL TIME_S ;延时程序
POP ACC
RET
;=========跑马灯程序==========================
DIS_3: MOV R3,41H
MOV TMOD, #01H ;令T0为定时器方式1
MOV TH0, #0D8H ;装入定时初值
MOV TL0, #0F0H
SETB EA ;开定时器中断总开关
SETB ET0 ;启动T0计数
SETB TR0
CLR A ;把A清零
;MOV A,#0FEH
LJMP KRET
HERE: AJMP HERE
TIMER0:
MOV TH0, #0D8H ;重装定时初值
MOV TL0, #0F0H
DJNZ R3,GOON
MOV R3,41H
CJNE R2,#01,A1
AJMP MOD1
AJMP A4
A1: CJNE R2,#02,A2
AJMP MOD2
AJMP A4
A2: CJNE R2,#03,A3
AJMP MOD3
AJMP A4
A3: CJNE R2,#04,A4
AJMP MOD4
A4: RETI
GOON: RETI
MOD1: MOV A,P2 ;方式一:跑马灯从当前位置向后移动一位
RL A
MOV P2,A
RETI
MOD2: MOV A, P2 ;方式二:跑马灯从当前位置向前移动一位
RR A
MOV P2, A
RETI
MOD3: MOV A, P2 ;方式三:跑马灯从当前位置向前移动两位
RL A
RL A
MOV P2, A
RETI
MOD4: ;方式四:实现LED点阵的花样控制
MOV DPTR,#TABA
MOV A,R6
MOVC A,@A+DPTR
MOV P0,A
INC R6
CJNE R6,#5,RE_0
RE_0: RETI
MOV R6,#0
RETI
;=========延时程序============================
DELAY: MOV R4,#200 ;延时程序,其中调用DIS是为了防止按键按下时会闪烁
D: DJNZ R4,D
RET
TIME_S:
MOV R5,#250 ;延时程序
D2: MOV R7,#250
D3: DJNZ R7,D3
DJNZ R5,D2
RET
NUM_CLOCK: ;定时器以每次0.01s的节奏循环的次数
DB 00H, ,96H,064H,032H,14H ;200 150 100 50 20
NUM:
DB 3FH,06H,5BH,4FH,66H
DB 6DH,7DH,07H,7FH,6FH
TABA: DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,07FH
DB 01H,02H,04H,08H,10H,20H,40H,80H
DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,07FH
DB 01H,02H,04H,08H,10H,20H,40H,80H
DB 0FEH,0FBH,0EFH,0BFH
DB 0FDH,0F7H,0DFH,07FH
DB 01H,04H,10H,40H
DB 02H,08H,20H,80H
DB 0FEH,0F7H,0BFH
DB 0FDH,0EFH,07FH
DB 0FBH,0DFH
DB 01H,08H,40H
DB 02H,10H,80H
DB 04H,20H
DB 0FEH,0EFH
DB 0FDH,0DFH
DB 0FBH,0BFH
DB 0F7H,07FH
DB 01H,10H
DB 02H,20H
DB 04H,40H
DB 08H,80H
;TABB: DB 01H,02H,04H,08H,10H,20H,40H,80H
END