找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2799|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

ATtiny13單片機Morse發(fā)送文本仿真程序 匯編語言

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:342822 發(fā)表于 2022-5-14 12:46 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式



這是德語教程中的一個例子
;====================================================================
; 新建項目向?qū)傻?Main.asm 文件
;
; 創(chuàng)建時間:   周四 2月 18 2021
; 處理器: ATtiny13
; 編譯器:  AVRASM (Proteus)
;====================================================================

; **************************************************************
; *按下按鈕開始莫爾斯文本輸出   *
; **************************************************************
;
.INCLUDE "tn13def.inc"
;;
;可選常數(shù)
;
.EQU cSpeed = 90 ; 在BPM傳輸速度,5..500 BPM
.EQU cTone = 1000 ; 間距赫茲,300..8000赫茲
;
; 固定常數(shù)
;
.EQU fClock = 1200000
.EQU cTc0Div = 8
;
; 計算常數(shù)
;
.EQU cTc0CmpA = fClock/cTc0Div/cTone/2
.EQU cTc0CmpB = cTc0CmpA/2
.EQU cTc0N = cTone*16/cSpeed
.EQU cTc0N2 = 2*cTc0N ;兩倍長
.EQU cTc0N3 = 3*cTc0N ; 長三倍
;
; 檢查設(shè)定值
;
.IF cTc0CmpA > 255
        .ERROR "Ton zu niedrig!"   ;聲音太低了!
        .ENDIF
.IF cTc0CmpA < 8
        .ERROR "Ton zu hoch!"      ; 音調(diào)太高!   
        .ENDIF
.IF cTc0N3 > 65535
        .ERROR "Frequenz zu niedrig!"  ;頻率太低!
        .ENDIF
.IF cTc0N < 8
        .ERROR "Frequenz zu hoch!"    ;頻率太高!
        .ENDIF
;
; 定義標(biāo)簽
;
.DEF rSreg = R15 ; 應(yīng)在 Ints 中注冊 Sreg
.DEF rmp = R16 ; 多用途寄存器
.DEF rimp = R17 ; 中斷多用途寄存器
.DEF rFlg = R18 ; 標(biāo)志
        .EQU bAktiv = 0 ; 輸出有效
        .EQU bPKurz = 1 ; 字符輸出
        .EQU bPLang = 2 ; 字符間暫停
.DEF rSig = R19 ; 輸出摩爾斯電碼
.DEF rLen = R20 ; 長短數(shù)字
; frei R21..R23
.DEF rCntL = R24 ; 半波數(shù)計數(shù)器NF,LSB
.DEF rCntH = R25 ;同上,MSB
;
; 重置和中斷向量
;
.CSEG ; 匯編到程序閃存
.ORG $0000 ; 以地址0開頭
;
; 重置和中斷的跳轉(zhuǎn)向量
;
        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服務(wù)程序
; 每次在匹配時執(zhí)行
; 引腳3(= PB4)更改(按下按鈕)
;
IntPcInt:
        in rSreg,SREG ; 安全標(biāo)志
        sbic PINB,4 ; 如果 PB4 為零,則跳過下一條命令
        rjmp IntPcInt1 ; 跳因為PB4一
        sbrc rFlg,bAktiv ; 如果已經(jīng)激活:忽略
        rjmp IntPcInt1 ; 已處于活動狀態(tài)
        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 中的半波持續(xù)時間
        out OCR0A,rimp
        ldi rimp,cTc0CmpB ; 比較 B 中的半持續(xù)時間半波
        out OCR0B,rimp
        ldi rimp,0b00110010 ; CTC,在靜音比較匹配時輸出 B
        out TCCR0A,rimp
        ldi rimp,0b00000010 ; 定時器預(yù)分頻器為 8
        out TCCR0B,rimp
        ldi rimp,0b00000100 ; 開啟 OCIE0A 中斷
        out TIMSK0,rimp
IntPcInt1:
        out SREG,rSreg ; 恢復(fù)標(biāo)志
        reti ; 從中斷返回
;
; 定時器到期時的中斷
;
IntTcCmpA:
        in rSreg,SREG ; 保存標(biāo)志
        sbiw rCntL,1 ; 再來一次?
        brne IntTcCmpARet
        ldi rCntH,HIGH(cTc0N) ; 重新加載計數(shù)器
        ldi rCntL,LOW(cTc0N)
        sbrs rFlg,bPKurz ; 短暫停位設(shè)置?
        rjmp IntTcCmpANoKu ; 短位未設(shè)置
        cbr rFlg,1<<bPKurz ; 撤消短位
        dec rLen ; 減少短/長字符數(shù)
        brne IntTcCmpAStumm ; 還沒有到零,沉默的停頓
        sbr rFlg,1<<bPLang ;字符之間的長時間停頓
        ldi rCntH,HIGH(cTc0N2) ; 持續(xù)時間加倍的計數(shù)器
        ldi rCntL,LOW(cTc0N2)
IntTcCmpAStumm:
        ldi rimp,0b00110010 ; 比較匹配靜音時的輸出B
        out TCCR0A,rimp
        rjmp IntTcCmpARet
IntTcCmpANoKu:
        sbrs rFlg,bPLang ; 長暫停位設(shè)置?
        rjmp IntTcCmpAAusgabe ; 否,繼續(xù)輸出字符
        cbr rFlg,1<<bPLang ; 重置長暫停位
        mov ZH,XH ; 將Z設(shè)置為讀取字符
        mov ZL,XL
        lpm ; 從Flash到R0讀取字符
        mov rimp,R0 ; 將字符復(fù)制到ripp
        subi rimp,0x20 ; 刪除控制字符
        brcs IntTcCmpAEnde ; 字符是控制字符,結(jié)束輸出
        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 ; 復(fù)制到狀態(tài) RAM
        adiw ZL,1 ; 指向字符串
        lpm ; 閱讀字符
        mov rLen,R0 ; 在字符長度存儲器中
        sbrc rLen,7 ; 位7信號空間
        rjmp IntTcCmpALeer
IntTcCmpAAusgabe:
        sbr rFlg,1<<bPKurz ; 設(shè)置短暫休息位
        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) ; 設(shè)置短和長中斷位
        ldi rCntH,HIGH(cTc0N2) ; 長時間休息
        ldi rCntL,LOW(cTc0N2)
        rjmp IntTcCmpAStumm
IntTcCmpAEnde:
        sbi PORTB,2 ; 關(guān)閉LED
        ldi rimp,0b00000000
        out TCCR0B,rimp ; 停止計時器
        out TIMSK0,rimp ; 關(guān)閉計時器中斷
        sbi PORTB,1 ; 開關(guān)輸出
        cbr rFlg,1<<bAktiv ; 關(guān)閉主動標(biāo)志
IntTcCmpARet:
        out SREG,rSreg ; 還原標(biāo)志寄存器
        reti
;
; 開始之后的主要程序
;
main:
;
; 為中斷的返回地址設(shè)置堆棧指針
;
        ldi rmp,LOW(RAMEND) ; 在SRAM結(jié)束時堆疊指針
        out SPL,rmp
;
; Angeschlossene Hardware initiieren啟動連接的硬件
;
        sbi DDRB,1 ; 將揚聲器輸出定義為輸出
        sbi PORTB,1 ; 將揚聲器輸出設(shè)置為 1
        sbi DDRB,2 ; 將LED輸出定義為輸出
        sbi PORTB,2 ; 關(guān)閉LED輸出
        cbi DDRB,4 ;將按鈕輸入定義為輸入
        sbi PORTB,4 ; 打開內(nèi)部上拉電阻
;
; 激活按鍵的引腳變化中斷
;
        ldi rmp,0b00010000 ; 掩蓋活動入口
        out PCMSK,rmp
        ldi rmp,0b00100000 ; 啟用 PCINT0 中斷
        out GIMSK,rmp
;
sei; 一般開啟中斷
;
; 設(shè)置中斷標(biāo)志
;
; 設(shè)置 CPU 睡眠模式
;
        ldi rmp,0b00100000 ; 啟用睡眠、空閑模式
        out MCUCR,rmp
;
; 帶中斷的循環(huán)
;
loop:
        sleep ; 讓處理器休眠
        nop ; 醒來后什么都不做
        rjmp loop ; 再次放置處理器
;
; ASCII 字符 0x20 到 0x5F 的摩爾斯電碼
; 低字節(jié)=代碼(從左到右輸出,0=短,1=長)
; 高字節(jié) = 點數(shù)/破折號
; 位 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 ; < = 發(fā)送的開始
.DB 0b10001000,5 ; =
.DB 0b01010000,5 ; > = 發(fā)送的末尾
.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源代碼結(jié)束

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表