6个LED数码管动态显示实验汇编代码
时间: 2024-03-23 13:37:26 浏览: 176
shumaguan.zip_共阳极数码管_数码管 动态
好的,以下是一个简单的6个LED数码管动态显示实验的汇编代码,你可以将其复制到汇编IDE中进行编辑和烧录:
```
.equ F_CPU = 16000000
.equ BAUD = 9600
.equ MYUBRR = F_CPU/16/BAUD-1
.def ledPort = PORTB
.def ledDir = DDRB
.def digitPort = PORTD
.def digitDir = DDRD
.cseg
.org 0x0000
jmp main
.org 0x001C
reti
.org 0x0032
sbi ledPort, 0 ; 6个数码管共阳极接在PB0~PB5
out digitPort, r24 ; 数字0~5的段码输出到PD0~PD5
push r18
push r19
push r20
push r21
push r22
push r23
push r24
push r25
push r26
push r27
ldi r18, 0x05 ; 从右往左逐个显示数字
ldi r19, 0x00 ; 低位数码管的段码地址
ldi r20, 0x01 ; 高位数码管的段码地址
ldi r21, 0x3F ; 数码管的段码数组
ldi r22, 0x37
ldi r23, 0x06
ldi r24, 0x5B
ldi r25, 0x4F
ldi r26, 0x66
ldi r27, 0x6D
.loop:
ldi r20, 0x01 ; 高位数码管的段码地址
ldi r21, 0x3F ; 数码管的段码数组
ldi r22, 0x37
ldi r23, 0x06
ldi r24, 0x5B
ldi r25, 0x4F
ldi r26, 0x66
ldi r27, 0x6D
mov r17, r18
ldi r18, 0x05
sub r18, r17 ; 将数字拆分成6个数字显示
cpi r18, 0x01
brne .num1
ldi r19, 0x00
rjmp .display
.num1:
cpi r18, 0x02
brne .num2
ldi r19, 0x01
rjmp .display
.num2:
cpi r18, 0x03
brne .num3
ldi r19, 0x02
rjmp .display
.num3:
cpi r18, 0x04
brne .num4
ldi r19, 0x03
rjmp .display
.num4:
cpi r18, 0x05
brne .num5
ldi r19, 0x04
rjmp .display
.num5:
ldi r19, 0x05
.display:
ldi r16, 0x00
out digitDir, r16 ; 数码管的段码地址输出到PD0~PD5
out digitPort, r19 ; 数码管的段码地址输出到PD0~PD5
lsl r18
brcs .digit2
ldi r21, 0x3F
rjmp .digit
.digit2:
ldi r21, 0x06
.digit:
out digitDir, r21 ; 数码管的段码输出到PD0~PD6
out digitPort, r22 ; 数码管的段码输出到PD0~PD6
out digitPort, r23 ; 数码管的段码输出到PD0~PD6
out digitPort, r24 ; 数码管的段码输出到PD0~PD6
out digitPort, r25 ; 数码管的段码输出到PD0~PD6
out digitPort, r26 ; 数码管的段码输出到PD0~PD6
out digitPort, r27 ; 数码管的段码输出到PD0~PD6
ldi r16, 0x10
out digitDir, r16 ; 数码管的段码地址输出到PD4~PD7
cpi r18, 0x10
brne .loop
pop r27
pop r26
pop r25
pop r24
pop r23
pop r22
pop r21
pop r20
pop r19
pop r18
reti
main:
; 初始化
ldi ledDir, 0x3F ; PB0~PB5输出
ldi digitDir, 0xFF ; PD0~PD7输出
ldi r17, 0x00 ; 数码管关闭状态
out digitPort, r17 ; 数码管关闭
; 开启定时器0
ldi r16, 0x00 ; 定时器0计数器初始值
out TCNT0, r16
ldi r16, 0x03 ; 定时器0时钟选择为F_CPU/64
out TCCR0B, r16
; 开启定时器0的比较匹配中断
ldi r16, 0x02 ; 定时器0的比较匹配A中断
sbi TIMSK0, r16
; 开启全局中断
sei
; 主循环
loop:
rjmp loop
; 定时器0的比较匹配A中断服务程序
TIMER0_COMPA_vect:
push r16
push r17
in r16, SREG
push r16
; 数码管的动态扫描
sbi ledPort, 0 ; 打开低位数码管
cbi ledPort, r18 ; 关闭高位数码管
ldi r16, 0x01
lsl r16, r18
cpi r18, 0x05
breq .delay
out TCNT0, r16 ; 设置下一个数码管的显示时间
rjmp .exit
.delay:
ldi r16, 0x7F ; 最后一个数码管的显示时间稍长
out TCNT0, r16
; 切换到下一个数字
inc r18
cpi r18, 0x06
breq .reset
rjmp .exit
.reset:
ldi r18, 0x00 ; 重新从数字0开始显示
.exit:
ldi r17, 0x3F ; 数码管关闭状态
out digitPort, r17 ; 数码管关闭
cbi ledPort, 0 ; 关闭数码管显示
pop r16
out SREG, r16
pop r17
pop r16
reti
```
这个程序会将数字从0到999999在6个数码管上以动态效果显示,每个数字显示的时间为1秒。你可以根据需要调整延时时间和数字的范围。注意,在汇编语言中,需要手动配置定时器和中断等。
阅读全文