Генератор с регулируемоей частотой на ардуино.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Кстати, применённая микросхема позволяет задействовать для стабилизации частоты технологию GPSDO и, в частности одно из предложенных радиолюбителями решений выполнено Кареном Тадевосяном RA3APW )))

 

На диапазоне 10м в режиме GPSDO среднеквадратическое отклонение несущей частоты составляет примерно 7 миллиГц, а пиковое значение примерно 90 миллиГц.

Дима, что ты там говорил о любительских конструкциях )))
 

MAG-N
MAG-N аватар
Offline
Зарегистрирован: 05.06.2017

По-моему, для данного генератора это уже перебор, тем более что надо тащить кабель от подоконника до стола с генератором для антенны GPS. Врядли внутри помещения Глонасс-ГПС будет работать.

MAG-N
MAG-N аватар
Offline
Зарегистрирован: 05.06.2017

Продолжил издевательства над Si5351. Повысил верхний предел частоты с 200Е7 до 220Е7 в строке 453, дохожу до  214 000 000 - норма, ещё плюс мегагерц и вместо 215 000 000 получаю 4000 Hz. Начинаю выяснять точную величину этого скачка - получилось 214 748 364 держит, а вместо 214 748 365 опять получаю 4000. Ладно бы "круглая" граница была, а то непонятно что.

Разобрался! Oказывается, уткнулся в предел int32, пришлось переменную freq сделать int64. Вроде работает, во всяком случае на 440 МГц вторую гармонику вижу, но теперь непонятно как работает регулировка частоты. В общем ну его нафиг, не очень-то и хотелось, откатился назад.

Если я правильно понял, всё это - следствие от добавления шага 0,1 Гц - переменная freq выросла в десять раз. Будем "скрещивать" версии 3.1 и 3.2 Десятые герца мне не нужны, а вот разделение пробелами или точками надо будет сделать.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

MAG-N, всё верно, именно из-за предела int32 я уменьшил верхнюю частоту, так как переход  с int32 на uint32 или на int64 тянул за собой огромные переделки из-за такого пустяка. PS:  Разница между 3.1 и 3.2 довольно существенна в плане улучшения кода. Особенно в частотометре.  Даже если выдрать только вывод на дисплей всё равно придёться повозиться, там же всё "заточено" под вывод удесятерённого значения. Так что проще смирится :)

MAG-N
MAG-N аватар
Offline
Зарегистрирован: 05.06.2017

Нацарапал утилитку для калибровки Si5351. Работает на "железе" V3.2, частота 10 МГц, но можно подставить любую другую. Работа с энкодером "сплагиачена" из скетча генератора (может чего лишнего навыдёргивал). В общем, работает и ладно. Cкетч генератора надо дополнить строкой (после строки 45), и вместо 80000 ввести свою константу (Cal.factor).

si5351.set_correction(80000, SI5351_PLL_INPUT_XO);



#include "Adafruit_ST7735.h"
#include <SPI.h>
#include "si5351.h"
#include <Wire.h>

#define enc_on()  timer_attach_interrupt(TIMER4, TIMER_UPDATE_INTERRUPT, enc_int); 
#define enc_off()  timer_detach_interrupt(TIMER4, TIMER_UPDATE_INTERRUPT); 

Adafruit_ST7735 tft = Adafruit_ST7735(PB12, PB11 ,PB10);
Si5351 si5351;

volatile int encstep=1; //шаг изменения частоты по умолчанию (желаемый *10)
volatile int32_t cal_step=0;
volatile int32_t cal_factor = 0;
uint64_t target_freq = 1000000000ULL; // 10 MHz, in hundredths of hertz

