Соколов Александр
Макет ЧМ радиомаяка сделан из Генератора радиосигналов
на Si5351A.
ЧМ реализована при помощи быстрой (на скорости около 700 кбит/сек I2C) смены коррекции
частоты синтезатора Si5351A. Суть ЧМ - колебания частоты в заданной полосе с частотой,
соответствующей звуковому сигналу. Конкретно - в коде реализован цикл, который
периодически (с частотой около 400 Гц) изменяет коррекцию частоты синтезатора так, чтобы
происходила отстройка от основного сигнала в полосе 2.5 кГц.
В отличие от классической ЧМ, в данном случае изменение частоты в полосе
происходит без промежуточных значений.
В прошивке применена библиотека
для работы с синтезатором, в которой специально, для реализации ЧМ, существуют
"урезанные" функции, которые намного быстрее позволяют установить коррекцию частоты.
Прошивка, для генератора сигналов:
#include <si5351.h>
#include <avr/wdt.h>
#include <avr/sleep.h>
#define SPEED 60
Si5351 si5351;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
cli();
MCUSR &= ~(1<<WDRF);
wdt_reset();
WDTCSR |= 1 << WDCE | 1 << WDE;
WDTCSR = 0;
wdt_enable(WDTO_8S);
WDTCSR |= 1 << WDIE;
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sei();
si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
si5351.set_correction(0, SI5351_PLL_INPUT_XO);
si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
si5351.set_freq(14557820000ULL, SI5351_CLK0);
si5351.pll_reset(SI5351_PLLA);
si5351.output_enable(SI5351_CLK0,0);
si5351.output_enable(SI5351_CLK1,0);
si5351.output_enable(SI5351_CLK2,0);
TWBR = 0b00000010;
wdt_reset();
}
void loop() {
sleep_mode();
sleep_mode();
sleep_mode();
si5351.output_enable(SI5351_CLK0,1);
si5351.set_freq(14557820000ULL, SI5351_CLK0);
delay(SPEED*10);
//VVV
tx_dot();
tx_dot();
tx_dot();
tx_dash();
delay(SPEED*3);
tx_dot();
tx_dot();
tx_dot();
tx_dash();
delay(SPEED*3);
tx_dot();
tx_dot();
tx_dot();
tx_dash();
delay(SPEED*7);
//DE
tx_dash();
tx_dot();
tx_dot();
delay(SPEED*3);
tx_dot();
wdt_reset();
delay(SPEED*7);
//UB8AFR/B
tx_dot();
tx_dot();
tx_dash();
delay(SPEED*3);
tx_dash();
tx_dot();
tx_dot();
tx_dot();
delay(SPEED*3);
tx_dash();
tx_dash();
tx_dash();
tx_dot();
tx_dot();
delay(SPEED*3);
tx_dot();
tx_dash();
delay(SPEED*3);
tx_dot();
tx_dot();
tx_dash();
tx_dot();
delay(SPEED*3);
tx_dot();
tx_dash();
tx_dot();
delay(SPEED*3);
tx_dash();
tx_dot();
tx_dot();
tx_dash();
tx_dot();
delay(SPEED*3);
tx_dash();
tx_dot();
tx_dot();
tx_dot();
delay(SPEED*7);
wdt_reset();
//MO05QD
tx_dash();
tx_dash();
delay(SPEED*3);
tx_dash();
tx_dash();
tx_dash();
delay(SPEED*3);
tx_dash();
tx_dash();
tx_dash();
tx_dash();
tx_dash();
delay(SPEED*3);
tx_dot();
tx_dot();
tx_dot();
tx_dot();
tx_dot();
delay(SPEED*3);
tx_dash();
tx_dash();
tx_dot();
tx_dash();
delay(SPEED*3);
tx_dash();
tx_dot();
tx_dot();
delay(SPEED*7);
wdt_reset();
si5351.output_enable(SI5351_CLK0,0);
}
ISR (WDT_vect) {
WDTCSR |= (1 << WDIE);
}
void txTone_on(int timer) {
for (int i = 0; i < timer/1.3; i++) {
delayMicroseconds(400);
si5351.set_correction2(-3000, SI5351_PLL_INPUT_XO);
si5351.set_correction2(2000, SI5351_PLL_INPUT_XO);
}
}
void txTone_off() {
si5351.set_correction2(0, SI5351_PLL_INPUT_XO);
}
void tx_dot() {
txTone_on(SPEED);
txTone_off();
delay(SPEED);
}
void tx_dash() {
txTone_on(SPEED*3);
txTone_off();
delay(SPEED);
}