基于ATmega328P汇编的16位数值拆分为LED显示数字的问题
ATmega328P汇编实现16位数值拆分(LED矩阵显示用)
问题背景
基于ATmega328P设计汇编计算器,需将计算结果拆分为单个数字以驱动LED矩阵显示。已完成8位单寄存器数值的拆分逻辑(代码如下),但无法实现16位高低双寄存器(resH为高8位,resL为低8位)的数值拆分。
现有8位拆分代码
ldi r19, 0 HUNDS: cpi resL, 100 ; 比较结果低8位与100 brlo TENS subi resL, 100 inc r19 rjmp HUNDS TENS: st x+, r19 ; 将百位计数存入显示缓冲区(对应第一个显示块) ldi r19, 0 ; 重置十位计数器 TENS_Test: cpi resL, 10 brlo UNITS subi resL ,10 inc r19 rjmp TENS_Test UNITS: st x+, r19 ; 存入十位计数 st x+, resL ; 存入个位数字
16位数值拆分解决方案
16位无符号数值范围为0~65535,最多需拆分为5位数字(万位、千位、百位、十位、个位)。核心思路是通过16位减法循环依次减去对应位的权重(10000、1000、100、10),统计每个位的数字,最后剩余值为个位。
完整16位拆分代码
; 假设16位结果存储在resH(高8位)和resL(低8位),X指针指向显示缓冲区 ; 寄存器分配:r19=当前位计数器,r20=权重高8位,r21=权重低8位 ; 处理万位(权重10000 = 0x2710) ldi r19, 0 MOV_HUN_THOU: ldi r20, 0x27 ldi r21, 0x10 ; 比较resH:resL 与 0x2710 cp resH, r20 brlo STORE_HUN_THOU breq CHECK_HUN_THOU_L rjmp SUB_HUN_THOU CHECK_HUN_THOU_L: cp resL, r21 brlo STORE_HUN_THOU SUB_HUN_THOU: ; 16位减法:resH:resL -= 0x2710 sub resL, r21 sbc resH, r20 inc r19 rjmp MOV_HUN_THOU STORE_HUN_THOU: st x+, r19 ; 存入万位数字 ldi r19, 0 ; 处理千位(权重1000 = 0x03E8) MOV_THOU: ldi r20, 0x03 ldi r21, 0xE8 cp resH, r20 brlo STORE_THOU breq CHECK_THOU_L rjmp SUB_THOU CHECK_THOU_L: cp resL, r21 brlo STORE_THOU SUB_THOU: sub resL, r21 sbc resH, r20 inc r19 rjmp MOV_THOU STORE_THOU: st x+, r19 ; 存入千位数字 ldi r19, 0 ; 处理百位、十位、个位(复用8位逻辑,此时resH已为0,只需处理resL) HUNDS_16: cpi resL, 100 brlo TENS_16 subi resL, 100 inc r19 rjmp HUNDS_16 TENS_16: st x+, r19 ldi r19, 0 TENS_Test_16: cpi resL, 10 brlo UNITS_16 subi resL ,10 inc r19 rjmp TENS_Test_16 UNITS_16: st x+, r19 st x+, resL
代码说明
- 万位处理:通过16位比较和减法,循环减去10000,统计万位数字。比较时先对比高8位,高8位小于权重高8位则直接存储;相等时再对比低8位。
- 千位处理:逻辑与万位一致,权重改为1000(0x03E8)。
- 百位及以下:经过万位和千位的减法后,剩余数值最大为999,此时
resH必然为0,可直接复用原8位拆分逻辑处理resL。 - 缓冲区存储:每一位数字依次通过
st x+, r19存入X指针指向的显示缓冲区,顺序为万位→千位→百位→十位→个位,适配LED矩阵的显示顺序。
内容的提问来源于stack exchange,提问作者Majd A.G
相关产品推荐
相关产品推荐

