Помощь - Поиск - Пользователи - Календарь
Перейти к полной версии этой страницы на форумах сайта Электрик: Однотактный ММА суправлением и сервисом на АТмега8
Форумы сайта ЭЛЕКТРИК > Сварка, самодельные устройства для сварки > Самодельные сварочные устройства
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205


imon220
Просто у меня положительная была 25-27в а отрицательная -1в
И я долго не мог решить проблему почему положительная часть такая большая
Диоды брал на радиорынке, раньше качество не вызывало вопросов а сейчас после того как три раза попадался брак то может быть
Ну сейчас сварочный в корпусе и пока что работает но хорошо не проверен еще.
slavyann
Цитата(imon220 @ 2.12.2022, 21:27) *
Просто у меня положительная была 25-27в а отрицательная -1в

Ну сейчас сварочный в корпусе и пока что работает но хорошо не проверен еще.

ну как аппарат ? живой ??
imon220
Много не пользовался, раз 10. Пару раз спалил два электрода подряд, а так в основном по мелочи. Но пока что проблем не было. Так-же не пробовал варить током больше 110А
Из проблем это резистор выставления тока, уже второй начинает глючить через время
imon220
Было время немного погонял на токе 160А но не долго, пол электрода спалил где-то. Жарит хорошо, метал плавится на ура
Ничего не бахнуло. За это время включал раз 10-15 и на токе в основном 70-120А. Проблема только в резисторе, надо хороший брать, последний вроде держится но ток мин теперь 38А а до этого два уже поменял, глючат через время.
Сделал в корпусе от ибп старого


truevoxdei
Приветствую! Парни, помогите, если у кого есть, прошу скиньте печатку в lay для силы с раскачкой с отрицательным смещением на транзисторах 1207 и 892. У меня была печатка в lay, когда то с этой ветки скачивал и управу v3 и силу в lay. Файл с управой v3 нашел, а силу нет. Надо доделать когда то начатый проект с раскачкой с отриц. смещением.
KT117
Вы бы хоть скрин какой платы дали, чтоб понять, чего хотите.
У меня есть что то похожее с транзистором, но не уверен что это то что вам нужно

https://imageup.ru/img8/4835804/2024-06-03_171604.png
p210
Когда то здесь кажется была прошивка для полумоста. Олег Ма..., простите, oleg1ma вроде, с разрешения Автора ея выдал. Или ошибаюсь? Если нет, будьте любезны дать ссылочку на прошивку.
nikon
Цитата(p210 @ 16.8.2024, 20:38) *
Или ошибаюсь?

Ошибаетесь,никто её так и не дождался.
sergey777.68.3
Всем привет.Если есть файл управы от Юрия двух-так на 3846 поделитесь beer.gif smoke.gif
High V
Вопрос: кто-нибудь имеет исходник? Мне нужен для инверсии ШИМ (прямое управление) и подстройки базового значения и максимального, так как UC3856N по входу CL SS Umin=0,69v(заводится) и Umax=1,7v для токов 30-150А. Как вариант можно конечно логическую инверсию на 74HC14 в связке с операционником от рельсы до рельсы. неохота огород городить.

Тема: Реверс-инжиниринг прошивки сварочного инвертера 1T200a (ATmega8)

Кто-нибудь делал реверс прошивки для этого аппарата? Интересует алгоритм управления током и логика Anti-Stick/HotStart.

Сейчас разобрал:
- ATmega8 @ 8MHz
- ШИМ на PB3 (OCR2)
- АЦП: PC0-кнопка 60/12В, PC1-HotStart, PC2-Uдуги, PC3-ручка тока, PC4-подстроечник, PC5/PC7-датчики температуры

Из того что наковырял:
- Базовый ШИМ = (ADC3>>4)+15 (для 60В режима)
- Anti-Stick: при Uдуги <1.5В запускается таймер 150 циклов (~3с), затем полное отключение
- HotStart: подъем тока на 30% на 500мс
- В коде куча 32-битной математики (умножение/деление) по адресам 0xFBE и 0x103E

Может у кого уже есть полный реверс или документация по алгоритмам? Буду благодарен за любую информацию.

Дизассемблированный листинг с комментариями получился около 3500 строк, примерно 21XX - код. Есть не точности из-за очень сложной логики. код выглядит чрезвычайно запутанным
ИТОГО: Извлечено 36 формул расчетов, включая:

3 формулы Anti-Stick

2 формулы ограничения ШИМ

2 формулы обработки АЦП

6 формул тепловой защиты

2 формулы управления вентилятором

2 формулы опорных напряжений

5 математических операций

4 формулы таймеров

10 логических условий
ПОЧЕМУ КОД ТАКОЙ?
1. Это ручная оптимизация для ATmega8
ATmega8 имеет всего 8 КБ флеш-памяти. Каждый байт на счету.

Что мы видим в коде:

rcall вместо прямых переходов — экономия памяти

mov/movw вместо загрузки констант — быстрее

Инлайн-код вместо функций — нет накладных расходов на вызов

Многоуровневые переходы — оптимизация размера

2. Отсутствие структурированного программирования
Это типичный "спагетти-код" на ассемблере:

Нет процедурного разделения

Глобальные флаги (R2, R3) вместо локальных переменных

Переходы rjmp в разные части кода

Общие точки входа/выхода

3. Исторически сложившийся код
Код писался годами, наслаивались правки:

Патчи вроде 0x684 (никогда не выполняющийся PORTD.1)

Дублирующиеся таймеры (0x0314 и 0x031C — близнецы)

Заглушки и ловушки (0xA98 — бесконечный цикл)

4. Аппаратные ограничения
Нет ОС, нет планировщика — всё в одном цикле

Прерывания минимальны — основной код делает всё

Ручное управление стеком (Y-указатель)

ЖЕСТКАЯ КРИТИКА КОДА
1. АДСКИЙ SPAGHETTI CODE
asm
0x5FC: if (button_changed) reset_timer4
0x616: check_hotstart_button
0x630: if (sleep_mode) goto 0x660 else compute_pwm
0x660: call 0x3C0
0x6C6: if (anti-stick_active) goto 0x6EA else load_9
...
Это не код, это лабиринт Минотавра. Программа прыгает туда-сюда как блоха на раскаленной сковородке.

Одна функция размазана по 10 разным местам

Один и тот же код выполняется через 5 разных путей

Возвраты из подпрограмм прыгают в совершенно неожиданные места

Вердикт: Отладка такого кода — это квест для сталкеров. Мутанты водятся, артефакты падают, схемы нет.

2. ФЛАГИ В РЕГИСТРАХ — ЭТО СРЕДНЕВЕКОВЬЕ
asm
sbrs r2, 4
sbrc r3, 3
bld r2, 7
Серьезно? Битовая арифметика вместо нормальных переменных? Это уровень "я только что из 1985 года и у меня 256 байт RAM".

Проблемы:

Нельзя понять, что значит R2.4 без комментария

Нельзя добавить новый флаг — надо перепаковывать биты

Отладка: попробуй отлови момент, когда взводится 7-й бит R3

Конфликты: один бит используется в 10 разных местах

Вердикт: Код, где флаги хранятся в битах регистров, должен гореть в аду вместе с перфокартами.

3. МАГИЧЕСКИЕ ЧИСЛА — КЛАДБИЩЕ ЗНАНИЙ
asm
0x35A: ldi r25, 0x3F ; 0x3f80
0x3DC: add r30, r30 ; Удвоение, но зачем?
0x6D4: subi r26, 0x8A ; -138? Почему?
Это не код, это шифровка ЦРУ. Через год сам автор не вспомнит, почему здесь 0x3F80, а не 0x3F81.

Правила хорошего тона:

Константы должны быть именованными

Коэффициенты должны лежать в таблице

Каждое магическое число должно иметь комментарий

Вердикт: Поддержка этого кода требует шаманства с бубном и жертвоприношений.

4. rcall В НИКУДА
asm
0x7AC: sbrc r3, 7
0x7AE: rcall 0xB94 ; сброс таймера
0x7B0: ldi r30, 0x42
А если R3.7 = 0? Тогда rcall НЕ ВЫПОЛНЯЕТСЯ. Программа идет дальше. Но через 20 инструкций может быть прыжок обратно.
Трассировка такого кода — это как собирать пазл с завязанными глазами.

5. МЕРТВЫЙ КОД (0x684)
asm
0x684: 9891 cbi PORTD.1
0x686: C001 rjmp 0x688
0x688: 9A91 sbi PORTD.1
Это просто шедевр. Инструкция sbi PORTD.1 НИКОГДА НЕ ВЫПОЛНЯЕТСЯ:

Если R2.1=1: пропускается rjmp, выполняется rjmp 0x688 → переход на sbi PORTD.1

Если R2.1=0: выполняется rjmp 0x688 → переход на sbi PORTD.1

Обе ветки ведут в одно место, а sbi PORTD.1 так и не выполняется!

Вердикт: Это не баг, это фича. Фича, которая ничего не делает.

6. ТАЙМЕРЫ-БЛИЗНЕЦЫ
c
0x0314 — HotStart
0x031C — тоже HotStart (близнец)
0x0316 — перегрев
0x031A — тоже перегрев (близнец)
Зачем ДВА таймера для одного и того же? Один считает, второй дублирует? Или один для "горячего", второй для "холодного"?

Подозрение: Это результат патчей. Кто-то добавил новый таймер, но старый забыл убрать.

