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

📄 asm.asm

📁 与AVR开发相关的一百个实例,源码用ASM语言编写
💻 ASM
📖 第 1 页 / 共 5 页
字号:
        SBRC    R16,7
        RJMP    DSTTL        ;任一键按下,结束显示累加和
        RJMP    DEALK0       ;程序执行完毕,转回
DSCLS:  RJMP    DSCLOS       ;转去关显示
SLFTS: ;.............
       ;.............
        RJMP    DEALK0        ; 自检程序执行完毕,转回

FDPAP: ;.............
       ;.............
        RJMP    DEALK0        ; 走纸程序执行完毕,转回
PRSMP: ;.............
       ;.............
        RJMP    DEALK0        ; 打印采样程序执行完毕,转回
PRTTL: ;.............
       ;.............
        RJMP    DEALK0        ;打印累加和程序执行完毕,转回

DSCLK:  RCALL    BRCLK       ;分解系统时钟送入显示缓存区         
        RCALL    DL1S        ;延时1秒
        RCALL    DSPA        ;显示时钟
        SBRC     R16,7       ;任一键按下,结束显示时钟
        RJMP     DSCLK       
        RJMP     DEALK0      ;程序执行完毕,转回

       ;.............
       ;.............        ;其他功能键处理略
       ;.............
       
       ;范例27               ;主显子程序
DSPA:   SBRC    R16,7        ;USE R0,R2,R11,R12,r13,r14,r15,r16,r17&Z,X POINTERS
        RJMP    DSA2         ;无键按下,跳转
DSA0:   CLR     R12  
        INC     R12          ;有键按下,将计数器置1
DSA1:   RCALL   DSPY
        DEC     R12
        BRNE    DSA1         ;等待键释放
DSA2:   RCALL   DSPY
        LDS     R16,$A3      
        SBRS    R16,7        ;有进入功能表程序标志?
        RET                  ;没有返回
        SBI     PORTA,0      ;
        SBIS    PINA,0       ;退出功能表程序吗?
        RET                  
        CBR     R16,$80      ;是,清除进入功能表程序标志($A3,7)
        STS     $A3,R16
        RCALL   FIL2
        LDI     R16,$0F      ;'F'
        STS     $6C,R16
        LDI     R16,$0E      ;'E'
        STS     $6E,R16
        LDI     R16,$17      ;'n'
        STS     $6F,R16
        LDI     R16,$0D      ;'d'
        STS     $70,R16      ;显示‘F End'
        RCALL   DL2S         ;2秒后
        RJMP    DIPA1        ;转到主程序(包括对堆栈)初始化
DL2S:   RCALL   DL1S         ;延时2秒子程序
DL1S:   LDI     R16,217      ;延时1秒子程序/4MHz clk
        MOV     R11,R16      ;4.618×217=1000ms
DLCOM:  RCALL   DSPA
        DEC     R11
        BRNE    DLCOM
        RET
        
       ;范例28               ;基显子程序,显示缓存区:$6C--$73,执行时间4.618ms/晶振4MHZ
                             ;主程序应对看门狗初始化,设置溢出时间为0.49秒! 
DSPY:   LDI     R17,$0F      ;使用R0,R2,R12,R13,R14,R15,R16&R17/z&x pointer!
        OUT     DDRA,R15     ;PA7--PA4为键列值输入
        CLR      R15
	  COM	    R15		
        OUT     DDRB,R15
        OUT     DDRC,R15     ;口B:段选输出,口C:位选输出
        OUT     PORTC,R15    ;关显
DPY1:   LDI     R26,$6C      ;指向显示缓存区首址:$6C
        CLR     R27
        LDI     R17,$7F
        MOV     R13,R17      ;位选初始化(首显最高位)
L0D:    LD      R17,X+
        LDI     R31,HIGH(table*2)
        LDI     R30,LOW(table*2)
        ADD     R30,R17
        ADC     R31,R27
L0C:    LPM                  ;取段选码
        OUT     PORTB,R0     ;送段选口
        OUT     PORTC,R13    ;位选口
        SEC                  ;
        ROR     R13          ;指下一位位选
        LDI     R17,3        ;4MHz(6 if 8MHz)
        CLR     R14
DLOP:   DEC     R14
        BRNE    DLOP
        DEC     R17
        BRNE    DLOP         ;延时0.5762毫秒
              IN	   R16,PORTA
        ORI    R16,$F0          ;保护PA3--PA0输出
        OUT     PORTA,R16    ;提拉PA7-PA4
        IN      R14,PINA     ;读入列值
NEX:    ROL     R14          ;use high 4bits!
        BRCC    L1           ;有键按下,跳转
NEX1:   INC     R17          ;指向下一列
        CPI     R17,4
        BRNE    NEX          ;各列都查完?
NEX2:   SER     R17
        OUT     PORTC,R17    ;将$FF写入位选口(关显)
        CPI     R26,$74
        BRNE    L0D          ;每位LED都显示一遍??
        MOV     R16,R15      ;YES 
        INC     R2           ;增一调DSPY次数寄存器
        MOV     R17,R2
        CPI     R17,100      ;到100次?
        BRNE    NEX3         
        CLR     R2           ;清除看门狗定时器时间到计数器/4.618ms×100=0.462s(<0.49s)
        WDR                  ;看门狗定时器复位
