在电子工艺中使用代码的爱好者之一的要求下,有必要编写一个函数(子例程,过程),该函数将从点和点的序列中发出颤音。 在摩尔斯电码中,字符的长度可以从1个字符(字母E和T)到9个字符(SOS三字母组合)。 将什么作为参数传递给上述函数? 如果您不受
许可证条款的限制
,我邀请您熟悉将莫尔斯电码填充到1个字节的过程。
在摩尔斯电码中,最常用的字符是1-6个字符。
; . Ee ; - Tt ; .. Ii ; .- Aa ; -. Nn ; -- Mm ; ... Ss ; ..- Uu ; .-. Rr ; .-- Ww ; -.. Dd ; -.- Kk ; --. Gg ; --- Oo ; .... Hh ; ...- Vv ; ..-. Ff ; ..-- ; .-.. Ll ; .-.- [AA] digraph UNKNOWN STATION ; .--. Pp ; .--- Jj ; -... Bb ; -..- Xx ; -.-. Cc ; -.-- Yy ; --.. Zz ; --.- Qq ; ---. ; ---- ; .---- 1 ; ..--- 2 ; ...-- 3 ; ....- 4 ; ..... 5 ; -.... 6 ; --... 7 ; ---.. 8 ; ----. 9 ; ----- 0 ; ..-.. ; ..-.- [INT] trigraph - military network question marker ; -..-. Slash/Fraction Bar [/] ; -.--. Parenthesis (Open) ; .-... [AS] digraph - Ampersand (or "Wait") [&] ; -...- [BT] digraph - Double Dash = or -- ; .-.-. Plus sign [+] ; .-.-. [AR] digraph - New Page Signal ; -.-.- Starting Signal ; ...-. Understood ; .--.-. ; .-.-.- Period [.] ; --..-- Comma [,] ; ..--.. [UD] digraph Question Mark [?] ; .----. Apostrophe ['] ; -.-.-- [KW] digraph - Exclamation Point [!] ; -.--.- Parenthesis (Close) ; ---... Colon [:] ; -.-.-. Semicolon [;] ; -....- Hyphen, Minus Sign [-] ; ..--.- Underscore [_] ; .-..-. Quotation mark ["] ; .--.-. [AC] digraph - At Sign [@] ; ...-.- End of work ; ...-..- [SX] digraph - Dollar sign [$] ; ........ [HH] digraph - Error/correction ; ...---... [SOS] trigraph
这些字符将放置在8位参数中。 字节必须包含一个字符序列(从1到6)及其数字(也从1到6)。 字符序列应在最低有效位或最高位对齐,以便于通过移位命令将其推入进位标志(Carry)。 对于计数器(c)和字符序列(s)的位置,我们有两种选择:
; arg [s,x,x,x,x,c,c,c]-1个字符
; arg [s,s,x,x,x,c,c,c]-2个字符
; arg [s,s,s,x,x,c,c,c]-3个字符
; arg [s,s,s,s,x,c,c,c]-4个字符
; arg [s,s,s,s,s,c,c,c]-5个字符
; arg [s,s,s,s,s,s / c,c,c]-6个字符
; arg [c,c,c,x,x,x,x,s]-1个字符
; arg [c,c,c,x,x,x,s,s]-2个字符
; arg [c,c,c,x,x,s,s,s]-3个字符
; arg [c,c,c,x,s,s,s,s]-4个字符
; arg [c,c,c,s,s,s,s,s]-5个字符
; arg [c,c,c / s,s,s,s,s,s]-6个字符
在第一实施例中,在最大序列长度的情况下,第6个字符被叠加在计数器的最高有效位上。
在第二实施例中,在序列的最大长度的情况下,第一个字符被叠加在计数器的最低有效位上。 在这种情况下,由于组合110和111都可以作为计数器的最大值(6),因此计数器的最低有效位可以忽略不计。如果计数器的值等于或小于5,则有效位不会叠加在计数器的位上。
我们选择第二个选项。 我们称这些点为零,破折号-单位。 由于字符序列与自变量的最低有效位对齐,因此字符序列以相反的顺序排列以向右推。 我们得到参数的编码:
; arg [c2,c1,c0 / s6,s5,s4,s3,s2,s1]
在摩尔斯电码中,点的持续时间被视为单位时间间隔。 短跑持续时间为3个间隔。 字符内部字符之间的间隔为1个间隔。 字符之间暂停-4个间隔。 单词间暂停-7个间隔。 要通知该功能,无需计算标志,只需输入暂停组合:
; arg [0,0,0,0,0,0,0,0]
接受参数arg [c2,c1,c0 / s6,s5,s4,s3,s2,s1]之后,函数应从中提取计数器和序列,“锯掉”字符并以3个间隔的暂停结束。
为了在单词之间形成停顿,我们将参数arg [0,0,0,0,0,0,0,0]传递给函数。 除了从前一个字符后暂停3个间隔外,该功能还必须计算4个间隔的暂停(总共7个间隔)。
要提取计数器,该函数必须将arg内容的副本向右移动5位,应用AND掩码(00000111),将计数器等于6(如果等于7)。接下来,逐步向右,从原始arg中提取字符。 如果“ 0”是一个点:1个蜂鸣间隔,1个暂停间隔。 如果“ 1”是破折号:3个蜂鸣间隔,1个暂停间隔。 练习完最后一个字符后-2个暂停间隔。 如果arg = 0:仅暂停4个间隔。
这种8位编码涵盖了所有摩尔斯字符和有向图,长度从1到6个字符。 请考虑以下示例:
; . Ee arg[0, 0, 1, x, x, x, x, 0] ; - Tt arg[0, 0, 1, x, x, x, x, 1] ; .. Ii arg[0, 1, 0, x, x, x, 0, 0] ; .- Aa arg[0, 1, 0, x, x, x, 1, 0] ; -. Nn arg[0, 1, 0, x, x, x, 0, 1] ; -- Mm arg[0, 1, 0, x, x, x, 1, 1] ; ... Ss arg[0, 1, 1, x, x, 0, 0, 0] ; ..- Uu arg[0, 1, 1, x, x, 1, 0, 0] ; .-. Rr arg[0, 1, 1, x, x, 0, 1, 0] ; .-- Ww arg[0, 1, 1, x, x, 1, 1, 0] ; -.. Dd arg[0, 1, 1, x, x, 0, 0, 1] ; -.- Kk arg[0, 1, 1, x, x, 1, 0, 1] ; --. Gg arg[0, 1, 1, x, x, 0, 1, 1] ; --- Oo arg[0, 1, 1, x, x, 1, 1, 1] ; .... Hh arg[1, 0, 0, x, 0, 0, 0, 0] ; ...- Vv arg[1, 0, 0, x, 1, 0, 0, 0] ; ..-. Ff arg[1, 0, 0, x, 0, 1, 0, 0] ; ..-- arg[1, 0, 0, x, 1, 1, 0, 0] ; .-.. Ll arg[1, 0, 0, x, 0, 0, 1, 0] ; .-.- arg[1, 0, 0, x, 1, 0, 1, 0] ; .--. Pp arg[1, 0, 0, x, 0, 1, 1, 1] ; .--- Jj arg[1, 0, 0, x, 1, 1, 1, 0] ; -... Bb arg[1, 0, 0, x, 0, 0, 0, 1] ; -..- Xx arg[1, 0, 0, x, 1, 0, 0, 1] ; -.-. Cc arg[1, 0, 0, x, 0, 1, 0, 1] ; -.-- Yy arg[1, 0, 0, x, 1, 1, 0, 1] ; --.. Zz arg[1, 0, 0, x, 0, 0, 1, 1] ; --.- Qq arg[1, 0, 0, x, 1, 0, 1, 1] ; ---. arg[1, 0, 0, x, 0, 1, 1, 1] ; ---- arg[1, 0, 0, x, 1, 1, 1, 1] ; .---- 1 arg[1, 0, 1, 1, 1, 1, 1, 0] ; ..--- 2 arg[1, 0, 1, 1, 1, 1, 0, 0] ; ...-- 3 arg[1, 0, 1, 1, 1, 0, 0, 0] ; ....- 4 arg[1, 0, 1, 1, 0, 0, 0, 0] ; ..... 5 arg[1, 0, 1, 0, 0, 0, 0, 0] ; -.... 6 arg[1, 0, 1, 0, 0, 0, 0, 1] ; --... 7 arg[1, 0, 1, 0, 0, 0, 1, 1] ; ---.. 8 arg[1, 0, 1, 0, 0, 1, 1, 1] ; ----. 9 arg[1, 0, 1, 0, 1, 1, 1, 1] ; ----- 0 arg[1, 0, 1, 1, 1, 1, 1, 1] ; ..-.. arg[1, 0, 1, 0, 0, 1, 0, 0] ; ..-.- [INT] arg[1, 0, 1, 1, 0, 1, 0, 0] ; -..-. [/] arg[1, 0, 1, 0, 1, 0, 0, 1] ; -.--. Parenthesis arg[1, 0, 1, 1, 0, 1, 1, 0] ; .-... [&] arg[1, 0, 1, 0, 0, 0, 1, 0] ; -...- [=] arg[1, 0, 1, 1, 0, 0, 0, 1] ; .-.-. [+] arg[1, 0, 1, 0, 1, 0, 1, 0] ; -.-.- Starting Signal arg[1, 0, 1, 1, 0, 1, 0, 1] ; ...-. Understood arg[1, 0, 1, 0, 1, 0, 0, 0] ; .--.-. arg[1, 1, 0, 1, 0, 1, 1, 0] ; .-.-.- [.] arg[1, 1, 1, 0, 1, 0, 1, 0] ; --..-- [,] arg[1, 1, 1, 1, 0, 0, 1, 1] ; ..--.. [?] arg[1, 1, 0, 0, 1, 1, 0, 0] ; .----. ['] arg[1, 1, 0, 1, 1, 1, 1, 0] ; -.-.-- [!] arg[1, 1, 1, 1, 0, 1, 0, 1] ; -.--.- Parenthesis arg[1, 1, 1, 0, 1, 1, 0, 1] ; ---... [:] arg[1, 1, 0, 0, 0, 1, 1, 1] ; -.-.-. [;] arg[1, 1, 0, 1, 0, 1, 0, 1] ; -....- [-] arg[1, 1, 1, 0, 0, 0, 0, 1] ; ..--.- [_] arg[1, 1, 1, 0, 1, 1, 0, 0] ; .-..-. ["] arg[1, 1, 0, 1, 0, 0, 1, 0] ; .--.-. [@] arg[1, 1, 0, 1, 0, 1, 1, 0] ; ...-.- End of work arg[1, 1, 1, 0, 1, 0, 0, 0]
如果仔细查看干燥残留物中残留的成分:
; ...-..- Dollar sign [$] [SX] digraph ; ........ Error/correction [HH] digraph or [EEEEEEEE] ; ...---... [SOS]
引入一个额外的函数void dot3woPostPause(),然后算出[X](-..-),[5](.....)或[:](---...),将是合乎逻辑的。
为了完整起见,请考虑“困难”的路径。 要计算出长度超过6个字符的莫尔斯二合一和三合一,有必要对编码进行补充,以计算出没有符号间停顿的“多余”字符(在“多余”字符之后没有2个间隔的后暂停)。
“多余”字符的数量是1到3。计数器2的数字容量。我们将仪表放在arg位[4,3]中,将序列放在arg位[2,1,0]中:
; arg [0,0,0,c1,c0,s3,s2,s1]
如果arg [7,6,5] = 000,则要提取计数器,该函数必须将arg内容的副本向右移动3位,并应用AND掩码(00000011)。 接下来,逐步从右侧逐步提取原始arg中的字符。 如果“ 0”是一个点:1个蜂鸣间隔,1个暂停间隔。 如果“ 1”是破折号:3个蜂鸣间隔,1个暂停间隔。 计算完最后一个字符后,不添加任何其他暂停。
现在,要计算“长”符号,您必须首先处理没有后暂停的字符,然后处理带有后暂停的字符。 为此需要两个8位参数。 参数中的字符总数必须与字符的长度相对应:
; ...-..- Dollar sign [$] [SX] digraph ; arg1[0, 0, 0, 0, 1, x, x, 0] arg2[1, 1, 1, 0, 0, 1, 0, 0] ; arg1[0, 0, 0, 1, 0, x, 0, 0] arg2[1, 0, 1, 1, 0, 0, 1, 0] ; arg1[0, 0, 0, 1, 1, 0, 0, 0] arg2[1, 0, 0, x, 1, 0, 0, 1] ; ; ........ Error/correction [HH] digraph or [EEEEEEEE] ; arg1[0, 0, 0, 1, 0, x, 0, 0] arg2[1, 1, 0, 0, 0, 0, 0, 0] ; arg1[0, 0, 0, 1, 1, 0, 0, 0] arg2[1, 0, 1, 0, 0, 0, 0, 0] ; ; ...---... [SOS] ; arg1[0, 0, 0, 1, 1, 0, 0, 0] arg2[1, 1, 0, 0, 0, 1, 1, 1]
将摩尔斯电码字符打包成8位代码可以用不同的编程语言和不同的平台实现。 对于Max(代码的爱人),我在
STM8 asm上准备了“ fish”的源代码。
用户“ Akon32”提供的备用8位编码,使您可以摆脱第二个参数:
; arg[0, 0, 0, 0, 0, 0, 0, 0] — [HH] + 2 ; arg[0, 0, 0, 0, 1, 0, 0, 1] — [$] + 2 ; arg[1, 0, s1, s2, s3, s4, s5, s6] — [6 ] + 2 ; arg[1, 1, 0, s1, s2, s3, s4, s5] — [5 ] + 2 ; arg[1, 1, 1, 0, s1, s2, s3, s4] — [4 ] + 2 ; arg[1, 1, 1, 1, 0, s1, s2, s3] — [3 ] + 2 ; arg[1, 1, 1, 1, 1, 0, s1, s2] — [2 ] + 2 ; arg[1, 1, 1, 1, 1, 1, 0, s1] — [1 ] + 2 ; arg[1, 1, 1, 1, 1, 1, 1, 0] — 4 ; arg[1, 1, 1, 1, 1, 1, 1, 1] — [SOS] + 2 ; 8 ; Carry ; ('1') ; ('0') (Carry) - ; 0b00000000, 0b11111111, 0b11111110
与字母序列(例如[S],[O],[S])不同,有向图和三向图(例如[SOS])的处理没有字母间的停顿。