Si5351 - ад для начинающего

Аватара пользователя
R9OFG
Сообщения: 1178
Зарегистрирован: 03 ноя 2019, 22:30
Позывной: R9OFG, ex R0AEK
Город: Новосибирск
Имя: Саша
Благодарил (а): 181 раз
Поблагодарили: 274 раза
Контактная информация:

Si5351 - ад для начинающего

Сообщение R9OFG » 25 янв 2021, 20:24

Интересный материал от Карена, RA3APW, про стабилизацию выходной частоты сишки. Данный способ позволяет до сотни раз уменьшить нестабильность частоты с si5351 :shock:

Только вот стоимость GPS модуля удручает!

Аватара пользователя
R9OFG
Сообщения: 1178
Зарегистрирован: 03 ноя 2019, 22:30
Позывной: R9OFG, ex R0AEK
Город: Новосибирск
Имя: Саша
Благодарил (а): 181 раз
Поблагодарили: 274 раза
Контактная информация:

Si5351 - ад для начинающего

Сообщение R9OFG » 25 июн 2022, 18:14

Вот тут, на мой взгляд, с моими ночами за этим пауком, самый простой код управления этой сишкой, взято из моего wspr маяка, по комментариям к коду легко понять как сишкой управлять в целом. Как бы минимализм модернизированного кода от Ханса ;)

Файл С
Spoiler

Код: Выделить всё

/*
Author: Hans Summers, 2015
Website: http://www.hanssummers.com

A very very simple Si5351a demonstration
using the Si5351a module kit http://www.hanssummers.com/synth
Please also refer to SiLabs AN619 which describes all the registers to use

Mod: R0AEK, 2021
Ver - 1.05
*/

#include <inttypes.h>
#include "Main.h"
#include "i2c.h"
#include "si5351a.h"

/*объявление констант и переменных---------------------------------------*/
uint32_t XTAL_FREQ	= 0;		//частота используемого кварцевого резонатора (по умолчанию 25.000 МГц)
uint32_t FREQ_PLLA	= 0;		//частота ФАПЧ-А (600/900 Мгц) (была 900 МГц, но работает нестабильно, "дрожание" !!!)

//uint32_t pllFreq;
//uint32_t xtalFreq;
//uint32_t l;
//float f;
//uint8_t mult;
//uint32_t num;
//uint32_t denom;
//uint32_t divider;

extern uint8_t BandPrev;		//указатель на индекс предыдущего иапазона
extern uint8_t BandCount;		//указатель на индекс текущего иапазона
extern uint8_t flagConnectToPC;	//указатель на флаг подключения к конфигуратору
extern uint8_t Uses6mBand;		//указатель на флаг использования диапазона 6m
extern uint8_t Uses2mBand;		//указатель на флаг использования диапазона 2m
extern uint32_t StartFreq;		//указатель на стартовую частоту для si5351 (1 МГц)
/*END объявление констант и переменных-----------------------------------*/