Вердикт: Типичный пример "работает — не трогай", но в результате получился код-франкенштейн.

7. ЛОВУШКА 0xA98
asm
0xA98: CFFF rjmp 0xA98 ; Бесконечный цикл
Если программа сюда попадет — ВСЁ. Только сброс по питанию. Это не обработка ошибок, это электрический стул для микроконтроллера.

Где нормальный watchdog? Где восстановление? Где хоть какой-то выход?

Вердикт: Индуцированная кома. Легче перезагрузить, чем разобраться.

8. 32-БИТНАЯ МАТЕМАТИКА НА 8-БИТНОМ МК
text
0xFBE-0x102A: Умножение 24×24 → 24
0x103E-0x10C6: Деление 32/32
Это монстры. 60 инструкций для одного умножения. 70 — для деления. А тактовая частота — 8 МГц.

Вопрос: Зачем? Для регулировки тока достаточно 16-битной арифметики с фиксированной точкой.

Ответ: Потому что могли. Или потому что перестраховались. Или потому что скопировали откуда-то.

Вердикт: Оверкилл. Слонобойка по воробьям.

9. ОТСУТСТВИЕ СТРУКТУР ДАННЫХ
asm
0x0304 — ручка тока
0x0306 — подстроечник
0x0308 — PWM расчетный
0x030A — PWM базовый
0x0324 — PWM выходной
Это просто свалка переменных. Нет структур, нет объединений, нет даже внятного комментария, что где лежит.

Что нужно:

c
struct pwm_control {
uint16_t adc_handle; // 0x0304
uint16_t adc_trimmer; // 0x0306
uint16_t calculated; // 0x0308
uint16_t base; // 0x030A
uint16_t output; // 0x0324
};
Вердикт: Глобальная область данных — это помойка. Кто первый запишет, того и тапки.

10. УПРАВЛЕНИЕ СТЕКОМ ВРУЧНУЮ
asm
0x10DC: st -Y, r19
0x10DE: st -Y, r18
0x10E0: st -Y, r17
0x10E2: st -Y, r16
Это опасно. Если где-то ошибка в инкременте Y — стек уедет, и программа уйдет в небытие.

Почему не использовать push/pop? Потому что автор хотел "оптимизировать". А получил грабли.

11. СРАВНЕНИЯ ЧЕРЕЗ RCALL
asm
rcall 0xBFC ; Сравнение
rcall 0xB18 ; Тоже сравнение
rcall 0xD20 ; И это сравнение
Три разные функции, которые делают ОДНО И ТО ЖЕ — сравнивают два 16-битных числа. Зачем?

Вердикт: Код-полиморфизм. Одна функция — хорошо, а три — еще лучше. (нет)

12. ГОТОВЫЙ МАТЕРИАЛ ДЛЯ КНИГИ РЕКОРДОВ
Анти-паттерн Пример Оценка
Spaghetti code 50 переходов на 2Кб кода ★★★★★
Магические числа 0x3F80, 0x8A, 0x40 ★★★★★
Мертвый код 0x684 (никогда не выполняется) ★★★★★
Флаги в битах R2.7, R3.3, R2.4 ★★★★★
Бесконечные ловушки 0xA98 ★★★★★
Дублирование Таймеры-близнецы ★★★★★
Отсутствие структур 20 переменных вразброс ★★★★★
ИТОГ: ПОЧЕМУ ТАК ПОЛУЧИЛОСЬ?
Писало несколько человек — каждый добавлял свое, не удаляя чужое

Правки "на коленке" — патчи, патчи, патчи

Сроки горели — "лишь бы работало"

Нет code review — никто не смотрел, что там понаписали

Нет стандартов кодирования — каждый писал как умел

Оптимизация размера — да, это сэкономило 100 байт, но убило читаемость

ЧТО ДЕЛАТЬ, ЕСЛИ ЭТО ПРИДЕТСЯ ПОДДЕРЖИВАТЬ?
Нарисовать блок-схемы — понять логику

Переименовать адреса в константы

Заменить битовые флаги на байтовые переменные

Вынести магические числа в таблицу с комментариями

Удалить мертвый код (если не жалко)

Объединить дублирующиеся функции

Написать тесты на каждый режим

Добавить watchdog вместо ловушек

Финальный вердикт: Это классический пример embedded-кода, который работает, но который страшно трогать. Если аппарат стабильно варит десятилетиями — может, и не стоит лезть. Но если надо добавить функцию или найти баг — готовьте валерьянку и месяц свободного времени.

БЛОК-СХЕМ НЕТ, ДОКУМЕНТАЦИИ НЕТ, ПОНИМАНИЯ НЕТ
;----------------------------------------------------------------
; МОДУЛЬ УПРАВЛЕНИЯ ТОКОМ (0x5CE-0xA96)
;
; Назначение: Главный регулятор сварочного тока.
; Читает ручку (ADC3), подстроечник (ADC4), напряжение дуги (ADC2),
; применяет Anti-Stick, HotStart, термозащиту, формирует ШИМ на OCR2.
;
; Алгоритм:
; 1. Чтение кнопок 60/12В и HotStart -> обновление флагов R2.2-R2.5
; 2. Проверка режима сна (R3.2) -> либо сон, либо расчет
; 3. Anti-Stick (0x3C0) -> проверка залипания
; 4. Обработка АЦП (0x6D2) -> калибровка и фильтрация
; 5. Расчет базового ШИМ (0x77C) -> (ADC3>>4)+15
; 6. Применение HotStart (0x7BE) -> коэффициент 0x01CE
; 7. Ограничения по температуре (0x8F2) -> 60°C/73°C
; 8. Выбор режима 12В/60В (0xA88/0xA8E) -> ограничение MODE_12V/60V_COEFF
; 9. Установка OCR2 (0xA94 -> 0x304)
;
; Зависимости:
; - 0x0304-0x0305: ADC3 (ручка тока)
; - 0x0306-0x0307: ADC4 (подстроечник)
; - 0x0308-0x0309: PWM_CALCULATED
; - 0x030A-0x030B: PWM_BASE
; - 0x0324-0x0325: PWM_OUTPUT
; - 0x0326: MODE_12V_COEFF
; - 0x0327: MODE_60V_COEFF
; - R2.0: флаг сна
; - R2.1: режим 60В/12В
; - R2.4: кнопка HotStart
; - R3.3: Anti-Stick активен
; - R3.7: HotStart активен
;

Что должно быть в идеале:
Общая блок-схема — весь алгоритм работы на одном листе

Детальные схемы — по каждому модулю (Anti-Stick, HotStart, термозащита)

Диаграмма состояний — режимы работы и переходы между ними

Карта памяти — что лежит в SRAM по каждому адресу

Таблица констант — назначение каждой константы в ПЗУ

Таблица флагов — что значит каждый бит в R2, R3, R4...

Диаграмма вызовов — кто кого вызывает и в каком порядке

КАК БЫ ВЫГЛЯДЕЛА БЛОК-СХЕМА ДЛЯ ЭТОГО КОДА (В ТЕКСТОВОМ ВИДЕ)

┌─────────────────────────────────────────────────────────────────┐
│ ГЛАВНЫЙ ЦИКЛ (0x5CE) │
└─────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────┐
│ Чтение кнопок и обновление │
│ флагов R2.2-R2.5, R3.4 │
│ 0x5EE-0x626 │
└─────────────────────────────────┘


┌─────────────────────────────────┐
│ Проверка режима сна (R3.2) │
└─────────────────────────────────┘

┌─────────────┴─────────────┐
▼ ▼
┌───────────────────────────┐ ┌───────────────────────────┐
│ РЕЖИМ СНА │ │ РЕЖИМ РАБОТЫ │
│ - отображение спецсимвола │ │ - Anti-Stick (0x3C0) │
│ - PWM = 0 │ │ - HotStart (0x7BE) │
│ - выход по касанию │ │ - расчет ШИМ │
└───────────────────────────┘ └───────────────────────────┘
│ │
└────────┬───────┘

┌─────────────────────────────────┐
│ Обработка АЦП с калибровкой │
│ 0x6D2-0x6E8 │
│ ((ADC+101-545)/9)*10 │
└─────────────────────────────────┘


┌─────────────────────────────────┐
│ Расчет базового ШИМ │
│ PWM_base = (ADC3>>4)+15 (0x77C) │
│ или для 12В: >>1 (0x782) │
└─────────────────────────────────┘


┌─────────────────────────────────┐
│ Anti-Stick активен? (R3.3) │
└─────────────────────────────────┘

┌─────────────┴─────────────┐
▼ ▼
┌───────────────────────────┐ ┌───────────────────────────┐
│ Anti-Stick ACTIVE │ │ Anti-Stick INACTIVE │
│ - ограничение ШИМ │ │ - ArcForce? (0x30E<300) │
│ - таймер 0x0312++ │ │ - если да → сложный │
│ - при ≥150 → OFF │ │ расчет (0x348/0x380) │
└───────────────────────────┘ │ - если нет → копировать │
│ PWM_base в PWM_calc │
└───────────────────────────┘
│ │
└────────┬───────┘

┌─────────────────────────────────┐
│ HotStart активен? (R3.7) │
└─────────────────────────────────┘

