Aquí les
traigo un sencillo generador de caracteres en código Baudot con modulación en
doble tono para conformar el protocolo RTTY, el mismo posee el generador de
tonos integrado y la generación de Baudot en el mismo.
El circuito
no está en el post porque en si es solo el micro controlador y un pin de salida
que en este caso se elige un 16F84A y se usa el pin RA2 como salida. Pero
claramente por la sencillez del programa puede usarse cualquier micro
controlador.
El
programa es muy sencillo de comprender.
Básicamente
tenemos dos funciones, freq1 y freq0, esto es para generar dos frecuencias (de ahí
viene el doble tono) donde la freq1 "del 1 lógico" la calcule yo a
800Hz y la freq0 "del 0 lógico" a 970Hz, nótese que la distancia es
de 170Hz por ende si quieren usar otros valores de frecuencia (que es
totalmente valido) deben tener una distancia de 170Hz entre una frecuencia y la
otra.
La norma
RTTY aparte de exigir estos 170Hz también exige que cada dato se envié a 22ms
por ende aquí vienen las cuentas.
tomamos
como ejemplo la función freq1, observamos que ponemos el pin de salida a 0 y después
a 1, la velocidad que usamos son 625us de Ton y 625us de Toff, quedando así una
periodo T de 1250us lo cual si lo pasamos a frecuencia nos da 800Hz, ahora
hasta ahí todo bien logramos los 800Hz que queríamos, pero cada dato debe
enviarse a 22ms entonces debemos hacer que se demore durante 22ms, para ello
usamos un loop del tipo while donde cuenta 17 veces y luego sale del loop, si
multiplicamos 17 * 1250us nos dará 21,2ms (es casi el valor de 22ms, gracias a
que existe una tolerancia no tendremos problemas).
La función
freq0 es lo mismo que esto pero calculado para 970Hz.
Estas
dos funciones forman parte de la generación de doble tono, lo que sería nuestro
"modem".
Ahora
viene la generación de baudot, para esto se crea un vector de 18 posiciones (lo
cual son 18 porque use 18 caracteres para formar " ELECTGPL
RTTY ").
El
protocolo dice que debe ser 1 bit de start a 0 lógico, seguido de esto 5 bit
del dato o el carácter y por ultimo 2 bit de Stop a 1 lógico. Notaran que en el
programa está al revés, es decir primero el stop y por último el start, eso es
por la forma en la que el micro entrega los bit de forma serie (pero pueden
cambiarlo, yo lo he dejado así porque ya lo había codificado así).
Tenemos
otro vector que es para la máscara, es decir tiene los valores ponderados de un
valor binario de 8 bit, esto es simple, la forma de enviar el dato de forma
serial, debe ser bit a bit, entonces esto lo hacemos comparando el dato a
enviar con la máscara. Por ejemplo en el loop que tiene un for que itera 8
veces lo que se hace es comprar el byte a enviar (start, dato, stop, stop) con
el byte de la máscara. Entonces si aplicamos la operación lógica AND, donde
exista un 1 lógico dará verdadero y donde exista un 0 lógico dará falso,
entonces si tenemos por ejemplo el primer byte a enviar "11001000" y
lo comparamos contra la máscara 8 veces (mediante el incremento del índice del
vector) nos dirá como resultado lo siguiente:
11001000 & 00000001 = False
11001000 & 00000010 = False
11001000 & 00000100 = False
11001000 & 00001000 = True
11001000 & 00010000 = False
11001000 & 00100000 = False
11001000
& 01000000 = True
11001000 & 10000000 = True
Esto es
lo que hace el for que itera 8 veces, de esta forma recorre bit a bit todo el
byte del dato y lo compara contra la máscara. Ahora, seguido de este tenemos la
condición, si es verdadero llama a la función freq0 y si es falso a la función
freq1, entonces como quedaría esto modulado?, de la siguiente forma.
800Hz
22ms 800Hz 22ms 800Hz 22ms 970Hz 22ms 800Hz 22ms 800Hz 22ms 970Hz 22ms 970Hz
22ms. Esta sería la salida del micro, que luego se repetirá como dice el while
unas 18 veces que coincide con los 18 valores vector de datos.
La
salida puede ser acoplada como en mi práctica a un transmisor de AM de 80m pero
es posible acoplarla a cualquier entrada de AF.
#include
<16F84A.h>
#fuses
XT
#use
delay(clock=4000000)
#define
AUDIO PIN_A2
freq1(){ //625us + 625us = 1250us = 800Hz
int q=0;
while(q<17){ //22ms / 1250us = 17 veces.
output_low(AUDIO);
delay_us(625);
output_high(AUDIO);
delay_us(625);
q++;
}
}
freq0(){ //515us + 515us = 1030us = 970Hz
int p=0;
while(p<21){ //22ms / 1030us = 21 veces.
output_low(AUDIO);
delay_us(515);
output_high(AUDIO);
delay_us(515);
p++;
}
}
void
main(){
int i,j;
byte valor;
byte const bitMask[8]={1,2,4,8,16,32,64,128};
byte const ByteDatosSalida[18]={
0b11001000, //11 00100 0, STOP STOP
ESPACIO START
0b11001000, //11 00100 0, STOP STOP
ESPACIO START
0b11000010, //11 00001 0, STOP STOP
"E" START
0b11100100, //11 10010 0, STOP STOP
"L" START
0b11000010, //11 00001 0, STOP STOP "E" START
0b11011100, //11 01110 0, STOP STOP
"C" START
0b11100000, //11 10000 0, STOP STOP
"T" START
0b11110100, //11 11010 0, STOP STOP
"G" START
0b11101100, //11 10110 0, STOP STOP
"P" START
0b11100100, //11 10010 0, STOP STOP
"L" START
0b11001000, //11 00100 0, STOP STOP
ESPACIO START
0b11001000, //11 00100 0, STOP STOP
ESPACIO START
0b11010100, //11 01010 0, STOP STOP
"R" START
0b11100000, //11 10000 0, STOP STOP
"T" START
0b11100000, //11 10000 0, STOP STOP
"T" START
0b11101010, //11 10101 0, STOP STOP
"Y" START
0b11001000, //11 00100 0, STOP STOP
ESPACIO START
0b11001000};//11 00100 0, STOP STOP
ESPACIO START
while(true){
delay_ms(3000); //delay de repeticion 3s
i=0;
while(i<18){
//cantidad de caracteres 18
valor=ByteDatosSalida[i]; //carga valor con dato de salida
for(j=0;j<8;j++){ //recorre los 8 bit del baudot
if(valor&bitMask[j])
//aplica la mascara
freq0(); //si es
verdadero envia 970Hz
else
freq1(); //si es falso
envia 800Hz
}i++;
}
}
}
EXCELENTE...
ResponderBorrar