AVR单片机控制8段LED数码管同时显示
这是一个简单的供单片机入门学习者练习用的8段LED数码管控制汇编程序,控制一个两位的数码管同时显示字符(动态刷新)。用AVR- Studio-4 开发,在AVR单片机Atmega48上调试通过。学习者可以举一反三应用到其他类型的单片机芯片。
arget : M48 ;
Crystal: 8.0000Mhz
.include “m48def.inc”
.org $0000 rjmp _main
.org $0020
_port_init:; 端口初始化
clr R2
out 0x5,R2 PortB清零
ldi R24,255
out 0x4,R24 定义PortB为输出
out 0x8,R2 PortC清零
ldi R24,3
out 0x7,R24 定义PortC.0,Portc.1为输出
ret
_tabs:;字形定义
.dw 192 0xC0,“0”
.dw 249 0xF9,“1”
.dw 164 0xA4,“2”
.dw 176 0xB0,“3”
.dw 153 0x99,“4”
.dw 146 0x92,“5”
.dw 130 0x82,“6”
.dw 248 0xF8,“7”
.dw 128 0x80,“8”
.dw 152 0x98,“9”
.dw 136 0x88,“A”
.dw 131 0x83,“B”
.dw 198 0xC6,“C”
.dw 161 0xA1,“D”
.dw 134 0x86,“E”
.dw 142 0x8E,“F”
.dw 255 0xFF,“8.”
_delay_1ms: 延时子程
ldi R16,1
ldi R17,0
L3:
subi R16,255 加1操作
sbci R17,255
cpi R16,232 0xE8
ldi R30,3 0x3E8 = 1000
cpc R17,R30
brlo L3 未达1000继续
ret
_delay:
push r21
push r20
push r17 入口:r16,r17装的是延时参数
push r16
movw R10,R16 将r16,r17的内容装入r10,r11
clr R20
clr R21
L8:
rcall _delay_1ms
subi R20,255 加1操作
sbci R21,255
cp R20,R10 与指定延时参数比较
cpc R21,R11
brlo L8 未达指定延时参数继续
pop r16
pop r17
pop r20
pop r21
ret
_led_display:
push R20 寄存器r20入栈,r20中带入字符表的索引
ldi R24,2
mul R24,R20 将r20中的值乘2,结果在r0中
movw R30,R0 将r0的值赋给r30,作为偏移量
ldi R24,low(_tabs<<1) 获取字符表基地址
ldi R25,high(_tabs<<1)
add R30,R24 偏移量+基地址构成z指针
adc R31,R25
lpm R20,Z+0 取字型送入r20 out 0x5,R20 字型送PortB,输出 ldi R22,0 循环100次计数寄存器r22清零
L10:
ldi R20,1 r20用于8LED数码管输出位控制,初始为1
L12:
out 0x8,R20 将8LED数码管位控制输出到端口PortC ldi R16,10 延时参数低位
ldi R17,0 延时参数高位
rcall _delay 调延时子程
inc R20 移位r20,准备显示另一位
cpi R20,3 判两位是否显示完
brlo L12 未显示完两位,继续
inc R22 r22加1
cpi R22,100 判是否已计满100 brlo L10 未计满则继续
pop R20 r20出栈 ret _main:
clr R20 初始化计数寄存器r20 rcall _port_init 初始化端口
L17:
cpi R20,16 比较循环计数
brne L21 未显示完16个字符继续
clr R20 从新开始
L21:
rcall _led_display 显示字符
inc R20 计数值加1
rjmp L17 返回
ret