Форум Радиолюбителей

si5340A

348831 просмотров, 196 ответов — стр. 8 из 14

ra0ahcra0ahc
Сообщений: 4868
9 июля 2019 г. в 08:40#106
Это уже исправленный вариант. В начале вообще приведение не делал так на 20 мгц ошибка 1 мгц была
А так нормуль. Он uint переделал в float и поделил на uint , результат float. Ну частотомером проверял - все точно .
Вы запустили?
ra0ahcra0ahc
Сообщений: 4868
9 июля 2019 г. в 08:44#107
У вас ошибка
Uint64_t нужно весь результат приводить , а не только результат деления
Это у вас ошибка из-за округления в промежуточном результате будет . Так не стоит делать . Только итоговый результат нужно по итогу обрезать . Я кстати на калькуляторе прогнал и получил тот же num что сам буилдер посчитал
Владимир_К
Сообщений: 1245
9 июля 2019 г. в 09:04#108
Uint64_t нужно весь результат приводить , а не только результат деления
Вы что скобок не заметили? Подставьте не "круглое" значение. Я вводил несколько цифр частоты. Ведь по своей сути формулы абсолютно одинаковы. Но Вы делите маленькое число "denom" на частоту, которая почти равна ему, и здесь будет погрешность. И потом эту погрешность Вы умножаете на очень большое число. Вот скрин экрана симулятора с Вашей строкой. Прикиньте на калькуляторе. Частота задана 39000000.
А вот с исправленной строкой. Сравните результат..


ra0ahcra0ahc
Сообщений: 4868
9 июля 2019 г. в 09:09#109
У вас denom за пределами приведения к uint64
Хорошо. Я проверю. Делов то на 5 минут. Только попозже. Но так для справки - изменение num на 49000 даёт изменение выхода на 1 гц всего лишь.
Владимир_К
Сообщений: 1245
9 июля 2019 г. в 09:14#110
У вас denom за пределами приведения к uint64
Не может он быть за пределами. Это не я его взял "с потолка". Это Clockbuilder выдал такое значение.
Все же такая погрешность меня смущает... Боюсь это компилятора глюки. Когда Atmel ушла от AVR Studio, сейчас ейной занимается Microsoft. Они заменили полностью компилятор, убрали поддержку Avrdude. В общем много неприятностей доставили. Конечно сейчас много новых, типа 5,6 7 версий, но там много свистопер...ок . Да и тормознутые.. А Вы в чем пишете для STM. Coocos?
ra0ahcra0ahc
Сообщений: 4868
9 июля 2019 г. в 09:17#111
Вы не поняли
Поставьте скобку не после деления а за denom)))) в вашем примере . Вы обрезали промежуточный результат а потом умножили его на denom
ra0ahcra0ahc
Сообщений: 4868
9 июля 2019 г. в 09:27#112
Я пишу в CLion платный
Владимир_К
Сообщений: 1245
9 июля 2019 г. в 09:31#113
Поставьте скобку не после деления а за denom
Поставил и получил то же значение, что и с Вашей строкой и оно ошибочное. Ну ладно, не будем толочь воду. У нас разные среды, потому спор беспочвенный. Мне важно получить правильный результат.
Владимир_К
Сообщений: 1245
9 июля 2019 г. в 09:32#114
Я пишу в CLion платный
Не, жаба давит.. . Обхожусь бесплатной.. Меня сейчас беспокоит другое.. Сколько он будет считать контроллер с этими Float. Одна строчка с Float добавила почти 5 кб программы.
ra0ahcra0ahc
Сообщений: 4868
9 июля 2019 г. в 09:53#115
В stm32 стоит сопроцессор для float. Исполнение мгновенное 18 тактов чтоли , а без fpu 800 тактов .
Ну смотрите по примеру что у вас :
Х=(Uint )(10.9)*10
И
X=(Uint)(10.9*10)
Есть разница ?
Владимир_К
Сообщений: 1245
10 июля 2019 г. в 08:35#116
Есть разница ?
Да, согласен.. Но у меня тут еще хуже ситуация. По моей формуле считает не правильно. Тут Вы правы. Цифра, которую считает компьютер - 725849473024, а должно быть 726840619323. А по Вашей формуле, выдает вообще 549755813760. Причем, число это какое-то заколдованное. Задал другую частоту - изменил на 500 кгц, а цифра эта осталась неизменной. Вот я и устроил полемику.. Вчера провозился часа три, так ничего и не добился. Примерно такая же формула (как Ваша) присутствует в расчете для Si5351A. И там мой компилятор выдает верный результат. Хрень какая-то..
ra0ahcra0ahc
Сообщений: 4868
10 июля 2019 г. в 08:48#117
Разбейте на переменные. Тогда точно ошибки не будет.
Владимир_К
Сообщений: 1245
11 июля 2019 г. в 08:25#118
У вас denom за пределами приведения к uint64
Именно так.. Я ошибочно посчитал, что в Си для AVR есть два формата чисел с плавающей запятой. Float и double. Вот тут например информация:
https://avrlab.com/node/35
Но это оказалось вовсе не так. Случайно при пошаговой отладке в окне со значениями переменных увидел, что и Double и Float в AVR Studio занимают 4 байта. Понятно, что из 4 байтов (32 бита) 44- разрядное число никак не получится. Потом еще где-то нашел, что в этом компиляторе эти форматы равноценны.
Но то уже мелочи. Покумекаю, если нормального решения не найду, перенесу программу на STM32. Валяется модуль от китайцев..
ra0ahcra0ahc
Сообщений: 4868
12 июля 2019 г. в 09:57#119
Посмотрите, есть у вас такая библиотека
#include <stdint-gcc.h>
она отвечает за размерность переменных.

