Código morse de 8 bits

A pedido de uno de los amantes del uso de códigos en manualidades electrónicas, se hizo necesario escribir una función (subprograma, procedimiento) que emitirá un trino a partir de una secuencia de puntos y guiones. En un código Morse, la longitud de un carácter puede ser de 1 carácter (letras E y T) a 9 caracteres (trigrafo SOS). ¿Qué pasar a la función anterior como parámetro? Si no está agobiado por los términos de la licencia, lo invito a que se familiarice con el proceso de rellenar el código Morse en 1 byte.

En el código Morse, los caracteres más utilizados son de 1-6 caracteres de longitud.

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

Estos caracteres se colocarán en un argumento de 8 bits. Un byte debe contener una secuencia de caracteres (del 1 al 6) y su número (también del 1 al 6). La secuencia de caracteres debe alinearse en el bit menos significativo o más alto para facilitar la inserción en la bandera de acarreo (Carry) mediante comandos de cambio. Obtenemos dos opciones para la ubicación del contador (c) y la (s) secuencia (s) de caracteres:

; arg [s, x, x, x, x, c, c, c] - 1 carácter
; 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, s / c, c, c] - 6 caracteres

; arg [c, c, c, x, x, x, x, s] - 1 carácter
; 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

En la primera realización, con la longitud máxima de secuencia, el sexto carácter se superpone en el bit más significativo del contador.

En la segunda realización, con la longitud máxima de secuencia, el primer carácter se superpone en el bit menos significativo del contador. En este caso, el bit menos significativo del contador puede considerarse insignificante, ya que ambas combinaciones 110 y 111 pueden tomarse como el valor máximo del contador (6). Si el valor del contador es 5 o menos, los signos significativos no se superponen en los bits del contador.

Elegimos la segunda opción. Llamamos a los puntos ceros, guiones - unidades. Dado que la secuencia de caracteres está alineada con el bit menos significativo del argumento, la secuencia de caracteres se organiza en el orden inverso para ser empujada hacia la derecha. Obtenemos la codificación del argumento:

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

En el código Morse, la duración de un punto se toma como un intervalo de tiempo unitario. La duración del tablero es de 3 intervalos. La pausa entre los caracteres dentro del carácter es de 1 intervalo. Pausa entre caracteres - 4 intervalos. Pausa entre palabras - 7 intervalos. Para informar a la función que no es necesario resolver los signos, simplemente ingrese la combinación de pausa:

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

Una vez aceptado el argumento arg [c2, c1, c0 / s6, s5, s4, s3, s2, s1], la función debe extraer el contador y la secuencia del mismo, "cortar" el carácter y finalizarlo con una pausa de 3 intervalos.

Para formar una pausa entre palabras, pasamos el argumento arg [0, 0, 0, 0, 0, 0, 0, 0] a la función. La función debe, además de una pausa posterior de 3 intervalos del carácter anterior, calcular una pausa de 4 intervalos (total de 7 intervalos).

Para extraer el contador, la función debe desplazar la copia del contenido de arg a la derecha en 5 bits, aplicar la máscara AND (00000111), igualar el contador a 6 si es igual a 7. Luego, paso a paso a la derecha, extraer caracteres del arg original. Si "0" es un punto: 1 intervalo de pitido, 1 intervalo de pausa. Si "1" es un guión: 3 intervalos de pitido, 1 intervalo de pausa. Después de practicar el último personaje - 2 intervalos de pausa. Si arg = 0: solo una pausa de 4 intervalos.

Esta codificación de 8 bits cubre todos los caracteres Morse y dígrafos de 1 a 6 caracteres de longitud. Considere los siguientes ejemplos:

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

Si observa de cerca lo que queda en el residuo seco:

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

sería lógico introducir una función adicional void dot3woPostPause () después de lo cual se resuelve [X] (-..-), [5] (.....) o [:] (---...).

Para completar, considere el camino "difícil". Para calcular los dígrafos y trigrafos de Morse con una longitud de más de 6 caracteres, es necesario hacer una adición a la codificación para resolver los caracteres "extra" sin una pausa entre símbolos (sin una pausa posterior de 2 intervalos después de los caracteres "extra").

El número de caracteres "extra" es de 1 a 3. La capacidad de dígitos del contador 2. Colocamos el medidor en los bits arg [4,3] y la secuencia en los bits arg [2,1,0]:

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

Con arg [7,6,5] = 000, para extraer el contador, la función debe desplazar la copia del contenido de arg a la derecha en 3 bits, aplicar la máscara AND (00000011). A continuación, paso a paso a la derecha para extraer caracteres del argumento original. Si "0" es un punto: 1 intervalo de pitido, 1 intervalo de pausa. Si "1" es un guión: 3 intervalos de pitido, 1 intervalo de pausa. Después de resolver el último carácter, no se agregan pausas adicionales.

Ahora, para resolver el símbolo "largo", primero debe procesar los caracteres sin una pausa posterior, luego los caracteres con una pausa posterior. Se necesitan dos argumentos de 8 bits para esto. El número total de caracteres en los argumentos debe corresponder a la longitud del carácter:

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

El empaquetado de caracteres de código Morse en código de 8 bits se puede implementar en diferentes lenguajes de programación y en diferentes plataformas. Para Max (amante de los códigos)), preparé el código fuente del "pez" en STM8 asm .

Codificación alternativa de 8 bits del usuario "Akon32", que le permite deshacerse del 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     


A diferencia de una secuencia de letras (p. Ej., [S], [O], [S]), los dígrafos y los trigrafos (p. Ej., [SOS]) se procesan sin pausas entre letras.

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


All Articles