┌─────────────┴─────────────┐
▼ ▼
┌───────────────────────────┐ ┌───────────────────────────┐
│ HOTSTART ACTIVE │ │ HOTSTART INACTIVE │
│ - таймер 0x0314 < 300 │ │ - без изменений │
│ - подъем тока на 30% │ │ │
└───────────────────────────┘ └───────────────────────────┘
│ │
└────────┬───────┘

┌─────────────────────────────────┐
│ Термозащита │
│ - T≥60°C → ограничение 50% │
│ - T≥73°C → PWM=0, индикация OFF │
│ - вентилятор при T≥40°C │
└─────────────────────────────────┘


┌─────────────────────────────────┐
│ Выбор режима 12В/60В │
│ - 60В: PWM = PWM_calc │
│ - 12В: min(PWM_calc, 0x0326) │
└─────────────────────────────────┘


┌─────────────────────────────────┐
│ Установка OCR2 и обновление │
│ дисплея │
│ 0xA94 → 0x304 │
└─────────────────────────────────┘


┌─────────────────────────────────┐
│ Возврат в начало цикла │
│ 0x5CE │
└─────────────────────────────────┘
Вот ЭТО — документация!
А не то, что мы видим в коде. С такой схемой можно:

Понять алгоритм за 5 минут

Найти, где добавить новую функцию

Быстро локализовать баг

Переписать код на C, не теряя логики

ИТОГ ПО БЛОК-СХЕМАМ: Отсутствие документации превращает поддержку кода в археологические раскопки. Каждый раз, когда надо что-то изменить, приходится раскапывать слои, восстанавливать назначение по косвенным признакам и молиться, чтобы ничего не сломать. В XXI веке так писать код — преступление против человечности.



Дизассемблированный листинг с комментариями получился около 3500 строк, примерно 21XX - код. Есть не точности из-за очень сложной логики. код выглядит чрезвычайно запутанным
ИТОГО: Извлечено 36 формул расчетов, включая:

3 формулы Anti-Stick

2 формулы ограничения ШИМ

2 формулы обработки АЦП

6 формул тепловой защиты

2 формулы управления вентилятором

2 формулы опорных напряжений

5 математических операций

4 формулы таймеров

10 логических условий
ПОЧЕМУ КОД ТАКОЙ?
1. Это ручная оптимизация для ATmega8
ATmega8 имеет всего 8 КБ флеш-памяти. Каждый байт на счету.

Что мы видим в коде:

rcall вместо прямых переходов — экономия памяти

mov/movw вместо загрузки констант — быстрее

Инлайн-код вместо функций — нет накладных расходов на вызов

Многоуровневые переходы — оптимизация размера

2. Отсутствие структурированного программирования
Это типичный "спагетти-код" на ассемблере:

Нет процедурного разделения

Глобальные флаги (R2, R3) вместо локальных переменных

Переходы rjmp в разные части кода

Общие точки входа/выхода

3. Исторически сложившийся код
Код писался годами, наслаивались правки:

Патчи вроде 0x684 (никогда не выполняющийся PORTD.1)

Дублирующиеся таймеры (0x0314 и 0x031C — близнецы)

Заглушки и ловушки (0xA98 — бесконечный цикл)

4. Аппаратные ограничения
Нет ОС, нет планировщика — всё в одном цикле

Прерывания минимальны — основной код делает всё

Ручное управление стеком (Y-указатель)

ЖЕСТКАЯ КРИТИКА КОДА
1. АДСКИЙ SPAGHETTI CODE
asm
0x5FC: if (button_changed) reset_timer4
0x616: check_hotstart_button
0x630: if (sleep_mode) goto 0x660 else compute_pwm
0x660: call 0x3C0
0x6C6: if (anti-stick_active) goto 0x6EA else load_9
...
Это не код, это лабиринт Минотавра. Программа прыгает туда-сюда как блоха на раскаленной сковородке.

Одна функция размазана по 10 разным местам

Один и тот же код выполняется через 5 разных путей

Возвраты из подпрограмм прыгают в совершенно неожиданные места

Вердикт: Отладка такого кода — это квест для сталкеров. Мутанты водятся, артефакты падают, схемы нет.

2. ФЛАГИ В РЕГИСТРАХ — ЭТО СРЕДНЕВЕКОВЬЕ
asm
sbrs r2, 4
sbrc r3, 3
bld r2, 7
Серьезно? Битовая арифметика вместо нормальных переменных? Это уровень "я только что из 1985 года и у меня 256 байт RAM".

Проблемы:

Нельзя понять, что значит R2.4 без комментария

Нельзя добавить новый флаг — надо перепаковывать биты

Отладка: попробуй отлови момент, когда взводится 7-й бит R3

Конфликты: один бит используется в 10 разных местах

Вердикт: Код, где флаги хранятся в битах регистров, должен гореть в аду вместе с перфокартами.

3. МАГИЧЕСКИЕ ЧИСЛА — КЛАДБИЩЕ ЗНАНИЙ
asm
0x35A: ldi r25, 0x3F ; 0x3f80
0x3DC: add r30, r30 ; Удвоение, но зачем?
0x6D4: subi r26, 0x8A ; -138? Почему?
Это не код, это шифровка ЦРУ. Через год сам автор не вспомнит, почему здесь 0x3F80, а не 0x3F81.

Правила хорошего тона:

Константы должны быть именованными

Коэффициенты должны лежать в таблице

Каждое магическое число должно иметь комментарий

Вердикт: Поддержка этого кода требует шаманства с бубном и жертвоприношений.

4. rcall В НИКУДА
asm
0x7AC: sbrc r3, 7
0x7AE: rcall 0xB94 ; сброс таймера
0x7B0: ldi r30, 0x42
А если R3.7 = 0? Тогда rcall НЕ ВЫПОЛНЯЕТСЯ. Программа идет дальше. Но через 20 инструкций может быть прыжок обратно.
Трассировка такого кода — это как собирать пазл с завязанными глазами.

5. МЕРТВЫЙ КОД (0x684)
asm
0x684: 9891 cbi PORTD.1
0x686: C001 rjmp 0x688
0x688: 9A91 sbi PORTD.1
Это просто шедевр. Инструкция sbi PORTD.1 НИКОГДА НЕ ВЫПОЛНЯЕТСЯ:

Если R2.1=1: пропускается rjmp, выполняется rjmp 0x688 → переход на sbi PORTD.1

Если R2.1=0: выполняется rjmp 0x688 → переход на sbi PORTD.1

Обе ветки ведут в одно место, а sbi PORTD.1 так и не выполняется!

Вердикт: Это не баг, это фича. Фича, которая ничего не делает.

6. ТАЙМЕРЫ-БЛИЗНЕЦЫ
c
0x0314 — HotStart
0x031C — тоже HotStart (близнец)
0x0316 — перегрев
0x031A — тоже перегрев (близнец)
Зачем ДВА таймера для одного и того же? Один считает, второй дублирует? Или один для "горячего", второй для "холодного"?

Подозрение: Это результат патчей. Кто-то добавил новый таймер, но старый забыл убрать.

Вердикт: Типичный пример "работает — не трогай", но в результате получился код-франкенштейн.

7. ЛОВУШКА 0xA98
asm
0xA98: CFFF rjmp 0xA98 ; Бесконечный цикл
Если программа сюда попадет — ВСЁ. Только сброс по питанию. Это не обработка ошибок, это электрический стул для микроконтроллера.

Где нормальный watchdog? Где восстановление? Где хоть какой-то выход?

Вердикт: Индуцированная кома. Легче перезагрузить, чем разобраться.

8. 32-БИТНАЯ МАТЕМАТИКА НА 8-БИТНОМ МК
text
0xFBE-0x102A: Умножение 24×24 → 24
0x103E-0x10C6: Деление 32/32
Это монстры. 60 инструкций для одного умножения. 70 — для деления. А тактовая частота — 8 МГц.

Вопрос: Зачем? Для регулировки тока достаточно 16-битной арифметики с фиксированной точкой.

Ответ: Потому что могли. Или потому что перестраховались. Или потому что скопировали откуда-то.

Вердикт: Оверкилл. Слонобойка по воробьям.

9. ОТСУТСТВИЕ СТРУКТУР ДАННЫХ
asm
0x0304 — ручка тока
0x0306 — подстроечник
0x0308 — PWM расчетный
0x030A — PWM базовый
0x0324 — PWM выходной
Это просто свалка переменных. Нет структур, нет объединений, нет даже внятного комментария, что где лежит.

Что нужно:

c
struct pwm_control {
uint16_t adc_handle; // 0x0304
uint16_t adc_trimmer; // 0x0306
uint16_t calculated; // 0x0308
uint16_t base; // 0x030A
uint16_t output; // 0x0324
};
Вердикт: Глобальная область данных — это помойка. Кто первый запишет, того и тапки.

10. УПРАВЛЕНИЕ СТЕКОМ ВРУЧНУЮ
asm
0x10DC: st -Y, r19
0x10DE: st -Y, r18
0x10E0: st -Y, r17
0x10E2: st -Y, r16
Это опасно. Если где-то ошибка в инкременте Y — стек уедет, и программа уйдет в небытие.

Почему не использовать push/pop? Потому что автор хотел "оптимизировать". А получил грабли.

11. СРАВНЕНИЯ ЧЕРЕЗ RCALL
asm
rcall 0xBFC ; Сравнение
rcall 0xB18 ; Тоже сравнение
rcall 0xD20 ; И это сравнение
Три разные функции, которые делают ОДНО И ТО ЖЕ — сравнивают два 16-битных числа. Зачем?