void setup() {
SPI.setModule(2);// выбор SPI2
i2c_master_enable(I2C1, I2C_REMAP); //SDA PB9, SCL PB8
Wire.begin();
si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
si5351.set_freq(target_freq, SI5351_CLK0);
pinMode(PB1,INPUT_PULLUP); //key encoder
pinMode(PB6,INPUT_PULLUP); //encoder
pinMode(PB7,INPUT_PULLUP); //encoder

///////// Таймер4 -обработчик энкодера     
TIMER4_BASE->CR1=(1<<2)|(1<<9);//CKD10 URS
TIMER4_BASE->CCMR1=0xf1f1; (1<<0)|(1<<8 );//cc1s, cc2s input mapped TI1/TI2
TIMER4_BASE->CCER=(1<<1)|(1<<5)|(1<<0)|(1<<4);//Capture/Compare 1,2 output polarity
TIMER4_BASE->SMCR=(1<<1)|(1<<0);//Encoder mode3(SMS bit)стр.407
TIMER4_BASE->CNT=0;
TIMER4_BASE->ARR=1;//ограничение счёта ( =3 для двухимпульсного энкодера)
TIMER4_BASE->SR=0; TIMER4_BASE->EGR=1; 
enc_on();
TIMER4_BASE->CR1|=(1<<0);//запуск 

attachInterrupt(PB1, key_enc_int, RISING); //прерывание кнопки энкодера

tft.initR(INITR_BLACKTAB);
tft.setRotation(3); tft.fillScreen(ST7735_BLACK); tft.setTextWrap(0);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK);  tft.setTextSize(1);
tft.setCursor(0, 10); tft.print("Si5351 Calibration utility");
tft.setCursor(35, 20); tft.print("(c) R1BAO 2018");
tft.setTextColor(ST7735_RED, ST7735_BLACK);  tft.setTextSize(2);
tft.setCursor(20, 35); tft.print("Cal.factor");
tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
tft.setCursor(15, 110); tft.print("Step=");
}

void loop() {
    
si5351.set_correction(cal_factor, SI5351_PLL_INPUT_XO);
si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
tft.setTextColor(ST7735_YELLOW, ST7735_BLACK);
tft.setTextSize(3);
if (cal_step==0){tft.setCursor(35, 65); tft.print("        ");}
if (abs(cal_factor)>=1000000){tft.setCursor(20, 65); tft.print(cal_factor);}
if (abs(cal_factor)<1000)   {tft.setCursor(20, 65);  tft.print(cal_factor); tft.print("    ");}
  else if (abs(cal_factor)<10000)  {tft.setCursor(20, 65);  tft.print(cal_factor); tft.print("   ");}
  else if (abs(cal_factor)<100000) {tft.setCursor(20, 65);  tft.print(cal_factor); tft.print("  ");}
  else if (abs(cal_factor)<1000000){tft.setCursor(20, 65);  tft.print(cal_factor); tft.print(" ");}

tft.setTextSize(2); 
tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
tft.setCursor(75, 110);
switch (encstep) { 
  case 1:   tft.print("1 Hz  "); break;
  case 10:  tft.print("10 Hz "); break;
  case 100: tft.print("100 Hz"); break;
 }
}

//обработчик прерываний энкодера
void enc_int(){   
  if((TIMER4_BASE->CR1)&1<<4) {cal_step+=(encstep*-1);} 
  else {cal_step+=(encstep*1);}
  if (cal_step>=10000) {cal_step=10000;}
  if (cal_step<=-10000) {cal_step=-10000;}
  cal_factor = cal_step*100;
}

// обработчик кнопки энкодера
void key_enc_int(){
  encstep*=10;
  if (encstep >100) {encstep=1;}
}

 

MAG-N
MAG-N аватар
Offline
Зарегистрирован: 05.06.2017

ua6em пишет:

И какова процедура калибровки?

Чем измерять частоту - это у кого что есть. Я, за неимением частотомера, использовал трансивер и пограмму WSJT-X. На частоте 10 МГц работают две станции эталонных частот из Москвы и Новосибирска, поэтому и выбрал её для калибровки. Настраиваемся, находим эталонную и свою частоты. Далее всё очень просто: энкодер по часовой стрелке - частота увеличивается, а значение Cal.factor будет отрицательным. Против часовой - частота уменьшается, Cal.factor положительный. Нажатие на кнопку энкодера - шаг перестройки. При шаге 1Гц меняется разряд сотен, а десятки и единицы - это для шага 0.1 и 0.01 Гц - я их не делал, нафиг не надо. У меня Cal.factor получился 79600, т.е. сдвиг частоты вниз на 796 Гц. После точной настройки полученное значение Cal.factor вписываем в скетч и радуемся.