/*
настройки из спецификации для PLL с mult, num и denom
mult в диапазоне 15..90
num в диапазоне 0..1,048,575 (0xFFFFF)
denom в диапазоне 0..1,048,575 (0xFFFFF)
*/
void setupPLL(uint8_t pll, uint8_t mult, uint32_t num, uint32_t denom)
{
	uint32_t P1;					// PLL конфигурационный регистр P1
	uint32_t P2;					// PLL конфигурационный регистр P2
	uint32_t P3;					// PLL конфигурационный регистр P3

	P1 = (uint32_t)(128 * ((float)num / (float)denom));
	P1 = (uint32_t)(128 * (uint32_t)(mult) + P1 - 512);
	P2 = (uint32_t)(128 * ((float)num / (float)denom));
	P2 = (uint32_t)(128 * num - denom * P2);
	P3 = denom;

	i2cSendRegister(pll + 0, (P3 & 0x0000FF00) >> 8);
	i2cSendRegister(pll + 1, (P3 & 0x000000FF));
	i2cSendRegister(pll + 2, (P1 & 0x00030000) >> 16);
	i2cSendRegister(pll + 3, (P1 & 0x0000FF00) >> 8);
	i2cSendRegister(pll + 4, (P1 & 0x000000FF));
	i2cSendRegister(pll + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
	i2cSendRegister(pll + 6, (P2 & 0x0000FF00) >> 8);
	i2cSendRegister(pll + 7, (P2 & 0x000000FF));
}

/*
установка MultiSynth с целочисленным делителем и R-делителем 
R-делитель - это битовое значение, которое помещается в соответствующий регистр, см. #define в si5351a.h
*/
void setupMultisynth(uint8_t synth, uint32_t divider, uint8_t rDiv)
{
	uint32_t P1;
	uint32_t P2;
	uint32_t P3;

	P1 = 128 * divider - 512;
	P2 = 0;							// P2 = 0, P3 = 1 форсирует целочисленное значение для делителя
	P3 = 1;

	i2cSendRegister(synth + 0,   (P3 & 0x0000FF00) >> 8);
	i2cSendRegister(synth + 1,   (P3 & 0x000000FF));
	i2cSendRegister(synth + 2,   ((P1 & 0x00030000) >> 16) | rDiv);
	i2cSendRegister(synth + 3,   (P1 & 0x0000FF00) >> 8);
	i2cSendRegister(synth + 4,   (P1 & 0x000000FF));
	i2cSendRegister(synth + 5,   ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
	i2cSendRegister(synth + 6,   (P2 & 0x0000FF00) >> 8);
	i2cSendRegister(synth + 7,   (P2 & 0x000000FF));
}

/*
в AN619 описаны значения битов - 0x80 отключает выбранный выходной каскад
Регистр 16/17/18 бит 7 в единицу для CLK0/1/2 соответственно
*/
// void si5351aOutputOff(uint8_t clk)
// {
// 	i2cSendRegister(clk, 0x80);
// }

/*
Выбираем, включаем CLK0 и устанавливаем заданную частоту на выходе
Возможный выбор частоты в диапазоне от 1MHz до 150MHz
Пример: si5351aSetFrequency(10000000);
установит на выходе CLK0 сигнал с частотой 10MHz

Ниже настраивается PLLA
и MultiSynth 0
и включает вывод на CLK0/1/2 в зависимости от выбранного диапазона
*/
void si5351aSetFrequency(uint32_t frequency)
{
 	uint32_t pllFreq;
 	uint32_t xtalFreq = XTAL_FREQ;
 	uint32_t l;
 	float f;
 	uint8_t mult;
 	uint32_t num;
 	uint32_t denom;
 	uint32_t divider;

 	//расчет коэффициента деления. 900,000,000 Hz - максимальная частота для PLLA
 	divider = FREQ_PLLA / frequency;
 	
 	//целочисленное деление
 	if (divider % 2) divider--;
 
 	//расчет частоты pllFreq: делитель * желаемую выходную частоту
 	pllFreq = divider * frequency;
 
 	//расчет множителя для получения заданной pllFreq
 	//состоит из трех частей:
 	//1: mult - целое число, которое должно быть в диапазоне 15..90
 	//2: num и denom - дробные части, числитель и знаменатель каждый из них 20 bits (диапазон 0..1048575)
 	//3: фактический множитель mult + num / denom
 	//для простоты мы установили знаменатель на максимум 1048575
 	mult = pllFreq / xtalFreq;
 	l = pllFreq % xtalFreq;
 	f = l;
 	f *= 1048575;
 	f /= xtalFreq;
 	num = f;
 	denom = 1048575;

	/*настройка PLLA с рассчитанным коэффициентом умножения*/
	setupPLL(SI_SYNTH_PLL_A, mult, num, denom);
	
	/*выключаем все выходы в режиме конфигуратора, далее включим необходимый выход в зависимости от диапазона*/
	if (flagConnectToPC == 1)
	{
		i2cSendRegister(SI_CLK0_CONTROL, 0x80);
		i2cSendRegister(SI_CLK1_CONTROL, 0x80);
		i2cSendRegister(SI_CLK2_CONTROL, 0x80);
	}
	
	/*установка делителя MultiSynth 0 с рассчитанным делителем
	последний этап деления R может делиться на степень 2, начиная с 1..128.
	представлен константами SI_R_DIV1....SI_R_DIV128 (см. заголовочный файл si5351a.h)
	если вы хотите вывести частоты ниже 1 МГц, вы должны использовать SI_R_DIV128*/
	
	
	/*ставим стартовую частоту на выходы в режиме ожидания*/
	if (frequency == StartFreq)
	{
		/*выход CLK0*/
		setupMultisynth(SI_SYNTH_MS_0, divider, SI_R_DIV_1);
		/*включение выхода CLK0 (биты 0x4F)
		и установка для входа MultiSynth 0 и значения PLLA*/
		i2cSendRegister(SI_CLK0_CONTROL, 0x4F | SI_CLK_SRC_PLL_A);
			
		if (Uses6mBand == '1')
		{
			/*выход CLK1*/
			setupMultisynth(SI_SYNTH_MS_1, divider, SI_R_DIV_1);
			/*включение выхода CLK1 (биты 0x4F)
			и установка для входа MultiSynth 0 и значения PLLA*/
			i2cSendRegister(SI_CLK1_CONTROL, 0x4F | SI_CLK_SRC_PLL_A);
		}
			
		if (Uses2mBand == '1')
		{
			/*выход CLK2*/
			setupMultisynth(SI_SYNTH_MS_2, divider, SI_R_DIV_1);
			/*включение выхода CLK2 (биты 0x4F)
			и установка для входа MultiSynth 0 и значения PLLA*/
			i2cSendRegister(SI_CLK2_CONTROL, 0x4F | SI_CLK_SRC_PLL_A);
		}
	}
	else
	{
		/*распределяем по выходам в зависимости от текущего диапазона*/
		/*HF*/
		if ((BandCount >= 1)&&(BandCount <= 10))
		{
			/*если КВ используем выход CLK0*/
			setupMultisynth(SI_SYNTH_MS_0, divider, SI_R_DIV_1);
			
			/*сброс PLL - вызывает щелчки при перестройке, для незначительных изменений частоты
			НЕ ИСПОЛЬЗУЕМ сброс PLL, тогда щелчков не будет*/
			/*если текущий диапазон не равен последнему в режиме конфигуратора, сбрасываем PLL*/
			if (flagConnectToPC == 1)
			{
				if (BandPrev != BandCount)
				{
					i2cSendRegister(SI_PLL_RESET, 0xA0);
				}
			}
			
			/*включение выхода CLK0 (0x4F)
			и установка для входа MultiSynth 0 и значения PLLA*/
			i2cSendRegister(SI_CLK0_CONTROL, 0x4F | SI_CLK_SRC_PLL_A);
		}
	
		/*6m*/
		if (BandCount == 11)
		{
			/*если 6m используем выход CLK1*/
			setupMultisynth(SI_SYNTH_MS_1, divider, SI_R_DIV_1);
			
			/*сброс PLL - вызывает щелчки при перестройке, для незначительных изменений частоты
			НЕ ИСПОЛЬЗУЕМ сброс PLL и тогда щелчков не будет*/
			/*если текущий диапазон не равен последнему в режиме конфигуратора, сбрасываем PLL*/
			if (flagConnectToPC == 1)
			{
				if (BandPrev != BandCount)
				{
					i2cSendRegister(SI_PLL_RESET, 0xA0);
				}
			}
			
			/*включение выхода CLK1 (0x4F)
			и установка для входа MultiSynth 0 и значения PLLA*/
			i2cSendRegister(SI_CLK1_CONTROL, 0x4F | SI_CLK_SRC_PLL_A);
		}
	
		/*2m*/
		if (BandCount == 12)
		{
			/*если 2m используем выход CLK2*/
			setupMultisynth(SI_SYNTH_MS_2, divider, SI_R_DIV_1);
			
			/*сброс PLL - вызывает щелчки при перестройке, для незначительных изменений частоты
			НЕ ИСПОЛЬЗУЕМ сброс PLL и тогда щелчков не будет*/
			/*если текущий диапазон не равен последнему в режиме конфигуратора, сбрасываем PLL*/
			if (flagConnectToPC == 1)
			{
				if (BandPrev != BandCount)
				{
					i2cSendRegister(SI_PLL_RESET, 0xA0);
				}
			}
			
			/*включение выхода CLK2 (0x4F)
			и установка для входа MultiSynth 0 и значения PLLA*/
			i2cSendRegister(SI_CLK2_CONTROL, 0x4F | SI_CLK_SRC_PLL_A);
		}
	}
	
	
}
Файл H
Spoiler

Код: Выделить всё

/*
Author: Hans Summers, 2015
Website: http://www.hanssummers.com

A very very simple Si5351a demonstration
using the Si5351a module kit http://www.hanssummers.com/synth
Please also refer to SiLabs AN619 which describes all the registers to use

Mod: R0AEK, 2021
Ver - 1.05
*/

#ifndef SI5351A_H
#define SI5351A_H

#include <inttypes.h>

/*установки значений регистров*/
#define SI_CLK0_CONTROL		16
#define SI_CLK1_CONTROL		17
#define SI_CLK2_CONTROL		18
#define SI_SYNTH_PLL_A		26
//#define SI_SYNTH_PLL_B		34
#define SI_SYNTH_MS_0		42
#define SI_SYNTH_MS_1		50
#define SI_SYNTH_MS_2		58
#define SI_PLL_RESET		177

/*установки R делителя*/
#define SI_R_DIV_1			0x00
//#define SI_R_DIV_2			0x10
//#define SI_R_DIV_4			0x20
//#define SI_R_DIV_8			0x30
//#define SI_R_DIV_16			0x40
//#define SI_R_DIV_32			0x50
//#define SI_R_DIV_64			0x60
//#define SI_R_DIV_128			0x70

#define SI_CLK_SRC_PLL_A	0x00
//#define SI_CLK_SRC_PLL_B	0x20

//void si5351aOutputOff(uint8_t clk);
void si5351aSetFrequency(uint32_t frequency);

#endif /* SI5351A_H */


Аватара пользователя
R9OFG
Сообщения: 1178
Зарегистрирован: 03 ноя 2019, 22:30
Позывной: R9OFG, ex R0AEK
Город: Новосибирск
Имя: Саша
Благодарил (а): 181 раз
Поблагодарили: 274 раза
Контактная информация:

Si5351 - ад для начинающего

Сообщение R9OFG » 25 июн 2022, 18:21

Если использовать код выше, можно освободить тонну места в памяти МК, отказавшись от использования известных и доступных библиотек для сишки

duss1981
Сообщения: 54
Зарегистрирован: 19 апр 2022, 07:42
Город: екатеринбург
Имя: Денис
Благодарил (а): 4 раза

Si5351 - ад для начинающего

Сообщение duss1981 » 07 фев 2023, 06:22

Добрый день, никто не сталкивался с такой проблемой. SI5351 в трансивере маламут через какое-то время, если постоянно перестраиваться, происходит срыв генерации, иногда частота постоянно и на регулирование не реагирует. Шина I2C работает. Заменил SI5351, купил в "конском" ЧИП и ДИПе, проблема остается. Очень часто приближаешься с сигналу, и вот почти в зоне фильтра и срыв.

Аватара пользователя
R9OFG
Сообщения: 1178
Зарегистрирован: 03 ноя 2019, 22:30
Позывной: R9OFG, ex R0AEK
Город: Новосибирск
Имя: Саша
Благодарил (а): 181 раз
Поблагодарили: 274 раза
Контактная информация:

Si5351 - ад для начинающего

Сообщение R9OFG » 07 фев 2023, 21:35

duss1981 писал(а):
07 фев 2023, 06:22
Добрый день, никто не сталкивался с такой проблемой. SI5351 в трансивере маламут через какое-то время, если постоянно перестраиваться, происходит срыв генерации, иногда частота постоянно и на регулирование не реагирует. Шина I2C работает. Заменил SI5351, купил в "конском" ЧИП и ДИПе, проблема остается. Очень часто приближаешься с сигналу, и вот почти в зоне фильтра и срыв.
Если с I2C точно все в порядке, либо опорник сишки глючит либо в программе баг. Теоретически больше нечему там ломаться. Сама сишка либо работает, либо вообще не работает.

Если программный баг то по ходу с частотой I2C шины не порядок, т.е. не полностью регистры в сишку передаются либо с ошибками которые сишка уже не воспринимает.

Valerii9F
Сообщения: 5
Зарегистрирован: 29 ноя 2023, 07:37
Город: Пермь
Имя: Валерий
Благодарил (а): 8 раз
Поблагодарили: 1 раз

Si5351 - ад для начинающего

Сообщение Valerii9F » 29 ноя 2023, 09:10

Привет други! Похоже на ад, точно..
Прикупил уже второй синтез (готовую плату), через год после первого, "неисправность" выявилась в обоих платах одинаковая ((
Суть в том, что с ростом частоты растёт её погрешность, на 15 МГц- 600 Гц, на 30-ти уже 1,2 кГц.
Screenshot_2023-11-29-10-58-07-914_com.miui.gallery.jpg
Сейчас мне нужна точность получше, хотя бы менее +- 50 Гц в диапазоне до 30 МГц.
Полез в меню, пункт "калибровка", вроде всё ясно..
Screenshot_2023-11-29-11-00-44-772_com.miui.gallery.jpg
Прикол в том, что когда калибрую кварц "в ноль", сигнал на выходе сишки начинает "срываться" и становится "грязным"
Screenshot_2023-11-29-11-04-41-324_com.miui.gallery.jpg
И так на обоих платах ((
Как понял, дело не в Сишке, а в программе?

Аватара пользователя
ru0aog
Сообщения: 942
Зарегистрирован: 30 сен 2021, 05:50
Позывной: ru0aog
Город: Красноярск
Имя: Станислав
Благодарил (а): 125 раз
Поблагодарили: 138 раз

Si5351 - ад для начинающего

Сообщение ru0aog » 29 ноя 2023, 11:49

Что за контроллер?
Есть "сокращённые" библиотеки для АТТини, которые теряют точность с повышением частоты.
Это связано с удалением математики с плавающей точкой из скетча.
Программа занимает меньше места и помещается в тини.

Аватара пользователя
R9OFG
Сообщения: 1178
Зарегистрирован: 03 ноя 2019, 22:30
Позывной: R9OFG, ex R0AEK
Город: Новосибирск
Имя: Саша
Благодарил (а): 181 раз
Поблагодарили: 274 раза
Контактная информация:

Si5351 - ад для начинающего

Сообщение R9OFG » 29 ноя 2023, 15:18

Valerii9F, 100% проблема в коде, в калькуляции выходной частоты участвует число частоты опорного кварца, чем точнее указано это число к реальной частоте кварца, тем точнее частота на выходе.

Valerii9F
Сообщения: 5
Зарегистрирован: 29 ноя 2023, 07:37
Город: Пермь
Имя: Валерий
Благодарил (а): 8 раз
Поблагодарили: 1 раз

Si5351 - ад для начинающего

Сообщение Valerii9F » 29 ноя 2023, 22:26

ru0aog писал(а):
29 ноя 2023, 11:49
Что за контроллер?
Atmel 20 U, так написано.
R9OFG писал(а):
29 ноя 2023, 15:18
100% проблема в коде
Вот этого я и боялся.
В программах вообще не разбираюсь.. Но тут уже упёрся, начну осваивать.
Синтез мне нужен для диапазона 10 метров, ПЧ 9 МГц, сегодня спокойно посидел, решил-погрешность суммирую со значением ПЧ, разница в начале- конце диапазона получится герц около 80-ти от реальной частоты.
Лучше чем ничего ))

Аватара пользователя
R9OFG
Сообщения: 1178
Зарегистрирован: 03 ноя 2019, 22:30
Позывной: R9OFG, ex R0AEK
Город: Новосибирск
Имя: Саша
Благодарил (а): 181 раз
Поблагодарили: 274 раза
Контактная информация:

Si5351 - ад для начинающего

Сообщение R9OFG » 30 ноя 2023, 08:32

Valerii9F писал(а):
29 ноя 2023, 22:26
решил-погрешность суммирую со значением ПЧ, разница в начале- конце диапазона получится герц около 80-ти от реальной частоты.
Многовато, что за библиотека для сишки?

Ответить

Вернуться в «Микроконтроллеры и программирование»