26.gif (4.18 MB, 下載次數: 94)
下載附件
2022-5-14 12:41 上傳
這是德語教程中的一個例子
;====================================================================
; 新建項目向導生成的 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源代碼結束
|