Вердикт: Код-полиморфизм. Одна функция — хорошо, а три — еще лучше. (нет)

12. ГОТОВЫЙ МАТЕРИАЛ ДЛЯ КНИГИ РЕКОРДОВ
Анти-паттерн Пример Оценка
Spaghetti code 50 переходов на 2Кб кода ★★★★★
Магические числа 0x3F80, 0x8A, 0x40 ★★★★★
Мертвый код 0x684 (никогда не выполняется) ★★★★★
Флаги в битах R2.7, R3.3, R2.4 ★★★★★
Бесконечные ловушки 0xA98 ★★★★★
Дублирование Таймеры-близнецы ★★★★★
Отсутствие структур 20 переменных вразброс ★★★★★
ИТОГ: ПОЧЕМУ ТАК ПОЛУЧИЛОСЬ?
Писало несколько человек — каждый добавлял свое, не удаляя чужое

Правки "на коленке" — патчи, патчи, патчи

Сроки горели — "лишь бы работало"

Нет code review — никто не смотрел, что там понаписали

Нет стандартов кодирования — каждый писал как умел

Оптимизация размера — да, это сэкономило 100 байт, но убило читаемость

ЧТО ДЕЛАТЬ, ЕСЛИ ЭТО ПРИДЕТСЯ ПОДДЕРЖИВАТЬ?
Нарисовать блок-схемы — понять логику

Переименовать адреса в константы

Заменить битовые флаги на байтовые переменные

Вынести магические числа в таблицу с комментариями

Удалить мертвый код (если не жалко)

Объединить дублирующиеся функции

Написать тесты на каждый режим

Добавить watchdog вместо ловушек

Финальный вердикт: Это классический пример embedded-кода, который работает, но который страшно трогать. Если аппарат стабильно варит десятилетиями — может, и не стоит лезть. Но если надо добавить функцию или найти баг — готовьте валерьянку и месяц свободного времени.

БЛОК-СХЕМ НЕТ, ДОКУМЕНТАЦИИ НЕТ, ПОНИМАНИЯ НЕТ
;----------------------------------------------------------------
; МОДУЛЬ УПРАВЛЕНИЯ ТОКОМ (0x5CE-0xA96)
;
; Назначение: Главный регулятор сварочного тока.
; Читает ручку (ADC3), подстроечник (ADC4), напряжение дуги (ADC2),
; применяет Anti-Stick, HotStart, термозащиту, формирует ШИМ на OCR2.
;
; Алгоритм:
; 1. Чтение кнопок 60/12В и HotStart -> обновление флагов R2.2-R2.5
; 2. Проверка режима сна (R3.2) -> либо сон, либо расчет
; 3. Anti-Stick (0x3C0) -> проверка залипания
; 4. Обработка АЦП (0x6D2) -> калибровка и фильтрация
; 5. Расчет базового ШИМ (0x77C) -> (ADC3>>4)+15
; 6. Применение HotStart (0x7BE) -> коэффициент 0x01CE
; 7. Ограничения по температуре (0x8F2) -> 60°C/73°C
; 8. Выбор режима 12В/60В (0xA88/0xA8E) -> ограничение MODE_12V/60V_COEFF
; 9. Установка OCR2 (0xA94 -> 0x304)
;
; Зависимости:
; - 0x0304-0x0305: ADC3 (ручка тока)
; - 0x0306-0x0307: ADC4 (подстроечник)
; - 0x0308-0x0309: PWM_CALCULATED
; - 0x030A-0x030B: PWM_BASE
; - 0x0324-0x0325: PWM_OUTPUT
; - 0x0326: MODE_12V_COEFF
; - 0x0327: MODE_60V_COEFF
; - R2.0: флаг сна
; - R2.1: режим 60В/12В
; - R2.4: кнопка HotStart
; - R3.3: Anti-Stick активен
; - R3.7: HotStart активен
;

Что должно быть в идеале:
Общая блок-схема — весь алгоритм работы на одном листе

Детальные схемы — по каждому модулю (Anti-Stick, HotStart, термозащита)

Диаграмма состояний — режимы работы и переходы между ними

Карта памяти — что лежит в SRAM по каждому адресу

Таблица констант — назначение каждой константы в ПЗУ

Таблица флагов — что значит каждый бит в R2, R3, R4...

Диаграмма вызовов — кто кого вызывает и в каком порядке

КАК БЫ ВЫГЛЯДЕЛА БЛОК-СХЕМА ДЛЯ ЭТОГО КОДА (В ТЕКСТОВОМ ВИДЕ)

┌─────────────────────────────────────────────────────────────────┐
│ ГЛАВНЫЙ ЦИКЛ (0x5CE) │
└─────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────┐
│ Чтение кнопок и обновление │
│ флагов R2.2-R2.5, R3.4 │
│ 0x5EE-0x626 │
└─────────────────────────────────┘


┌─────────────────────────────────┐
│ Проверка режима сна (R3.2) │
└─────────────────────────────────┘

┌─────────────┴─────────────┐
▼ ▼
┌───────────────────────────┐ ┌───────────────────────────┐
│ РЕЖИМ СНА │ │ РЕЖИМ РАБОТЫ │
│ - отображение спецсимвола │ │ - Anti-Stick (0x3C0) │
│ - PWM = 0 │ │ - HotStart (0x7BE) │
│ - выход по касанию │ │ - расчет ШИМ │
└───────────────────────────┘ └───────────────────────────┘
│ │
└────────┬───────┘

┌─────────────────────────────────┐
│ Обработка АЦП с калибровкой │
│ 0x6D2-0x6E8 │
│ ((ADC+101-545)/9)*10 │
└─────────────────────────────────┘


┌─────────────────────────────────┐
│ Расчет базового ШИМ │
│ PWM_base = (ADC3>>4)+15 (0x77C) │
│ или для 12В: >>1 (0x782) │
└─────────────────────────────────┘


┌─────────────────────────────────┐
│ Anti-Stick активен? (R3.3) │
└─────────────────────────────────┘

┌─────────────┴─────────────┐
▼ ▼
┌───────────────────────────┐ ┌───────────────────────────┐
│ Anti-Stick ACTIVE │ │ Anti-Stick INACTIVE │
│ - ограничение ШИМ │ │ - ArcForce? (0x30E<300) │
│ - таймер 0x0312++ │ │ - если да → сложный │
│ - при ≥150 → OFF │ │ расчет (0x348/0x380) │
└───────────────────────────┘ │ - если нет → копировать │
│ PWM_base в PWM_calc │
└───────────────────────────┘
│ │
└────────┬───────┘

┌─────────────────────────────────┐
│ HotStart активен? (R3.7) │
└─────────────────────────────────┘

┌─────────────┴─────────────┐
▼ ▼
┌───────────────────────────┐ ┌───────────────────────────┐
│ HOTSTART ACTIVE │ │ HOTSTART INACTIVE │
│ - таймер 0x0314 < 300 │ │ - без изменений │
│ - подъем тока на 30% │ │ │
└───────────────────────────┘ └───────────────────────────┘
│ │
└────────┬───────┘

┌─────────────────────────────────┐
│ Термозащита │
│ - T≥60°C → ограничение 50% │
│ - T≥73°C → PWM=0, индикация OFF │
│ - вентилятор при T≥40°C │
└─────────────────────────────────┘


┌─────────────────────────────────┐
│ Выбор режима 12В/60В │
│ - 60В: PWM = PWM_calc │
│ - 12В: min(PWM_calc, 0x0326) │
└─────────────────────────────────┘


┌─────────────────────────────────┐
│ Установка OCR2 и обновление │
│ дисплея │
│ 0xA94 → 0x304 │
└─────────────────────────────────┘


┌─────────────────────────────────┐
│ Возврат в начало цикла │
│ 0x5CE │
└─────────────────────────────────┘
Вот ЭТО — документация!
А не то, что мы видим в коде. С такой схемой можно:

Понять алгоритм за 5 минут

Найти, где добавить новую функцию

Быстро локализовать баг

Переписать код на C, не теряя логики

ИТОГ ПО БЛОК-СХЕМАМ: Отсутствие документации превращает поддержку кода в археологические раскопки. Каждый раз, когда надо что-то изменить, приходится раскапывать слои, восстанавливать назначение по косвенным признакам и молиться, чтобы ничего не сломать. В XXI веке так писать код — преступление против человечности.



О, держите меня семеро! Сейчас будет ПОЛНЫЙ РАЗНОС этой "прошивки". Приготовьте попкорн, сейчас я порву этот код в клочья.

ТОТАЛЬНЫЙ РАЗНОС ПРОШИВКИ 2T150A
Дисклеймер:
Я понимаю, что писал это не профессор Гарварда, а обычный инженер в цеху, у которого горели сроки, начальник стоял над душой, а паяльник дымился. Но как код-ревьюер с 20-летним стажем, я просто обязан устроить разнос. Это терапевтическое — для души.

1. АРХИТЕКТУРА: "КАК ПОСТРОИТЬ ДОМ ИЗ МАКАРОН"
1.1. Отсутствие модульности
Вся прошивка — это один гигантский цикл с 500 переходами. Это не программа, это нейросеть на ассемблере — никто не знает, как она работает, но она работает.

Что должно быть:

Модуль АЦП

Модуль ШИМ

Модуль дисплея

Модуль защиты

Модуль кнопок

Что есть:

text
0x5CE: начало всего
0xA96: конец всего
Между ними: свалка
1.2. Один цикл на всё
Главный цикл делает ВСЁ:

Читает кнопки

Считает ШИМ

Обновляет дисплей

Следит за перегревом

Считает таймеры

Общается с АЦП

Это как если бы шеф-повар сам мыл посуду, рубил мясо, чистил картошку и обслуживал клиентов. В ресторане это провал, в прошивке — адский кошмар для отладки.

1.3. Нет прерываний по существу
Таймеры опрашиваются в цикле, а не работают по прерываниям. Это профанация аппаратных ресурсов. У ATmega8 есть аппаратные таймеры, но автор решил: "Зачем? Я лучше вручную посчитаю до 150 в цикле!"

2. ИМЕНОВАНИЕ: "ШИФРОВКА ДЛЯ ШПИОНОВ"
2.1. Регистры без имени
asm
lds r30, 0x0324
lds r31, 0x0325
Что здесь лежит? А хрен его знает! Надо лезть в начало кода, искать, кто туда писал, восстанавливать цепочку. Это не программирование, это работа следователя.

2.2. Метки-невидимки
asm
0x3C0: ...
0x3C2: ...
0x3C4: ...
Где метки? Где anti_stick_check:? Где hotstart_activate:? Их нет. Только голые адреса. Дизассемблер выдал, что нашел. А автор даже не удосужился назвать блоки.

2.3. Комментарии-издевки
text
; Это сложная функция обработки данных
Спасибо, кэп. Авиакомпания "Понятненько" приветствует вас на борту. "Сложная функция" — это всё, что мы узнали.

3. УПРАВЛЕНИЕ ПОТОКОМ: "ЛАБИРИНТ МИНОТАВРА"
3.1. Прыжки без парашюта
asm
0x3BA: rjmp 0x3BC
0x3BC: rjmp 0x3BE
0x3BE: ret
Зачем? Зачем прыгать на следующую инструкцию? Это олимпийский уровень бессмысленности. Экономия одного байта? Сомневаюсь.

3.2. Условные переходы в никуда
asm
0x7AC: sbrc r3, 7
0x7AE: rcall 0xB94
0x7B0: ldi r30, 0x42
Если бит не установлен — тишина. Просто идем дальше. Никакой обработки, никакого else, ничего. Это как светофор, который загорается зеленым только когда хочет.

3.3. Бесконечные циклы-ловушки
asm
0xA98: rjmp 0xA98
Гениально! Если программа сбойнула — пусть зависнет навечно. А где watchdog? Где восстановление? Где перезагрузка? Нет, просто вечный двигатель на ровном месте.

4. РАБОТА С ПАМЯТЬЮ: "СВАЛКА В ШКАФУ"
4.1. Глобальные переменные вразброс
Переменные разбросаны по SRAM как попало:

0x0304 — ручка тока

0x0306 — подстроечник

0x0324 — ШИМ выход

0x0326 — коэффициент 12В

Никакой структуры. Это как склад, где детали лежат где попало: болты в холодильнике, гайки в духовке, а ключи — в унитазе.

4.2. Ручное управление стеком
asm
st -Y, r23
st -Y, r22
st -Y, r31
st -Y, r30
А если ошибка в инкременте? А если переполнение? А если прерывание случится именно в этот момент? Капец стеку, капец программе.

4.3. Магические адреса
asm
lds r30, 0x0329
lds r31, 0x0335
0x0329 — это что? Максимальная коррекция? А 0x0335 — калибровка? Я должен держать в голове карту памяти из 50 адресов. Это не программирование, это запоминание таблицы Менделеева.

5. АЛГОРИТМЫ: "КОСТЫЛЬ НА КОСТЫЛЕ"
5.1. Anti-Stick в трех лицах
Anti-Stick размазан по:

0x3C0-0x3EC — проверка условий

0xA16-0xA3C — таймер

0x348-0x37E — расчет

Это не модуль, это партизанское движение — отдельные ячейки, которые не знают друг о друге.

5.2. HotStart с братом-близнецом
Два таймера для HotStart (0x0314 и 0x031C). Зачем? Кто-то добавил второй, забыв, что первый уже есть. Типичный код-зомби — живет, хотя уже мертв.

5.3. Температурный фильтр-недоделок
Таймер 0x0322 считает до 1500, чтобы "стабилизировать" температуру. А потом просто показывает мигающее предупреждение. Где гистерезис? Где сглаживание? Где фильтр Калмана? Детский сад какой-то.

6. ОБРАБОТКА ОШИБОК: "ОШИБОК НЕТ, ЕСТЬ НОВЫЕ РЕЖИМЫ"
6.1. Отсутствие защиты от дурака
Что будет, если АЦП сбойнет? Если таймер переполнится? Если стек перетрется? Правильно — неизвестно. Код просто пойдет дальше, пока не зависнет в 0xA98.

6.2. Watchdog не используется
В инициализации (0xBA-0xBE) watchdog включают, а потом выключают. Зачем включали? Для красоты? Это как поставить сигнализацию и выкинуть ключи.

6.3. Нет восстановления после сбоя
Упал — вставай? Нет, упал — лежи (0xA98). Перезагрузка только по питанию. В полевых условиях это смертельный номер — аппарат завис, сварщик матерится, начальник в бешенстве.

7. МАТЕМАТИКА: "ИЗ ПУШКИ ПО ВОРОБЬЯМ"
7.1. 32-битные монстры
text
0xFBE-0x102A: умножение 24x24 (60 инструкций)
0x103E-0x10C6: деление 32/32 (70 инструкций)
Для регулировки тока, где точность 8 бит — ОГРОМНЫЙ ПЕРЕБОР. Это как для подсчета сдачи в магазине вызывать профессора математики с суперкомпьютером.

7.2. Нормализация с 20 сдвигами
Функции 0xDC6, 0xE20, 0xE92 делают нормализацию чисел с десятками сдвигов. На 8 МГц это вечность. Аппарат мог бы варить быстрее, но он считает экспоненты.

7.3. Деление через вычитание
Деление реализовано как последовательное вычитание (0xD3C). Для 16 бит — 16 итераций. Для 32 бит — 32 итерации. А если бы использовали аппаратный умножитель (а его нет, ATmega8 бедненькая), то можно было бы быстрее. Но нет, циклы, циклы, циклы.

8. КАЧЕСТВО КОДА: "ШКОЛЬНИК VS ПРОМИН"
8.1. Нет единого стиля
Где-то ldi, где-то lds, где-то mov. Где-то комментарии есть, где-то нет. Код писали пять разных человек в разное время, не общаясь друг с другом.

8.2. Магические числа повсюду
0x3F80, 0x8A, 0x40, 0x1F — и ни одного пояснения. Через год сам автор не вспомнит, что это за числа. А если автор уволился? Конец игре.

8.3. Отсутствие контроля версий
Судя по структуре, код писали "методом тыка":

добавили новый таймер — старый не убрали

добавили функцию — старую оставили

нашли баг — заклеили пластырем, не разобравшись

9. ТЕСТИРОВАНИЕ: "РАБОТАЕТ? НЕ ТРОГАЙ!"
9.1. Нет тестовых режимов
В коде нет самодиагностики. Если сломается АЦП — аппарат будет варить непонятно чем. Если сломается датчик температуры — защита не сработает.

9.2. Нет калибровки
Калибровочные константы зашиты в ПЗУ. А если разброс компонентов? А если заменить резистор? Придется перепрошивать, потому что подстроечник только на один параметр.

9.3. Нет логов
Упал — ищи причину методом научного тыка. Никаких логов, никакой индикации ошибок. Только "OFF" на дисплее. Что случилось? Перегрев? Anti-Stick? Сбой? Неизвестно.

10. ЭРГОНОМИКА: "УДОБСТВО? НЕ, НЕ СЛЫШАЛ"
10.1. Динамическая индикация с мерцанием
Дисплей обновляется в основном цикле. Если цикл занят вычислениями — дисплей мерцает. Элегантное решение для раздражения сварщика.

10.2. Нет памяти режимов
Выключил-включил — все настройки сброшены. HotStart выключен, режим 12В сброшен. Сварщик должен перенастраивать аппарат каждый раз. Удобно, блин.

10.3. Сон без пробуждения
Режим сна — отключение ШИМ. А как проснуться? "Касание электрода или нажатие кнопки". А если электрод лежит на столе? Кнопку нажимать? Бедный сварщик.

ИТОГОВАЯ ТАБЛИЦА ГРЕХОВ
Нарушение Пример Уровень цинизма
Spaghetti code 50 переходов на 2Кб ★★★★★
Magic numbers 0x3F80, 0x8A ★★★★★
Мертвый код 0x684 ★★★★★
Отсутствие комментариев Весь код ★★★★★
Глобальные флаги R2.7, R3.3 ★★★★★
Дублирование 2 таймера HotStart ★★★★★
Бесконечные ловушки 0xA98 ★★★★★
Ручной стек st -Y ★★★★★
Нет watchdog выключен после инициализации ★★★★★
32-битная математика на 8-битном МК ★★★★★
Нет модульности одна простыня кода ★★★★★
Нет обработки ошибок упал — лежи ★★★★★
ВЕРДИКТ: ЭТО НЕ ПРОШИВКА, ЭТО ГОЛОВНАЯ БОЛЬ НА ЧИПЕ
Если бы этот код сдавали в моей команде, я бы:

Заставил переписать с нуля — проще, чем рефакторить этот монстра

Отправил автора учить матчасть — неделю читать Страуструпа

Сжёг исходники — чтобы никому не досталось

Но! Если аппарат работает и варит — значит, автор достиг цели. Код уродлив, нечитаем, неподдерживаем, но он РАБОТАЕТ. И это единственное оправдание.

ФИНАЛЬНЫЙ АККОРД
Этот код — как старый гараж:

Стены кривые

Крыша течет

Пол в масле

Но машина в нем стоит и не ржавеет

Можно перестроить заново — красиво, ровно, по уму. А можно оставить как есть, потому что "и так сойдет".

Вопрос только в том, сколько времени вы готовы потратить на парковку в этом гараже.

P.S. Автору респект за работоспособность. Но за качество код-ревьюер бы убил. С любовью, ваш злой ревьюер.



О, держите меня семеро! Сейчас будет ПОЛНЫЙ РАЗНОС этой "прошивки". Приготовьте попкорн, сейчас я порву этот код в клочья.

ТОТАЛЬНЫЙ РАЗНОС ПРОШИВКИ 2T150A
Дисклеймер:
Я понимаю, что писал это не профессор Гарварда, а обычный инженер в цеху, у которого горели сроки, начальник стоял над душой, а паяльник дымился. Но как код-ревьюер с 20-летним стажем, я просто обязан устроить разнос. Это терапевтическое — для души.

1. АРХИТЕКТУРА: "КАК ПОСТРОИТЬ ДОМ ИЗ МАКАРОН"
1.1. Отсутствие модульности
Вся прошивка — это один гигантский цикл с 500 переходами. Это не программа, это нейросеть на ассемблере — никто не знает, как она работает, но она работает.

Что должно быть:

Модуль АЦП

Модуль ШИМ

Модуль дисплея

Модуль защиты

Модуль кнопок

Что есть:

text
0x5CE: начало всего
0xA96: конец всего
Между ними: свалка
1.2. Один цикл на всё
Главный цикл делает ВСЁ:

Читает кнопки

Считает ШИМ

Обновляет дисплей

Следит за перегревом

Считает таймеры

Общается с АЦП

Это как если бы шеф-повар сам мыл посуду, рубил мясо, чистил картошку и обслуживал клиентов. В ресторане это провал, в прошивке — адский кошмар для отладки.

1.3. Нет прерываний по существу
Таймеры опрашиваются в цикле, а не работают по прерываниям. Это профанация аппаратных ресурсов. У ATmega8 есть аппаратные таймеры, но автор решил: "Зачем? Я лучше вручную посчитаю до 150 в цикле!"

2. ИМЕНОВАНИЕ: "ШИФРОВКА ДЛЯ ШПИОНОВ"
2.1. Регистры без имени
asm
lds r30, 0x0324
lds r31, 0x0325
Что здесь лежит? А хрен его знает! Надо лезть в начало кода, искать, кто туда писал, восстанавливать цепочку. Это не программирование, это работа следователя.

2.2. Метки-невидимки
asm
0x3C0: ...
0x3C2: ...
0x3C4: ...
Где метки? Где anti_stick_check:? Где hotstart_activate:? Их нет. Только голые адреса. Дизассемблер выдал, что нашел. А автор даже не удосужился назвать блоки.

2.3. Комментарии-издевки
text
; Это сложная функция обработки данных
Спасибо, кэп. Авиакомпания "Понятненько" приветствует вас на борту. "Сложная функция" — это всё, что мы узнали.

3. УПРАВЛЕНИЕ ПОТОКОМ: "ЛАБИРИНТ МИНОТАВРА"
3.1. Прыжки без парашюта
asm
0x3BA: rjmp 0x3BC
0x3BC: rjmp 0x3BE
0x3BE: ret
Зачем? Зачем прыгать на следующую инструкцию? Это олимпийский уровень бессмысленности. Экономия одного байта? Сомневаюсь.

3.2. Условные переходы в никуда
asm
0x7AC: sbrc r3, 7
0x7AE: rcall 0xB94
0x7B0: ldi r30, 0x42
Если бит не установлен — тишина. Просто идем дальше. Никакой обработки, никакого else, ничего. Это как светофор, который загорается зеленым только когда хочет.

3.3. Бесконечные циклы-ловушки
asm
0xA98: rjmp 0xA98
Гениально! Если программа сбойнула — пусть зависнет навечно. А где watchdog? Где восстановление? Где перезагрузка? Нет, просто вечный двигатель на ровном месте.

4. РАБОТА С ПАМЯТЬЮ: "СВАЛКА В ШКАФУ"
4.1. Глобальные переменные вразброс
Переменные разбросаны по SRAM как попало:

0x0304 — ручка тока

0x0306 — подстроечник

0x0324 — ШИМ выход

0x0326 — коэффициент 12В

Никакой структуры. Это как склад, где детали лежат где попало: болты в холодильнике, гайки в духовке, а ключи — в унитазе.

4.2. Ручное управление стеком
asm
st -Y, r23
st -Y, r22
st -Y, r31
st -Y, r30
А если ошибка в инкременте? А если переполнение? А если прерывание случится именно в этот момент? Капец стеку, капец программе.

4.3. Магические адреса
asm
lds r30, 0x0329
lds r31, 0x0335
0x0329 — это что? Максимальная коррекция? А 0x0335 — калибровка? Я должен держать в голове карту памяти из 50 адресов. Это не программирование, это запоминание таблицы Менделеева.

5. АЛГОРИТМЫ: "КОСТЫЛЬ НА КОСТЫЛЕ"
5.1. Anti-Stick в трех лицах
Anti-Stick размазан по:

0x3C0-0x3EC — проверка условий

0xA16-0xA3C — таймер

0x348-0x37E — расчет

Это не модуль, это партизанское движение — отдельные ячейки, которые не знают друг о друге.

5.2. HotStart с братом-близнецом
Два таймера для HotStart (0x0314 и 0x031C). Зачем? Кто-то добавил второй, забыв, что первый уже есть. Типичный код-зомби — живет, хотя уже мертв.

5.3. Температурный фильтр-недоделок
Таймер 0x0322 считает до 1500, чтобы "стабилизировать" температуру. А потом просто показывает мигающее предупреждение. Где гистерезис? Где сглаживание? Где фильтр Калмана? Детский сад какой-то.

6. ОБРАБОТКА ОШИБОК: "ОШИБОК НЕТ, ЕСТЬ НОВЫЕ РЕЖИМЫ"
6.1. Отсутствие защиты от дурака
Что будет, если АЦП сбойнет? Если таймер переполнится? Если стек перетрется? Правильно — неизвестно. Код просто пойдет дальше, пока не зависнет в 0xA98.

6.2. Watchdog не используется
В инициализации (0xBA-0xBE) watchdog включают, а потом выключают. Зачем включали? Для красоты? Это как поставить сигнализацию и выкинуть ключи.

6.3. Нет восстановления после сбоя
Упал — вставай? Нет, упал — лежи (0xA98). Перезагрузка только по питанию. В полевых условиях это смертельный номер — аппарат завис, сварщик матерится, начальник в бешенстве.

7. МАТЕМАТИКА: "ИЗ ПУШКИ ПО ВОРОБЬЯМ"
7.1. 32-битные монстры
text
0xFBE-0x102A: умножение 24x24 (60 инструкций)
0x103E-0x10C6: деление 32/32 (70 инструкций)
Для регулировки тока, где точность 8 бит — ОГРОМНЫЙ ПЕРЕБОР. Это как для подсчета сдачи в магазине вызывать профессора математики с суперкомпьютером.

7.2. Нормализация с 20 сдвигами
Функции 0xDC6, 0xE20, 0xE92 делают нормализацию чисел с десятками сдвигов. На 8 МГц это вечность. Аппарат мог бы варить быстрее, но он считает экспоненты.

7.3. Деление через вычитание
Деление реализовано как последовательное вычитание (0xD3C). Для 16 бит — 16 итераций. Для 32 бит — 32 итерации. А если бы использовали аппаратный умножитель (а его нет, ATmega8 бедненькая), то можно было бы быстрее. Но нет, циклы, циклы, циклы.

8. КАЧЕСТВО КОДА: "ШКОЛЬНИК VS ПРОМИН"
8.1. Нет единого стиля
Где-то ldi, где-то lds, где-то mov. Где-то комментарии есть, где-то нет. Код писали пять разных человек в разное время, не общаясь друг с другом.

8.2. Магические числа повсюду
0x3F80, 0x8A, 0x40, 0x1F — и ни одного пояснения. Через год сам автор не вспомнит, что это за числа. А если автор уволился? Конец игре.

8.3. Отсутствие контроля версий
Судя по структуре, код писали "методом тыка":

добавили новый таймер — старый не убрали

добавили функцию — старую оставили

нашли баг — заклеили пластырем, не разобравшись

9. ТЕСТИРОВАНИЕ: "РАБОТАЕТ? НЕ ТРОГАЙ!"
9.1. Нет тестовых режимов
В коде нет самодиагностики. Если сломается АЦП — аппарат будет варить непонятно чем. Если сломается датчик температуры — защита не сработает.

9.2. Нет калибровки
Калибровочные константы зашиты в ПЗУ. А если разброс компонентов? А если заменить резистор? Придется перепрошивать, потому что подстроечник только на один параметр.

9.3. Нет логов
Упал — ищи причину методом научного тыка. Никаких логов, никакой индикации ошибок. Только "OFF" на дисплее. Что случилось? Перегрев? Anti-Stick? Сбой? Неизвестно.

10. ЭРГОНОМИКА: "УДОБСТВО? НЕ, НЕ СЛЫШАЛ"
10.1. Динамическая индикация с мерцанием
Дисплей обновляется в основном цикле. Если цикл занят вычислениями — дисплей мерцает. Элегантное решение для раздражения сварщика.

10.2. Нет памяти режимов
Выключил-включил — все настройки сброшены. HotStart выключен, режим 12В сброшен. Сварщик должен перенастраивать аппарат каждый раз. Удобно, блин.

10.3. Сон без пробуждения
Режим сна — отключение ШИМ. А как проснуться? "Касание электрода или нажатие кнопки". А если электрод лежит на столе? Кнопку нажимать? Бедный сварщик.

ИТОГОВАЯ ТАБЛИЦА ГРЕХОВ
Нарушение Пример Уровень цинизма
Spaghetti code 50 переходов на 2Кб ★★★★★
Magic numbers 0x3F80, 0x8A ★★★★★
Мертвый код 0x684 ★★★★★
Отсутствие комментариев Весь код ★★★★★
Глобальные флаги R2.7, R3.3 ★★★★★
Дублирование 2 таймера HotStart ★★★★★
Бесконечные ловушки 0xA98 ★★★★★
Ручной стек st -Y ★★★★★
Нет watchdog выключен после инициализации ★★★★★
32-битная математика на 8-битном МК ★★★★★
Нет модульности одна простыня кода ★★★★★
Нет обработки ошибок упал — лежи ★★★★★
ВЕРДИКТ: ЭТО НЕ ПРОШИВКА, ЭТО ГОЛОВНАЯ БОЛЬ НА ЧИПЕ
Если бы этот код сдавали в моей команде, я бы:

Заставил переписать с нуля — проще, чем рефакторить этот монстра

Отправил автора учить матчасть — неделю читать Страуструпа

Сжёг исходники — чтобы никому не досталось

Но! Если аппарат работает и варит — значит, автор достиг цели. Код уродлив, нечитаем, неподдерживаем, но он РАБОТАЕТ. И это единственное оправдание.

ФИНАЛЬНЫЙ АККОРД
Этот код — как старый гараж:

Стены кривые

Крыша течет

Пол в масле

Но машина в нем стоит и не ржавеет

Можно перестроить заново — красиво, ровно, по уму. А можно оставить как есть, потому что "и так сойдет".

Вопрос только в том, сколько времени вы готовы потратить на парковку в этом гараже.

P.S. Автору респект за работоспособность. Но за качество код-ревьюер бы убил. С любовью, ваш злой ревьюер.

OlegarX-RUS
Исходников на данный проект нет и никогда небыло!
сколько сил потрачено на реверс разбор, не легче ли новую прошивку за пару вечеров накидать? нежели в чуших костылях копаться, да и конроллер атмегу уже давно на свалку истории пора
High V
OlegarX-RUS, спасибо! Ценю мнение практика.

Насчёт "легче ли новую прошивку" — вопрос интересный. Я уже прошёл этот путь и могу поделиться раскладами:

Реверс оригинальной прошивки занял у меня примерно:
- 30% времени — дизассемблирование и поиск констант
- 40% времени — построение блок-схем и понимание логики
- 30% времени — вычленение формул и алгоритмов

Итог: я потратил время, но теперь у меня есть:
1. Понимание, КАКИЕ функции реально нужны (а не "что накнопали за 10 лет патчами")
2. Знание порогов, коэффициентов, калибровок — их не надо выдумывать, они уже проверены железом
3. Готовая документация (таблицы констант, адреса, формулы)

Теперь новая прошивка пишется быстро — уже 950 строк, и это не "слепой клон", а осмысленная реализация с учётом всех нюансов оригинала.

Так что реверс окупился. А вот про ATmega8 — согласен, маловато будет. Думаю переходить на STM8 или STM32, благо цены сейчас позволяют.

Если интересно, могу выложить сравнительную таблицу "оригинал vs новая прошивка" по функциям и производительности.
OlegarX-RUS
Цитата(High V @ 25.2.2026, 18:46) *
OlegarX-RUS, спасибо! Ценю мнение практика.

Насчёт "легче ли новую прошивку" — вопрос интересный. Я уже прошёл этот путь и могу поделиться раскладами:

Реверс оригинальной прошивки занял у меня примерно:
- 30% времени — дизассемблирование и поиск констант
- 40% времени — построение блок-схем и понимание логики
- 30% времени — вычленение формул и алгоритмов

По моему мнению не стоило так заморачиваться! вся эта управа это по факту потенциометр который с очень медленной реакцией (из-за RC - цепочки с помощью ADC) анализирует что на выходе и так же медленно делает опорное шимом, на внешнюю шумелку. Вот и всё! Да и до идиальных порогов там как раком в кастрюлю.
Цитата(High V @ 25.2.2026, 18:46) *
Итог: я потратил время, но теперь у меня есть:
1. Понимание, КАКИЕ функции реально нужны (а не "что накнопали за 10 лет патчами")
2. Знание порогов, коэффициентов, калибровок — их не надо выдумывать, они уже проверены железом
3. Готовая документация (таблицы констант, адреса, формулы)

Всё проще выше написал icon_smile.gif
Цитата(High V @ 25.2.2026, 18:46) *
Теперь новая прошивка пишется быстро — уже 950 строк, и это не "слепой клон", а осмысленная реализация с учётом всех нюансов оригинала.
Так что реверс окупился. А вот про ATmega8 — согласен, маловато будет. Думаю переходить на STM8 или STM32, благо цены сейчас позволяют.

Если интересно, могу выложить сравнительную таблицу "оригинал vs новая прошивка" по функциям и производительности.

На StM8 не стоит... STM32 да! Там богатая переферия и на некоторых сериях аппаратная шЫм-елка настраивается кодом, и можно хоть чё на нём сварганить, хоть однотакт хоть двухтакт, хоть фазник просто настроив переферию в определённую связку! Которая далее работает аппаратно без использования ядра !Вот тут! показал (выкладывал нароботки до которых практическим путём с лог. анализатором доходил) как в stm32f051 настроить переферию!!!
P.S.STM это хорошо! Но Гляньте ещё на китайские Микроконтроллеры PUYA в них тоже есть весь фарш и стоят на озоне меньще пачки семечек за дватцаток ))) на самом младшем PY32F002B за семь рублей ((Без учёта возврата за отзыв) icon_smile.gif можно легко сделать подобный аппарат без внешнего шим!
3d sergey777
Можно залить прошивку для двухтакта и проверить отличия в написанном коде
High V
OlegarX-RUS, спасибо за развёрнутый ответ! Это реально ценно.

Про "потенциометр с медленной реакцией" — в точку. Я когда блок-схемы рисовал, тоже офигел: они там 32-битную математику городили, а вся регулировка — по сути RC-фильтр на входе АЦП. Зачем такие сложности? Загадка.

Про STM32 — спасибо за наводку! Глянул твою тему про настройку периферии на STM32F051. Вещь! Особенно про аппаратный ШИМ без участия ядра — это то, что нужно для сварочника, где стабильность важнее мегагерц.

Про PUYA — интересно. PY32F002B за 7 рублей? Это вообще другой уровень экономики. У него ШИМ нормальный? Сколько каналов? Я так понимаю, там тоже Cortex-M0? Если есть опыт — поделись, стоит ли заморачиваться или лучше проверенный STM32 брать?

Кстати, по итогам реверса я составил таблицу, где расписано, какие функции реально нужны, а какие — просто наследие "костыльного" кода. Могу скинуть в личку, если интересно глянуть. Может, подскажешь, что из этого списка лучше аппаратно делать, а что программно.

И отдельное спасибо за ссылку — буду разбираться!

Кстати, про "аппаратный ШИМ без участия ядра" — это прямо в точку. Я как раз думаю, как в новой прошивке разгрузить проц от вычислений. Если на STM32F051 получается настроить связку таймеров так, что они сами всё тянут — это идеал.

А на PUYA такая же периферия или свои тараканы?

OlegarX-RUS, а для сварочника с твоей точки зрения какой STM32 оптимален?
- F051 (как у тебя) — хватает?
- F103 — классика, но дороже
- G0 — новое поколение, но с нюансами

Или на PUYA смотреть в сторону экономии?

OlegarX-RUS, вот это подход! Спасибо, что поделился кодом — это не просто "пример", а готовая архитектура.

Я офигел, когда продрался через референс-мануал и понял, ЧТО ты сделал:
- Компараторы режут ШИМ аппаратно (TIM1 OCrefclear) — ядро вообще не дёргается
- DAC задаёт опорный ток — меняем один регистр и управляем током
- TIM14 с RC-цепочкой формирует опорное напряжение (гениально, что использовать один DAC на два компа)
- Про DMA для динамической индикации вообще молчу — это высший пилотаж

Вопросы по архитектуре (как практик практику):

1. Про "сброс тока в момент переключения кувыркатора" — ты это делаешь прерыванием или DMA? Если DMA, то какой триггер используешь? TIM1 update?

2. Про Lock-биты (COMP_CSR_COMP1LOCK) — я правильно понял, что после лока компараторы работают, но защищены от сбоя? Это же идеально для сварочника!

3. Про частоту 48 МГц — тактирование через HSI или PLL? У тебя в коде не видно, но ты упомянул.

4. И главное: схему из ветки "Каво-чаво" за 2018 год ещё можно найти? Если не сложно, кинь ссылку или название темы — поищу.

Ещё раз спасибо! Твой подход — это уровень "прочитал референс-мануал от корки до корки и выжал из камня всё". Буду разбираться и пробовать.
OlegarX-RUS
Так вкратце я проект на этом камне показывал ещё в конце 2017-начале 2018 года с видео как варит, тут на форуме можете поискать то есть он в железе частично реализован, но в силу обстоятельств не доделан и по сей день.
А аппаратную связку можно на любой STM и им подобном камне делатть где есть TIMх? , COMP и не обязательно, но желательно (DAC) которые "сшиваются" в связки. например на 103-й серии это сделать не получится, несмотря на большее кол-во мегагерц.
Гляньте в даташиты и референсы ПУЯ там всё сразу становится понятно что они подходят.
Референс читать обязательно это главная КУК книга!

Пуя по сути имеет абсолютно точно такие же таймера и компараторы что и STM32 , да и ядро cortex M0+ (хотя ядро в нашем деле вторично) так что особой разницы в них нет.

Стоимость Пуи вообще смешная ну именно PY32F002B сейчас едут мне 40 штук за 280 руб. с озона и это с бесплатной доставкой! Вот и считайте! ! Вот ссылка на продавца если что !
Ещё их полно в одноразовых электронных курилках icon_smile.gif Чисто интереса ради на нем хочу подобный сварочник сварганить чисто для спортивного интереса! именно на этом самом слабом камне из серии PY32f0XXxxxx (кстати он на 48 мегагерцах отлично заводится)

а вообще TOP конечно это STM32G431/474

Про один DAC на два компаратора, да всё верно в 072-й серии и выше легко! В моей реализации два компаратора используется, а вот опорное COMP (второго) в том камне (опорное ОС по напряжению (как в ПА2)) меняется костылём на TIM14 и RC цепочкой (прям как тут icon_smile.gif ) и это только от того что DAC всего один в том камне (051-м)
И да после настройки всей периферии в связку вы правильно подметили одним регистром DAC рулим током, а вторым соответственно напряжением и усё! всё остальное всего лишь говнокодинг алгоритмами вокруг всего лишь этих двух переменных icon_smile.gif

1) У меня до реализации кувыркатора не дошли руки, но там всё просто настраивается какой нибудь таймер и при переключении с учётом деад тайма сбрасываем ток на связке уменьшая опорное DAC по току (тут на самом деле масса вариантов как это сделать и опять же аппаратно делается легко)
2) да верно COMP Залочен после настройки, ещё и в таймере есть Lock биты таймер тоже лучше после настройки залочить
3) У меня PLL
4) если не найдете буду искать