А вообще нам такая точность не нужна. Там 4 знак после запятой Гц получается на единицу. Поэтому и 4 байта тоже хватит разрядности (в разумных пределах).
Если есть сомнения ставите long.... один пример не тормазнет систему.
ra0ahcra0ahc
Сообщений: 4868
12 июля 2019 г. в 11:00#120
Под синтезатор Игоря (деление на 4) . Это значит, что выходная частота на сишке будет в 4 раза ниже нормальной частоты- это в пределах 10..20 МГц на сишке
Функции выглядят так.....


void saveReg5340A(void) {//ini 5340

// char buf[20];

for (int i = 0; i < SI5340_REVD_REG_CONFIG_NUM_REGS; i++) {
if (i == 6) HAL_Delay(500);
sendByte5340(si5340_revd_registers.address,si5340_revd_registers.value);
}

//N_PIBYP - дробный режим
sendByte5340(0x0A04,0);
//Write SOFT_RST = 1 (0x001C). -ресет
sendByte5340(0x001c,1);

//выходной делитель
//The R dividers are with the output drivers and are even integer dividers.
//0x024A-0x024C R0 Divider
//24-bit Integer Number. Divide value = (R0_REG+1) x 2 !!!!!!!!!
//To set R0 = 2, set OUT0_RDIV_FORCE2 = 1, and then the R0_REG value is irrelevant.
//Setting R0_REG=0 will disable the divider.
//Write SOFT_RST = 1 (0x001C). -ресет

// 0x0108 bit-2 R/W
// OUT0_RDIV_FORC E2
// 0 R0 divider value is set by R0_REG
// 1 R0 divider value is forced into divide by 2

//при деление на 2 :
// * 0x0112[0] OUT0_PDN 0 0x0 Output driver 0: 0 to power up the driver, 1 to power down the driver. Clock outputs will be weakly pulled- low.
// * 0x0112[1] OUT0_OE 1 0x1 Output driver 0: 0 to disable the output, 1 to enable the output
// * 0x0112[2] OUT0_RDIV_FORCE2 1 0x1

// при делении на 4 и выше OUT0_RDIV_FORCE2 =0, R0_REG=1......
//по этой формуде Divide value = (R0_REG+1) x 2

//ставим делитель на 4
// * 0x0112[2] OUT0_RDIV_FORCE2=2
sendByte5340(0x0112,0);
//0x024A R0_REG=1
sendByte5340(0x024a,1);

}

void si5340aSetFrequency(uint32_t freq) {

uint64_t num;
uint32_t denom = 2147483648;
uint64_t pllFreq = 13200000000;
num = (uint64_t) ((double)denom * ((float) pllFreq / freq));

send5340(0x03, N0_NUM, num);
}

void send5340(uint8_t page, uint8_t reg, uint64_t P1) {
uint8_t x[2];
uint8_t y[7];
x[0] = 0x01;
x[1] = page;

while (HAL_I2C_Master_Transmit(&hi2c3, 0b11101000, (uint8_t *) &x, 2, 500) != HAL_OK) {
BSP_LCD_DisplayHStringAt(0, 20, "err wr 5340 page", LEFT_MODE);
};

y[0] = reg;
y[6] = (uint8_t) ((P1 & 0xFF0000000000) >> 40);
y[5] = (uint8_t) ((P1 & 0x00FF00000000) >> 32);
y[4] = (uint8_t) ((P1 & 0x0000FF000000) >> 24);
y[3] = (uint8_t) ((P1 & 0x000000FF0000) >> 16);
y[2] = (uint8_t) ((P1 & 0x00000000FF00) >> ;
y[1] = (uint8_t) (P1 & 0x0000000000FF);

while (HAL_I2C_Master_Transmit(&hi2c3, 0b11101000, (uint8_t *) &y, 7, 500) != HAL_OK) {
BSP_LCD_DisplayHStringAt(0, 20, "err wr 5340 filling", LEFT_MODE);
};
}

void sendByte5340(uint16_t add, uint8_t val){
uint8_t x[2];
uint8_t y[2];

x[0] = 0x01;
x[1] = (uint8_t)(add>>; //page

while (HAL_I2C_Master_Transmit(&hi2c3, 0b11101000, (uint8_t *) &x, 2, 500) != HAL_OK) {
BSP_LCD_DisplayHStringAt(0, 20, "err wr 5340 page", LEFT_MODE);
};

y[0] = (uint8_t)(add & 0xff); //adress
y[1] = val; // value
while (HAL_I2C_Master_Transmit(&hi2c3, 0b11101000, (uint8_t *) &y, 2, 500) != HAL_OK) {
BSP_LCD_DisplayHStringAt(0, 20, "err wr 5340 filling", LEFT_MODE);
};

}