NEX3:   RET                  
L1:     LDS     R16,$73      ;计算键值代码/查键值
        SUB     R16,R26      ;$73-(r26)-->r16
        LSL     R16
        LSL     R16          ;行值*4
        ADD     R16,R17      ;键值代码=行值*4+列值
        LDI     R30,LOW(TABL0*2)
        ADD     R30,R16
        LDI     R31,HIGH(TABL0*2)
        ADC     R31,R27
LA00:   LPM                  ;查出键值
        MOV     R15,R0       ;放在R15
LA10:   INC     R12          ;计数器增1以备判断键释放
        RJMP    NEX1         ;转回查下一列
TABL0:  .DB     10,0,11,20,1,2,3,16,4,5,6,22,7,8,9,18,12,15,19,23,14,17,21,13
TABLE:  .DB      $3F,$06,$5B,$4F,$66,$6D,$7D,$07,$7F,$67,$77,$7C,$39 ;0--C
        .DB      $5E,$79,$71,$6F,$74,$04,$1F,$40,$38,$37,$54,$5C   ;'d'---'o'
        .DB      $73,$67,$50,$6D,$78,$1C,$3E,$7E,$F8,$6E,$49,$00  
        .DB      $48,$52,$D3,$76  ;$25(=),$26(/)$27(?) END AT $28(H)
        .DB      $BF,$86,$DB,$CF,$E6,$ED,$FD,$87,$FF,$E7;THE  0.($29)--9.($32)
        .DB      $D7,$C9,$80      ;THE 'X.' 'Z.' &'.'($33--$35)
        .DB      $DE,$EF,$B8,$F3,$E7,$D0,$DC,$ED,$86,$F9,$B9H,$F7,$F1,$B7,$D4
                ;the d.,g.,L.,p.,q.,r.,o.,s.,l.,E.,C.,A.,F.,M.,n.(36--44h)
                
       ;范例29  ;键入数字序列左移处理子程序
LSDD8:  LDI     R26,$6C      ;8bcd码($6C--$73H)
        LDS     R27,$A3
        CBR     R27,8        ;清$A3,3
        STS     $A3,R27
        CLR     R27
        CPI     R16,10       ;10为清除键
        BRNE    DDL
        RCALL   FIL2         ;清除显示缓存区($6c-$73)!
        LDS     R16,$A3
        SBR     R16,8
        STS     $A3,R16      ;建清除显示缓存区标志$A3,3=1
        RET
DDL:    INC     R26          ;数字键按下,序列左移
        LD      R16,X        ;
        SUBI    R16,$29      ;数字带小数点?
        BRCC    DD4          ;若带则将其复原(参考DSPY子程序段码表)
        SUBI    R16,$D7      ;恢复
DD4:    ST      -X,R16       ;移入左邻单元
DD5:    INC     R26         
        CPI     R26,$73      
        BRNE    DDL          ;各数字都左移了一位?
        ST      X,R15        ;新键入数字进入数字序列末位
        LDI     R26,$6C
DEL:    LD      R16,X
        CPI     R16,10       ;是BCD码?
        BRCS    DEL2         
        CPI     R16,$29
        BRCC    DELRT        ;大于$29为错误!
DELA:   INC     R26          ;0--9/$24/$14为有效!
        CPI     R26,$73
        BRNE    DEL          ;缓存区检查完毕?
        RJMP    DELRT
DEL2:   CPI     R16,0
        BRNE    DELRT
        LDI     R16,$24      ;0改为空白
        ST      X,R16
        RJMP    DELA         ;
DELRT:  LDS     R16,$A0      ;小数点位置单元
        TST     R16
        BREQ    DDRET        ;($a0)=0,无小数点
        NEG     R16
        ADD     R16,$73
        MOV     R26,R16      ;找到缓存区内带小数点的数据位
        LD      R16,X
        SUBI    R16,$D7      ;加上小数点
        ST      X,R16
        CPI     R16,$4D      ;在空白码加了小数点($24(空白)+$29=$4d)?
        BRNE    STLR1
        LDI     R16,$29
        ST      X,R16        ;是,将其改为'0.'
STLR1:  CPI     R26,$73
        BREQ    DDRET        ;并将其后所有空白都改为0
        INC     R26
        LD      R16,X
        CPI     R16,$24
        BRNE    DDRET
        CLR     R16
        ST      X,R16
        RJMP    STLR1
DDRET:  RET

FIL2:   LDI     R26,8        ;在显示缓存区内填充空白
        MOV     R14,R26
FIL2A:  LDI     R26,$6C
FIL:    CLR     R27
        LDI     R16,$24
FILP:   ST      X+,R16
        DEC     R14
        BRNE    FILP
        RET

       ;范例30               ;双键输入检查数据子程序,Ky1数据键/Ky2回车键
KYIN2:  LDI     R26,$60      ;寄存器地址:portb:$18/ddrb:$17/pinb:$16
        CLR     R27          ;指向数据区首地址
        CBI     DDRB,7
        CBI     DDRB,6       ;pb7和pb6皆为输入口
        SER     R17
        OUT     DDRC,R17     ;c口为数据显示口
LA0:    LD      R17,X        ;取数据
        CPI     R17,$0A
        BRCS    LA1
        CLR     R17
LA1:    LDI     R31,HIGH(table*2)
        LDI     R30,LOW(table*2);DSPY段选码表
        ADD     R30,R17
        ADC     R31,R27      
        LPM
        COM     R0           ;段选码取出并取反
        OUT     PORTC,R0     ;送C口
        SBI     PORTB,7
        SBIC    $16,7
        RJMP    NXA1         ;数字键未按下,转
        RCALL   DL50         ;否则延时
XA2:    SBI     PORTB,6
        SBIC    $16,6
        RJMP    XA0          ;只有数字键按下,转
XA20:   RCALL   DL50         ;两键都按下,先延时50mS
        SBI     PORTB,6
        SBIS    $16,6
        RJMP    XA20
        SBI     PORTB,7
        SBIS    $16,7
        RJMP    XA20         ;等两键都释放
        RCALL   DL50
XA21:   SBI     PORTB,6
        SBIS    $16,6
        RJMP    XA21         ;等待释放
        SBI     PORTB,7
        SBIS    $16,7
        RJMP    XA21         ;再次等待释放
        RJMP    NXA6         ;先按数字键,再按回车键,待2都键释放后退出子程序
XA0:    SBI     PORTB,7
        SBIS    $16,7
        RJMP    XA2          ;等待数字键释放
XA1:    RCALL   DL50         ;延时
        SBI     PORTB,7
        SBIS    $16,7
        RJMP    XA1          ;再次等待释放
        INC     R17          ;数字增1
        CPI     R17,10
        BRCS    NXA1
        CLR     R17          ;超过10,将键值归为0
NXA1:   SBI     PORTB,6
        SBIC    $16,6
        RJMP    LA1          ;回车键也未按下,重新查键
        RCALL   DL50         ;延时
NXA3:   SBI     PORTB,6
        SBIS    $16,6
        RJMP    NXA3         ;再次等待回车键释放
        RCALL   DL50
        SBI     PORTB,6
        SBIS    $16,6
        RJMP    NXA3         
        ST      X+,R17       ;数字转入缓存区
        SER     R17
        OUT     PORTB,R17    ;关显
        RCALL   DL50         ;
        CPI     R26,$70      ;到规定数字个数?
        BRNE    LA0          ;
        LDI     R17,$86      ;显示'E'nd
        OUT     PORTC,R17    ;
NXA4:   SBI     PORTB,6
        SBIS    $16,6
        RJMP    NXA5         ;回车键按下,转
        SBI     PORTB,7
        SBIC    $16,7        ;数字键按下,转
        RJMP    NXA4         ;否则反复查键
NXA40:  RCALL   DL50
        SBI     PORTB,7
        SBIS    $16,7
        RJMP    NXA40        
        SBI     PORTB,7
        SBIS    $16,7
        RJMP    NXA40        ;等待键释放
        RJMP    KYIN2        ;转检查键入数据
NXA5:   RCALL   DL50
        SBI     PORTB,6
        SBIS    $16,6        
        RJMP    NXA5
        SBI     PORTB,6
        SBIS    $16,6
        RJMP    NXA5         ;等回车键释放
NXA6:   SER     R17
        OUT     PORTB,R17    ;关显,结束子程序
        RET
DL50:  ;RCALL   DL25         ;延时50毫秒子程序/8Mhz(去掉指令前“;”号)
DL25:   CLR     R14          ;延时50毫秒子程序/4Mhz
        CLR     R15
DL50L:  DEC     R15
        NOP
        BRNE    DL50L
        DEC     R14
        BRNE    DL50L
        RET
        
       ;范例31
LPRNT:  SER     R17          ;宽行打印机检测及控打程序
        OUT     DDRC,R17     ;C口为打印机输出口!
        SBI     DDRD,7
        CBI     DDRD,3       ;pd7为选通输出口,pd3(INT1)查忙输入口
        SBI     PORTD,3
        SBIC    PIND,3       ;查打印机忙信号
        RJMP    ERR5         ;打印机尚未工作忙信号即已为高,打印机不能打印
        LDI     R17,$0D      ;写回车命令给打印机
        OUT     PORTC,R17
        CBI     PORTD,7      ;发出选通信号
        NOP                  
        NOP
        NOP
        SBI     PORTD,7      ;strobe
        LDI     R16,50
TSPRT:  SBI     PORTD,3
        SBIc    PIND,3       
        RJMP    LPRT2        ;50次内忙信号高起来为正常
        DEC     R16          ;否则为非正常状态
        BRNE    TSPRT
ERR5:   LDI     R16,5
        RCALL   ERRX         ;显示5号错误
        RJMP    DIPA1        ;转主程序初始化

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -