这是德语教程中的一个例子
;====================================================================
; 新建项目向导生成的 Main.asm 文件
;
; 创建时间: 周四 2月 18 2021
; 处理器: ATtiny13
; 编译器: AVRASM (Proteus)
;====================================================================
; **************************************************************
; *按下按钮开始莫尔斯文本输出 *
; **************************************************************
;
.INCLUDE "tn13def.inc"
;;
;可选常数
;
.EQU cSpeed = 90 ; 在BPM传输速度,5..500 BPM
.EQU cTone = 1000 ; 间距赫兹,300..8000赫兹
;
; 固定常数
;
.EQU fClock = 1200000
.EQU cTc0Div = 8
;
; 计算常数
;
.EQU cTc0CmpA = fClock/cTc0Div/cTone/2
.EQU cTc0CmpB = cTc0CmpA/2
.EQU cTc0N = cTone*16/cSpeed
.EQU cTc0N2 = 2*cTc0N ;两倍长
.EQU cTc0N3 = 3*cTc0N ; 长三倍
;
; 检查设定值
;
.IF cTc0CmpA > 255
.ERROR "Ton zu niedrig!" ;声音太低了!
.ENDIF
.IF cTc0CmpA < 8
.ERROR "Ton zu hoch!" ; 音调太高!
.ENDIF
.IF cTc0N3 > 65535
.ERROR "Frequenz zu niedrig!" ;频率太低!
.ENDIF
.IF cTc0N < 8
.ERROR "Frequenz zu hoch!" ;频率太高!
.ENDIF
;
; 定义标签
;
.DEF rSreg = R15 ; 应在 Ints 中注册 Sreg
.DEF rmp = R16 ; 多用途寄存器
.DEF rimp = R17 ; 中断多用途寄存器
.DEF rFlg = R18 ; 标志
.EQU bAktiv = 0 ; 输出有效
.EQU bPKurz = 1 ; 字符输出
.EQU bPLang = 2 ; 字符间暂停
.DEF rSig = R19 ; 输出摩尔斯电码
.DEF rLen = R20 ; 长短数字
; frei R21..R23
.DEF rCntL = R24 ; 半波数计数器NF,LSB
.DEF rCntH = R25 ;同上,MSB
;
; 重置和中断向量
;
.CSEG ; 汇编到程序闪存
.ORG $0000 ; 以地址0开头
;
; 重置和中断的跳转向量
;
rjmp main ; Reset vector
reti ; Int0 interrupt vector
rjmp IntPcInt ; PCINT0向量
reti ; TC0 overflow vector
reti ; Eeprom ready vector
reti ; Analog comparator int vector
rjmp IntTcCmpA ; TC0 CompA向量
reti ; TC0 CompB vector
reti ; WDT vector
reti ; ADC conversion complete vector
;
; PCINT0服务程序
; 每次在匹配时执行
; 引脚3(= PB4)更改(按下按钮)
;
IntPcInt:
in rSreg,SREG ; 安全标志
sbic PINB,4 ; 如果 PB4 为零,则跳过下一条命令
rjmp IntPcInt1 ; 跳因为PB4一
sbrc rFlg,bAktiv ; 如果已经激活:忽略
rjmp IntPcInt1 ; 已处于活动状态
ldi XH,HIGH(2*MorseText) ; 指向输出文本的指针
ldi XL,LOW(2*MorseText)
ldi rCntH,0 ; 定义延迟
ldi rCntL,1
cbi PORTB,2 ; 打开 LED
sbr rFlg,(1<<bAktiv)|(1<<bPLang) ;
ldi rimp,cTc0CmpA ; 比较 A 中的半波持续时间
out OCR0A,rimp
ldi rimp,cTc0CmpB ; 比较 B 中的半持续时间半波
out OCR0B,rimp
ldi rimp,0b00110010 ; CTC,在静音比较匹配时输出 B
out TCCR0A,rimp
ldi rimp,0b00000010 ; 定时器预分频器为 8
out TCCR0B,rimp
ldi rimp,0b00000100 ; 开启 OCIE0A 中断
out TIMSK0,rimp
IntPcInt1:
out SREG,rSreg ; 恢复标志
reti ; 从中断返回
;
; 定时器到期时的中断
;
IntTcCmpA:
in rSreg,SREG ; 保存标志
sbiw rCntL,1 ; 再来一次?
brne IntTcCmpARet
ldi rCntH,HIGH(cTc0N) ; 重新加载计数器
ldi rCntL,LOW(cTc0N)
sbrs rFlg,bPKurz ; 短暂停位设置?
rjmp IntTcCmpANoKu ; 短位未设置
cbr rFlg,1<<bPKurz ; 撤消短位
dec rLen ; 减少短/长字符数
brne IntTcCmpAStumm ; 还没有到零,沉默的停顿
sbr rFlg,1<<bPLang ;字符之间的长时间停顿
ldi rCntH,HIGH(cTc0N2) ; 持续时间加倍的计数器
ldi rCntL,LOW(cTc0N2)
IntTcCmpAStumm:
ldi rimp,0b00110010 ; 比较匹配静音时的输出B
out TCCR0A,rimp
rjmp IntTcCmpARet
IntTcCmpANoKu:
sbrs rFlg,bPLang ; 长暂停位设置?
rjmp IntTcCmpAAusgabe ; 否,继续输出字符
cbr rFlg,1<<bPLang ; 重置长暂停位
mov ZH,XH ; 将Z设置为读取字符
mov ZL,XL
lpm ; 从Flash到R0读取字符
mov rimp,R0 ; 将字符复制到ripp
subi rimp,0x20 ; 删除控制字符
brcs IntTcCmpAEnde ; 字符是控制字符,结束输出
adiw XL,1 ; X 指向下一个字符
cpi rimp,$40 ; 小字母?
brcs IntTcCmpANoKlein
subi rimp,$20 ; 大字母中的小字母
IntTcCmpANoKlein:
lsl rimp ; 表偏移乘以 2
ldi ZH,HIGH(2*MorseTabelle) ; Z 指向表
ldi ZL,LOW(2*MorseTabelle)
add ZL,rimp ;将偏移量添加到表格顶部
ldi rimp,0 ; 增加溢出
adc ZH,rimp
lpm ; 阅读莫尔斯电码
mov rSig,R0 ; 复制到状态 RAM
adiw ZL,1 ; 指向字符串
lpm ; 阅读字符
mov rLen,R0 ; 在字符长度存储器中
sbrc rLen,7 ; 位7信号空间
rjmp IntTcCmpALeer
IntTcCmpAAusgabe:
sbr rFlg,1<<bPKurz ; 设置短暂休息位
lsl rSig ; 将下一个信号推入进位
brcc IntTcCmpAPieps ; 短信号
ldi rCntH,HIGH(cTc0N3) ; 长信号
ldi rCntL,LOW(cTc0N3)
IntTcCmpAPieps:
ldi rmp,0b00010010 ; CTC,在切换上的比较匹配时输出b
out TCCR0A,rmp
rjmp IntTcCmpARet
IntTcCmpALeer:
sbr rFlg,(1<<bPKurz)|(1<<bPLang) ; 设置短和长中断位
ldi rCntH,HIGH(cTc0N2) ; 长时间休息
ldi rCntL,LOW(cTc0N2)
rjmp IntTcCmpAStumm
IntTcCmpAEnde:
sbi PORTB,2 ; 关闭LED
ldi rimp,0b00000000
out TCCR0B,rimp ; 停止计时器
out TIMSK0,rimp ; 关闭计时器中断
sbi PORTB,1 ; 开关输出
cbr rFlg,1<<bAktiv ; 关闭主动标志
IntTcCmpARet:
out SREG,rSreg ; 还原标志寄存器
reti
;
; 开始之后的主要程序
;
main:
;
; 为中断的返回地址设置堆栈指针
;
ldi rmp,LOW(RAMEND) ; 在SRAM结束时堆叠指针
out SPL,rmp
;
; Angeschlossene Hardware initiieren启动连接的硬件
;
sbi DDRB,1 ; 将扬声器输出定义为输出
sbi PORTB,1 ; 将扬声器输出设置为 1
sbi DDRB,2 ; 将LED输出定义为输出
sbi PORTB,2 ; 关闭LED输出
cbi DDRB,4 ;将按钮输入定义为输入
sbi PORTB,4 ; 打开内部上拉电阻
;
; 激活按键的引脚变化中断
;
ldi rmp,0b00010000 ; 掩盖活动入口
out PCMSK,rmp
ldi rmp,0b00100000 ; 启用 PCINT0 中断
out GIMSK,rmp
;
sei; 一般开启中断
;
; 设置中断标志
;
; 设置 CPU 睡眠模式
;
ldi rmp,0b00100000 ; 启用睡眠、空闲模式
out MCUCR,rmp
;
; 带中断的循环
;
loop:
sleep ; 让处理器休眠
nop ; 醒来后什么都不做
rjmp loop ; 再次放置处理器
;
; ASCII 字符 0x20 到 0x5F 的摩尔斯电码
; 低字节=代码(从左到右输出,0=短,1=长)
; 高字节 = 点数/破折号
; 位 7 = 1:空格
Morsetabelle:
; Zeichen 20 .. 2F
.DB 0b00000000,0b10000000 ; 空白的
.DB 0b01000000,5 ; ! = 等待
.DB 0b01001000,6 ; "
.DB 0b11011000,5 ; # = ~n
.DB 0b01101000,5 ; $ = ? 醉了
.DB 0b01000000,5 ; % = ?
.DB 0b00000000,0b10000000 ; & = 未使用,为空
.DB 0b01111000,6 ; '
.DB 0b10110000,5 ; (
.DB 0b10110100,6 ; )
.DB 0b00000000,0b10000000 ; * = 未使用,为空
.DB 0b00010100,6 ; + = 拼接写入
.DB 0b11001100,6 ; ,
.DB 0b10000100,6 ; -
.DB 0b01010100,6 ; .
.DB 0b10010000,5 ; /
;Zeichen 30 .. 3F
.DB 0b11111000,5 ; 0
.DB 0b01111000,5 ; 1
.DB 0b00111000,5 ; 2
.DB 0b00011000,5 ; 3
.DB 0b00001000,5 ; 4
.DB 0b00000000,5 ; 5
.DB 0b10000000,5 ; 6
.DB 0b11000000,5 ; 7
.DB 0b11100000,5 ; 8
.DB 0b11110000,5 ; 9
.DB 0b11100000,6 ; :
.DB 0b10101000,6 ; ;
.DB 0b10101000,5 ; < = 发送的开始
.DB 0b10001000,5 ; =
.DB 0b01010000,5 ; > = 发送的末尾
.DB 0b00110000,6 ; ?
;Zeichen 40 .. 4F
.DB 0b11110000,4 ; @ = 通道
.DB 0b01000000,2 ; A
.DB 0b10000000,4 ; B
.DB 0b10100000,4 ; C
.DB 0b10000000,3 ; D
.DB 0b00000000,1 ; E
.DB 0b00100000,4 ; F
.DB 0b11000000,3 ; G
.DB 0b00000000,4 ; H
.DB 0b00000000,2 ; I
.DB 0b01110000,4 ; J
.DB 0b10100000,3 ; K
.DB 0b01000000,4 ; L
.DB 0b11000000,2 ; M
.DB 0b10000000,2 ; N
.DB 0b11100000,3 ; O
;Zeichen 50 .. 5F
.DB 0b01100000,4 ; P
.DB 0b11010000,4 ; Q
.DB 0b01000000,3 ; R
.DB 0b00000000,3 ; S
.DB 0b10000000,1 ; T
.DB 0b00100000,3 ; U
.DB 0b00010000,4 ; V
.DB 0b01100000,3 ; W
.DB 0b10010000,4 ; X
.DB 0b10110000,4 ; Y
.DB 0b11000000,4 ; Z
.DB 0b01010000,4 ; [ = ?
.DB 0b11100000,4 ; \ = ?
.DB 0b00110000,4 ; ] = ?
.DB 0b00000000,8 ; ^ = Irrung
.DB 0b00110100,6 ; _
;
; 莫尔斯输出文本
;
MorseText:
;.DB "<test test test>",0,0
.DB "<HALLO! HIER IST EIN ATMEL TINY13 BEI DER ARBEIT!>",0,0
; .DB "paris paris paris paris paris paris paris paris paris paris ",0,0
;.DB "<Die kalte Hand am Arsch des Sheriffs.>",0
;
; Ende Quellcode源代码结束
|