
Только вот стоимость GPS модуля удручает!
Сообщение R9OFG » 25 янв 2021, 20:24
R9OFG
Сообщение R9OFG » 25 июн 2022, 18:14
Код: Выделить всё
/*
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);
}
}
}
Код: Выделить всё
/*
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
Сообщение R9OFG » 25 июн 2022, 18:21
R9OFG
Сообщение duss1981 » 07 фев 2023, 06:22
duss1981
Сообщение R9OFG » 07 фев 2023, 21:35
Если с I2C точно все в порядке, либо опорник сишки глючит либо в программе баг. Теоретически больше нечему там ломаться. Сама сишка либо работает, либо вообще не работает.duss1981 писал(а): ↑07 фев 2023, 06:22Добрый день, никто не сталкивался с такой проблемой. SI5351 в трансивере маламут через какое-то время, если постоянно перестраиваться, происходит срыв генерации, иногда частота постоянно и на регулирование не реагирует. Шина I2C работает. Заменил SI5351, купил в "конском" ЧИП и ДИПе, проблема остается. Очень часто приближаешься с сигналу, и вот почти в зоне фильтра и срыв.
R9OFG
Сообщение Valerii9F » 29 ноя 2023, 09:10
Valerii9F
Сообщение ru0aog » 29 ноя 2023, 11:49
ru0aog
Сообщение R9OFG » 29 ноя 2023, 15:18
R9OFG
Сообщение Valerii9F » 29 ноя 2023, 22:26
Atmel 20 U, так написано.
Вот этого я и боялся.
Valerii9F
Вернуться в «Микроконтроллеры и программирование»
Создано на основе phpBB® Forum Software © phpBB Limited