📄 asm.asm
字号:
;范例18 ;定点小数十翻二
CONV4: LDI R17,32 ;r12r13r14r15<--r8r9r10r11<--(r12r13r14r15)
MOV R7,R17 ;左移32次
CV4: CLC ;例:$0.FFFFFFD5<--0.99999999
MOV R16,R15 ;$0.FFFFFFFF92<--0.9999999999
RCALL LSDAA
MOV R15,R16
MOV R16,R14
RCALL LSDAA
MOV R14,R16
MOV R16,R13
RCALL LSDAA
MOV R13,R16
MOV R16,R12
RCALL LSDAA
MOV R12,R16 ;定点十进制小数左移并调整
ROL R11
ROL R10
ROL R9
ROL R8 ;定点二进制小数带进位位左移一位
DEC R7
BRNE CV4
MOV R12,R8 ;最终结果转入R12--R15
MOV R13,R9
MOV R14,R10
MOV R15,R11
RET
AVR实用程序
;范例19 ;等步距线性内插计算子程序
.EQU TBLGTH=10
CHETA: LDI R16,TBLGTH-1 ;r16<--表长(即字数)-1
LDI R31,HIGH(chtbl*2);y0(函数初值)在r14r15,STEP(步长)在r10r11,自变量X在r12r13
LDI R30,LOW(chtbl*2+1);查表指针,首指数据表第1字之高位字节!
RCALL CPMR1 ;X与表中第一个字型数据(X0)比较
BRCC CHRET ;X<X0 查表结束,Y=Y0
CHET1: RCALL CMPR1 ;X与表中下一个数据比较
BRCC NX33 ;X<X(i+1) 找到插值区间
ADD R15,R11 ;否则Y0中加入一个STEP:Yk=Y0+k*step(步距为负时则
;减去|STEP|)
ADC R14,R10
DEC R16
BRNE CHET1 ;未查到表格终值,循环;否则结束,Y取得最大值Yn
CHRET: RET
NX33: SBIW R30,5 ;指针退回(-5),指向Xi
MOV R8,R14
MOV R9,R15 ;保存Y0+i*STEP
RCALL SUBS ;(X-Xi)-->r16r17
MOV R15,R17
MOV R14,R16 ;转入r14r15
RCALL MUL16 ;(X-Xi)*STEP-->r12r13r14r15
MOV R10,R12
MOV R11,R13 ;保存乘积高位字
LPM ;X(i+1)低位字节
MOV R13,R0
ADIW R30,1
LPM ;X(i+1)高位字节
MOV R12,R0
SBIW R30,3 ;指针指向Xi
RCALL SUBS ;X(i+1)-Xi-->r16r17
MOV R12,R10
MOV R13,R11 ;取回乘积高位字
MOV R10,R16
MOV R11,R17 ;X(i+1)-Xi-->r10r11
RCALL DIV165 ;(X-Xi)*STEP/[X(i+1)-Xi]-->r14r15
ADD R15,R9
ADC R14,R8 ;Y0+i*STEP+(X-Xi)*STEP/[X(i+1)-Xi]-->r14r15
RET ;若STEP为负值则改为计算(r8r9)减去(r14r15)之值
CMPR1: LPM ;取数据高位字节
ADIW R30,2 ;指向下一数据的高位字节
CP R0,R12 ;与X高位字节相比较
BRNE CPRT1 ;不相等即转出
SBIW R30,3 ;否则调整指针
LPM ;取数据低位字节
ADIW R30,3 ;指向下一数据的高位字节
CP R0,R13 ;与X低位字节相比较
CPRT1: RET ;以进位C带回比较结果
SUBS: LPM ;计算(X-Xi)或[X(i+1)-Xi]并送入r16r17
MOV R5,R0 ;取Xi低位字节
ADIW R30,1
LPM ;取Xi高位字节
SBIW R30,1 ;仍指向Xi低位字节
SUB R13,R5
MOV R17,R13
SBC R12,R0
MOV R16,R12 ;计算差并将其转入R16R17
RET
;自变量x表长为12字
CHTBL:DW 19214,23404,27600,32799,37009,40211,45414,48618,51821,55029,57787,60070
;步距表长为11字
STEPT: DW 356,366,379,395,415,440,471,509,555,603,657
;不等步距线性内插计算子程序,步距表首址在R6R7中
;自变量X在R12R13之中, 函数初值Y0在R14R15中
;范例20 ;表长(字个数)-1在R16中
CHTSTP: LDI R31,HIGH(chtbl*2)
LDI R30,LOW(chtbl*2+1);查表指针
LDI R16,LOW(stept*2)
MOV R7,R16
LDI R16,HIGH(stept*2)
MOV R6,R16 ;步距表指针
LDI R16,TBLGTH-1 ;r16<--表长(字个数)-1
RCALL CMPR1 ;X与表首数据比较
BRCC CHSTPT ;X<X0 查表结束,有Y=Y0
CHSTP1: RCALL CMPR1 ;否则与表中下一数据比较
BRCC CHSTP3 ;X<X(i+1),找到插值区间!
RCALL GTSTP ;查表取STEP字型变量
ADD R15,R11 ;Y0<--Y0+STEPk
ADC R14,R10
DEC R16
BRNE CHSTP1 ;未查到表格终值循环;否则结束,Y取得最大值Yn
CHSTPT: RET
CHSTP3: SBIW R30,5 ;指针退回,指向Xi低位字节
MOV R8,R14
MOV R9,R15 ;Y0+∑STEPk送入r14 r15
RCALL SUBS ;(X-Xi)->r16r17
MOV R15,R17
MOV R14,R16 ;(X-Xi)转入R14R15
RCALL GTSTP ;查表取STEPi-->R10R11
RCALL MUL16 ;(X-Xi)*STEPi-->R12R13R14R15
MOV R10,R12
MOV R11,R13 ;保存积高位字
LPM
MOV R13,R0
ADIW R30,1
LPM
MOV R12,R0
SBIW R30,3
RCALL SUBS ;(X(i+1)-Xi)-->r16 r17
MOV R12,R10
MOV R13,R11
MOV R10,R16
MOV R11,R17 ;取回积高位字 &(X(i+1)-Xi)-->r10r11
RCALL DIV165 ;(X-Xi)*STEPi/[X(i+1)-Xi]-->r14r15
ADD R15,R9 ;
ADC R14,R8 ;Y0+∑STEPk+(X-Xi)*STEPi/[X(i+1)-Xi]-->r14r15
RET
GTSTP: MOV R5,R6 ;查取STEP字型变量/POINTER in r6r7!
MOV R6,R30
MOV R30,R5
MOV R5,R7
MOV R7,R31
MOV R31,R5 ;(r6r7)<-->Z
LPM
MOV R11,R0
ADIW R30,1
LPM
MOV R10,R0 ;STEPk取到r10r11
ADIW R30,1
MOV R5,R6
MOV R6,R30
MOV R30,R5
MOV R5,R7
MOV R7,R31
MOV R31,R5 ;指针增2后送回r6r7
RET
;范例21 ;功能表程序
FUNC2: LDS R16,$A3 ;use r0,r8,r9,r10,r11,r16&r17/& subprogram dspa
SBR R16,$80 ;功能表程序标志
STS $A3,R16
LDI YH,2
LDI YL,0 ;功能内容表SRAM地址
RCALL FLFUNC ;CLR r27!
LDI R16,2
ST X,R16 ;显示'FUNC.2'
RCALL DL2S
CLR R9 ;功能内容寻址偏移量R9!
CLR R8 ;功能名称寻址偏移量(R8)=(r9)*3
FFUNC0: RCALL DSF_ ;显示'F- '
FF0: RCALL DSPA ;in subprogram dspy clr. r27!
CPI R16,11 ;回车键按下?
BRNE FF2P
FF0C: RCALL COMBNO ;合成功能名称送入r16
CPI R16,20 ;是最后一个功能名称?
BRNE FF1
CLR R9 ;是,两偏移量初始化!
CLR R8
FF1: LDI ZH,HIGH(FTABL*2)
LDI ZL,LOW(FTABL*2);功能名称表指针
ADD ZL,R8
ADC ZH,R27 ;(r27)=0 ALWAYS
LPM
MOV R16,R0
RCALL BRA3A ;分解新功能名称到$6E/$6F
FF0G: LDI R28,0
ADD R28,R9 ;功能内容指针加偏移量
LD R16,Y
LDI R26,$72
RCALL BRAX ;将新功能内容分解到$72/$73
FF0A: RCALL DSPA ;显示新功能名称/内容
CPI R16,11
BRNE FF0B ;回车键按下?
INC R8
INC R8
INC R8 ;是,功能名称寻址偏移量加3
INC R9 ;功能内容寻址偏移量加1
RJMP FF0C ;转回
FF2P: RJMP FF2
FF0B: CPI R16,10
BRNE FF0D
RCALL DSF_ ;清除键按下,清除显示区后,显示‘F-’
FF1B: RCALL DSPA
CPI R16,11
BREQ FF1 ;转恢复当前显示
CPI R16,10
BRCC FF1B
RJMP FF2D ;只有数字键按下才转出去处理
FF0D: CPI R16,10
BRCC FF0A
FF1D: LDI R17,$24 ;
STS $73,R17 ;数字键处理,先在缓存区内放一空白
FF0E: LDS R17,$73
STS $72,R17 ;键入数字左移
STS $73,R16 ;存入新数字
FF0F: RCALL DSPA
CPI R16,10
BREQ FF0G ;清除键按下,恢复显示旧功能内容
BRCS FF0E ;键入数字左移更新
CPI R16,11
BRNE FF0F
LDS R26,$72 ;回车键按下
RCALL COMBA ;合成新功能内容(combin $72&$73 into binary(r16))
MOV R17,R8
INC R17
LDI ZH,HIGH(FTABL*2)
LDI ZL,LOW(FTABL*2)
ADD ZL,R17 ;取当前功能内容下限
ADC ZH,R27
FF1F: LPM
CP R16,R0
BRCS DSER2 ;新功能内容小于下限,错误
INC R17
LDI ZH,HIGH(FTABL*2)
LDI ZL,LOW(FTABL*2)
ADD ZL,R17 ;取当前功能内容上限
ADC ZH,R27
LPM
CP R0,R16
BRCS DSER3 ;新功能内容大于上限,错误
FF7: LDI R28,0
ADD R28,R9 ;功能内容表首地址为$200!
ST Y,R16 ;合法的新功能内容进入功能内容表
INC R9
INC R8
INC R8
INC R8 ;调整偏移量,进入下一个功能显示
RJMP FF0C
FF1P: RJMP FF1
DSER2: RCALL FERR2 ;显示'F Err.2'2秒
RCALL EXCH0
RJMP FF0G ;恢复原数据显示
DSER3: RCALL FERR3 ;显示'F Err.3'2秒
RCALL EXCH0
RJMP FF0G ;恢复原数据显示
FF2: CPI R16,10
BRCS FF2D ;功能键按下,转初始
RJMP FF0
FF2D: LDI R17,$24 ;数字键按下,在显示缓存区内左移
STS $6F,R17 ;
FF3: LDS R17,$6F
STS $6E,R17
STS $6F,R16
FF4: RCALL DSPA
CPI R16,10
BRNE FF41
RCALL DSF_ ;清除数字,显示‘F-’
FF40: RCALL DSPA
CPI R16,11
BREQ FF1P ;转回显示当前功能名称及内容
CPI R16,10
BRCC FF40 ;无效键按下,转回
RJMP FF2D ;否则转数字处理
FF41: BRCS FF3
CPI R16,11
BRNE FF4
RCALL COMBNO ;合成新功能名称
CLR R10 ;功能名称偏移量计数器清除
CLR R11 ;功能内容偏移量计数器清除
SFFLP: LDI ZH,HIGH(FTABL*2)
LDI ZL,LOW(FTABL*2)
ADD ZL,R10
ADC ZH,R27
LPM
CP R0,R16 ;
BREQ SFFND ;在功能名称表中找到新名称
INC R11 ;
INC R10
INC R10
INC R10 ;调整偏移量
LDI R17,60
CP R10,R17 ;功能名称指针偏移量超过59?
BRCS SFFLP ;否,继续查功能名称表
RCALL FERR1 ;查完功能名称表未查到键入功能名称!
RJMP FFUNC0 ;转回恢复原显示
SFFND: MOV R9,R11 ;得到功能内容指针偏移量
MOV R8,R10 ;得到功能名称指针偏移量
RJMP FF0G ;转显示新功能名称及内容
FTABL: .DB 1,0,1,2,1,8,3,0,2,4,0,1 5,1,2,6,0,4,7,1,4,8,1,2,9,2,7,10,1,5,11,1
.DB 5,12,0,5,13,1,2,14,1,7,15,1,10,16,1,4,17,2,4,18,2,5,19,1,2,20,1,3
COMBNO: LDI XL,$6E ;取$6E$6F中的BCD码,合成新功能名称子程序
COMBA: LD R16,X+
CPI R16,$24
BRNE CMBA
CLR R16
CMBA: MOV R0,R16
LSL R16
LSL R16
ADD R16,R0
LSL R16 ;高位BCD乘10
LD R0,X
ADD R16,R0 ;加低位BCD
RET
DSF_: RCALL FIL8 ;准备显示'F- '
LDI R16,$0F
STS $6C,R16
LDI R16,$14
STS $6D,R16
RET
BRA3A: LDI XL,$6E ;二进制数转换为两位BCD码并显示
BRAX: LDI R17,$24 ;十位为0时显示空白
ST X,R17
BRHOUR: CLR R0 ;
BRX0: SUBI R16,10 ;减10
BRCS BRX2
INC R0
RJMP BRX0
BRX2: SUBI R16,-10 ;不够减恢复出十位BCD
TST R0
BREQ BRX1
ST X,R0 ;放入显示区
BRX1: INC R26
ST X,R16
BRART: RET
FERR1: LDI XL,$71 ;显示'F Err.1'
LDI R16,1
ST X,R16
RJMP FER123
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -