Комментарии 20
Как хорошо, что по итогу весь пазл сложился. Успехов в поиске новых лам)
"меандр курильщика" (Явление Гиббса) ещё возникает в результате цифровой обработки сигнала в осциллографе, особенно на медленных развёртках, вы в целом писали об этом в своей статье, просто хочу акцентировать что это проявляется ещё и таким образом, амплитуда реального сигнала меньше чем нам показывает осциллограф
А не пробовали в качестве драйвера линии( вместо всяких L9110S и IR4427 ) "MAX232":?
1) рожден для этого
2) питание только 5В
3) встроенная защита выходов
...
Виноват, там же еще 0 В есть.
А нет схемы входных цепей часов( там самоподтяжки к "0" нет случаем)?
А то может задействовать 2 выхода RS232 через диодный смеситель( один тянет к +, другой к -, а 0 сам получается)
Как вы понимаете, число 20 очень плохо делится на числа кратные тройке
Зато 24 очень даже делится и на 3, и на 6, а вся приведённая математика пересчитывается в целые числа, без всяких периодов :)
Решил всё же предать ГОСТовские схемы, и освоил-таки программу fritizing .....
Уже думал плюсануть, и тут...<Хнык>
Посмотрел на жменю горелых платок L9110S .....
Также — спасибо "доброму азиату", замкнувшему выход моста на C4. Который следует располагать у нагрузки (искрящего моторчика и т.п. индуктивности) и отделять от моста индуктивностью проводов (а иной раз — и дополнительным дросселем).
Или — уменьшить его раз в 50..100.
У вас, кажется, в обработчике TIMER1_COMPA_vect
в случае frame_counter=20
ничего не происходит. Но я, собственно, не за этим.
Для реализации подобных конечных автоматов можно из любопытства попытаться применить идею из https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html . С помощью нее можно писать код в императивном стиле, вместо явной обработки состояний:
#define BEGIN_COROUTINE static int32_t state = -1; switch(state) { case -1:
#define YIELD do { state = __LINE__; return; case __LINE__: ; } while(0);
#define END_COROUTINE }
ISR(TIMER1_COMPA_vect) {
static uint8_t cur_pos_num;
static int8_t i;
BEGIN_COROUTINE
for (;;) {
for (cur_pos_num = 0; cur_pos_num < 6; ++cur_pos_num) {
for (i = 9; i >= 0; --i) {
set_posi_sig();
YIELD;
if (i == numbers[cur_pos_num]) {
set_nego_sig();
} else {
set_zero_sig();
}
YIELD;
}
for (i = 0; i < 20; ++i) {
set_zero_sig();
YIELD;
}
}
}
END_COROUTINE
}
Если под номер состояния выделять большой int расточительно, то можно каждый раз явно передавать в YIELD какое-то уникальное число:
#define YIELD(s) do { state = s; return; case s: ; } while(0);
Практическая целесообразность под большим вопросом, но по-моему довольно интересный трюк.
Разгадываем ребус вторичных часов «Воронеж»