RuslanX
RuslanX аватар
Offline
Зарегистрирован: 20.05.2017

Спасибо большое dimax за генератор. Очень хороший получился аппарат.

Я сделал два генератора что бы через смеситель получить пакеты импульсов. 

Все отлично работает, но как говорится аппетит приходит во время еды. В пакетах нет сихронизации по фазе ну и конечно их качает. Малость не приятно, но не смертельно. Большое Спасибо.

  

miklin
Offline
Зарегистрирован: 08.06.2018

 Моя плата V3.2.

MAG-N
MAG-N аватар
Offline
Зарегистрирован: 05.06.2017

А я не стал связываться с мультиплексором. Поставил дешифратор 74138 и к нему 4 реле, они пятивольтовые с током потребления около 10 мА. Если применить 74145, у которого ток выхода до 80 мА и допустимое напряжение на выходе 15 В - можно использовать 9-12 вольтовые реле с бОльшим током срабатывания.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Выложил полный архив с  Arduino IDE и всеми свежими библиотеками и скетчем версии 3.2 в сообщении   #50  Просто разархивировать и выбрать скетч в примерах. Кстати там чуть свежее версия скетча, но принципиальных отличий от ранее выложенной нет.

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

anri пишет:

 Загрузка прошла и сразу после нее появилось сообщение в трее что подключено неопознанное устройство. Теперь стмку комп не видит.

Именно так и должно быть, в сетапе ведь отключается виртуальный СОМ порт. Повторная перепрошивка возможна нажатием на ресет в нужный момент, или просто отлюченную плату включить в USB порт в нужный момент.

MAG-N
MAG-N аватар
Offline
Зарегистрирован: 05.06.2017

Похвастаюсь :-) Мой вариант генератора.  Снимал на телефон - ну не умеет он с близкого расстояния снимать, так что извините за качество. Это называется оптическая аберрация.

MAG-N
MAG-N аватар
Offline
Зарегистрирован: 05.06.2017

Самое главное - работает, и очень хорошо работает. Clock Gen настроил по эталонной частоте, потом по этому генератору настроил частотомер (на PIC-e), затем пересчитал "множитель DDS для частоты F_CPU 72МГц"  - и погрешность установки частоты в этом режиме стала почти "нулевая" :-) В режиме PWM на частоте 36 МГц ошибка 1200 герц - но тут тяжело исправить, надо конденсаторы, которые возле кварца, подгонять - ну его нафиг, и так хорошо. Непонятно одно - почему частота скачет на несколько десятков герц туда-сюда, причём только в режиме PWM. Вот картинка сигнала 36000000. Цена деления - 50 Гц.

А это сигнал Si5351, трансивер на частоте 35.999 - биения 1 кГц

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

MAG-N, думаю, что виноват PLL синтезатор в МК.  В Si5351 тоже PLL, но он всё таки задумывался изначально как тактовый генератор, и у него параметры лучше.

MAG-N
MAG-N аватар
Offline
Зарегистрирован: 05.06.2017

Наверное, так как на частоте 9 МГц та же пила, но размах раз в пять-шесть меньше, как и отклонение. На глаз уже не очень заметно, а ухо чует.  Да и не очень то надо на таких частотах PWM гонять, ну мегагерц-два ещё может и понадобится, а дальше Х его З. Самая высокая частота PWM в моих "самоделках" - 31 кГц для управления вентилятором в усилителе на 144 МГц. На звуковых частотах и на малых оборотах эта зараза работает скорее динамиком, чем вентилятором. Зудит, как комар.

michaeltex
Offline
Зарегистрирован: 20.02.2019

Здравствуйте! 

michaeltex
Offline
Зарегистрирован: 20.02.2019

miklin пишет:

 Моя плата V3.2.

Подскажите, а что у вас за модель энкодеров(с кучей ног) ?

MAG-N
MAG-N аватар
Offline
Зарегистрирован: 05.06.2017

Энкодер - это тот, который сверху, а с кучей ног - это потенциометры.