Нестабильность из-за задержек
- Сообщения: 23
- Зарегистрирован: Ср ноя 21, 2018 02:29:02
МК -- аналог обычного кнопочного переключателя. ((Корпус генератора очень маленький, галетник или типа п2к уж больно много места займут. Делать на жменьке логике или триггеров на сегодняшний день -- " религия не позволяет", да и экономия места . На одном мк все переключения -- класс. Кнопки поставлю под с-диодами, давим сд -- он проседает и мжёт кн. Один элемент на панели -- две функции : кн и индикатор, опять же экономия места.)) Пост от Ivanoff-iv на 5-ой стр. вверху отвечает по полной , но без д11-13 и кн на РС5 , и с добавкой двух строк на начальное включение РВ0 и РВ4. В железе пока не пробовал, а в протеусе всё идёт на ура.
- Реклама
- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
Не впечатляет, это делитель, и шаг в 1Гц вы не получите и привязан к определенному выводу порта, хотя джиттер отсутствует.Ivanoff-iv писал(а):Генератор... держи
dds-синтез, меандр, правда с джиттером (на ошибку таймера 1 тик), шаг в 1Гц, и на любую ножку порта
Спойлер
Код: Выделить всё
// Пусть нам нужно генерировать частоту 1012 Гц, учитывая, что основную процедуру таймер у нас исполняет 65536 раз в секунду
// 32768*2 / (65536 / 1012) = 1012
uint16_t n_counter = 1012;
union BytByte {
struct {
uint8_t h;
unsigned char b0: 1;
unsigned char b1: 1;
unsigned char b2: 1;
unsigned char b3: 1;
unsigned char b4: 1;
unsigned char b5: 1;
unsigned char b6: 1;
unsigned char b7: 1;
} bit;
uint16_t byte;
}__attribute__((packed));
ISR(TIMER2_COMPA_vect) // Timer Period: 0,01525 ms
{ static union BytByte myBByte;
myBByte.byte += n_counter;
if(myBByte.bit.b7)
PORTB |= (1<<(PORTB0));
else
PORTB &= (~(1<<(PORTB0)));
}
к выводу порта не привязан, не делитель, но и на высоких частотах в 1 Гц может и не влезть...
сейчас усовершенствую... добавлю сохранение остатка от деления - это повысит точность, но должно добавить джиттер в пределах 2 тактов ядра МК.
сейчас усовершенствую... добавлю сохранение остатка от деления - это повысит точность, но должно добавить джиттер в пределах 2 тактов ядра МК.
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
Ivanoff-iv, не надо соревноваться, нет смысла.
Максимум что я могу получить на тактовой частоте ядра 16МГц, частота таймера 131072Гц, шаг перестройки равен 0,000030517578125Гц, это точное число, умножите его на 32768 вы получите ровно 1Гц, максимально генерируемая частота 65536Гц.
Этим алгоритмом мне удавалось разгонять stm32f030 тактовая ядра 72МГц, частота таймера 2097152Гц (да 2МГц), что давало мне шаг перестройки 0,00048828125, умножите его на 2048 вы получите ровно 1Гц, и максимум генерируемой частоты 1048576Гц(1МГц).
В этом алгоритме чем выше частота таймере тем меньше джиттер.
Максимум что я могу получить на тактовой частоте ядра 16МГц, частота таймера 131072Гц, шаг перестройки равен 0,000030517578125Гц, это точное число, умножите его на 32768 вы получите ровно 1Гц, максимально генерируемая частота 65536Гц.
Этим алгоритмом мне удавалось разгонять stm32f030 тактовая ядра 72МГц, частота таймера 2097152Гц (да 2МГц), что давало мне шаг перестройки 0,00048828125, умножите его на 2048 вы получите ровно 1Гц, и максимум генерируемой частоты 1048576Гц(1МГц).
В этом алгоритме чем выше частота таймере тем меньше джиттер.
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Ридико Леонид Иванович на ассемблере как то решал проблему джитера. Я тогда ещё прогал на асме. Потом мне было не до этого, и я не занимался этим вопросом. Позже обстоятельства, перешёл на си, другие задачи. Недавно столкнулся с этим вопросом. Делал что то вроде генератора импульсов. Вывод на пины программный, по прерыванию. И обратил внимание, что есть задержка. Пишу на си. Полез в дизасм, увидел, что пролог, эпилог портит всю картину. Я стал менять местами переключение пина мк. Добился стабильности, но джитер на один такт остался. Я понимаю так. Нужно отталкиваться от чего то, то ли младшего бита таймера, то ли счётчика команд. Но, я не помню, доступно ли значение счётчика команд. И в ближайшее время собираюсь поднять этот вопрос.
Скорее всего, значение счётчика команд будет недоступно. И нужно отталкиваться от аппаратного таймера, настроенного на работу без предделителя. А это означает, что один таймер будет уже занят как минимум именно для этой задачи.
Короче, навскидку, решение джитера. Смотрим на младший бит. В зависимости от ситуации, если выставлен бит, то. Или наеборот. Ставим nop-ы.
Скорее всего, значение счётчика команд будет недоступно. И нужно отталкиваться от аппаратного таймера, настроенного на работу без предделителя. А это означает, что один таймер будет уже занят как минимум именно для этой задачи.
Короче, навскидку, решение джитера. Смотрим на младший бит. В зависимости от ситуации, если выставлен бит, то. Или наеборот. Ставим nop-ы.
- Реклама
я сделал по другому: сначала получаю период импульса в тактах мк, это лонг переменная, откусываю от неё младший бит, сколько осталось в старшем, столько раз (минус 1) насчитываю переполнение 8битного таймера, число в младшем бите делю на 2, прибавляю к нему 128 полученное число записываю в регистр сравнения (таймер в стс режиме в регистре до этого было фф) и делаю 2 оборота.
так получаю точность в 2 такта мк.
сейчас пошел дальше: пытаюсь достичь точность в 1 такт, и учесть остаток от деления при вычислении периода (это будет джиттер в 1 такт мк, но иначе точнее чем 1 такт не получить...
код почти дописан - на следующей неделе буду довылизывать и утрамбовывать в тини13...
так получаю точность в 2 такта мк.
сейчас пошел дальше: пытаюсь достичь точность в 1 такт, и учесть остаток от деления при вычислении периода (это будет джиттер в 1 такт мк, но иначе точнее чем 1 такт не получить...
код почти дописан - на следующей неделе буду довылизывать и утрамбовывать в тини13...
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Для того чтобы устранить джитер, нужно понимать архитектуру мк. Когда срабатывает прерывание, может выполняться команда либо за один такт, либо 2 такта. Именно поэтому нужно следить за младшим байтом счётчика. Но и этого мало, нужно просчитывать весь путь в обработчике прерывания до переключения пина, для того, чтобы в нужном месте вставить nop-ы.
да, это я понимаю. поэтому все зависимые от времени процессы возлагаю на периферию - мне проще правильно и заранее рассчитать OCR0A, чем лепить нопы или программные задержки.
в прерывании же от момента вызова до момента переключения пина не будет ничего изменяющего время, даже пин будет переключаться тогглом, чтобы код включения и выключения не отличался.
Добавлено after 5 minutes 29 seconds:
единственный джиттер при правильном коде возможен и он неустраним - это от того что 1 такт мк составляет 1/9600000 секунды и из программы его длительность никак в достаточной степени предсказуемо не изменить.
Добавлено after 16 minutes 32 seconds:
чтото я припоминаю про разное время входа в прерывание... надо бы освежить - перечитать Demiurg, спасибо за напоминание
в прерывании же от момента вызова до момента переключения пина не будет ничего изменяющего время, даже пин будет переключаться тогглом, чтобы код включения и выключения не отличался.
Добавлено after 5 minutes 29 seconds:
единственный джиттер при правильном коде возможен и он неустраним - это от того что 1 такт мк составляет 1/9600000 секунды и из программы его длительность никак в достаточной степени предсказуемо не изменить.
Добавлено after 16 minutes 32 seconds:
чтото я припоминаю про разное время входа в прерывание... надо бы освежить - перечитать Demiurg, спасибо за напоминание
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Есть один способ. Но, джедайский. Выстроить программу таким способом, чтобы размер команды был одинаков всегда. RJMP к примеру. Но, это накладывает определённые ограничения на максимальную частоту генератора. Если есть индикация, чтобы в статике.
То есть, если лезем в настройки, это означает конец работы генератора, запуск после настроек.
Вызов настроек из прерывания. То есть, кнопы вешаем на внешние прерывания.
Так, на подумать.
То есть, если лезем в настройки, это означает конец работы генератора, запуск после настроек.
Вызов настроек из прерывания. То есть, кнопы вешаем на внешние прерывания.
Так, на подумать.
- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
Ivanoff-iv, глянул я ваш код, в протеусе его осциллографом, джиттер просто ужасный, я имею ввиду фазовое дрожание сигнала, в том коде то что вы предоставили джиттер 330мкс.
Если вкратце: в PIC есть NCO-модуль, это аппаратный сумматор, он качается от тактовой частоты ядра 16МГц, джиттер в нем 1/16МГц.
В моем коде использовался программный сумматор.
И так чип stm32f030, код обработки прерывания DMAmyBByte.byte += Omega; это и есть сумматорТактовая МК 72МГц, чем выше эта частота тем быстрее выполняется расчет в прерывании, таймер настроен на частоту 3МГц, увы, выше надо поднимать тактовую частоту, чип выше не тянет.
Таймер пинает с частотой 3МГц DMA, буфер DMA 512 ячеек. можно было бы сказать байт, но там не байт, uint16_t.
Прерывание DMA половинка и полный, пока 1 половинка заполняется, 2 половинка выплевывается, процесс кольцевой, запустил и забыл.
Выплевывается в регистр ШИМ который принимает всего два значения, 0-0% 1-100%.
Всего 3МГц при оптимизации -Os, на помню NCO-модуль в PIC качается от 16МГц, а AD9833 от 25МГц.
Если вкратце: в PIC есть NCO-модуль, это аппаратный сумматор, он качается от тактовой частоты ядра 16МГц, джиттер в нем 1/16МГц.
В моем коде использовался программный сумматор.
И так чип stm32f030, код обработки прерывания DMA
Спойлер
даю в том варианте, в котором он у меня естьКод: Выделить всё
void DMA1_Channel4_5_IRQHandler(void)
{
uint16_t *dp;
uint32_t irq; uint16_t n;
static union BytByte myBByte;
DMA1->IFCR = irq = DMA1->ISR & DDS_IRQ_MASK; /* Get and clear the irq flags */
dp = &DmaBuff[(irq & DMA_ISR_TCIF4) ? DDS_NDMA / 2 : 0]; /* Last or Half transfer? (determins which part of circular buffer to be filled) */
n = DDS_NDMA / 2;
do {
myBByte.byte += Omega;
*dp = myBByte.bit.b15;
dp += 1;
} while (--n != 0);
}
Таймер пинает с частотой 3МГц DMA, буфер DMA 512 ячеек. можно было бы сказать байт, но там не байт, uint16_t.
Прерывание DMA половинка и полный, пока 1 половинка заполняется, 2 половинка выплевывается, процесс кольцевой, запустил и забыл.
Выплевывается в регистр ШИМ который принимает всего два значения, 0-0% 1-100%.
Всего 3МГц при оптимизации -Os, на помню NCO-модуль в PIC качается от 16МГц, а AD9833 от 25МГц.
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Но мы в теме AVR.
- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
[uquote="Demiurg",url="/forum/viewtopic.php?p=4021255#p4021255"]Но мы в теме AVR.[/uquote]При тактовой 16МГц, частота таймера 200кГц, с натягом 250кГц, джиттер составит 1/250кГц = 4мкс.
Вопросы есть?
Вопросы есть?
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Ну как бы я выше написал. На си, разбег 1-2 такта. Прибил гвоздями переключение пина в прерывании. На ассемблере я это сделаю ещё лучше. Понял как. Как бы решение уже написал.
- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
Частота прерывания таймера должна соответствовать степени двойки: 65536Гц 131072Гц 262144Гц и т.д. это нужно что бы получить идеальный шаг к примеру в 1Гц, в противном случае он будет дробный, к примеру 1,05Гц или 1,34Гц.Demiurg писал(а):На ассемблере я это сделаю ещё лучше.
Емкость сумматора (битность) влияет на шаг перестройки:
к примеру при частоте прерывания таймера 65536Гц
16 бит - шаг 1Гц
17 бит - шаг 0,5Гц
18 бит - шаг 0,25Гц
джиттер в любом случае составит 1/65536Гц = ~15мкс
при частоте прерывания таймера 131072Гц
17 бит - шаг 1Гц
18 бит - шаг 0,5Гц
19 бит - шаг 0,25Гц
джиттер в любом случае составит 1/131072Гц = ~7,62мкс
Проблема в том что при 17 бит уже 32 битная переменная нужна, ну нету у нас uint24_t.
А вот эта конструкция
Код: Выделить всё
if(myBByte.bit.b7)
PORTB |= (1<<(PORTB0));
else
PORTB &= (~(1<<(PORTB0)));Код: Выделить всё
sbrs
rjmp
sbi
cbiВот эта
Код: Выделить всё
uint16_t n_counter = 1012;Если прерывание таймера 131072Гц, то максимум n_counter может принимать 65535, 2 байта.
А если прерывание таймера 262144Гц, то максимум n_counter может принимать 131071, увы 4 байта надо.
На stm32 проще дело обстоит, там расчеты идут непосредственно с 32 битными переменными.
Как опыты показали, Атмега с успехом гонится до 27МГц, а не которые экземпляры работают и от 32МГц.
А с другой стороны есть специализированная микруха AD9833, и стоит копейки.
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Код: Выделить всё
sbic
rjmp label_1
sbi
rjmp label_2
label_1:
cbi
label_2:
AD9833, интересная таракашка. Где, почём берёшь?
- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
Вроде бы.Demiurg писал(а):Ты асм подзабыл...
Во общем так:
Спойлер
Резервируем четыре регистраКод: Выделить всё
register uint16_t n_counter asm("r6"); // r6 r7
register uint16_t myBByte asm("r8"); // r8 r9Код: Выделить всё
myBByte = 0;
n_counter=998;Код: Выделить всё
// 32768*2 / (524288 / 7984) = 998
ISR(TIMER2_COMPA_vect) // Timer Period: 1,9375 us = 516129 Hz (524288Hz)
{
asm volatile(
" add r8, r6 \n\t"
" adc r9, r7 \n\t"
" sbrc r9, 0x07 \n\t"
" sbi 0x05,0 \n\t"
" sbrs r9, 0x07 \n\t"
" cbi 0x05,0 \n\t"
:::);
}С частоты МК 16МГц частота прерывания таймера в 516129 Гц
джиттер на этой частоте составит 1,9375 us
а шаг сумматора 8Гц
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Я бы посоветовал тебе найти статью Ридико про генератор сигналов на AVR. Он писал, что ему самому давали советы зарубежные эмбеддеры по оптимизации ассемблерного кода. Можно от регистра отталкиваться, можно от пина. И именно второй метод эффективнее при меандре. Да и вообще, зачастую есть случаи, когда нужно смотреть на состояние пина. Это ресурс вообще то. Когда сам пин и есть индикатор состояния. Не нужен доп регистр под эту задачу.
Кстати, Ридико один из тех, у кого я учился примерам работы с AVR.
Кстати, Ридико один из тех, у кого я учился примерам работы с AVR.
- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
Это вот эту что ли?Demiurg писал(а):Я бы посоветовал тебе найти статью Ридико
Уважаемый, я перепробовал все методы, все коды, которые есть в инете, даже Чена на stm32f100 12 битный DAC, +еще по i2c лепил к f030 mcp4725, других не было в наличии.
В основе всех методов лежит один и тот же принцип.
В статье Ридико используется 28 битный сумматор, +внешний ЦАП.
Синус, элементарно
Спойлер
Порт PORTD 8бит ЦАП R-2RТаблица синуса 256 значений
Код: Выделить всё
uint8_t period[] = {
128 ,125 ,122 ,119 ,116 ,112 ,109 ,106 ,103 ,100 ,97 ,94 ,91 ,88 ,85 ,82 ,79 ,76 ,73 ,71 ,68 ,65 ,62 ,60 ,57 ,55 ,52 ,50 ,47 ,45 ,42 ,40 ,38 ,36 ,34 ,31 ,29 ,27 ,26 ,24 ,22 ,20 ,19 ,17 ,16 ,14 ,13 ,11 ,10 ,9 ,8 ,7 ,6 ,5 ,4 ,4 ,3 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,3 ,4 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ,11 ,13 ,14 ,16 ,17 ,19 ,20 ,22 ,24 ,26 ,27 ,29 ,31 ,34 ,36 ,38 ,40 ,42 ,45 ,47 ,50 ,52 ,55 ,57 ,60 ,62 ,65 ,68 ,71 ,73 ,76 ,79 ,82 ,85 ,88 ,91 ,94 ,97 ,100 ,103 ,106 ,109 ,112 ,116 ,119 ,122 ,125 ,128 ,131 ,134 ,137 ,140 ,144 ,147 ,150 ,153 ,156 ,159 ,162 ,165 ,168 ,171 ,174 ,177 ,180 ,183 ,185 ,188 ,191 ,194 ,196 ,199 ,201 ,204 ,206 ,209 ,211 ,214 ,216 ,218 ,220 ,222 ,225 ,227 ,229 ,230 ,232 ,234 ,236 ,237 ,239 ,240 ,242 ,243 ,245 ,246 ,247 ,248 ,249 ,250 ,251 ,252 ,252 ,253 ,254 ,254 ,255 ,255 ,255 ,255 ,255 ,255 ,255 ,255 ,255 ,255 ,255 ,254 ,254 ,253 ,252 ,252 ,251 ,250 ,249 ,248 ,247 ,246 ,245 ,243 ,242 ,240 ,239 ,237 ,236 ,234 ,232 ,230 ,229 ,227 ,225 ,222 ,220 ,218 ,216 ,214 ,211 ,209 ,206 ,204 ,201 ,199 ,196 ,194 ,191 ,188 ,185 ,183 ,180 ,177 ,174 ,171 ,168 ,165 ,162 ,159 ,156 ,153 ,150 ,147 ,144 ,140 ,137 ,134 ,131
};Код: Выделить всё
union BytByte {
struct {
uint8_t l;
uint8_t h;
} bit;
uint16_t byte;
};
register uint16_t n_counter asm("r6"); // r6 r7
register union BytByte myBByte asm("r8"); // r8 r9Код: Выделить всё
ISR(TIMER2_COMPA_vect)
{
myBByte.byte += n_counter;
PORTD = period[myBByte.bit.h];
}Код: Выделить всё
// Пусть нам нужно генерировать частоту 1000 Гц, учитывая, что основную процедуру таймер у нас исполняет 262144 раз в секунду
// 32768*2 / (262144 / 1000Гц) = 250
myBByte.byte = 0;
n_counter=250;джиттер 1/262144 = 3,8 us
[uquote="Dimon456",url="/forum/viewtopic.php?p=4021250#p4021250"]Ivanoff-iv, глянул я ваш код, в протеусе его осциллографом, джиттер просто ужасный, я имею ввиду фазовое дрожание сигнала, в том коде то что вы предоставили джиттер 330 мкс[/uquote] Где такое
как увидеть? да, шаг приращения частоты просто ужасный на "верхах", но джиттера нет совсем.
сейчас переделываю - при такте 9,6МГц получил до 15кГц с шагом от 0,3Гц с меньшим шагом упирается в разрядность инт переменной, задающей частоту (при шаге 0,1 максимум составляет 6,5кГц).
джиттер теперь есть, составляет 1 такт МК, т.е. чуть больше 0,1us.
по прежнему хватает тини 13, задействован её таймер... ресурсов хватает и на другие вычисления. (писал на С).
принцип такой: из частоты (Frq) нахожу полупериод, который разделяю на 3 переменные:
Hr-количество полных оборотов таймера
Min - количество тактов плюсом к оборотам таймера (эти переменные были и в прошлой версии но под другими именами)
Sec - остаток от деления - т.е. к каждому полупериоду надо добавить Sec/Frq такта. но т.к. добавить величину меньше такта нельзя, то я складываю её в счетчик (почти DDS
) и по его переполнению увеличиваю на 1 раз период на 1 такт - так в среднем получается ровно та частота, которую задавали.
сейчас переделываю - при такте 9,6МГц получил до 15кГц с шагом от 0,3Гц с меньшим шагом упирается в разрядность инт переменной, задающей частоту (при шаге 0,1 максимум составляет 6,5кГц).
джиттер теперь есть, составляет 1 такт МК, т.е. чуть больше 0,1us.
по прежнему хватает тини 13, задействован её таймер... ресурсов хватает и на другие вычисления. (писал на С).
принцип такой: из частоты (Frq) нахожу полупериод, который разделяю на 3 переменные:
Hr-количество полных оборотов таймера
Min - количество тактов плюсом к оборотам таймера (эти переменные были и в прошлой версии но под другими именами)
Sec - остаток от деления - т.е. к каждому полупериоду надо добавить Sec/Frq такта. но т.к. добавить величину меньше такта нельзя, то я складываю её в счетчик (почти DDS
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- Сообщения: 2089
- Зарегистрирован: Вс июн 19, 2016 09:32:03
[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=4022665#p4022665"]сейчас переделываю - при такте 9,6МГц получил до 15кГц с шагом от 0,3Гц с меньшим шагом упирается в разрядность инт переменной, задающей частоту (при шаге 0,1 максимум составляет 6,5кГц).
джиттер теперь есть, составляет 1 такт МК, т.е. чуть больше 0,1us.
по прежнему хватает тини 13, задействован её таймер... ресурсов хватает и на другие вычисления. (писал на С).[/uquote]
А ничего что у встроенного генератора tiny13 точность ±2% после калибровки? Это сколько тактов помимо того одного?
джиттер теперь есть, составляет 1 такт МК, т.е. чуть больше 0,1us.
по прежнему хватает тини 13, задействован её таймер... ресурсов хватает и на другие вычисления. (писал на С).[/uquote]
А ничего что у встроенного генератора tiny13 точность ±2% после калибровки? Это сколько тактов помимо того одного?