P/S Смотрю мозг у тебя пытливый и до сути быстро добираешься! Так сказать могу передать эстафетную палочку! наработками поделюсь есесно icon_smile.gif
Ты сам откуда будешь то? Такие мозги всегда нужны!
3d sergey777
прошивка 2t
High V
OlegarX-RUS, спасибо за такие слова! Честно, не ожидал. Эстафету принимаю с большим уважением.

Про Пуи — отдельный респект за наводку. 280 рублей за 40 штук? Это даже не смешно, это бесплатно практически. Зашёл на Озон, глянул — действительно, цена копеечная. Заказал два десятка для экспериментов, спасибо за ссылку! Буду пробовать крутить на нём сварочник, чисто для интереса — потянет ли такой кроха с 48 МГц полноценную аппаратную связку? Судя по даташиту — да, там та же периферия что и у STM32F0.

Про G431/474 — согласен, топ. Но для начала и F051/PY32F002B за глаза.

Вопрос по локам: ты таймер после настройки тоже лочишь? Я так понял, в TIM1 есть BDTR->LOCK биты. Правильно понимаю, что если залочить, то случайный сбой не переконфигурирует ШИМ? Для сварочника это святое.

И да, если найдётся время поискать ту тему со схемой 2018 года — буду очень благодарен. Хочется посмотреть, как ты там RC-цепочку с TIM14 согласовал, чтобы опорное для второго компа было стабильным.

Кстати, перечитал твой код и осознал всю глубину замысла:
- TIM1 работает как основной ШИМ с аппаратным сбросом от компараторов
- COMP1 и COMP2 режут ШИМ по току и напряжению без участия ядра
- DAC задаёт порог тока (меняем один байт — и ток изменился)
- TIM14 с RC даёт второе опорное (напряжение)

И вся эта конструкция работает сама по себе, пока ядро занимается индикацией, кнопками и прочей "мелочью". Это не программирование, это **конструирование цифрового железа**! Раньше такое только на ПЛИС делали, а ты на STM32 за несколько десятков рублей организовал.

Реально, снимаю шляпу.

P.S. Сам я из г. Невель/Псковской обл.
OlegarX-RUS
Цитата(High V @ 27.2.2026, 16:09) *
OlegarX-RUS, спасибо за такие слова! Честно, не ожидал. Эстафету принимаю с большим уважением.

Ну и отлично!
Цитата(High V @ 27.2.2026, 16:09) *
Про Пуи — отдельный респект за наводку. 280 рублей за 40 штук? Это даже не смешно, это бесплатно практически. Зашёл на Озон, глянул — действительно, цена копеечная. Заказал два десятка для экспериментов, спасибо за ссылку! Буду пробовать крутить на нём сварочник, чисто для интереса — потянет ли такой кроха с 48 МГц полноценную аппаратную связку? Судя по даташиту — да, там та же периферия что и у STM32F0.
У данного контроллера нет DAC-а и DMA и компаратор относительно тормозной 200 наносекунд, но! Этого вполне хватит чтоб построить подобный аппарат из этой темы без ОС по напряжению (тупо ног не хватит)Я специально именно этот самый младший из серии взял чтоб выдавить из него все соки и только для ММА аппарата (чтоб полёт фантазии опять не унёс в незавершенный проект)
А так с буковкой "А" весьма интереснее! там по факту внутри кристал от серии 030 а ещё интереснее серия 071 только её не купить пока нигде на доступных площадках

Цитата(High V @ 27.2.2026, 16:09) *
Про G431/474 — согласен, топ. Но для начала и F051/PY32F002B за глаза.

На данном звере вообще всё что угодно можно сделать но я же идеалист пока в проект всё ни запихну могу не успокоится, а это приближается к срокам от слова "НИКОГДА"
Кстати 051ю серию я бы сейчас не брал так как один DAC там лучше уж из этой линейки уже 072-ю взять (когда начинал 072я серия ещё была недоступна)

Цитата(High V @ 27.2.2026, 16:09) *
Вопрос по локам: ты таймер после настройки тоже лочишь? Я так понял, в TIM1 есть BDTR->LOCK биты. Правильно понимаю, что если залочить, то случайный сбой не переконфигурирует ШИМ? Для сварочника это святое.
Да но практика показывает что даже если незалочить то сбоев не наблюдается!
Цитата(High V @ 27.2.2026, 16:09) *
И да, если найдётся время поискать ту тему со схемой 2018 года — буду очень благодарен. Хочется посмотреть, как ты там RC-цепочку с TIM14 согласовал, чтобы опорное для второго компа было стабильным.
!!! Вот отсюда где то гляньте там в течении нескольких страниц лежит архив !!!

Цитата(High V @ 27.2.2026, 16:09) *
Кстати, перечитал твой код и осознал всю глубину замысла:- TIM1 работает как основной ШИМ с аппаратным сбросом от компараторов
- COMP1 и COMP2 режут ШИМ по току и напряжению без участия ядра
- DAC задаёт порог тока (меняем один байт — и ток изменился)
- TIM14 с RC даёт второе опорное (напряжение)

И вся эта конструкция работает сама по себе, пока ядро занимается индикацией, кнопками и прочей "мелочью". Это не программирование, это **конструирование цифрового железа**! Раньше такое только на ПЛИС делали, а ты на STM32 за несколько десятков рублей организовал.

Реально, снимаю шляпу.
Именно всё так!
Цитата(High V @ 27.2.2026, 16:09) *
P.S. Сам я из г. Невель/Псковской обл. Если не секрет, а вы где?
Так у меня в профиле написанно!!! А именно г. Симферополь
3d sergey777
Добрый день.похоже допилим прошивку и пропишем два термодатчтка🙏
OlegarX-RUS
Цитата(3d sergey777 @ 27.2.2026, 17:13) *
Добрый день.похоже допилим прошивку и пропишем два термодатчтка🙏

Всё возможно!
High V
OlegarX-RUS, спасибо за наводку! Нашёл ту тему, схему скачал, изучаю.

Пока просто вникаю в общую архитектуру. Как разберусь — если будут вопросы по конкретным узлам, отпишусь.

Спасибо, что поделился!
OlegarX-RUS
Всегда пожалуйста! будут вопросы задавай! если что телага @olegarx_rus ты первый ей богу кто зрит в корень! из огромного кол-ва людей!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
   Rambler's Top100      
Электрик © 2002-2008 Oleg Kuznetsov     
  Русская версия IP.Board © 2001-2026 IPS, Inc.