controller_m30 1 17 июля, 2021 Опубликовано 17 июля, 2021 · Жалоба Вариант с покупкой готового модуля для высокоточной генерации частоты. Если ТС живёт в крупном городе, то возможно стоит поискать в местном радиомагазине DDS-генератор сигнала AD9833 (скорее всего находятся в отделе для Arduino). Микросхема выдаёт такие сигналы: синус, меандр, треугольник. Диапазон выходной частоты от 0 до 12.5МГц, с шагом 0.1Гц. Или ещё более крутой вариант AD9834. Выдаёт синус и треугольник. По частоте на выходе: до 37.5МГц при тактовой 75МГц с разрешением 0.28Гц. А при тактировании 1МГц - разрешение 0.004Гц. Фотки модулей (для поиска в радиомагазине), и примерные ссылки на Али (чисто для ориентировки по ценам, и чтоб бегло посмотреть описание): AD9833, AD9834 Скрытый текст Сам пользовался AD9833 для точной генерации частоты. Программируется просто. Второй вариант только рассматривал, но не работал с ним. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 17 июля, 2021 Опубликовано 17 июля, 2021 · Жалоба 1 hour ago, jcxz said: Частота тактирования ЦАП и частота сигнала получаемого с него - никак не связаны (ну т.е. - если конечно частота получаемого сигнала много меньше частоты тактирования ЦАП). При частоте тактирования ЦАП = 46875Гц нет никаких проблем получить на выходе синусоидальный сигнал с частотой = ровно 8 кГц (ФНЧ по выходу ЦАП-а конечно никто не отменял). Не понял Вас, можете пояснить, как при частоте квантования ЦАП = 46875Гц получить ровно 8 кГц? Там же получается нецелое число точек на период. 31 minutes ago, controller_m30 said: DDS-генератор сигнала AD9833 Спасибо, интересная штука, но мне кроме синуса нужно и другие сигналы воспроизводить, нужен ЦАП Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 17 июля, 2021 Опубликовано 17 июля, 2021 · Жалоба 24 минуты назад, Dima1060 сказал: Не понял Вас, можете пояснить, как при частоте квантования ЦАП = 46875Гц получить ровно 8 кГц? Там же получается нецелое число точек на период. Примерно так: #define F_TON 8000 //[Hz] #define F_SMPL 46875 //[Hz] #define AMPLITUDE 100 //амплитуда #define divRound(a, b) (((a) + (b) / 2) / (b)) //деление a/b с округлением до ближайшего целого static u32 phase; while (...) { phase += (u32)divRound(1ull * F_TON << 32, F_SMPL); s32 j = sine(phase); //далее: масштабируем по амплитуде и выводим в ЦАП (лучше через DMA) j = __SMMULR(j, AMPLITUDE * 2); ... } Цикл генерит сэмплы синусоиды F_TON с сэмпловой частотой =F_SMPL. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
controller_m30 1 17 июля, 2021 Опубликовано 17 июля, 2021 · Жалоба 10 минут назад, Dima1060 сказал: но мне кроме синуса нужно и другие сигналы воспроизводить, нужен ЦАП Да, да. Это предложение только для генерации точной тактовой частоты в одном из модулей схемы. Например, это может быть основная частота МК (вместо кварца 8МГц используется такой генератор), или для точного регулирования частоты модуля I2S в МК (вход I2S_CKIN, как предлагали выше), или только для частоты работы самого ЦАП, если там есть такой вход. Т.е. из всех возможностей, в генераторе используется только вывод меандра, и его частота. Генератор относительно недорогой, и точный с большим запасом для данного применения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 17 июля, 2021 Опубликовано 17 июля, 2021 · Жалоба 45 минут назад, jcxz сказал: Примерно так: Цикл генерит сэмплы синусоиды F_TON с сэмпловой частотой =F_SMPL. Фазу можно точнее накапливать (например, алгоритм Брезенхема), но будет небольшой фазовый шумок. У jcxz без фазового шума, но с небольшим отклонением по частоте (где-то в 6 знаке после запятой 8000.0000016298145 Гц). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Herz 6 17 июля, 2021 Опубликовано 17 июля, 2021 · Жалоба 1 час назад, jcxz сказал: #define divRound(a, b) (((a) + (b) / 2) / (b)) //деление a/b с округлением до ближайшего целого Ух ты! Первый раз такой фокус вижу. А зачем здесь a и b в скобках? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 17 июля, 2021 Опубликовано 17 июля, 2021 · Жалоба 1 минуту назад, Herz сказал: Ух ты! Первый раз такой фокус вижу. А зачем здесь a и b в скобках? Это стандартный приём. Зачем: представьте, что в качестве аргумента b в макрос будет подставлено какое-то выражение. Например: divRound(x, 1 + 20). Тогда (если без скобок) выражение будет вычислено неверно. Поэтому: Правило хорошего тона - заключать все аргументы макроса в скобки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Herz 6 17 июля, 2021 Опубликовано 17 июля, 2021 · Жалоба Ясно, спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
blackfin 32 17 июля, 2021 Опубликовано 17 июля, 2021 · Жалоба 10 minutes ago, Herz said: Ух ты! Первый раз такой фокус вижу. А зачем здесь a и b в скобках? Фокус и правда зачетный.. )) Подставляем: a = 10, b = 1, находим: divRound(10,1) = 5. С другой стороны: a/b = 10/1 = 10.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 17 июля, 2021 Опубликовано 17 июля, 2021 · Жалоба 2 минуты назад, blackfin сказал: находим: divRound(10,1) = 5. ((10) + ((1) / 2) / 1 = (10 + 1 / 2) / 1 = (10 + 0) / 1 = 10 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 17 июля, 2021 Опубликовано 17 июля, 2021 · Жалоба 3 минуты назад, blackfin сказал: Подставляем: a = 10, b = 1, находим: divRound(10,1) = 5. Может вам стоит повторить школьный курс математики? Этак с 1-го класса.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
blackfin 32 17 июля, 2021 Опубликовано 17 июля, 2021 · Жалоба 9 minutes ago, jcxz said: Может вам стоит повторить школьный курс математики? Этак с 1-го класса.... Постоянно повторяю.. )) PS. Очень мелкий текст на мобильнике. Увидел две скобки после b. Был не прав.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 17 июля, 2021 Опубликовано 17 июля, 2021 · Жалоба 34 минуты назад, Herz сказал: Ух ты! Первый раз такой фокус вижу. А зачем здесь a и b в скобках? Есть ещё такой: #define divCeil(a, b) (((a) + (b) - 1) / (b)) //деление a/b с округлением до ближайшего большего целого Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 17 июля, 2021 Опубликовано 17 июля, 2021 · Жалоба Раз уж мы про округления, то f_ton = 8000 f_smpl = 46875 def divRound(a, b): return ((a + b // 2) // b) p1 = 0 p2 = 0 for i in range(f_smpl): p1 += divRound(f_ton << 32, f_smpl) p1 &= 0xFFFFFFFF; p2 += f_ton if p2 > f_smpl: p2 -= f_smpl p3 = (p2 << 32) // f_smpl p3 &= 0xFFFFFFFF print(i, p1, p3, p1 - p3) p3 дает нулевую фазовую ошибку через f_smpl семплов, а p1 дает ошибку 1.63E-6. warn{это Python, поэтому // - это не комментарий, а целочисленное деление} Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 17 июля, 2021 Опубликовано 17 июля, 2021 · Жалоба 26 минут назад, adnega сказал: Раз уж мы про округления, то ... Зачем так сложно? Если так уж хочется ещё точнее поддерживать частоту, то достаточно просто увеличить точность phase - сделать его 64-битным. С 64-разрядным приращением. И для sine() брать старшие 32 разряда от phase. Тогда вместо LDR\ADD\STR будет LDRD\ADD\ADC\STRD - всего на 1 команду больше. PS: Даже с 32-разрядной фазой - Вы же сами посчитали погрешность частоты. Она составит какие-то доли ppm. Ещё поискать нужно генератор, который даст сопоставимую погрешность. А если генератор имеет на порядки меньшую точность, то какой смысл считать фазу точнее? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться