⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asm.asm

📁 与AVR开发相关的一百个实例,源码用ASM语言编写
💻 ASM
📖 第 1 页 / 共 5 页
字号:
       ;范例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 + -