Código morse de 8 bits

A pedido de um dos amantes do uso de códigos in no artesanato eletrônico, tornou-se necessário escrever uma função (sub-rotina, procedimento) que emitisse um trinado a partir de uma sequência de pontos e traços. Em um código Morse, o tamanho de um caractere pode variar de 1 caractere (letras E e T) a 9 caracteres (trigrama SOS). O que passar para a função acima como parâmetro? Se você não se sobrecarrega com os termos da licença, convido você a se familiarizar com o processo de inserir o código Morse em 1 byte.

No código Morse, os caracteres mais usados ​​têm de 1 a 6 caracteres.

; . 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 

Esses caracteres serão colocados em um argumento de 8 bits. Um byte deve conter uma sequência de caracteres (de 1 a 6) e seu número (também de 1 a 6). A sequência de caracteres deve ser alinhada no bit menos significativo ou mais alto para facilitar a inserção no sinalizador de transporte (transporte) por comandos de deslocamento. Temos duas opções para a localização do contador (c) e a sequência (s) de caracteres:

; arg [s, x, x, x, x, c, c, c] - 1 caractere
; arg [s, s, x, x, x, c, c, c] - 2 caracteres
; arg [s, s, s, x, x, c, c, c] - 3 caracteres
; arg [s, s, s, s, x, c, c, c] - 4 caracteres
; arg [s, s, s, s, s, c, c, c] - 5 caracteres
; arg [s, s, s, s, s / c, c, c] - 6 caracteres

; arg [c, c, c, x, x, x, x, s] - 1 caractere
; arg [c, c, c, x, x, x, s, s] - 2 caracteres
; arg [c, c, c, x, x, s, s, s] - 3 caracteres
; arg [c, c, c, x, s, s, s, s] - 4 caracteres
; arg [c, c, c, s, s, s, s, s] - 5 caracteres
; arg [c, c, c / s, s, s, s, s, s] - 6 caracteres

Na primeira modalidade, com o comprimento máximo de sequência, o sexto caractere é sobreposto no bit mais significativo do contador.

Na segunda modalidade, com o comprimento máximo de sequência, o 1º caractere é sobreposto no bit menos significativo do contador. Nesse caso, o bit menos significativo do contador pode ser considerado insignificante, uma vez que ambas as combinações 110 e 111 podem ser tomadas como o valor máximo do contador (6). Se o valor do contador for 5 ou menos, sinais significativos não serão sobrepostos nos bits do contador.

Nós escolhemos a segunda opção. Chamamos os pontos de zeros, traços - unidades. Como a sequência de caracteres está alinhada com o bit menos significativo do argumento, a sequência de caracteres é organizada na ordem inversa para ser empurrada para a direita. Nós obtemos a codificação do argumento:

; arg [c2, c1, c0 / s6, s5, s4, s3, s2, s1]

No código Morse, a duração de um ponto é tomada como um intervalo de tempo unitário. A duração do traço é de 3 intervalos. A pausa entre os caracteres dentro do caractere é de 1 intervalo. Pausa entre caracteres - 4 intervalos. Pausa entre palavras - 7 intervalos. Para informar à função que não é necessário calcular os sinais, basta inserir a combinação de pausa:

; arg [0, 0, 0, 0, 0, 0, 0, 0]

Tendo aceitado o argumento arg [c2, c1, c0 / s6, s5, s4, s3, s2, s1], a função deve extrair o contador e a sequência, “cortar” o caractere e terminar com uma pausa de 3 intervalos.

Para formar uma pausa entre as palavras, passamos o argumento arg [0, 0, 0, 0, 0, 0, 0, 0, 0] para a função. A função deve, além de uma pós-pausa de 3 intervalos do caractere anterior, realizar uma pausa de 4 intervalos (total de 7 intervalos).

Para extrair o contador, a função deve deslocar a cópia do conteúdo do arg para a direita em 5 bits, aplicar a máscara AND (00000111), equiparar o contador a 6 se for igual a 7. Em seguida, passo a passo à direita, extrair caracteres do arg original. Se "0" for um ponto: 1 intervalo de bipe, 1 intervalo de pausa. Se "1" for um traço: 3 intervalos de bipe, 1 intervalo de pausa. Depois de praticar o último personagem - 2 intervalos de pausa. Se arg = 0: apenas uma pausa de 4 intervalos.

Essa codificação de 8 bits abrange todos os caracteres e algarismos Morse de 1 a 6 caracteres. Considere os seguintes exemplos:

 ; . 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] 

Se você observar atentamente o que resta no resíduo seco:

 ; ...-..- Dollar sign [$] [SX] digraph ; ........ Error/correction [HH] digraph or [EEEEEEEE] ; ...---... [SOS] 

seria lógico introduzir uma função adicional void dot3woPostPause () após a qual trabalhe [X] (-..-), [5] (.....) ou [:] (---...).

Para completar, considere o caminho "difícil". Para calcular os algarismos e trigramas Morse com um comprimento superior a 6 caracteres, é necessário adicionar uma codificação para calcular caracteres "extras" sem uma pausa entre caracteres (sem uma pausa após 2 intervalos após os caracteres "extras").

O número de caracteres “extras” é de 1 a 3. A capacidade de dígitos do contador 2. Colocamos o medidor nos bits de arg [4,3] e a sequência nos bits de arg [2,1,0]:

; arg [0, 0, 0, c1, c0, s3, s2, s1]

Com arg [7,6,5] = 000, para extrair o contador, a função deve deslocar a cópia do conteúdo do arg para a direita em 3 bits, aplicar a máscara AND (00000011). Em seguida, passo a passo à direita para extrair caracteres do argumento original. Se "0" for um ponto: 1 intervalo de bipe, 1 intervalo de pausa. Se "1" for um traço: 3 intervalos de bipe, 1 intervalo de pausa. Após calcular o último caractere, nenhuma pausa adicional é adicionada.

Agora, para descobrir o símbolo "longo", você deve primeiro processar os caracteres sem uma pós-pausa, depois os caracteres com uma pós-pausa. Dois argumentos de 8 bits são necessários para isso. O número total de caracteres nos argumentos deve corresponder ao comprimento do caractere:

 ; ...-..- 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] 

A compactação de caracteres de código Morse em código de 8 bits pode ser implementada em diferentes linguagens de programação e em diferentes plataformas. Para Max (amante dos códigos)), preparei o código fonte do "peixe" no STM8 asm .

Codificação alternativa de 8 bits do usuário "Akon32", permitindo que você se livre do segundo argumento:
 ; 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     


Diferentemente de uma sequência de letras (por exemplo, [S], [O], [S]), os dígrafos e trigramas (por exemplo, [SOS]) são processados ​​sem pausas entre letras.

Source: https://habr.com/ru/post/pt473038/


All Articles