找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2010|回复: 0
收起左侧

ATtiny13单片机Morse发送文本仿真程序 汇编语言

[复制链接]
ID:342822 发表于 2022-5-14 12:46 | 显示全部楼层 |阅读模式
26.gif


这是德语教程中的一个例子
;====================================================================
; 新建项目向导生成的 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源代码结束

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表