kloker, кстати намедни на радиокоте выложили проект генератора на F303, видели? Он конечно в разных весовых категориях с моим. По всем возможностям обходит мой, его смело можно отнести в категорию "измерительный прибор" ибо и аппаратно и программно соответствует, таких широких возможностей у самоделок я вообще никогда раньше не видел (!). Автор основательно поработал. Но в отличии от моей поделки в сборке сложен, - требует изготовления печатных плат, подетальной пайки, в общем только для опытных радиолюбителей. Пробежавшись по характеристикам всё таки нашёл узкое место- частота дискретизации в режиме DDS всего 1.4МГц . (У моего 4,5 МГц при F_CPU= 72MHz && выводе в встроенный цап ). А ещё немаловажно, что обещает автор - проект будет развиваться.
Так я выше сказал - замените на "Hz". Так будет правильнее.
заменил. обновил библиотеки в выложенном комплекте, поправил сдвиги. все работает. спасибо автору за полезный девайс.
а si5351 только меандр умеет выдавать? хотя конечно и цап неплохую форму выдает на довольно приличных частотах, но не на мегагерцах конечно. резисторы в делитель брал smd с допуском 1%.
с другой стороны, на десятках мегагерц у меня осциллографу становится наплевать на форму, все стремится к синусу. :) да и уровень невысок.
venus, ещё adg704 давит фронты. У него заявлена пропускная способность что-то вроде до 200 МГц, но под этой цифрой подразумевается синус :) Если я когда нибудь буду переносить в другой корпус, то коммутацию сделаю на релюшках, как Mag-N. Может даже шикану, и куплю мелкие вч-релюшки.
PS про Herz я как-то и незадумывался, с буквой t оно даже симметричнее смотрится, надо тоже исправить :)
по поводу реле - я тоже у себя использовал, в посте 81 писал. хз насколько высокочастотные, но мелкие, с 3.3в питанием и 30ма потреблением, по адекватной цене на али - G6K-2F-Y
да, если разводить - не стоит забывать что они имеют полярность.
В данной конструкции можно любые малогабаритные реле использовать. Это ведь не реле обхода антенного усилителя или РА, где ВЧ напряжение 100-200 В и более.
мне тоже палитра больше от red понравилась, так что в я него просто сдвиги из green добавил в ините.
загрузчик брал последний в теме. он, помнится, boot1 джампер использует вместо ресета, так что можно постоянно плату держать под прошивку. вот только у меня почему-то устройство usb только serial с pid=0004 появляется, а под прошивку pid=0003 упорно отсутствует, в том числе после добавления резистора с A12 на 3.3. и разъем microusb был дрянной родной, пропайка не помогла, поменял, но на usb-устройства само собой не повлияло. так что мне проще stlink'ом пользоваться. хотя в принципе неважно, девайс уже в корпус закинул, выбросив потроха из ростелекомовской iptv-приставки. брендовый девайс получился. :)
вольтметр зацеплен на аккум и немного подвирает, на 2%, на входе резистор больший воткнул без подбора. наверное, стоит коррекцию прямо в коде поставить.
не хватает разве что сохранения параметров и текущего режима. ну и регулируемого выходного напряжения.
Заметил одну особенность : очищаем память контроллера, заливаем загрузчик. Далее прошиваем хоть Блинк, хоть Графиктест или что-то подобное и так раз 20 подряд - всё прошивается без лишних телодвижений. Но стоит прошить любую версию данного генератора, и для следующей прошивки надо давить РЕСЕТ. Если затем опять загрузить что-то другое (через РЕСЕТ), то автоматическая загрузка восстанавливается. Загружаем генератор - и опять те же Я... Положение джампера BOOT1 никак не влияет.
MAG-N, я вроде писал про это. В скетче отключается всё лишнее, в том числе прерывания USB, без них не работает USBCDC, который образует ком-порт, без него IDE не может инициировать загрузку бутлоадера.
Собирал я этот формирователь (по номиналам деталей похож на тот, что с Радиосканнера)- и сейчас он работает, но у него нижний предел частоты был порядка нескольких сотен герц. Добился нижнего предела 1 Гц, для чего параллельно С2 поставил керамику 10 мкФ, а параллельно С7 и С10 - электролиты по 100 мкФ. При этом верхний предел упал где-то со 100 до 80 МГц. Мне нижний предел важнее был. А чувствительность - это питания полевику маловато, не зря в "Фрегате" он от 12В питается. В даташите на транзистор явно указано "VHF and UHF applications with 12 V supply voltage"
Dimax, тебе уже задавали этот вопрос на другой ветке, но позволю себе повториться: как программно, аппаратно или комплексно промодулировать сигнал Si5351? Предлагалось изменять биты управления, но как это практически сделать видимо так никто и не понял, а мне тем более не разобраться. Думаю, что одной частоты модуляции в 1000Гц всех устроило бы.
как программно, аппаратно или комплексно промодулировать сигнал Si5351? Предлагалось изменять биты управления
Он для этого не предназначен. У AD985x есть токовый выход, там нетрудно сделать внешнюю амплитудную модуляцию. Так же там можно сделать частотную модуляцию -при подключении в 8бит параллельном режиме можно с высокой скоростью задавать частоту. Всего этого у Si нет.
У Si5351 есть нога VddOut - питание выходного буфера, оно хоть в даташите конкретными значениями обозначено (Output VDDO: 1.8, 2.5, or 3.3 V), но может и как вход для АМ заработает? Тут пробовать надо. Вот только кому эта АМ нужна, разве что самолеты с землей работают. Как это ни странно, но до сих пор обмен на взлете-посадке идет в режиме АМ, хоть Боинг, хоть Кукурузник.
alex410, в 3.x это сложнее сделать, т.к. все готовые формы рассчитываются математически. Но суть будет такая же - создать массив на 512 байт, поместить его в флэш my_mass[] __FLASH__ ={ тут форма на 512 байт}; а в функции, где идёт расчёт и заливка массива в памяти вместо расчёта скопировать данные из своего массива в основной.
Всем привет. Собрал на печатке и вот какая засада. Заработал, почти сразу, только ресет как подпаял, забыл сразу. Через некоторое время вставляя холдер с аккумом, пока без тумблера, и не запускается. Экран сначала желтый потом срабатывает заливка черным и все, нет ничего более, генерации тоже нет. Аккумом 18650 питаю через Step Up, дает 4.99 с питанием норм. Не пойму на чем может тормозится программа. Кроме Блупилл, экрана и энкодера ни чего нет. Я так понял в коде ни чего не надо менять под такой конфиг?
Исправил, удалил вот эти строки и заработало:
//si5351_found = si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);//если нашёлся si5351 поднимается флажок
//if (si5351_found == 1) { si5351.set_freq(16E6*SI5351_FREQ_MULT, SI5351_CLK1);// фиксированная частота с выхода 1
//si5351.set_freq(20E6*SI5351_FREQ_MULT, SI5351_CLK2); }//фиксированная частота с выхода 2
Еще, может кому пригодится. У меня было смещение изображение небольшое, скомпенсировал в файле Adafruit_ST77xx.cpp
x += _xstart+1; // добавил один пиксель по x
y += _ystart+2; // добавил два по y
Venus, ты как-то выкладывал свою прошивку с правкой цвета фронта импульса на экране и возможностью установки независимых частот на выходах Siшки. Я не ее скачал, а модератор почистил переписку. Скинь пожалуйста ее еще раз. Надеюсь не удалят полезные изменения и плюшки, глядишь и пригодятся кому нибудь
прошивка - обычная 3.5 с минимальной косметикой. ну и под делитель мой откалибрована, дабы правильно напряжение аккума показывать. которая с "144greentab" в названии - не под мой дисплей, а чей-то еще.
Доброе время суток. Захотелось собрать это устройство, уже начал рисовать печатку. Решил проверить на макетке, залил 3,5 версию через СТ-линк, заработало, но, вывод изображения получилось перевернутым, тоисть контакты справа, а здесь смотрю у всех слева. Хорошо что не спешил делать плату.
dimax Я не об этом ... В описании Si5351 написано что есть NVM память, из которой берутся настройки в момент старта Si5351. Я так понял что можно рассчитать данные для всех выходов, записать их в эту память и потом при старте нужные частоты будут на выходах без участия МК. Но вот как записать данные в эту память не увидел.
The Si5351 is a highly flexible clock generator which is entirely configurable through its I2C interface. The device’s default configuration is stored in non-volatile memory (NVM) as shown in Figure 11. The NVM is a one time programmable memory (OTP) which can store a custom user configuration at power-up. This is a useful feature for applications that need a clock present at power-up (e.g., for providing a clock to a processor).
Я так понял что можно рассчитать данные для всех выходов, записать их в эту память и потом при старте нужные частоты будут на выходах без участия МК.
вот это интересно, тоже хочу такое :) Почитаю.
PS: Разобрался.
How can I burn the NVM on a blank Si5351 part?•Silicon Labs does not currently support customer NVM burning for this product family. •However, you can easily create a new custom part with a newly defined default startup state using ClockBuilder Pro. Once the part is submitted at the end of the process,you will be able to contact your local distributor to order the new part number.
По-простому: эта модель не поддерживает сохранение пользователем конфигурации, но вы можете заказать у вашего продавца чип с уже записанной вашей конфигурацией. В общем отбой.
-"Адаптивное" тактирование МК от si5351, за счёт чего:
- регулировка частоты в PWM режиме стала линейной вплоть до конца диапазона. (условное ограничение на 1МГц, выше будет уменьшаться число градаций duty).
-DDS режим теперь иначе сделан - не использует весь вычислительный ресурс МК, а работает "в фоне" через DMA.
-добавлена возможность измерять среднеквадратичное напряжение в режиме генерации синуса. Это удобно, если
-Сохранение настроек частоты, режима и шага при отключении питания (при наличии подключенной батарейки)
-режим "Meandr DDS" ввиду бесполезности заменил на режим "Noise DDS" (генератор шума)
-больше нет поддержки МК F103 с встроенным ЦАП
-больше нет поддержки фиксированных тактовых частот МК 72 /128 МГц -МК автоматически задаст себе нужную тактовую частоту в зависимости от требуемой
выходной, примерный диапазон перестройки тактовой не более 2МГц (98..100МГц, т.е. МК работает с небольшим разгоном.)
Новые тех. характеристики генераторов:
Управление тактовым генератором Si5351, "меандр":
Диапазон частот: 4кГц - 225 МГц
Шаг перестройки частоты: 1Гц ... 10МГц
Генерация PWM/DDS :
Диапазон частот : 0,1 Гц – 1 МГц;
Шаг перестройки частоты: 0,1Гц ... 100 кГц
Частота дискретизации DDS: переменная, до 7,7 МГц при 100 МГц тактовой.
Кол-во градаций регулировки заполнения PWM: 99 (от1 до 99%)
Изменения и советы по аппаратной части:
- Схема от предыдущих версий отличается очень незначительно, всё тот же bluepill на stm32f103c8t6 как основа,
но подойдут только версии с 128к флэша. (Узнать можно программатором) Либо взять МК stm32f103cbt6, в котором 128к обязано быть. si5351 теперь обязательный компонент проекта, т.к. он тактирует МК. Необходимо отпаять на плате микроконтроллера кварц и конденсатор от ноги PD0, а на PD0 подать тактовый сигнал с вывода CLK0 si5351, очень желательно подвести и отдельную землю от выхода si5351. От этого соединения сильно зависит стабильность работы, поэтому надо сделать максимально качественно.
-программа использует бэкап-регистры, для корректной работы должна быть подключена батарейка, при отсутствии её подать на вывод Vbat напряжение 3,3. вольта.
-Не желательно питать от дешевого импульсного источника (в режимах DDS возможны помехи)
-Улучшена защита от дребезга кнопки энкодера (изменено подключение RC-цепочки).
-Применение мультиплексора как и ранее опционально, коммутация высокочастотного сигнала от si5351 через мультиплексор не желательна. Либо подключаться напрямую к разъёму на плате si5351, либо использовать реле (вариант от MAG-N в сообщении #57)
-для корректного измерения не-TTL высокочастотных сигналов в режиме "частотометр" желательно использовать специальный усилитель-формирователь в TTL, и подавать сигнал не коммутируя его прямо на пин А15 платы. Можно сделать простой пассивный формирователь TTL из конденсатора и 2х резисторов , который формирует смещение примерно 1,7 вольта для чёткого соответствия TTL уровням. В этом случае входной амплитуды Vamp=1вольт должно быть достаточно для работы частотометра. Для меньших входных напряжений у измеряемой высокой частоты необходим вч-усилитель.
Информация по программе:
Аддон (от Роджера Кларка) немного модифицировал, добавив новый профиль для платы,
что бы начальную конфигурацию программа прошла тактируюясь от встроенного в мк генератора (64МГц с учётом множителя на 16) , а не от кварца. После стандартной инициализации запускается генератор si5351, с частотой 25МГц с выхода CLK0, который идёт на вход OSC_IN (PD0) микроконтроллера. Далее в программе перенастраивается тактирование на внешний вход и включается умножение x4. В режимах PWM и DDS тактовая частота МК подстраивается под необходимую выходную частоту.
Так же сделаны мелкие модификации библиотек: ( SPI -что б дружила с самой последней версией графического драйвера от адафрута.
si5351 -что б не глючил при переходе через частоту 170MHz )
Ввиду этого разумнее будет либо заливать готовый BIN программатором, если менять под себя ничего не нужно. Либо скачать мой заархивированный ArduinoIDE со всеми необходимыми библиотеками и модификациями и уже из него компилировать. Скетч генератора уже есть в архиве, отдельно вставлять не надо (Файл-> Примеры -> 12.Generator_v3_6)
-Объём скомпилированной прошивки уже перевалил за 80к, так что в меню МК надо выбирать stm32f103cb у которого размер флеша 128к. (скриншот выбора платы в меню выше)
-не проверялась возможность загрузки через бутлоадер, я грузил через STLINK
Схема:
Скетч:
/* Генератор с регулируемой частотой v3.6 (C)Dimax */
#define pwm2_polar 0 //полярность выхода PWM2 (вывод PA7)
#define paper 0x000000 // цвет фона экрана
//для пересчёта множителя необходимо: частоту на экране прибора * текущий множитель и разделить на фактически измеренную частоту
#define VrefINT 1209 //внутренее опорное напряжение в милливольтах
#define Mn 6.06 //множитель для пересчёта напряжения с учётом резисторного делителя.
#define SHOWVRMS 1 //измерять ли напряжение в режиме генерации синусоиды: 0-нет 1-да
#define DDSFREQMAX 5000000 //максимальная частота DDS *10
#define PWMFREQMAX 10000000 //максимальная частота PWM *10
#define FREQDEFAULT 10000 // частота по-умолчанию * 10
#define freq_save() bkp_write(1, freq & 0xffff); bkp_write(2, freq >> 16);//сохранение переменной с текущей частотой
#define freq_restore() freq = bkp_read(1) | (bkp_read(2) << 16);//восстановление частоты
#define freq_si5351_save() bkp_write(4, freq & 0xffff); bkp_write(5, freq >> 16);//сохранение переменной с текущей частотой
#define freq_si5351_restore() freq = (bkp_read(4) | (bkp_read(5) << 16));//восстановление частоты si5351
#define mode_save() bkp_write(3, ( (mode&0xff) | (encstep<<8)) ); //сохранение № режима и шага
#define mode_restore() mode = bkp_read(3)&0xff; encstep =bkp_read(3)>>8;//восстановление режима и шага
#include "Adafruit_GFX.h"
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <libmaple/usart.h>
#include <SPI.h> //https://github.com/etherkit/Si5351Arduino/issues/65
#include "si5351.h"
#include <Wire.h>
#include <libmaple/bkp.h>
Adafruit_ST7735 tft = Adafruit_ST7735(-1, PB11,PB10); //PB12 освобождён, вывод CS дисплея запаять на землю.
Si5351 si5351;
boolean modevolt, infreqpsc;
volatile int enc_tic=0, duty=50, mon_flag=255, modebit=1;
volatile int16_t mode;// 0- GEN_si5351, 1-PWM, 2-Duty, 3-impuls , 4..8 DDS, 9-Freqmeter, 10-VoltMeter
volatile uint8_t encstep=1; //шаг изменения частоты 0 - 0,1 Гц 1 -1Гц 2-10Гц 3-100Гц 4-1000Гц 5-10 000Гц 6- 100 000Гц.... 7 -1Mhz 8-10МГц
volatile byte imp_mode=1; //единицы счёта длины импульса по умолчанию 0-мс, 1-мкс, 2 -такт
volatile byte imp_mode_menu=0; //переменная выбора меню в одновибраторе (значение длины/единица времени/шаг)
volatile uint32_t freq; //частота по умолчанию (желаемая *10)
volatile uint64_t fcpu=1000000000; // фактическая частота МК (*10), пересчитывается в программе автоматически
float t_hi, t_low; //переменные счёта длины импульсов
uint32_t Vcc; //переменная внутреннего измерения напряжения питания МК (милливольты)
int Vin_low=0, Vin_hi=15000; //переменные пределов для вольтмера (милливольты)
uint8_t wave[512]; //массив для таблицы DDS синтеза
uint8_t sine_logo[] __FLASH__ ={0x17,0x18,0x19,0x1b,0x1c,0x1d,0x1f,0x20,0x21,0x23,0x24,0x25,0x26,
0x27,0x28,0x29,0x29,0x2a,0x2b,0x2b, 0x2c,0x2c,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2c,0x2c,0x2b,
0x2b,0x2a,0x29,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x21,0x20,0x1f,0x1d,0x1c,0x1b,0x19,0x18,0x17,
0x15,0x14,0x12,0x11,0x10,0xe,0xd,0xc,0xa, 0x9,0x8,0x7,0x6,0x5,0x4,0x4,0x3,0x2,0x2,0x1,0x1,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x2,0x2,0x3,0x4,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xc,0xd,0xe,0x10,0x11,0x12,0x14,0x15};
void setup() {
SPI.setModule(2);// выбор SPI2
tft.initR(INITR_BLACKTAB);
tft.setRotation(3);//дисплей горизонтально, контакты слева
tft.fillScreen(paper);//залить цветом по умолчанию
tft.setTextWrap(0);//не переносить строки
// Serial1.begin(9600); //вывод в UART1 для отладки
RCC_BASE->APB1ENR|= (1<<2)|(1<<1)|(1<<0); //включить тактирование tim-2,3,4
RCC_BASE->APB2ENR|= (1<<3)|(1<<11)|(1<<2)|(1<<0)|(1<<4);////включить тактирование port-a-b-c,tim1
RCC_BASE->AHBENR|=1<<0;//включить тактирование dma1
AFIO_BASE->MAPR|=(1<<25) |(1<<8)|(1<<6); //JTAG Disabled tim 1 && tim 2 Partial remap
i2c_master_enable(I2C1, I2C_REMAP, 200000); //SDA PB9, SCL PB8
Wire.begin();
//Serial1.println("Start");
do{ //проверка si5351, если не найден то из цикла проверки не выйдет
if (si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0)==0){ //Serial1.println("I2C address Si5351 not detected");
} delay(300);
si5351.update_status();
if ( !si5351.dev_status.REVID){ //Serial1.println("Error read Si5351 ID");
} } while (!si5351.dev_status.REVID);
si5351.set_freq(2500000000, SI5351_CLK0);// будущая тактовая 25МГц для мк с выхода0 (*100)
//переключение на внешнее тактирование от si5351 25MHz и pll x4
RCC_BASE->CFGR&=~(3<<0);//set hsi system clock
while (RCC_BASE->CFGR&(3<<2));
RCC_BASE->CR&=~(1<<24);//pll off
while (RCC_BASE->CR&(1<<25));
RCC_BASE->CR|= (1<<18)|(1<<16);// HSE on, ext osc
while ( !RCC_BASE->CR&(1<<17));
RCC_BASE->CFGR|=1<<16; // HSE oscillator clock selected as PLL input clock
RCC_BASE->CFGR&=~(15<<18);//clear pll mul
RCC_BASE->CFGR|=2<<18;//PLLMUL:0010 , pll input clock x 4
RCC_BASE->CR|=(1<<24);//pll on
while (!RCC_BASE->CR&(1<<25));
RCC_BASE->CFGR|=1<<1;//PLL selected as system clock
while (!RCC_BASE->CFGR&(2<<2));
RCC_BASE->CR&=~(1<<0);// hsi off
//usart_set_baud_rate(USART1, 100000000, 9600); //смена настройки UART на новую тактовую частоту
systick_init(SYSTICK_RELOAD_VAL);
pinMode(PB0,PWM); //buzzer
pinMode (PB1,INPUT_ANALOG); // вход АЦП
pinMode(PB5,INPUT_PULLUP);//key encoder
pinMode(PB3,OUTPUT); //мультиплексор
pinMode(PB4,OUTPUT); //мультиплексор
pinMode(PB6,INPUT_PULLUP);//encoder
pinMode(PB7,INPUT_PULLUP);//encoder
mytone(1000,50);//сигнал после старта
attachInterrupt(PB5, key_enc_int, RISING);//прерывание кнопки энкодера
attachInterrupt(PB6, enc_int, CHANGE); attachInterrupt(PB7, enc_int, CHANGE);//прерывания энкодера
adc_enable_single_swstart(ADC1);//запуск АЦП
ADC1->regs->CR2 |= ADC_CR2_TSVREFE; // Enable VREFINT conversion
ADC1->regs->SMPR1=3<<21; //ADC (vrefint) Sample time = 28.5 cycles
ADC1->regs->SMPR2=3<<27; //ADC (channel 9) Sample time = 28.5 cycles
bkp_init(); bkp_enable_writes();
//если что-то есть в bkp регистрах сохранённой частоты, то восстановить последнюю частоту , режим и шаг
if ( bkp_read(1) || bkp_read(2) ) {freq_restore(); mode_restore(); }
// иначе загрузить частоту и режим по-умолчанию
else { mode=1; freq=FREQDEFAULT; freq_save(); mode_save(); }
si5351.set_freq( (bkp_read(4)|(bkp_read(5)<< 16)) * 10ULL, SI5351_CLK1); // восттановленная частота с выхода1
#undef F_CPU
#define F_CPU 100000000 //новая тактовая частота, Герц
enc_mode(0);// запустить режим соответсвующий переменной mode
} //end setup
void loop() {
// в режиме DDS sinus дополнительно измерять скв напряжение
if (mode==4 && SHOWVRMS){
Vcc=(double) Mn * ((uint32_t)(my_sq_adcread(9) *3300 )/4096);
mon_out();
}
// вольтметр и частотометр запускаются циклически, в отличии от других режимов
if (mode==9) {mon_out(); freq_meter(); }//сначала вывести картинку, потом измерять
if (mode==10) {volt_meter();}
if (mon_flag) { mon_out();} //в остальных ситуациях при наличии флага вывода на дисплей
}
///////////////////////////////////////////////////////////////////////////
/////////*********** ВЫВОД НА ДИСПЛЕЙ************//////////////////////////
///////////////////////////////////////////////////////////////////////////
void mon_out(){
char mybuf[15];
if (mon_flag&(1<<1)){ //если была смена режимов
tft.fillScreen(paper); //чистить полностью экран только при смене режимов
//************** Вывод первой строчки*****************************
tft.setCursor(0, 0); // вперёд, вниз
tft.setTextColor(ST7735_GREEN, paper);
tft.setTextSize(2);
switch(mode){
case 0: tft.print(" Clock Gen "); break;
case 1: tft.print(" PWM Mode "); break;
case 2: tft.print(" Duty Mode "); break;
case 3: tft.print(" Impuls Mode "); break;
case 4: tft.print(" Sinus DDS "); break;
case 5: tft.print(" Triangle DDS"); break;
case 6: tft.print(" Pila1 DDS "); break;
case 7: tft.print(" Pila2 DDS "); break;
case 8: tft.print(" Noise DDS "); break;
case 9: tft.print(" Freq. meter "); break;
case 10: tft.print(" Volt. meter "); break;
}
} //КОНЕЦ если была смена режимов
//*****************Вывод второй строчки*****************************
if (mon_flag&((1<<1)|(1<<2)) ){ //если была смена режимов или смена частоты
tft.setTextColor(ST7735_WHITE, paper);
tft.setCursor(0, 19); tft.setTextSize(3);
if (mode !=3) { // в одновибраторе не использовать стандартный вывод
if (freq>=1E8) {tft.print(" "); tft.setTextSize(2);tft.setCursor(0, 21);}
if (freq<10) {sprintf(mybuf," 0,%ld ", freq );} //9 -> 0,9
else if (freq<100){sprintf(mybuf," %ld,%ld ", freq/10, freq%10 );} //99 -> 9,9
else if (freq<1E3){sprintf(mybuf," %ld,%ld ", freq/10, freq%10 );} //999 -> 99,9
else if (freq<1E4){sprintf(mybuf," %ld,%ld ", freq/10, freq%10 );} //9999 -> 999,9
else if (freq<1E5){sprintf(mybuf," %ld %03ld ", freq/10000, (freq/10)%1000 );} //99999 -> 9.999
else if (freq<1E6){sprintf(mybuf," %ld %03ld ", freq/10000, (freq/10)%1000 );} //999999 -> 99.999
else if (freq<1E7){sprintf(mybuf," %ld %03ld ", freq/10000, (freq/10)%1000 );} //999999 -> 999.999
else if (freq<1E8){sprintf(mybuf,"%ld %03ld %03ld", freq/10000000, (freq%10000000)/10000, (freq%10000)/10 );} //9999999 -> 9.999.999
else {sprintf(mybuf,"%3ld %03ld %03ld", freq/10000000, (freq%10000000)/10000, (freq%10000)/10 );} //99999999 -> 99.999.999
} //end if (mode !=3)
// вывод в режиме одновибратора
if (mode==3) { sprintf(mybuf," %3ld ", freq/10 ); if (imp_mode_menu == 0) {tft.setTextColor(ST7735_BLACK,ST7735_WHITE);} }
tft.print(mybuf); //вывод частоты
}// Конец если была смена режима или частоты для второй строки
//********************Вывод третьей строчки*****************************
tft.setTextColor(ST7735_RED,paper); //красный цет строки для всех вариантов
if (mode==10){ //если вольтметр
tft.setTextSize(3); //крупно
tft.setCursor(50, 43);
tft.print(" mV"); }
else if (mon_flag&((1<<1)|(1<<10)) && mode==9 ) { //если частотометр
tft.setTextSize(2);
tft.setCursor(0, 43);
tft.print(" Hertz ");
tft.setTextSize(1);
infreqpsc? tft.print("max 266MHz") : tft.print("max 33MHz ") ;
}
else if (mode==3) { //если одновибратор
if (imp_mode_menu == 1) {tft.setTextColor(ST7735_RED,ST7735_WHITE);}
tft.setTextSize(2);
tft.setCursor(50, 43);
switch (imp_mode) {
case 0: tft.print(" mS "); break;
case 1: tft.print(" uS "); break;
case 2: tft.print(" Takt "); break;
}}
else if (mode<9 && mon_flag&(1<<1) ) { //если режим генераторов и менялся режим, то выводить
tft.setTextSize(3);
tft.setCursor(35, 43);//x,y
tft.print("Hertz");
}
//********************* "осциллограммы"******************************
if (mon_flag&((1<<1)|(1<<4)) ){ //если была смена режима или дьюти
if (mode!=10){ tft.fillRect(5,90, 100,38,paper); }// зачистка пяточка (вправо, вниз, ширина вправо, длина вниз)
tft.drawRect(0,67, 160,61,ST7735_MAGENTA);//рамка: вправо, вниз, ширина вправо, длина вниз
if (mode==1 ||mode==2 || mode==9){
tft.drawFastVLine(5, 90, 30, ST7735_CYAN); // восход фронта статическая вер линия
tft.drawFastHLine(5, 91, duty, ST7735_YELLOW);//длина единицы
tft.drawFastHLine(5, 90, duty, ST7735_YELLOW);//паралельная линия для выделения
tft.drawFastVLine(duty+5, 91, 30, ST7735_YELLOW);// спад
tft.drawFastVLine(duty+4, 90, 30, ST7735_YELLOW);//паралельная линия для выделения
tft.drawFastVLine(105, 90, 30, ST7735_YELLOW);//спад конец такта статическая вер. линия
tft.drawFastVLine(104, 90, 30, ST7735_YELLOW);//паралельная линия для выделения
tft.drawFastHLine(duty+5, 120, (100-duty), ST7735_YELLOW);//линия единицы 2-го такта
tft.drawFastHLine(duty+5, 119, (100-duty), ST7735_YELLOW);//паралельная линия для выделения
}
}//Конец если была смена режима или дьюти
if (mon_flag&(1<<1)){ //вывод псевдоосциллограмм в разных режимах толко при смене режима
if (mode==3){ //логотип одновибратора емли менялся режим
tft.drawFastHLine(5,123,28,ST7735_YELLOW);// смещ вправо, смещ вниз, длина вправо
tft.drawFastHLine(5,122,26,ST7735_YELLOW);// паралельная линия для выделения
tft.drawFastVLine(32,73,50,ST7735_YELLOW); // смещ вправо, смещ вниз, высота вниз
tft.drawFastVLine(31,73,50,ST7735_YELLOW);// паралельная линия для выделения
tft.drawFastHLine(31,73,30,ST7735_YELLOW);// смещ вправо, смещ вниз, длина вправо
tft.drawFastHLine(31,74,30,ST7735_YELLOW);
tft.drawFastVLine(61,73,50,ST7735_YELLOW);
tft.drawFastVLine(60,73,50,ST7735_YELLOW);
tft.drawFastHLine(61,123,32,ST7735_YELLOW);
tft.drawFastHLine(61,122,32,ST7735_YELLOW);
}
if (mode==4){ // логотип синуса если менялся режим 5пкс вправо и 78пкс вниз
for(uint8_t n=0; n<100; n++){tft.drawPixel(5+n, 78+ sine_logo[n],ST7735_YELLOW);
} //END for
} // END if (mode==4)
else if (mode==5){// логотип треугольника
tft.drawLine(5,98,30,73,ST7735_YELLOW);
tft.drawLine(30,73,80,123,ST7735_YELLOW);
tft.drawLine(80,123,105,98,ST7735_YELLOW);
} //END mode==5
else if (mode==6){ //логотип пилы1
tft.drawLine(5,123,105,73,ST7735_YELLOW);
tft.drawFastVLine(105, 73, 50, ST7735_YELLOW);//спад конец такта статическая вер. линия
} //END if (mode==6)
else if (mode==7){//логотип пилы2
tft.drawFastVLine(5, 73, 50, ST7735_YELLOW); // восход фронта статическая вер линия
tft.drawLine(5,73,105,123,ST7735_YELLOW);
}// END if (mode==7)
else if (mode==0){ //логотип меандра
tft.drawFastVLine(5,73,25,ST7735_YELLOW);
tft.drawFastHLine(5,73,50,ST7735_YELLOW);
tft.drawFastVLine(55,73,50,ST7735_YELLOW);
tft.drawFastHLine(55,123,50,ST7735_YELLOW);
tft.drawFastVLine(105,98,25,ST7735_YELLOW);
}
else if (mode==8){// логотип шума если менялся
for(uint8_t n=0; n<100; n++){ uint8_t y=random(0,44);
tft.drawFastVLine(5+n,123-y,y ,ST7735_YELLOW);
} //END for
} // END if (mode==8)
}//КОНЕЦ вывод псевдоосциллограмм в разных режимах только при смене режима
//*********************** характеристики сигнала****************************************
tft.setCursor(5, 70); // вперёд, вниз
tft.setTextColor(ST7735_WHITE, paper);
tft.setTextSize(1);
if (mode==1 ||mode==2 || mode==9){
tft.print("+Width="); if (t_hi<1E3) {tft.print(t_hi); tft.print(" uS ");} else {tft.print(t_hi/1000); tft.print(" mS ");}
tft.setCursor(5, 80); // вперёд, вниз
tft.print("-Width="); if (t_low<1E3) {tft.print(t_low); tft.print(" uS ");} else {tft.print(t_low/1000); tft.print(" mS ");}
tft.setCursor(114, 70); tft.print("Duty=");
tft.setCursor(114, 80); tft.print(duty);tft.print(" % ");
} //END if (mode < 2 || mode==9)
if (mode==10) { tft.print("Vcc=");tft.print(Vcc); tft.print(" mV "); }
if (mode==4&&SHOWVRMS) { tft.print("Vrms=");tft.print(Vcc); tft.print(" mV "); }
// if (mode==9){ return;} // в режиме частотометра выводить на экран больше ничего не нужно.
/////////// установка курсора и вывод шага в разных режимах ///////////////
if (mon_flag&((1<<1)|(1<<3))) {// выводить Step если менялся режим или шаг
if (mode==3) { // в режиме одновибратора
if (imp_mode_menu==2) { tft.setTextColor(ST7735_BLACK,ST7735_WHITE);}
else { tft.setTextColor(ST7735_WHITE, paper);}
tft.setCursor(114, 70); tft.print("Step=");
tft.setCursor(114, 80);//курсор в поле значения шага
}
else if (mode<9) { tft.setCursor(114, 95); tft.print("Step="); tft.setCursor(114, 105);}
else if (mode==10) {tft.setCursor(100, 70); tft.print("Step=");} //только в вольтметре
switch (encstep) {
case 0: tft.print(" 0,1"); break;
case 1: tft.print(" 1"); break;
case 2: tft.print(" 10"); break;
case 3: tft.print(" 100");break;
case 4: tft.print(" 1E3");break;
case 5: tft.print(" 1E4");break;
case 6: tft.print(" 1E5");break;
case 7: tft.print(" 1E6");break;
case 8: tft.print(" 1E7");break;
}// END switch case
}// Конец выводить Step если менялся режим или шаг
// вывод прочей информации
if (mode==3) {// вывод меню запуска импульса
if (imp_mode_menu==3) { tft.setTextColor(ST7735_RED,ST7735_WHITE ); }
else { tft.setTextColor(ST7735_RED, paper ); }
tft.setTextSize(3);
tft.setCursor(100, 95);
tft.print("Run");
}
/// вывод пределов для вольтметра
if (mode==10) {
tft.setCursor(5, 80); // вперёд, вниз
tft.setTextSize(2);
tft.setTextColor(modevolt? ST7735_YELLOW : ST7735_WHITE , paper);//выбрать жёлтый цвет если активен
sprintf(mybuf,"Low_mv=%5d", Vin_low);//выводить 5 символов
tft.print(mybuf); //вывод нижнего предела
tft.setTextColor(modevolt? ST7735_WHITE : ST7735_YELLOW , paper);
tft.setCursor(5, 100); // вперёд, вниз
sprintf(mybuf," Hi_mv=%5d", Vin_hi);
tft.print(mybuf); //вывод верхнего предела
}
mon_flag=0;
}//END mon_out
//обработчик прерываний энкодера
void enc_int(){
static char EncPrev=0; //предыдущее состояние энкодера
static char EncPrevPrev=0; //пред-предыдущее состояние энкодера
char EncCur = 0;
if(!( GPIOB_BASE->IDR&64 )){EncCur = 1;} //опрос фазы 1 энкодера
if(!( GPIOB_BASE->IDR&128 )){ EncCur |= 2;} //опрос фазы 2 энкодера
if(EncCur != EncPrev) //если состояние изменилось,
{
if(EncPrev == 3 && //если предыдущее состояние 3
EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны,
{
if(EncCur == 2) //если текущее состояние 2,
enc_mode(-1); //шаг вверх
else //иначе
enc_mode(1); //шаг вниз
}
EncPrevPrev = EncPrev; //сохранение пред-предыдущего состояния
EncPrev = EncCur; //сохранение предыдущего состояния
}
}// END VOID
// ФУНКЦИЯ конфигурации режимов
void enc_mode(int8_t in){
modebit= digitalRead(PB5); //состояние кнопки PB5. 0-нажата
if (!modebit) {// если сейчас идёт переключение режимов (кнопка нажата)
mytone(880,30); //звук переключения режимов
mode+=in;
if(mode>10){mode=10; modevolt=!modevolt; } //вместо переключения режима переключить текущую регулировку границ вольтметра
if(mode<0){mode=0;}//ограничение смены режима
if (mode==0){freq_si5351_restore(); clock_gen();} //если выбран si5351
if (mode==1 || mode==2 ){freq_restore(); timer_set();} // PWM&Duty
if (mode==3) { TIMER1_BASE->BDTR=0; freq=100;}//настройки в при входе в режим одновибратора
if (mode >3 && mode <9) {freq_restore(); dds_set(); } //dds
else {DMA1_BASE->CCR5&= ~DMA_CCR_EN;} //DDS_dma_disable
if (mode==9) {freq=0;}// сбросить в ноль freq в режиме частотометра
comm(); mon_flag|=(1<<1); enc_step_control();
mode_save();
return;
} // END if !modebit
//сюда попадает при изменении частоты (вращение энкодера без нажатия)
mytone(4400,7); //звук изменения частоты
switch(mode){ //если сейчас идёт изменение частоты
case 0: freq_si5351_restore(); set_freq(in); clock_gen(); freq_si5351_save() ; break;
case 1: freq_restore(); set_freq(in); timer_set(); freq_save(); break;
case 2: duty+=in; timer_set(); break; //в duty ничего не сохраняю.
case 3: if (imp_mode_menu==0){ set_freq(in); if (freq<10) freq=10; if (freq> 500000) {freq=500000;} } //переключение длительности импульса
else if (imp_mode_menu==1){ imp_mode++; if (imp_mode >2){imp_mode=0;} }//переключение 0-мс, 1-мкс, 2 -такт
else if (imp_mode_menu==2){ encstep++; if (encstep>6) {encstep=0;} enc_step_control();} //переключение шага
else if (imp_mode_menu==3){ impuls(); } //генерация импульса
break;
case 4 ... 8: set_freq(in); dds_set(); freq_save(); break; // DDS режимы
case 9: break; // в частотометре не реагировать на вращение энкодера
case 10: modevolt? Vin_low+=( pow(10,encstep)*in/10) : Vin_hi+=( pow(10,encstep)*in/10); //регулировка пределов вольтметра
if (Vin_low<0||Vin_low>99999 ){Vin_low=0;} if (Vin_hi<0||Vin_hi >99999){Vin_hi=0;} break; //ограничения не менее ноля и не более 4х символов
} //end switch case
mon_flag|=(1<<2);//флаг смены частоты
comm();
}//end enc_mode
void set_freq(int8_t in){
uint32_t freq_temp = freq+( pow(10,encstep)*in);
if (in==-1) {
if (!freq_temp) {if (encstep>1){encstep--; } mon_flag|=1<<3 ;}
else {freq= freq_temp;} //если не уменьшилось, то присвоить новое значение
}
//при увеличении проблем быть не должно
else {freq= freq_temp;}
}
// обработчик кнопки энкодера:
void key_enc_int(){//сюда должно попадать только при отжимании кнопки (Rising Edge)
if(!modebit){ // если до этого менялся режим то выдержать паузу (низкий звук в спикер) и выйти
mytone(30,150); //150ms примерно соответсвует времени отпускания кнопки после вращения
while( (TIMER2_BASE->SR)==0);//подождать пока пропищит
modebit=1; return; //и выйти
}
//сменить режим и выйти если были в duty mode:
if (mode==2) { mode=1; mon_flag|=(1<<1); enc_step_control() ; mode_save(); mytone(880,30); while( (TIMER2_BASE->SR)==0); return;}
// иначе было переключение шага
mytone(160,100); //выдать звук переключения шага
while( (TIMER2_BASE->SR)==0);//подождать пока пропищит
if (mode==9) {infreqpsc=!infreqpsc; mon_flag|=(1<<10); return;} //включать/отключать делитель в режиме частотометра
if (mode==3) { imp_mode_menu++; mon_flag|=(1<<2)|(1<<3); if(imp_mode_menu >3){imp_mode_menu=0 ;} }
else { encstep++; enc_step_control(); }
mode_save();
}//end
/////////////ограничение шага в зависимости от режимов и частот/////////////////////////////////
void enc_step_control(){
// для CLOCK режима если шаг более 1 МГц то шаг сбросить на 0,1 или 1 Герц (зацикливание переключений)
if (mode==0 && encstep >8) {encstep=1;} // Для CLOCK режима макс шаг 10МГц, минимальный 1 Гц
//если кнопка нажата(lOW) значит сейчас переключался режим, и обнулять шаг не надо.
if ( mode==1 && encstep >6) {modebit? encstep=0 :encstep=6 ;} //для PWM макс шаг 100 000 Гц, минимальный 0,1Гц
if ( mode==3 ) { if (encstep >4) {encstep=1;}}// для одновибратора макс 10000 единиц минимум 1
if (mode>3 && mode<9 && encstep >6) {modebit? encstep=0 :encstep=6 ;} //для DDS макс шаг 100 000 Гц
if (encstep==0 && freq >=10000 ) encstep=1;// менять шаг 0,1 Гц -> 1Гц на частотах выше 1кГц для всех режимов
if (mode==10 && (encstep >4 || encstep ==0)) {encstep=1;} //для вольтметра макс 1000 мв
mon_flag|=(1<<3); //флаг вывода на дисплей (обновить шаг)
}
////////////////НАСТРОЙКА ТАЙМЕРА-ГЕНЕРАТОРА/////////////////////////////////////////////
void timer_set(){ //
if (freq > PWMFREQMAX) {freq=PWMFREQMAX; freq_save(); }
uint32_t divider=1;
uint64_t cpu_tic=F_CPU*10ULL /freq;
while ( (cpu_tic/divider) > 65536) {divider++;}
uint32_t arr=cpu_tic/divider;
fcpu=(uint64_t)freq *arr * divider; //fcpu - вычисленная необходимая тактовая частота МК (*10)
GPIOA_BASE->CRL=0xB4444444; //PA7 alt_output PA0-PA6 input
if ( (GPIOA_BASE->CRH&0xf) != 0xB) {GPIOA_BASE->CRH&=~(0xf<<0);// clear_bits_PA8
GPIOA_BASE->CRH|=0xB; //PA8 Alternate function output Push-pull
}
TIMER1_BASE->CR1|=(1<<7); // ARPE: ARR preload enable
TIMER1_BASE->CCER=(1<<0)|(1<<2)|(pwm2_polar<<3);//cc1e/cc1ne enable
TIMER1_BASE->BDTR=(1<<15);// Main output enable ,
TIMER1_BASE->CCMR1=(6<<4)|(1<<3)|(1<<2);//PWM mode 1, CCR1 preload enable, OC1FE fast enable
TIMER1_BASE->PSC=divider-1;
TIMER1_BASE->ARR=arr-1;
// установка заданного DUTY
if(duty>99){duty=99;} if(duty<1){duty=1;}
TIMER1_BASE->CCR1= (float) (TIMER1_BASE->ARR+1)* duty/100.0 ;
static int old_duty =duty; if (old_duty !=duty){ old_duty =duty; mon_flag|=(1<<4);}
uint32_t imp_long=(uint32_t) (arr*divider); //длина периода в тактах
uint32_t imp_hi=(uint32_t) ((TIMER1_BASE->CCR1)*divider); // длина импульса в тактах
t_low= (imp_long-imp_hi) /(fcpu/1E7) ; //время LOW /1E6 И /10 т.к. fcpu*10
t_hi= imp_hi /(fcpu/1E7); //время HI
if (TIMER1_BASE->CNT > arr-1) {TIMER1_BASE->CNT =0;}//на всякий случай
TIMER1_BASE->CR1&=~((1<<1)|(1<<3)); //Update enable + clear impuls if activ
TIMER1_BASE->CR1|=(1<<0); // tim1 EN,
TIMER1_BASE->EGR=1<<0;// Update ARR, PSC, CCR
// коррекция тактовой частоты для мк
si5351.set_freq( (fcpu/4)*10ULL , SI5351_CLK0);
mon_flag|=(1<<2);
}//end timer_set
// КОНФИГУРАЦИЯ DDS РЕЖИМОВ
void dds_set(){
if (freq > DDSFREQMAX) {freq=DDSFREQMAX; freq_save(); }
TIMER1_BASE->CCER=0;//Отключить аппартаную ногу таймера
GPIOA_BASE->CRH&=~(0xf<<0);// отключить ногу PA8
GPIOA_BASE->CRL = 0x33333333;// pa0-pa7 выход
static uint16_t oldSM=0;//прошлый размер массива
static uint8_t oldMODE=255;// прошлый режим
uint16_t x;//временная переменная для расчётов таблицы
//подгонка размера массива под максимальный SampleRate
uint16_t SM = 512; while (((uint64_t)freq * SM) > (F_CPU*10LL /13) ) {SM--; }
uint16_t psc=1, arr;
// расчёт делителя для таймера
while ( ((uint64_t)F_CPU*10ULL / psc / (freq*SM)) >65536 ){psc++;}
//расчёт регистра перезагрузки
arr= (F_CPU*10ULL/psc) / (freq*SM);
TIMER1_BASE->PSC=psc-1; //коррекция тактирования при смене частоты.
TIMER1_BASE->ARR= arr-1; //коррекция тактирования при смене частоты.
TIMER1_BASE->DIER=(1<<8); //тактировать DMA при событии: Update timer
TIMER1_BASE->CNT=0;
TIMER1_BASE->CR1=1;
//если изменился размер массива или режим или если DMA выключен, то
if (oldSM != SM || oldMODE !=mode || !(DMA1_BASE->CCR5&1) ) {// не прерывать понапрасну DMA
oldSM=SM; oldMODE=mode;
if (mode==4) { for(uint16_t n=0; n<SM; n++){wave[n]=255*(sin(TWO_PI*float(n)/SM)+1)/2 ;} }
else if (mode==5) { for( uint16_t n=0; n<SM; n++){if (n<(SM/2)){ x= (n*255)/(SM/2) ;} else {x= ((SM-n)* 255)/(SM/2);}
(x>255)? (wave[n]=255) : wave[n]=x ;
} }//треугольник
else if (mode==6) { for(uint16_t n=0; n<SM; n++){ wave[n]=n * 256/SM ;
} }//пила1
else if (mode==7){ for(uint16_t n=0; n<SM; n++){ wave[n]= ~(n* 256/SM) ;
} }//пила2
else if (mode==8){ for(uint16_t n=0; n<SM; n++){ wave[n]=random(0, 255); }}//шум
DMA1_BASE->CCR5&= ~DMA_CCR_EN; //dma_disable
DMA1_BASE->CCR5= DMA_CCR_PL_HIGH | DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_DIR_FROM_MEM;
DMA1_BASE->CPAR5= (uint32_t)&(GPIOA->regs->ODR);
DMA1_BASE->CMAR5=(uint32_t)wave;
DMA1_BASE->CNDTR5=SM;
DMA1_BASE->CCR5|= DMA_CCR_EN;// DMA start
}//конец if (oldSM != SM ||
fcpu=freq*SM*psc*arr; // новая тактовая частота рассчитана
si5351.set_freq( (fcpu/4)*10ULL , SI5351_CLK0);
mon_flag|=(1<<2);
}//END DDS set()
void mytone(int frq, int ms ){
if (mode==9){return;} //таймер в режиме частотометра занят
uint16_t psc=1; uint32_t tim_arr;
// настройка генератора звука на таймере3
tim_arr = (fcpu/20)/frq;// fcpu/10/2
while ( (tim_arr/psc) > 65535) {psc++;}
__asm volatile( "cpsid i" );
TIMER2_BASE->SMCR=0;
TIMER3_BASE->CCR3=0; //обнулить регистр соответсвующий используемому выходу
TIMER3_BASE->PSC=psc-1;
TIMER3_BASE->ARR=(tim_arr/psc)-1;
TIMER3_BASE->CCMR2=(1<<5)|(1<<4);// OC3M:011 Toggle
TIMER3_BASE->CCER=3<<8;//cc3e подключить аппаратную ногу
TIMER3_BASE->SMCR=(1<<2)|(1<<0)|(1<<4);//SMS:101 && TS:001 строб от 2-го таймера
TIMER3_BASE->EGR=1; //перечитать регистры.
TIMER3_BASE->CR1=1;
/// настройка выдержки времени на таймере2
psc=1;
tim_arr = (fcpu/10000) * ms;// fcpu /1000 /10
while ( (tim_arr/psc) > 65536) {psc++;}
TIMER2_BASE->CCMR2=0;
TIMER2_BASE->CR2=0;
TIMER2_BASE->CR1=(1<<3)|(1<<2);//один импульс, без прерываний
TIMER2_BASE->CNT=0;
TIMER2_BASE->CR2=(1<<4); //MMS:001 сигнал разрешения работы другим таймерам
TIMER2_BASE->PSC=psc-1;
TIMER2_BASE->ARR=(tim_arr/psc)-1;
TIMER2_BASE->EGR=1; //перечитать регистры.
TIMER2_BASE->SR=0;//отчистить флаги
TIMER2_BASE->CR1|=(1<<0);
__asm volatile( "cpsie i" );
}
void clock_gen(){ //функция работа с синтезатором si5351
GPIOA_BASE->CRH&=~(0xf<<0);// отключить PA8
GPIOA_BASE->CRL=0x44444444; //отключить PA0-PA7 (input)
fcpu=1000000000; // на всякий случай сделать тактовую стандартной
si5351.set_freq( (fcpu/4)*10ULL , SI5351_CLK0);
if (freq <40000){freq=40000;} if (freq>225E7){ freq=225E7;} //допустимые рамки частот 4кГц - 225МГц
si5351.set_freq(freq * 10ULL, SI5351_CLK1); //домножить на 10, т.к. нужна частота в сотых герца, а freq в десятых долях.
mon_flag|=(1<<2);//и флажок на отображение частоты.
}
void comm(){ //коммутация выходов через мультиплексор
if (mode>0 && mode<4 ) {digitalWrite(PB3,LOW); digitalWrite(PB4,LOW);} //выход таймера
else if (mode>3 && mode<9 ) {digitalWrite(PB3,HIGH); digitalWrite(PB4,LOW);}//выход DDS
else if (mode==0 ) {digitalWrite(PB3,LOW); digitalWrite(PB4,HIGH);} //выход_1 Si5351
else if (mode==9) {digitalWrite(PB3,HIGH); digitalWrite(PB4,HIGH);} //вход А15
}
void volt_meter() {
static boolean alarm=0;
//измерение напряжения питания МК
Vcc = (VrefINT <<12) / my_sq_adcread(17);
//измерение напряжения на входе ADC9(PB1)
for (int n=0; n<=65535; n++ ) {asm volatile("nop"); } //Типа delay
freq = (double) Mn * ((uint32_t)(my_sq_adcread(9) * Vcc *10)/4096);
// если напряжение не удовлетворяет условиям, и буззер не работает -то включить
if (freq < ((uint32_t)Vin_low*10)) { alarm =1; if (TIMER2_BASE->SR!=0) {mytone (200, 10000);} }
else if (freq > ((uint32_t)Vin_hi*10)) { alarm =1; if (TIMER2_BASE->SR!=0) {mytone (1000, 10000);} }
else alarm=0;
//если всё ок, а буззер работает, то выключить.
if (!alarm && (!TIMER2_BASE->SR) ) {mytone (0, 0);}
mon_flag|=(1<<2);
}
uint32_t my_sq_adcread(byte adc_in) {
uint64_t akkum=0;
for (int n=0; n<=32767; n++ ) {//собирать 16384 выборок
akkum += sq(adc_read(ADC1,adc_in)); //суммировать квадраты
if( mon_flag) return 0;
} //END собирать 16384 выборок
return (sqrt(akkum>>15));
}
///////////////////// ФУНКЦИЯ ОДНОВИБРАТОРА///////////////////////
void impuls(){
if (fcpu != 1000000000){fcpu = 1000000000; si5351.set_freq( (fcpu/4)*10ULL , SI5351_CLK0); }
uint32_t tim_arr=0, div_imp_mode=0;
GPIOA_BASE->CRL=0xB4444444; //PA7 alt_output PA0-PA6 input
if ( (GPIOA_BASE->CRH&0xf) != 0xB) {GPIOA_BASE->CRH&=~(0xf<<0);// clear_bits_PA8
GPIOA_BASE->CRH|=0xB; //PA8 Alternate function output Push-pull
}
__asm volatile( "cpsid i" );
TIMER1_BASE->BDTR= 1<<14; //Automatic output enable
TIMER1_BASE->CCMR1=(7<<4);//PWM2 Mode
TIMER1_BASE->CCER=(1<<0)|(1<<2)|(pwm2_polar<<3);//cc1e/cc1ne enable
TIMER1_BASE->CCR1=1; // поднять ногу на этом такте
TIMER1_BASE->CR1=(1<<3);//режим "один импульс"
if (imp_mode<2){ // кроме такта
switch(imp_mode){// 0-мс, 1-мкс, 2 -такт
case 0: div_imp_mode=1000; break; // делитель для миллисекунд
case 1: div_imp_mode=1000000; break;// делитель для микросекунд
}
tim_arr = (freq/10) * (uint32_t)(F_CPU/div_imp_mode) ;
uint32_t divider=1;
while ( (tim_arr/divider) > 65535) {divider++;}
TIMER1_BASE->PSC=divider-1; // Прескалер
TIMER1_BASE->ARR=(tim_arr/divider)-1; //длина импульса
TIMER1_BASE->CCR4= TIMER1_BASE->ARR;//повесить флаг по окончании импульса
}
else { TIMER1_BASE->ARR = (freq/10);} //если imp_mode == такт,
TIMER1_BASE->EGR=1;
mytone(2200,100);
TIMER1_BASE->CR1|=(1<<0);
while( (TIMER1_BASE->SR&(1<<4))==0 ) ;//ждать подождать пока закончится импульс
__asm volatile( "cpsie i" );
}
void freq_meter(){
/////////////////////счётчик импульсов
si5351.set_freq(2500000000, SI5351_CLK0);// тактовая частота по умолчанию с выхода 1
pinMode(PA15,INPUT_PULLDOWN); // вход частотометра
uint32_t imp_long,imp_hi;//переменные измерения длины такта
__asm volatile( "cpsid i" );
/// Timer2 счёт младших 16 бит
RCC_BASE->APB2RSTR |= 1<<11; //reset timer 1
RCC_BASE->APB2RSTR&= ~(1<<11);
RCC_BASE->APB1RSTR |= (1<<0) |(1<<1) ; //сброс таймера2,3
RCC_BASE->APB1RSTR &= ~((1<<0)|(1<<1)); // сброс таймера2,3
TIMER2_BASE->CR2=1<<5; //MMS:010 управление подчинённым в режиме "Update"
TIMER2_BASE->SMCR= (1<<14)|(5<<0)|(infreqpsc<<13)|(infreqpsc<<12);// режим 2 внешнего тактирования + делитель/8 + разрешение работы от таймера1
TIMER2_BASE->ARR=65535; //считать до максимума
TIMER2_BASE->EGR=1; //перечитать регистры.
TIMER2_BASE->CR1|=(1<<0);//start timer2
/// Timer3 счёт старших 16 бит
TIMER3_BASE->SMCR=(1<<2)|(1<<1)|(1<<0)|(1<<4);//SMS:111 && TS:001 такт брать от 2-го таймера
TIMER3_BASE->ARR=65535; //считать до
TIMER3_BASE->EGR=1; //перечитать регистры.
TIMER3_BASE->CR1|=(1<<0);//start timer3
/// настройка времени разрешения на таймере1 для таймера2
TIMER1_BASE->CR1=0; TIMER1_BASE->CNT=0;
TIMER1_BASE->CCER=0;// отключить выходы таймера на физ ноги
uint16_t psc=1;
uint32_t tim_arr = F_CPU;// чтобы измерять менее 1 секунды добавить делитель
while ( (tim_arr/psc) > 65536) {psc++;}
TIMER1_BASE->PSC=psc-1;//
TIMER1_BASE->ARR=(tim_arr/psc)-1;
TIMER1_BASE->EGR=1; //перечитать регистры.
TIMER1_BASE->CR1=(1<<3)|(1<<2);//один импульс, без прерываний
TIMER1_BASE->CR2=(1<<4); //MMS:001 сигнал разрешения работы другим таймерам
TIMER1_BASE->CR1|=(1<<0);
__asm volatile( "cpsie i" );
while (TIMER1_BASE->CR1&1) {asm volatile("nop"); if(mon_flag) {return;} }
freq= TIMER3_BASE->CNT<<16 | TIMER2_BASE->CNT; //частота (не удесятерённая)
if (infreqpsc) {freq*=8;}// если включен делитель на 8 то результат умножить на 8
if (freq>1E5){freq*=10; t_low=0;t_hi=0; duty=0; mon_flag|=(1<<2)|(1<<4); return;} //выйти если freq больше 100кГц
// Перенастройка таймера 2 в режии измерения длительности импульса и скважности для частот менее 100 кГц
uint32_t divider=1;
while ((F_CPU/divider/((freq>0)? freq : 1 )) > 65000) {divider++;}
__asm volatile( "cpsid i" );
RCC_BASE->APB1RSTR |= 1<<0; //сброс таймера2
RCC_BASE->APB1RSTR &= ~(1<<0); // запуск таймера 2
TIMER2_BASE->CR1=0;//стоп таймер
TIMER2_BASE->PSC= divider-1;
TIMER2_BASE->SMCR=(1<<4)|(1<<6)|(1<<2);// TS:101 SMS:100 вход TI1FP1 , Режим сброса
TIMER2_BASE->CCMR1=(1<<0)|(1<<9);//CC1 input,mapped on TI1, CC2 input,mapped on TI1
TIMER2_BASE->CCER=(1<<5)|(1<<0)|(1<<4);//cc1-Hi,cc2-lo
TIMER2_BASE->EGR=1; //перечитать регистры.
/// настройка таймера1 для счёта тайм-аута при измерения PWM
TIMER1_BASE->CR1=(1<<3);//один импульс, без прерываний
TIMER1_BASE->CNT=0; TIMER1_BASE->CR2=0; TIMER1_BASE->CCER=0;
TIMER1_BASE->PSC=F_CPU/15625 -1; // тактовая таймера 15625 Герц
TIMER1_BASE->ARR=31250;//считать до 31250 (2 секунды)
TIMER1_BASE->EGR=1; //перечитать регистры.
timer_attach_interrupt(TIMER1, TIMER_UPDATE_INTERRUPT, myint);
TIMER1_BASE->CR1|=(1<<0);// старт счёта 2х секунд
__asm volatile( "cpsie i" );
TIMER2_BASE->CR1=(1<<0);// старт захвата PWM
while( (TIMER2_BASE->SR&0x65F)!=0x65F) {//
asm volatile("nop"); if(mon_flag) {timer_detach_interrupt(TIMER1, TIMER_UPDATE_INTERRUPT); return;} }
TIMER2_BASE->CR1=0;// стоп таймер
timer_detach_interrupt(TIMER1, TIMER_UPDATE_INTERRUPT);
imp_long=(uint32_t) ((TIMER2_BASE->CCR1)*divider);
imp_hi=(uint32_t) ((TIMER2_BASE->CCR2)*divider);
if (freq <1000){ freq= F_CPU*10 /imp_long ;
} //если freq Менее 1кГц то использовать данные второго НЧ-измерения частоты (*10)
else {freq*=10; } //иначе просто удесятерить результат для корректного вывода информации.
duty= (float) imp_hi / (imp_long / 100.0) ;
if (duty > 100 || duty < 0) {duty=0;} // на всякий случай ограничение
t_low= (double)(imp_long-imp_hi) / (F_CPU/1E6) ;
t_hi= (double) imp_hi /(F_CPU/1E6);
mon_flag|=(1<<2)|(1<<4);
} //END freq meter
// прерывание тайм-аута при отсутствиии сигнала на входе при измерении PWM
void myint(){
mon_flag|=((1<<2)|(1<<4)); t_low=0; t_hi=0; duty=0; freq=0;
timer_detach_interrupt(TIMER1, TIMER_UPDATE_INTERRUPT);
}
Убедительная просьба не использовать кнопку "Цитировать" под этим постом, т.к. у меня пропадёт возможность редактировать ошибки, да и просто засирать тему повторной информацией не стоит.
снял старую плату, без варварства не обошлось, хотя с виду осталась живой. поставил 128Kb, все прошилось и запустилось. осцилом только завтра потыкаю, посмотреть, насколько все у меня плохо. :) потому как все не по феншую - питание от импульсника, выход через коммутатор, после цапа регулятор на ad8052.
пока есть ссылки, где какие платы покупал - здесь 128kb, здесь 64kb. ссылки не реферальные, может кому пригодится.
Dimax , на входе частотомера можно избавиться от одного резистора. Нужно включить внутреннюю подтяжку, а снаружи оставить только противоположный резистор 39К. Я на Ф303 так сделал.
нужен полноценный усилитель-формирователь с встроенным делителем частоты. А они трудоёмкие и капризные. Поэтому я и забил на это дело :)
Формирователь - да, от 0 до мегагерц 80-100 не сразу, но работает, а делителей полно, хоть на 2 хоть на 256, частота от 1 ГГц и выше, у них еще и "чуйство" загрублять приходится, чтобы на пролетающую мимо муху не реагировали :-) Только после делителя надо и частотомер соответствующим образом подстроить.
Спасибо. Учту пожелания. Завалялась парочка делителей на SAB и понравилось исполнение частотомера. Не мог бы скинуть полную его схему и пошивку или ссылку на проект, чтобы тему не засорять?
Тем не менее вопрос по энкодеру - а критично количество импульсов на оборот ручки и фазировка каналов? В исходнике генератора на STM версии 3.6 вроде не обнаружилось ничего на эту тему...
Тем не менее вопрос по энкодеру - а критично количество импульсов на оборот ручки и фазировка каналов? В исходнике генератора на STM версии 3.6 вроде не обнаружилось ничего на эту тему...
Крайне желательно, что б один щелчок энкодера формировал один полный импульс, подробности были в описании версии 3.0 .
venus пишет:
режим impulse у меня работает странно. при переходе в него из duty изначальное состояние то нулевое, то единичное. если в нем сделать run, то при переходе назад в duty/pwm, генерация там отсутствует полностью. для запуска достаточно сходить в любой режим dds. я в принципе импульсом не пользуюсь, но проверял и не понял, что с ним.
Еще вопрос - фильтр-усилитель имеет смысл прикручивать только на выход DDS, а на PWM не надо, а то получится вселенское зло. Тем более что микросхема усилителя тянет 3 МГц всего (такое в коробочке лежит в столе).
Начал собирать 3.6, благо почти все железо есть, но мелькнула шальная мысль - видимо скоро будет версия 3.7 с добавкой ADF4350 (4351) на борт и полосой частот от 0.1Гц до 4400МГц
Подобную сборку (SI4351 + ADF4350) применили в антенном анализаторе VNA, а вот генератора с такой полосой не встречал.
Заливал файлы в bin, не хочет запускаться с СИ. Хотел прошить через IDE, плату устанавливал STM32F103C6/fake STM32F103C8. Частоту выставил 72МГц. IDE ругается на плату
Сбрось пож. скрин своих установок
Изменил плату на STM32F103C_HSI series Загрузка прошла, но бестолку
Плату перед монтажом проверял - 128к, светодиоды моргали значит был рабочий порт кварца. Питание 5.01В, вся периферия подключена, буду пробовать менять СИшку, благо две заказывал.
kloker, кстати намедни на радиокоте выложили проект генератора на F303, видели? Он конечно в разных весовых категориях с моим. По всем возможностям обходит мой, его смело можно отнести в категорию "измерительный прибор" ибо и аппаратно и программно соответствует, таких широких возможностей у самоделок я вообще никогда раньше не видел (!). Автор основательно поработал. Но в отличии от моей поделки в сборке сложен, - требует изготовления печатных плат, подетальной пайки, в общем только для опытных радиолюбителей. Пробежавшись по характеристикам всё таки нашёл узкое место- частота дискретизации в режиме DDS всего 1.4МГц . (У моего 4,5 МГц при F_CPU= 72MHz && выводе в встроенный цап ). А ещё немаловажно, что обещает автор - проект будет развиваться.
К теме как отличить настоящий МК, сфоткал сейчас свой блюпил, у меня надписи читаются без труда (фотка кликабельна).
заменил. обновил библиотеки в выложенном комплекте, поправил сдвиги. все работает. спасибо автору за полезный девайс.
а si5351 только меандр умеет выдавать? хотя конечно и цап неплохую форму выдает на довольно приличных частотах, но не на мегагерцах конечно. резисторы в делитель брал smd с допуском 1%.
с другой стороны, на десятках мегагерц у меня осциллографу становится наплевать на форму, все стремится к синусу. :) да и уровень невысок.
venus, ещё adg704 давит фронты. У него заявлена пропускная способность что-то вроде до 200 МГц, но под этой цифрой подразумевается синус :) Если я когда нибудь буду переносить в другой корпус, то коммутацию сделаю на релюшках, как Mag-N. Может даже шикану, и куплю мелкие вч-релюшки.
PS про Herz я как-то и незадумывался, с буквой t оно даже симметричнее смотрится, надо тоже исправить :)
релюшки надо завтра посмотреть, какие есть на работе, может попадутся подходящие.
Я герконовые поставил, у них при пяти вольтах ток срабатывания меньше 10 мА - подключены напрямую к выходам дешифратора 74138. Вот такие:
по поводу реле - я тоже у себя использовал, в посте 81 писал. хз насколько высокочастотные, но мелкие, с 3.3в питанием и 30ма потреблением, по адекватной цене на али - G6K-2F-Y
да, если разводить - не стоит забывать что они имеют полярность.
В данной конструкции можно любые малогабаритные реле использовать. Это ведь не реле обхода антенного усилителя или РА, где ВЧ напряжение 100-200 В и более.
мне тоже палитра больше от red понравилась, так что в я него просто сдвиги из green добавил в ините.
загрузчик брал последний в теме. он, помнится, boot1 джампер использует вместо ресета, так что можно постоянно плату держать под прошивку. вот только у меня почему-то устройство usb только serial с pid=0004 появляется, а под прошивку pid=0003 упорно отсутствует, в том числе после добавления резистора с A12 на 3.3. и разъем microusb был дрянной родной, пропайка не помогла, поменял, но на usb-устройства само собой не повлияло. так что мне проще stlink'ом пользоваться. хотя в принципе неважно, девайс уже в корпус закинул, выбросив потроха из ростелекомовской iptv-приставки. брендовый девайс получился. :)
вольтметр зацеплен на аккум и немного подвирает, на 2%, на входе резистор больший воткнул без подбора. наверное, стоит коррекцию прямо в коде поставить.
не хватает разве что сохранения параметров и текущего режима. ну и регулируемого выходного напряжения.
Заметил одну особенность : очищаем память контроллера, заливаем загрузчик. Далее прошиваем хоть Блинк, хоть Графиктест или что-то подобное и так раз 20 подряд - всё прошивается без лишних телодвижений. Но стоит прошить любую версию данного генератора, и для следующей прошивки надо давить РЕСЕТ. Если затем опять загрузить что-то другое (через РЕСЕТ), то автоматическая загрузка восстанавливается. Загружаем генератор - и опять те же Я... Положение джампера BOOT1 никак не влияет.
MAG-N, я вроде писал про это. В скетче отключается всё лишнее, в том числе прерывания USB, без них не работает USBCDC, который образует ком-порт, без него IDE не может инициировать загрузку бутлоадера.
в режиме pwm, если поставить шаг 1E4, на второе увеличение частота прыгает на 36MHz.
в режиме pwm, если поставить шаг 1E4, на второе увеличение частота прыгает на 36MHz.
Это из-за того, что на частотах выше 8кГц нет привязки шага к герцам. Можно ввести доп условие:
И тогда не будет так резко скакать.
чисто для частотометра http://www.radioscanner.ru/forum/topic38601.html
тот же фрегат, обвес отличается и питание одно. в принципе можно без селектора входов сделать, в виде внешнего щупа, только с питанием от прибора.
Собирал я этот формирователь (по номиналам деталей похож на тот, что с Радиосканнера)- и сейчас он работает, но у него нижний предел частоты был порядка нескольких сотен герц. Добился нижнего предела 1 Гц, для чего параллельно С2 поставил керамику 10 мкФ, а параллельно С7 и С10 - электролиты по 100 мкФ. При этом верхний предел упал где-то со 100 до 80 МГц. Мне нижний предел важнее был. А чувствительность - это питания полевику маловато, не зря в "Фрегате" он от 12В питается. В даташите на транзистор явно указано "VHF and UHF applications with 12 V supply voltage"
dimax, спасибо за генератор. Хороший приборчик, сделал усилитель на DDS OUT, но пока мучась идут искажения. Время будет доделаю.
Dimax, тебе уже задавали этот вопрос на другой ветке, но позволю себе повториться: как программно, аппаратно или комплексно промодулировать сигнал Si5351? Предлагалось изменять биты управления, но как это практически сделать видимо так никто и не понял, а мне тем более не разобраться. Думаю, что одной частоты модуляции в 1000Гц всех устроило бы.
Спасибо!
как программно, аппаратно или комплексно промодулировать сигнал Si5351? Предлагалось изменять биты управления
Он для этого не предназначен. У AD985x есть токовый выход, там нетрудно сделать внешнюю амплитудную модуляцию. Так же там можно сделать частотную модуляцию -при подключении в 8бит параллельном режиме можно с высокой скоростью задавать частоту. Всего этого у Si нет.
У Si5351 есть нога VddOut - питание выходного буфера, оно хоть в даташите конкретными значениями обозначено (Output VDDO: 1.8, 2.5, or 3.3 V), но может и как вход для АМ заработает? Тут пробовать надо. Вот только кому эта АМ нужна, разве что самолеты с землей работают. Как это ни странно, но до сих пор обмен на взлете-посадке идет в режиме АМ, хоть Боинг, хоть Кукурузник.
MAG-N, это сообщение редактировалось. Поначалу плата Си и дисплей питались от USB, а после перепайки резисторов всю схему запитал от стаба STM.
Видимо придется ставить отдельные схемы модуляторов АМ и ЧМ, а Си использовать как задающий генератор
Подскажите как в прошивке под stm32 прописать свою форму сигнал, ступеньки аля видеосигнал? в версии 2.4 это было легко, а тут не соображу
alex410, в 3.x это сложнее сделать, т.к. все готовые формы рассчитываются математически. Но суть будет такая же - создать массив на 512 байт, поместить его в флэш my_mass[] __FLASH__ ={ тут форма на 512 байт}; а в функции, где идёт расчёт и заливка массива в памяти вместо расчёта скопировать данные из своего массива в основной.
Всем привет. Собрал на печатке и вот какая засада. Заработал, почти сразу, только ресет как подпаял, забыл сразу. Через некоторое время вставляя холдер с аккумом, пока без тумблера, и не запускается. Экран сначала желтый потом срабатывает заливка черным и все, нет ничего более, генерации тоже нет. Аккумом 18650 питаю через Step Up, дает 4.99 с питанием норм. Не пойму на чем может тормозится программа. Кроме Блупилл, экрана и энкодера ни чего нет. Я так понял в коде ни чего не надо менять под такой конфиг?
Исправил, удалил вот эти строки и заработало:
Еще, может кому пригодится. У меня было смещение изображение небольшое, скомпенсировал в файле Adafruit_ST77xx.cpp
Venus, ты как-то выкладывал свою прошивку с правкой цвета фронта импульса на экране и возможностью установки независимых частот на выходах Siшки. Я не ее скачал, а модератор почистил переписку. Скинь пожалуйста ее еще раз. Надеюсь не удалят полезные изменения и плюшки, глядишь и пригодятся кому нибудь
man_200, честно говоря, уже не помню. вероятно, все это было здесь: http://venus.rontel.ru/gen35/
прошивка - обычная 3.5 с минимальной косметикой. ну и под делитель мой откалибрована, дабы правильно напряжение аккума показывать. которая с "144greentab" в названии - не под мой дисплей, а чей-то еще.
Доброе время суток. Захотелось собрать это устройство, уже начал рисовать печатку. Решил проверить на макетке, залил 3,5 версию через СТ-линк, заработало, но, вывод изображения получилось перевернутым, тоисть контакты справа, а здесь смотрю у всех слева. Хорошо что не спешил делать плату.
Silver_D, в скетче нужный поворот задаётся функцией
tft.setRotation();
dimax я что то краем глаза глянул даташит и не увидел как записать данные в NVM ? Что бы стартовал на нужной мне частоте ?
dimax Я не об этом ... В описании Si5351 написано что есть NVM память, из которой берутся настройки в момент старта Si5351. Я так понял что можно рассчитать данные для всех выходов, записать их в эту память и потом при старте нужные частоты будут на выходах без участия МК. Но вот как записать данные в эту память не увидел.
The Si5351 is a highly flexible clock generator which is entirely configurable through its I2C interface. The device’s default configuration is stored in non-volatile memory (NVM) as shown in Figure 11. The NVM is a one time programmable memory (OTP) which can store a custom user configuration at power-up. This is a useful feature for applications that need a clock present at power-up (e.g., for providing a clock to a processor).
Я так понял что можно рассчитать данные для всех выходов, записать их в эту память и потом при старте нужные частоты будут на выходах без участия МК.
вот это интересно, тоже хочу такое :) Почитаю.
PS: Разобрался.
How can I burn the NVM on a blank Si5351 part?•Silicon Labs does not currently support customer NVM burning for this product family. •However, you can easily create a new custom part with a newly defined default startup state using ClockBuilder Pro. Once the part is submitted at the end of the process,you will be able to contact your local distributor to order the new part number.
По-простому: эта модель не поддерживает сохранение пользователем конфигурации, но вы можете заказать у вашего продавца чип с уже записанной вашей конфигурацией. В общем отбой.
Убедительная просьба не использовать кнопку "Цитировать" под этим постом, т.к. у меня пропадёт возможность редактировать ошибки, да и просто засирать тему повторной информацией не стоит.
снял старую плату, без варварства не обошлось, хотя с виду осталась живой. поставил 128Kb, все прошилось и запустилось. осцилом только завтра потыкаю, посмотреть, насколько все у меня плохо. :) потому как все не по феншую - питание от импульсника, выход через коммутатор, после цапа регулятор на ad8052.
пока есть ссылки, где какие платы покупал - здесь 128kb, здесь 64kb. ссылки не реферальные, может кому пригодится.
Dimax , на входе частотомера можно избавиться от одного резистора. Нужно включить внутреннюю подтяжку, а снаружи оставить только противоположный резистор 39К. Я на Ф303 так сделал.
нужен полноценный усилитель-формирователь с встроенным делителем частоты. А они трудоёмкие и капризные. Поэтому я и забил на это дело :)
Формирователь - да, от 0 до мегагерц 80-100 не сразу, но работает, а делителей полно, хоть на 2 хоть на 256, частота от 1 ГГц и выше, у них еще и "чуйство" загрублять приходится, чтобы на пролетающую мимо муху не реагировали :-) Только после делителя надо и частотомер соответствующим образом подстроить.
Рабочаяя схема
Спасибо. Учту пожелания. Завалялась парочка делителей на SAB и понравилось исполнение частотомера. Не мог бы скинуть полную его схему и пошивку или ссылку на проект, чтобы тему не засорять?
Cхема и прошивка http://wdfiles.ru/noRT
Сделано "по мотивам" FCL-метра, только выбросил все лишнее (Микеланжело, мля :-) )
http://www.cqham.ru/forum/showthread.php?11744-FCL-meter-FAQ-%C2%EE%EF%F0%EE%F1%FB-%E8-%EE%F2%E2%E5%F2%FB-2
Всем привет. Вот наконец пришли платки с Китая и собрал приборчик. Спасибо dimax за отличный проект.
Двополярки ОС любят, тем более что копеешная микруха много места не занимает.
https://drive.google.com/file/d/1tszNU8_aaFPRSW5sGpb5sQTYfDZTMXqD/view?u...
А что, просто, со вкусом и из доступных деталей, а главное рассыпью. Только СИшки не вижу. Видимо первый вариант генератора.
В качестве вишенки на этом торте не хватает печатки в LAY, для полноты проекта.
Два диода не будут защищать 34063 и 7806 в случае встречного большого напряжения по цепи 12-и вольтовой нагрузки.
Достаточно поставить один диод только на этот провод, рядом с L3, мощный Шотки.
Кстати, 7805 вместо 34063 не проще было поставить? Он мощнее и точно батарею зарядит.
И последнее, с 34063, поставив еще один диод, можно получить и отрицательное напряжение -5В, что позволит исключить 7660, а усилитель питать +/- 5В
Главное что аппарат работает, применю твой усилитель и спасибо за проект!
Вариант то первый, только программа и распиновка версии 3,5
А мощности там и не нужно, 250 - 350мА достаточно, да и не греется.
Отрицательное напряжение с 34063 как то не хочется брать, он помехи большие делает, да и развязка питания аналога от цифры лучше.
Добавлю архив в диск, лай и герберы, может кто захочет заказать.
https://drive.google.com/drive/folders/1CCySKNDxiA8S2Vq3ZmepnDKEk5bZh2Qw...
Спасибо за схемы и печатку!
Тем не менее вопрос по энкодеру - а критично количество импульсов на оборот ручки и фазировка каналов? В исходнике генератора на STM версии 3.6 вроде не обнаружилось ничего на эту тему...
Тем не менее вопрос по энкодеру - а критично количество импульсов на оборот ручки и фазировка каналов? В исходнике генератора на STM версии 3.6 вроде не обнаружилось ничего на эту тему...
Крайне желательно, что б один щелчок энкодера формировал один полный импульс, подробности были в описании версии 3.0 .
да, теперь вроде все логично. спасибо.
С энкодером понятно, спасибо.
Еще вопрос - фильтр-усилитель имеет смысл прикручивать только на выход DDS, а на PWM не надо, а то получится вселенское зло. Тем более что микросхема усилителя тянет 3 МГц всего (такое в коробочке лежит в столе).
достаточно на dds, pwm сигнал там все равно присутствует в инвертированном виде. а быстрые операционники (>100MHz) стоят рублей по десять.
3.5 работает и нет желания его раскидывать
Начал собирать 3.6, благо почти все железо есть, но мелькнула шальная мысль - видимо скоро будет версия 3.7 с добавкой ADF4350 (4351) на борт и полосой частот от 0.1Гц до 4400МГц
Подобную сборку (SI4351 + ADF4350) применили в антенном анализаторе VNA, а вот генератора с такой полосой не встречал.
Хотелось бы надеяться
man_200, новых версий больше не планируется,хочу наконец заняться другими делами.
Спасибо. Только мусор на экране присутствует. Можно как то пофиксить? https://yadi.sk/i/P6Y0KOuKPcm8nw
Заливал файлы в bin, не хочет запускаться с СИ. Хотел прошить через IDE, плату устанавливал STM32F103C6/fake STM32F103C8. Частоту выставил 72МГц. IDE ругается на плату
Сбрось пож. скрин своих установок
Изменил плату на STM32F103C_HSI series Загрузка прошла, но бестолку
Чешу репу
В посте #130 русским по белому написано:
Может у Вас плата с 64К памяти?
Сейчас именно такие установки
Плату перед монтажом проверял - 128к, светодиоды моргали значит был рабочий порт кварца. Питание 5.01В, вся периферия подключена, буду пробовать менять СИшку, благо две заказывал.