Здравствуйте. Помогите сделать изменения в скетче.
Имеется:
генератор частот на Ардуино Нано, совместно с si5351, вывод на дисплей 1602 по i2c.
Функции генератора:
Вывод на дисплей 2-х значений частоты от 10 КГц, до 210 МГц по каналам CLK0 и CLK1.
Перестройка частоты по одному каналу, по второму каналу и одновременно на двух каналах.
Кнопка выбора каналов:
#define VFO_USES_SW 4 // get_btn(1) кнопка выбора текущего канала: CLK0, CLK1, CLK0+CLK1
Кнопка вкл/выкл каналов:
#define CLK_CN_OFF 15 // get_btn(2) кнопка вкл/выкл каналов ON/OFF
Проблема:
При выборе канала CLK0 частота генератора меняется, при выборе CLK1 частота генератора тоже меняется. При выборе обоих генераторов CLK0+CLK1 частота на НИХ одновременно не меняется. Как исправить?
Я действительно новичок и это моя первая ардуинка.
Вод код, который я выдернул из другого скетча и совместно с нейросетью сделал полу-рабочий вариант.
#include "si5351mcu.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h> // библиотека управления экраном lcd1602 по I2C
/***********************************************************************************************/
#define F_MIN 10000UL // Нижний предел частоты
#define F_MAX 210000000UL // Верхний предел частоты
#define quartz 25000000 // Действительная частота кварца
/* При наличии точного частотомера, подключить прибор, выставить на выходе С1 или С0, частоту
25 000 000 Гц, затем вращая ручку энкодера получить на дисплее частотомера
показания 25 000 000 герц, полученное значение ввести в поле #define quartz
*/
#define ENCODER_A 2 // Encoder pin A
#define ENCODER_B 3 // Encoder pin B
#define ENCODER_BTN 11 // get_btn(0) кнопка "STEP" шаг изменения частоты
#define VFO_USES_SW 4 // get_btn(1) кнопка выбора текущего канала: CLK0, CLK1, CLK0+CLK1
#define CLK_CN_OFF 15 // get_btn(2) кнопка вкл/выкл каналов ON/OFF
/***********************************************************************************************/
LiquidCrystal_I2C lcd(0x27, 16, 2); //I2C Address 0x27 (or 0x3F) используется для новых библиотек lcd_1602 и подобных экранов
Si5351mcu si;
const byte act_vfo_simbol[8] = {
B00010,
B00110,
B01110,
B11110,
B01110,
B00110,
B00010,
0
};// программируемый символ активного генератора
const uint32_t radix_size[8] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000}; // шаги частоты
const char* radix_lcd[8] = {" 1", " 10", " 100", " 1K", " 10K", "100K", " 1M", " 10M"};
// массив значений выводимых на экран
volatile byte radix_num = 6;// порядковый номер в таблице шагов, должен быть равен старт radix
volatile uint32_t radix = radix_size[6]; // Шаг перестройки по умолчанию при старте = 1MГц
volatile uint32_t vfo[4] = {30000000UL, 31000000UL}; //стартовая частота при запуске синтезатора.
const byte SW[3] = {ENCODER_BTN, VFO_USES_SW, CLK_CN_OFF};
volatile boolean SW_save[3];
boolean changed_f = 0; // флаг разрешения изменения частоты, 0 - запрет
boolean encA_sav = 1;
boolean encB_sav = 1;
boolean dispF_on = 1; // флаг отображения частоты
boolean dispF_on_save;
byte vfo_act0 = 0; // флаг активности канала CLK0
byte vfo_act1 = 0; // флаг активности канала CLK1
//byte swp_on = 0; // выбранный режим работы, 0,1 (1 = ГКЧ)
byte vfo_uses = 0; // выбранный канал
short incr; // направление приращения частоты, значения : -1, 1, 0
volatile uint32_t f_swp = 0;
/**************************************/
/* Установка частоты */
/* incr - направление приращения */
/* vfo_num - номер канала si5351 */
/**************************************/
void set_frequency(byte vfo_num)
{
uint32_t t_vfo;
t_vfo = vfo[vfo_num];
if (incr == 1)
t_vfo += radix;
if (incr == -1)
t_vfo -= radix;
if ((t_vfo <= F_MAX) & (t_vfo >= F_MIN))
vfo[vfo_num] = t_vfo;
}
/*********************************************/
/* обработка включения/выключения каналов Si */
/*********************************************/
void vfo_enable_sw()
{
if (get_btn(2))
{
if (vfo_uses == 0) if (vfo_act0) vfo_act0 = 0; else vfo_act0 = 1; // если CLK0 = ON то OFF
else if (vfo_uses == 1) if (vfo_act1) vfo_act1 = 0; else vfo_act1 = 1; // если CLK1 = ON то OFF
else if (vfo_uses == 2)
{
if (vfo_act0 & vfo_act1) {
vfo_act0 = 0; vfo_act1 = 0;
}
else {
vfo_act0 = 1; vfo_act1 = 1;
}
}
out_clk_en();
display_active_VFO();
}
}
/*void vfo_enable_sw()
{
if (get_btn(2))
{
// Переключаем состояние обоих каналов одновременно
if (vfo_act0 & vfo_act1) { // Если оба включены
vfo_act0 = 0;
vfo_act1 = 0;
} else { // Если хотя бы один выключен
vfo_act0 = 1;
vfo_act1 = 1;
}
out_clk_en();
display_active_VFO();
}
}*/
/**************************************/
/* Обработка кнопок */
/**************************************/
boolean get_btn(byte btn_num)
{
boolean _tmp;
_tmp = digitalRead(SW[btn_num]);
if (!_tmp & SW_save[btn_num])
{
SW_save[btn_num] = _tmp;
return 1;
}
SW_save[btn_num] = _tmp;
return 0;
}
/**************************************/
/* Обработка энкодера */
/**************************************/
void encoder()
{
boolean encA, encB;
encA = digitalRead(ENCODER_A);
encB = digitalRead(ENCODER_B);
if ((!encA && encA_sav) or (!encB && encB_sav))
{
if (encA > encB) {
incr = 1;
return;
}
else if (encA < encB) {
incr = -1;
return;
}
encA_sav = encA;
encB_sav = encB;
changed_f = 1;
return;
}
encA_sav = encA;
encB_sav = encB;
changed_f = 0;
return;
}
/************************************* ОТОБРАЖЕНИЕ ИНФОРМАЦИИ НА LCD ************************/
/*******************************************/
/* Отображение частоты текущего генератора */
/*******************************************/
void display_frequency(byte f_num)
{
uint16_t f, fs;
uint32_t x_vfo;
if (dispF_on)
{
x_vfo = vfo[f_num];
lcd.setCursor(0, f_num);
lcd.print(' ');
fs = x_vfo / 1000000; // делим частоту до мегагерц
if (fs < 10)
lcd.print(' ');
if (fs > 99)
lcd.setCursor(0, f_num);
if (fs > 0)
{ lcd.print(fs);
lcd.print('.');
}
else
{ lcd.print(' ');
lcd.print(' ');
}
f = (x_vfo % 1000000) / 1000; // остаток деления на 1 000 000, делим на 1000 до килогец
if (f < 100 and fs > 0)
lcd.print('0');
if (f < 100 and fs < 1)
lcd.print(' ');
if (f < 10)
lcd.print('0');
lcd.print(f);
lcd.print('.');
f = x_vfo % 1000; // остаток деления, сотни герц
if (f < 100)
lcd.print('0');
if (f < 10)
lcd.print('0');
lcd.print(f);
}
}
/*********************************/
/* Отображаем активный генератор */
/*********************************/
void display_active_VFO()
{
char sign1, sign2;
if (vfo_act0) sign1 = 0; else sign1 = '<';
if (vfo_act1) sign2 = 0; else sign2 = '<';
if (vfo_uses == 0)
sign2 = ' ';
else if (vfo_uses == 1)
sign1 = ' ';
lcd.setCursor(11, 0);
lcd.print(sign1);
lcd.setCursor(11, 1);
lcd.print(sign2);
}
/********************************** */
/* Отображаем шаг изменения частоты */
/************************************/
void display_radix()
{
lcd.setCursor(12, 0);
lcd.print(radix_lcd[radix_num]); // на экран значение приращения из таблицы
}
/****************************************** ON | OFF VFO ************************************/
void out_clk_en()
{
if (vfo_act0) si.enable(0); else si.disable(0); // при "истинно" вкл. выхода Si
if (vfo_act1) si.enable(1); else si.disable(1); // иначе выключить
}
/****************************************** MAIN *****************************************/
void setup()
{
lcd.init(); // Инициализация дисплея
lcd.backlight(); // Подключение подсветки
lcd.createChar(0, act_vfo_simbol); // загрузка символа 0 в LCD
lcd.clear(); // очитска экрана и памяти LCD
Wire.begin(); // запуск обмена по I2C
// Инициализация Si5351
si.init(quartz);
// если 27Mhz кварц, вводим 27000000, для 25Мгц вводим 25000000, затем:
// изм. показания контр. частотомера / на отображаемую LCD частоту * 25МГц, вводим значение.
si.setFreq(0, vfo[0]); // предустановка частоты CLK0
si.setFreq(1, vfo[1]); // тоже для CLK1
si.setPower(0, SIOUT_8mA);// ток выхода для 50 Ом
si.setPower(1, SIOUT_8mA);// возможные значения тока выхода 2,4,8МА
si.off(); // все выходы в ноль
pinMode(ENCODER_BTN, INPUT_PULLUP);
pinMode(ENCODER_A, INPUT_PULLUP);
pinMode(ENCODER_B, INPUT_PULLUP);
pinMode(VFO_USES_SW, INPUT_PULLUP);
pinMode(CLK_CN_OFF, INPUT_PULLUP);
display_frequency(0); // обновление дисплея
display_frequency(1); // обновление дисплея
display_active_VFO(); // отображение доступного для перестройки канала синтезатора
display_radix(); // шаг приращения частоты на экран
}
void loop() {
encoder(); // Обработка энкодера
if (get_btn(0)) { // Кнопка "STEP"
radix_num++;
if (radix_num > 7) radix_num = 0;
radix = radix_size[radix_num];
display_radix();
}
if (get_btn(1)) { // Кнопка выбора VFO
vfo_uses++;
if (vfo_uses > 2) vfo_uses = 0;
display_active_VFO();
}
vfo_enable_sw(); // Кнопка включения/выключения VFO
if (changed_f) {
set_frequency(vfo_uses); // Обновление частоты выбранного VFO
// **Устанавливаем частоты для CLK0 и CLK1**
si.setFreq(0, vfo[0]); // Установка частоты на Si5351 CLK0
si.setFreq(1, vfo[1]); // Установка частоты на Si5351 CLK1
display_frequency(0); // Обновление дисплея
display_frequency(1); // Обновление дисплея
changed_f = 0; // Сброс флага
}
}
/*vfo_enable_sw(); // Кнопка включения/выключения VFO
if (changed_f) {
// Обновление частоты для обоих VFO
set_frequency(0);
set_frequency(1);
// Устанавливаем частоты для CLK0 и CLK1
si.setFreq(0, vfo[0]); // Установка частоты на Si5351 CLK0
si.setFreq(1, vfo[1]); // Установка частоты на Si5351 CLK1
display_frequency(0); // Обновление дисплея
display_frequency(1); // Обновление дисплея
changed_f = 0; // Сброс флага
}*/