Светодиодные фонари и световые приборы. Всё о светотехнике.
Вернуться   Форум FONAREVKA.RU Мастерские светотехников Мастерская: INFERION
Расширенный поиск
Забыли пароль? Регистрация

  • О нашем проекте
  • Светотехника и световые приборы
  • Правила форума
Проект FONAREVKA.RU специализируется на предоставлении всей необходимой информации по светотехнике:

— светодиодные фонари;
— различные источники питания;
— разнообразные зарядные устройства;
— освещение помещений и наружное освещение;
— световые приборы для личного, пассажирского и грузового транспорта;
— специальные световые приборы для медицины, для растений, для аквариумов, для террариумов, а также аварийно-сигнальные световые приборы;
— альтернативные источники света;
— лазеры и лазерная техника.

Если у вас есть вопросы по выбору фонарей, аккумуляторов и зарядных устройств ознакомьтесь с FAQ от наших экспертов:

F.A.Q. по выбору фонарей различных типов;
F.A.Q. по выбору аккумуляторов;
F.A.Q. по выбору зарядных устройств.
Ответ  Создать новую тему
Просмотров в теме 27713   Ответов в теме 57   Подписчиков на тему 4   Добавили в закладки 0
Опции темы Поиск в этой теме
Старый 15.04.2013, 02:36 Автор темы   1

 
Аватар для INFERION
 
Регистрация: 07.04.2013
Последняя активность: 13.06.2023 02:24
Адрес: Украина, Полтава
Сообщений: 5774
Сказал(а) спасибо: 340
Поблагодарили: 8154 раз(а) в 2385 сообщениях

По умолчанию Программная реализация драйвера на примере Indigo 3.0s

Будет МНОГО (я предупреждал) писанины, ассемблерного кода, осциллограмм. Тема врятли будет интересна тем, кто пишет на Си, или вообще не занимается подобными вещами (разработкой стабилизаторов на МК). Я не претендую на звание какого-то там доктора наук, профессора и т.п. Всё что будет написано ниже - просто мой опыт, которым я решил с вами поделится. Чтоб хоть как-то спрятать весь этот БОЛЬШОЙ 3.141592654... часть текста я спрячу под спойлеры...

И так:
Задача - построить стабилизатор тока на ATtiny25/45/85 с блекджеком и шлюхами .
Топология - мониторим ток на шунте, крутим напряжение самостоятельного преобразователя - TPS63030.

Техническую часть вопроса о схемотехнике я опускаю. Как рассчитывать схемки и какие детальки лепить - те кто способны это осилить и без меня знают. Поэтому я просто кину готовую схему:
Нажмите на изображение для увеличения
Название: Indigo 3.0s.png
Просмотров: 3471
Размер:	77.5 Кб
ID:	72812
Да, очень похожа на Indigo 4.0 из соседней темы, не просто так ведь и название похоже? Это, кстати, к вопросу о прошивке в свободном доступе. Тут она и будет рассматриваться, правда к чуть другой и упрощённой схеме.
Объяснять тут на первый взгляд нечего. МК следит за падением на шунте, подкручивая свой ШИМ - классика. Допустим схемку мы набросали, резисторы рассчитали, кондёры в скользких местах тоже, решили что питание МК фильтровать не надо, входы АЦП глушить фильтрами тоже. Мол и в программе эти все гадости ликвидируем (ассемблер же!). Собрали прототип:
Нажмите на изображение для увеличения
Название: P4084445.JPG
Просмотров: 3003
Размер:	206.1 Кб
ID:	72810
Распаяли на нём ISP, для удобства отлаживания, и залили тестовую примитивную программу, чтоб убедится в работоспособности:
Нажмите на изображение для увеличения
Название: P4124449.jpg
Просмотров: 2911
Размер:	40.7 Кб
ID:	72811Нажмите на изображение для увеличения
Название: P4124448.jpg
Просмотров: 2779
Размер:	71.6 Кб
ID:	72813
Всё готово. Начинаем писать программу, и тут начинается гора вопросов...
1. АЦП прилично шумит, как бороться с шумом?
2. Как работать с EEPROM, чтоб максимально продлить её срок службы?
3. Как реализовать обратную связь, чтоб быстро и стабильно работала?
4. Как, и какие прикрутить защиты от переразряда и перегрева?

1. Шум АЦП.
Сам по себе АЦП не шумит. У него такая архитектура, что там шуметь просто нечему. R2R ЦАП и компаратор, всё... Резисторы шумят, да, но явно не с амплитудой в 0,1%. Компаратор тоже может шуметь, но подобные вещи шумят, как правило, ещё меньше за резисторы. Есть у нас ещё ИОН, вот как он там устроен - я не знаю, но весь АЦП в сборе даёт где-то 0,25LSB шуму при тактовой 1МГц (макс. скорость) во время работы ШИМ и программы. Это даже мало, для эффективного использования передискретизации нам оптимален шум в 1LSB. Т.е. при грамотной реализации программы шум мешать нам не будет. Возникает вопрос - как грамотно реализовать?

Народ, судя по гуглу, борется с шумом двумя способами:
- Следует рекомендациям даташита. Запускаем измерение, и пока меряет - НЕ ДЫШАТЬ!!! Т.е. уходить чуть ли не Power-down, пока АЦП не разрешит дальнейшую работу ядра и всей периферии. Да, способ хороший, когда нам ничего одновременно с этим делать не надо, а разрешения в 10 бит достаточно. Передискретизация, ввиду отсутствия шума, работать будет плохо. Поэтому получим то, что написано в даташите - 10 бит, и никак не больше.
- Использует ADLAR, внимание, для того чтоб упросить процедуру отсечения последних двух якобы "всегда" зашумленных и не несущих совершенно "никакой" полезной информации бит. Вместо того чтоб заниматься усреднением ошибки - делаем ошибку искусственно достаточно большой, чтоб на её фоне не замечать исходную. Аппаратное умножение значения АЦП на 64 чудесным образом превращается в деление на 4 (X=X*64/256=X/4), достаточно просто тягать данные с ADCH, а на младшую часть, где затерялись два младших бита, просто забить. Ну да, а для чего же его ещё использовать, как не для забивания гвоздей?

В нашем случае требуется одновременная работа и ШИМ, и программы, и АЦП, поэтому бороться с шумом придётся менее примитивными способами. По-сути всё сводится к достаточно жесткой синхронизации всего этого дела, чтоб ошибка вырождалась в постоянную величину. Другими словами - наложение спектров (частоты дискретизации и помех) дало в результате 0Гц. Привязать софт к ШИМ не проблема, существуют прерывания и флаги, а вот с АЦП сложнее, и в этом нам "помогли" разработчики камня. Во первых устройство выборки/хранения (далее УВХ) там кривое. За отведённые ему 1,5...2 такта АЦП, в авто триггерном режиме, он просто не успевает "сохранить" аналоговое значение со слишком высокоомного источника сигнала. Такими источниками является, к примеру, встроенный температурный сенсор, ИОН, различные делители напряжения где-то там снаружи, даже встроенный дифференциальный усилитель, необходимый для измерения шунта, тугой на подъём. Ещё и у самого УВХ есть внутреннее сопротивление.
1,5...2 такта - очень мягко сказано. Предусмотрительные инженеры сделали так, чтоб при переключении каналов АЦП первый раз подключал УВХ на 13,5 тактов, чего всё равно оказалось мало. Как минимум один такой семпл нужно выбрасывать.
Вторая проблема авто триггерного режима - невозможность его перенастроить, пока он работает и что-то меряет. Т.е. вы закинуть в него новые настройки можете, но когда полезете забирать результат - окажется что он подсунул вам не то, а то что надо - только только начал измерять... Приходится останавливать, перенастраивать, и снова запускать.
Третья проблема такого режима - невозможность синхронизации с ШИМ. Можно синхронно запустить, даже частоту ШИМ подкрутить под частоту дискретизации АЦП, но тогда останавливать их уже нельзя, а соответственно и с реконфигурацией будут проблемы. Асинхронный же режим гарантировано обеспечит нас отменным генератором шума...
Синхронизировать АЦП с таймером можно и аппаратно, но проблема реконфигурации остаётся...

Получается что АЦП нужно использовать в режиме одиночных выборок, и каждый раз запускать вручную. Запустили, ушли делать свои дела, подождали пока таймер скажет "готово" - забрали результат, перенастроили если нужно, и снова запустили... Почему результат забираем не по прерыванию/флагу АЦП "Я готов - забирай"? Потому что в таком случае софт привязан к ШИМ, а т.к. АЦП привязан к софту - ну вы поняли...
Теперь вылазит ещё один момент. Максимальная чувствительность АЦП к грязи (субъективная) в тот момент, когда он меряет младшие биты. Те самые, которые обычно зашумлены. В эти моменты необходимо бросать всё и таки не дышать, иначе результат будет заметно хуже. В нашем случае ничего особого не требуется, достаточно посчитать количество тактов, за которые АЦП производит измерение, и выполнять код кусками, засыпая хотя бы за пару тактов АЦП до окончания измерения. К примеру таймер переполняется за 256 тактов ядра, АЦП на максимальной скорости, в режиме одиночных выборок, требуется 200 тактов ядра, при переполнении срабатывает прерывание, в котором "что-то" (об этом ниже) делается около 40 тактов, значит у нас есть 16 тактов чтоб прочитать значение и запустить АЦП (в обратном порядке глючит). Запустили АЦП, с этого момента у нас есть около 180-ти тактов, чтоб что-то сделать, дальше необходимо... заснуть? Хорошо бы, да инженеры и тут умудрились насолить. Вот нельзя спать, АЦП команду Sleep рассматривает как установку бита ADSC (видать думает что мы перестали дышать и пора значит работать), т.е. сразу же начинает мерять следующий семпл, как только справится с текущим. Из-за чего мы не можем его по понятным причинам перенастроить и запустить, ибо он уже занят... И что делать? Да что, в цикле только висеть и остаётся. Цикл нужно оформить максимально коротким и монотонным, чтоб он создавал аккуратный шум на как можно более высокой частоте. С этим хорошо справляется BRTC. Переходит сам на себя до тех пор, пока прерывание таймера не поставит флаг T. Пока АЦП меряет 1 бит - цикл успеет навернуть 4 круга (тактовая ядра 8МГц).

ФУУУУХ... С АЦП разобрались, едем дальше...

2. Работа с EEPROM.
Ну, с этим я долго не возился, почти сразу всё нормально завелось согласно задумке. Задача:
Переключение режимами осуществляется разрывами питания, для этого требуется где-то хранить информацию о предыдущем режиме, чтоб можно было глянуть что же было до этого и, соответственно, что сейчас включать. Определить длительность выключения не сложно, достаточно повесить на RESET конденсатор и при запуске опрашивать бит "EXTRF". Если он стоит, значит конденсатор успел разрядится и некоторое время удерживал лапу после подачи питания. Тогда загружаем сохранённый режим. Иначе же выключение было кратковременным и МК должен проверить флаг "PORF". Если он стоит, значит сброс сопровождался ПОЛНЫМ выключением питания, т.е. всё в порядке, и можно перезаписывать и загружать режим на шаг выше. А вот если его нет (сам он не убирается, его надо сразу же чистить при обнаружении) - значит перезагрузка произошла из-за супервизора. т.е. сел аккумулятор и переключать режим вверх нельзя - ложная тревога. Тут или пытаться запустится с током по-меньше, или вообще уйти дрыхнуть до лучших времён. Пока всё просто и понятно, проблема начинается с использования EEPROM...

EEPROM недолговечен, обещают около 100 000 циклов записи. С таким ресурсом мы очень быстро "доклацаемся", что делать? Во первых ячеек у нас вагон, нужно придумать механизм, размазывающий по ним нагрузку. Во вторых в каждой ячейке аж 8 бит, необязательно стирать всю ячейку, чтоб перезаписать 1 бит. Это недокументированная особенность, но использовать её никто не запрещает. После стирания содержимое ячейки - 0xFF. При записи бит можно только сбросить, установить - только стиранием всей ячейки. Можно производить стирание 1 раз на 8 циклов записи, что как минимум в 2...8 раз продлит ресурс каждой ячейки. А если всё таки получили повреждение? Да, нужно придумать как детектировать ошибки, и обходить их стороной, если не получается устранить. Ещё полезная недокументированная особенность AVR, которая может стать причиной глюков - регистры общего назначения (R0...R31 которые) таки хранят данные без питания, несмотря на всю свою энергозависимость. Несколько часов...недель, но хранят. Поэтому эти ячейки нужно тереть при конфигурации, иначе мусор в них может сбить с толку программу. Эту особенность полезно прикрутить к нашей кнопке на случай, если ВСЯ EEPROM окончательно загнётся. Что интересно - тут текста больше чем кода, реализующего всё это, несмотря на всю свою ассемблерность:
Код:
	clr	R16
	in	R21,	MCUSR
	out	MCUSR,	R16		;Очистить MCUSR
	sbrs	R21,	PORF		;Не переключать, если PORF очищен
	ser	R21

	clr	R18			;Поиск активного байта (хоть какого-нибудь рабочего)
	rjmp	eeloop
rdeelp:	inc	R18
	cpi	R18,	EEPROMEND-8	;Конец памяти кнопки
	brcs	eeloop
	clr	R18			;Альтернативная память
	mov	R16,	R28
	sbi	GPIOR0, 0		;Флаг альтернативного режима
	rjmp	eeend
eeloop:	out	EEARL,	R18		;Прочитать байт из EEPROM
	sbi	EECR,	EERE
	in	R16,	EEDR
	cpi	R16,	0x00
	breq	rdeelp			;Прочитать следующий, если 0x00

eeend:	cpi	R16,	0b11111111	;Декодирование активного байта
	breq	pwr1
	cpi	R16,	0b01111111
	breq	pwr2
	cpi	R16,	0b00111111
	breq	pwr3
	cpi	R16,	0b00011111
	breq	pwr4
	cpi	R16,	0b00001111
	breq	pwr1
	cpi	R16,	0b00000111
	breq	pwr2
	cpi	R16,	0b00000011
	breq	pwr3
	cpi	R16,	0b00000001
	breq	pwr4
	sbis	GPIOR0,	0
	rjmp	rdeelp			;Прочитать следующий при ошибке
	ser	R16			;Первый режим при ошибке в альтернативном режиме

pwr1:	sbrc	R21,	EXTRF		;Установка текущего режима
	rjmp	pwr1ld
	rcall	pwrup
	rjmp	pwr2ld
pwr1ld:	ldi	R16,	EEPROMEND-7
	rjmp	pwrout

pwr2:	sbrc	R21,	EXTRF
	rjmp	pwr2ld
	rcall	pwrup
	rjmp	pwr3ld
pwr2ld:	ldi	R16,	EEPROMEND-5
	rjmp	pwrout

pwr3:	sbrc	R21,	EXTRF
	rjmp	pwr3ld
	rcall	pwrup
	rjmp	pwr4ld
pwr3ld:	ldi	R16,	EEPROMEND-3
	rjmp	pwrout

pwr4:	sbrc	R21,	EXTRF
	rjmp	pwr4ld
	rcall	pwrup
	rjmp	pwr1ld
pwr4ld:	ldi	R16,	EEPROMEND-1
	rjmp	pwrout


pwrup:	lsr	R16			;Сохранить следующий режим (хоть куда-нибудь)
	mov	R28,	R16
	clr	R19
	ldi	R17,	0b00100100	;Write Only, EEMPE
newrt:	out	EEDR,	R16
	out	EEARL,	R18
	out	EECR,	R17
	sbi	EECR,	EEPE
pwrlp:	sbic	EECR,	EEPE
	rjmp	pwrlp
	sbi	EECR,	EERE
	in	R17,	EEDR
	cp	R17,	R16
	brne	pwrer
	tst	R16
	breq	eeclr
	ret
pwrer:	ldi	R17,	0b00000100	;Erase and Write, EEMPE
	clr	R20
	out	EEDR,	R20
	out	EECR,	R17
	sbi	EECR,	EEPE
pwrlp1:	sbic	EECR,	EEPE
	rjmp	pwrlp1
	rjmp	adrinc
eeclr:	ser	R16
	ldi	R17,	0b00010100	;Erase Only, EEMPE
adrinc:	cpi	R19,	EEPROMEND-8	;Счётчик количества байт
	brcs	ewlpok
	ret
ewlpok:	inc	R18
	inc	R19
	cpi	R18,	EEPROMEND-8	;Конец памяти кнопки
	brcs	newrt
	clr	R18
	rjmp	newrt


pwrout: ;Тут загружаем из EEPROM ток, используя содержимое R16 в качестве адреса.

Можно сделать и хитрее, вместо опроса MCUSR запускать АЦП на измерение напряжения того самого конденсатора. Это позволит отключить RESET, подцепить на него полноценную кнопку и при этом оставить возможность использования альтернативного режима, ещё и более гибко определять время выключенного состояния. Для лазера не очень применимо из-за опасности самостоятельного включения при перебое питания, если используется управление передней кнопкой. А для фонарика покатит...

Разобралисть, следующая передача...

3. Обратная связь по току O_o.
Вот только сейчас понимаю, насколько много мне ещё придётся писать... Попробую по-короче.
Задача: Необходимо разобраться какой тип регулятора сюда оптимально влепить, и как его рассчитать.

Самым простым регулятором я считаю триггерный, работающий по принципу "больше - глушим, меньше - 100% тяги". Собирается обычно на компараторе с явным и неявным гистерезисом, его обожают тулить во всякие ZXSC400, LM2621 и прочий хлам. Даже бабушкин утюг работает с таким регулятором - термореле называется. Этот вариант сразу отбрасываем, у нас как минимум для него недостаточно быстродействия, хотя сам по себе он при грамотной реализации весьма не плох, т.к. характер регулирования напоминает Сигма-Дельта Модуляцию в звуковых АЦП/ЦАП. Ещё живой пример - самоосциллирующие усилители класса D, UcD, которые сейчас рвут в хлам классику по всем параметрам (лампофилы - не берите близко к сердцу). Суть в том, что на ВЧ происходит генерация из-за ПОС, но на НЧ ПОС превращается в ООС и там то как раз сигнал хорошо повторяет опорное значение. Программно такое реализовать на AVR эффективнее, чем использование АЦП, я пока не пробовал. Для небольших скоростей да, в тех же терморегуляторах прокатит. К примеру китайцы используют такой механизм в паяльных станциях Lukey. Я бы его назвал тиристорным регулятором из-за того, что он по проводам, сети и нагревателю бьёт как отбойным молотком, аж свет моргает...

Более сложный механизм - Пропорциональный (П) и Пропорционально-интегральный (ПИ) регуляторы. Почему я их рассматриваю вместе? П-регулятор как частный случай ПИ-регулятора, его ставят там, где ПИ не может работать устойчиво (об этом ниже), поэтому сейчас поведаю только о ПИ. Примеров такой ОС масса. Это классическая ОС всех наших стабилизаторов в радиоэлектронике. Т.е. ОУ (Операционный Усилитель) как П-регулятор с огромным усилением и частотной коррекцией (кондёром в цепи ОС), которая является интегратором. На большой частоте (высоких скоростях) усиление такого регулятора снижается для избежания возбуждения (перерегулирования). Снижение усиления П-регулятора приводит к возникновению статической ошибки, которую добивает интегратор на более низких частотах. Отдельно они редко используются, а вот вместе - идеальная пара. С них и начнём, но я сначала расскажу вкратце ещё о двух типах связи, забегая наперёд (пригодится, поверьте).

ПИД - все слышали, да? Весь гугл им изгажен, а толковой информации мало. Это тот же ПИ, только с дополнительным дифференциальным (Д) звеном. Его можно представить как фильтр ВЧ, который компенсирует снижение усиления ошибки ПИ-регулятора на высоких скоростях (частотах). Нам он ниже здорово пригодится, ибо как выяснится позже - без него эта схема устойчивой не будет...

Прямая связь, предикативная ОС, управление с разомкнутой петлёй, фильтр Калмана... Я периодически натыкаюсь на описание одного и того же механизма под разными названиями и разного уровня сложности, и как правильно этот тип связи назвать - не знаю. Но идея шикарная, и благодаря цифре внедряется всюду. Суть в том, что некий "чёрный ящик", написанный сумрачным гением, изучает управляемую цепь, строит её виртуальную модель, и прежде чем сделать какой-то шаг - гоняет эту модель в виртуальной среде и выясняет что же она сделает ещё до того, как это произойдёт в реальности. Звучит громоздко и ресурсожруще, правда? Да вот нифига, несколько строк кода и мы симулируем RC-фильтр, колебательный контур, или целый динамик. На AVR в реальном времени. Я вот даже фотку у себя нашел, как тинька рисует 16 бит синус виртуальным колебательным контуром, затрачивая 4 байта на переменные и порядка 20-ти тактов на семпл:
Нажмите на изображение для увеличения
Название: P3120030.jpg
Просмотров: 2884
Размер:	108.1 Кб
ID:	72792


С ОС мы уже определились, попробуем начать с ПИ-регулятора, рассчитаем коэффициенты. Начнём с самого худшего сценария, когда напряжение питания максимально, а дифференциальное сопротивление нагрузки минимально. В этом случае сигнал ошибки с шунта и отклик преобразователя на изменения заполнения ШИМ будут максимальны. Нам необходимо определится с исходными данными для этого сценария. Напряжение питания у нас максимум 4,35V, но мы возьмём 5V на всякий случай. Дифференциальное сопротивление типичной для данной весовой категории нагрузки на 0,5A (макс. ток драйвера, там сопротивление это минимально) - 1...0,5Ом, если верить графикам ВАХ в даташитах на всякие CREE XP-G, фиолетовые ЛД (лазерные диоды) и т.п. Плюс 0,1Ом шунта про запас.
Ранее в схеме мы рассчитали сопротивления в цепи ОС под интересующий нас диапазон напряжений, влепили конденсатор интересующей нас ёмкости, чтоб достаточно хорошо задавить пульсации ШИМ, и теперь можем определить сколько LSB ШИМ нам требуется для изменения тока на 1A. Получить так сказать условные попугаи, с которыми можно работать в программе. Закон Ома я тут рассказывать не буду, кто рассчитал цепь - сумеет и в обратном порядке всё посчитать. Скажу только что тут у меня получилось около 10V на 100% ШИМ (7...2V при изменении среднего значения ШИМ с 0 до 2,522V). На меньших напряжениях питания зависимость будет не такая крутая, но нас это сейчас не беспокоит, сценарий худший. К тому же точно всё рассчитывать смысла нет, ибо всё равно потом добивать осциллографом.
Если мы хотим прогуляться через весь диапазон токов, т.е. получить от АЦП 0...1023 (0...65472 с ADLAR) - нам придётся изменить заполнение ШИМ всего на 100%/(10V/(0,5A*0,6Ом))=3%. Т.е. вопрос о расширении разрядности ШИМ ОЧЕНЬ актуален, посему сразу переходим в 16-ти разрядную систему, используя плотностно-импульсную модуляцию младшего бита ШИМ. Да, привет интегрирование остатка в системе с ограниченной разрядностью. Не сможем пропихнуть в один период, так хоть размажем по нескольким. Это справедливо и для АЦП, т.к. мы поставили ADLAR и собираемся использовать передискретизацию. И так, какой вывод? Для теоретической устойчивости необходимо отклонения, полученные с АЦП, делить как минимум на 32 (100%/3%=33,33), и только после этого модифицировать ими заполнение ШИМ. Это справедливо для ситуации, когда за один период система полностью примет новое значение, но на практике это не будет по трём причинам:
- На выходе ШИМ сидит RC фильтр, который противно крутит фазу и режет спектр. Лечится специальным алгоритмом компенсации (та самая прямая связь, с моделью). Благо его параметры нам известны - постоянная времени порядка 1,024мс (не просто так, да).
- Дифференциальный усилитель АЦП тоже режет спектр и крутит фазу. Частота среза по даташиту 4кГц, значит компенсировать в текущих условиях эту паразитную RC-цепь (скорее всего передаточная дифф. усилителя повторяет передаточную RC-цепи) не получится. Да и вредно это, т.к. компенсация подразумевает использование ВЧ-фильтра, который явно не способствует подавлению шума.
- Преобразователь тоже не супер мега быстрый, но на его фоне АЦП просто нервно курит в сторонке.
Всё это в сумме даёт некую общую задержку. С RC-фильтром на выходе ШИМ мы разберёмся, его отбрасываем. По сравнению с тормозами АЦП преобразователь - формула один, поэтому его тоже отбрасываем. Частота дискретизации у нас 31,25кГц, если считать что на частоте 2кГц АЦП практически ничего не искажает - мы получаем по 16 семплов на период. В периоде, как мы помним, нам необхомо делить показания на 32, а если у нас период состоит из 16-ти семплов, то каждый придётся делить на 32*16=512. Это на самом деле дофига, т.к. даже с учётом предварительного аппаратного умножения 10-ти разрядного числа на 64 мы теряем целых 2 бита информации! Поэтому придётся их тоже куда-то складывать и использовать, когда насобирается целое число. И так, пишем с коэффициентом 256. А вдруг заработает?

Написали, зашили, смотрим:
Нажмите на изображение для увеличения
Название: P4134450.JPG
Просмотров: 821
Размер:	150.0 Кб
ID:	72793Нажмите на изображение для увеличения
Название: P4134452.JPG
Просмотров: 779
Размер:	127.5 Кб
ID:	72794Нажмите на изображение для увеличения
Название: P4134453.JPG
Просмотров: 793
Размер:	124.9 Кб
ID:	72795
Нифига оно не заработало. Получили генератор вместо стабилизатора. Значит закидываем расчётное значение:
Нажмите на изображение для увеличения
Название: P4134454.JPG
Просмотров: 804
Размер:	141.4 Кб
ID:	72796
Что за выброс? Рассмотрим детальнее:
Нажмите на изображение для увеличения
Название: P4134455.JPG
Просмотров: 915
Размер:	147.0 Кб
ID:	72797
Похоже на косяки с компенсатором RC-цепи, поковыряю его:
Нажмите на изображение для увеличения
Название: P4134456.JPG
Просмотров: 722
Размер:	115.9 Кб
ID:	72798
Круто, а если так?:
Нажмите на изображение для увеличения
Название: P4144461.JPG
Просмотров: 776
Размер:	136.2 Кб
ID:	72800
Подробнее:
Нажмите на изображение для увеличения
Название: P4134457.JPG
Просмотров: 711
Размер:	155.8 Кб
ID:	72799
Съедобно. Получается попали в точку, коэффициент - 512, имеем код (упрощённый для понимания):
Код:
currfb:	clt
lpcur:	brtc	lpcur
	in	R23,	ADCL		;Записать данные АЦП в буфер
	in	R24,	ADCH
	sbi	ADCSRA,	6

	ldi	ZH, HIGH(RAMEND-23)
	ldi	ZL, LOW(RAMEND-23)
	ld	R16,	Z+		;Загрузить Iref
	ld	R17,	Z+

	cp	R23,	R16		;ПИ-звено
	cpc	R24,	R17		;+/-
	brcs	loTon

	sub	R23,	R16		;Tonnom-=(Iout-Iref)/512
	sbc	R24,	R17
	lsr	R24
	ror	R23
	adc	R7,	R23		;Интегратор остатка от деления
	adc	R24,	R1
	sub	R3,	R24
	sbc	R4,	R1
	rjmp	currfb			;Клиппинг ОС (КЗ)
	clr	R3
	clr	R4
	rjmp	currfb

loTon:	sub	R16,	R23		;Tonnom+=(Iref-Iout)/512
	sbc	R17,	R24
	lsr	R17
	ror	R16
	adc	R7,	R16		;Интегратор остатка от деления
	adc	R17,	R1
	add	R3,	R17
	adc	R4,	R1
	rjmp	currfb
	ser	R16			;Клиппинг ОС (перегрузка)
	mov	R3,	R16
	mov	R4,	R16
	rjmp	currfb

Теперь увеличиваю выходное сопротивление источника питания до 1Ом:
Нажмите на изображение для увеличения
Название: P4144462.JPG
Просмотров: 934
Размер:	160.6 Кб
ID:	72801
Во как! Это называется паразитной ПОС (положительной обратной связью), которую я и ловил добавляя сопротивление. Когда ток на выходе растёт - преобразователь начинает потреблять больше, напряжение проседает вместе со средним значением ШИМ, из-за чего ток продолжает расти. Ну и наоборот. ОС МК должна быть достаточно быстрой, чтоб своевременно реагировать на подобную ситуацию и выруливать изменения быстрее, чем они успевают пробиваться через фильтр. Тут нам помогает компенсация этого фильтра, которая делает его для ОС невидимым, в то время когда не званным помехам приходится пробираться через него самостоятельно... Но что блин делать? Быстрее ОС не сделать - возбуждение, а этой скорости мало, вот вот начнётся генерация. Да, конечно же дифференциальное звено . Прикручиваем:
Код:
;--------------------------------------------------------------------
;ОС по макс. току:

currfb:	clt
lpcur:	brtc	lpcur

	in	R23,	ADCL		;Записать данные АЦП в буфер
	in	R24,	ADCH
	sbi	ADCSRA,	6
	sbi	GPIOR0, 1		;512 семплов стабилизации тока
	ser	R29

curfb1:	ldi	ZH, HIGH(RAMEND-23)
	ldi	ZL, LOW(RAMEND-23)
	ld	R16,	Z+		;Загрузить Iref
	ld	R17,	Z+
;--------------------------
	ld	R18,	Z+		;Дифференциальное звено
	ld	R19,	Z+		;Загрузить IrefDiffdmp

	cp	R18,	R23		;Сглаживание
	cpc	R19,	R24		;+/-
	breq	dmoutc
	brcc	morecd

	mov	R20,	R23		;X=(Iout-IrefDiffdmp)/512
	mov	R21,	R24
	sub	R20,	R18
	sbc	R21,	R19
	lsr	R21
	ror	R20
	adc	R8,	R20		;Интегратор остатка от деления
	adc	R21,	R1
	add	R18,	R21		;IrefDiffdmp+=X
	adc	R19,	R1
	sub	R3,	R21		;Tonnom-=X
	sbc	R4,	R1
	brcc	dmoutc
	clr	R3
	clr	R4
	rjmp	dmoutc


morecd:	mov	R20,	R18		;X=(IrefDiffdmp-Iout)/512
	mov	R21,	R19
	sub	R20,	R23
	sbc	R21,	R24
	lsr	R21
	ror	R20
	adc	R8,	R20		;Интегратор остатка от деления
	adc	R21,	R1
	sub	R18,	R21		;IrefDiffdmp-=X
	sbc	R19,	R1
	add	R3,	R21		;Tonnom+=X
	adc	R4,	R1
	brcc	dmoutc
	ser	R20
	mov	R3,	R20
	mov	R4,	R20

dmoutc:	st	-Z,	R19		;Записать IrefDiffdmp
	st	-Z,	R18
;---------------------------

	cp	R23,	R16		;ПИ-звено
	cpc	R24,	R17		;+/-
	brcs	loTon

	sub	R23,	R16		;Tonnom-=(Iout-Iref)/512
	sbc	R24,	R17
	lsr	R24
	ror	R23
	adc	R7,	R23		;Интегратор остатка от деления
	adc	R24,	R1
	sub	R3,	R24
	sbc	R4,	R1
	brcc	iout1			;Клиппинг ОС (КЗ)

pwroff:	cli				;Выключение при сбое
	clr	R16
	out	TCCR1,	R16		;Вырубить ШИМ
	out	PLLCSR,	R16		;Остановить ФАПЧ
	out	ADCSRA,	R16		;Выключить АЦП
	out	PORTB,	R16		;Сбросить порт
	ldi	R17,	0b10110000
	ldi	R16,	0b10110100
lpwoff:	out	MCUCR,	R16		;BOD Sleep, Sleep, режим Power-down, BOD Sleep Enable
	out	MCUCR,	R17		;BOD Sleep, Sleep, режим Power-down
	SLEEP				;Вечный сон...
	rjmp	lpwoff


loTon:	sub	R16,	R23		;Tonnom+=(Iref-Iout)/512
	sbc	R17,	R24
	lsr	R17
	ror	R16
	adc	R7,	R16		;Интегратор остатка от деления
	adc	R17,	R1
	add	R3,	R17
	adc	R4,	R1
	brcc	iout1
	ser	R16			;Клиппинг ОС (перегрузка)
	mov	R3,	R16
	mov	R4,	R16

iout1:	dec	R29
	brne	crmxlp
	sbic	GPIOR0,	1	
	rjmp	clrbt1
	rjmp	main

clrbt1:	cbi	GPIOR0, 1
crmxlp:	clt
lpcur2:	brtc	lpcur2
	in	R23,	ADCL		;Записать данные АЦП в буфер
	in	R24,	ADCH
	cpi	R29,	1
	brne	llcmax
	sbic	GPIOR0,	1	
	rjmp	llcmax
	ldi	R16,	0b00101100	;Измерение Vcc
	out	ADMUX,	R16
llcmax:	sbi	ADCSRA,	6
	rjmp	curfb1

Нажмите на изображение для увеличения
Название: P4144463.JPG
Просмотров: 826
Размер:	99.3 Кб
ID:	72802Нажмите на изображение для увеличения
Название: P4144465.JPG
Просмотров: 793
Размер:	111.5 Кб
ID:	72803
Гораздо лучше, свою работу оно делает. На практике никогда таких аккумуляторов не будет, с целым Омом сопротивления, но устойчивость лучше проверить заранее...
Дифференциальное звено как ПИ-регулятор, только наоборот. Поэтому и коэффициент ему пришиваем такой же - 512. Всё, что происходит быстрее чем на него успевает среагировать ПИ-регулятор - притормаживается до вменяемой скорости дифференциальным звеном. Это не совсем ПИД, т.к. звено включено нестандартно и охватывает лишь шунт, с опорным значением возится ПИ. Просто это проще, а у нас ресурсов не вагон...
И так, мы реализовали работающий скелет (среду) с ОС по току. Свою прямую функцию драйвер делает, теперь нам не составит труда добавить некоторые функции, о которых и пойдёт речь ниже.

4. Защиты.
Т.к. мускулы у драйвера самоходные - реализовывать защиту от перенапряжения, перегрузки и перегрева ключа нет смысла. От переполюсовки программа вообще не защитит, но у нас есть полевик на входе. Что остаётся? Я так понимаю переразряд батареи нужно корректно отрабатывать, и перегрев. Начнём с простого, и снова ОС...

Защита от перегрева.
Простейший вариант - триггер. Добрались до какой-то там температуры - что-то ВНЕЗАПНО сделало. Переключило на мощность по-меньше, или вовсе вырубилось. Обычно я приблизительно такие реализации и вижу...
Более сложный вариант - "аналоговая" ОС, что-то из области ПИ, ПИД и т.п. Чтоб мягко ограничивала мощность, удерживая температуру на пороге. Гугл говорит что для термоконтроля ПИД вне конкуренции, изучим:
Для того чтоб заставить работать ПИД - необходимо точно знать условия, или хотя бы гарантировать их неизменность, т.к. каждое звено этого регулятора что-то требует, и требования эти противоречивы требованиям соседа. Например у нас есть фонарь (лазер) в конкретном корпусе, с казалось бы известными параметрами. Мощность нагревателя известна, теплоёмкость тоже, влияние этой всей бодяги на тормоза термодатчика можно подобрать на практике. Настроили, сунули под одеяло - возбуд. Теплоотдача ухудшилась, температура растёт быстрее, дифференциальное звено начинает перерегулировать. Сунули в стакан с водой - возбуд. Теплоёмкость увеличилась, температура растёт медленно и интегратор перерегулирует. Хуже всего то, что эти условия могут тянутся практически до бесконечности (вместо стакана озеро, к примеру). "Тело" не пойми как себя может вести, поэтому требуется максимально устойчивая ОС. Условия то на самом деле хренпоймические! Причём настолько, что даже ПИ-регулятор будет неустойчив (пример с интегратором уже привёл). Что остаётся, П? Выходит что так, у него нет никакой памяти, он действует по факту и грубо. Но хотя бы действует... Устойчивость задаётся усилением ошибки. Тормоза (инерция) на стабильность влияют в лучшую сторону, поэтому если заставить стабильно работать голый драйвер, то с радиатором он уж точно заведётся нормально. Тут ещё придётся поплясать с бубном вокруг АЦП, который очень плохо работает с температурным сенсором, давая около 1LSB на градус. Шум давить тяжело, учитывая что программа у нас меряет температуру всего 60 раз в секунду и шум спокойно может стать заметным на глаз. С одной стороны чем больше мы сделаем усиление, тем точнее будет держатся температура, но тем грубее будет работа регулятора (меньше ступенек). Я решил остановится на 10LSB. Т.е. граница будет размазана на 10 градусов, в зависимости от условий охлаждения и подводимой мощности. Система обладает не хилой инерцией, этим грех не воспользоваться. Можно влепить фильтр НЧ, чтоб он сглаживал шум. Главное чтоб его постоянная времени была достаточно меньшей за постоянную времени системы нагреватель-радиатор-термодатчик, иначе можно получить возбуждение. Т.к. нагреваться радиатор (рядом с нагревателем, где и находится термодатчик) обычно быстрее, чем остывает - имеет смысл делать асимметричный фильтр, чтоб положительные изменения температуры пропускал быстрее отрицательных. Голой плату использовать не планируется, поэтому желательно ОС сделать такой, чтоб получить на этой плате колебания. Это поднимет характеристики драйвера в конечном изделии, на какой бы кусок говна его там не прикрутили. Опыт показал, что оптимальными коэффициенты оказались в 32 для положительных, и 128 для отрицательных изменений соответственно. Числа эти показывают 1/(61Гц/X) постоянной времени в секундах. Т.е. задежка вверх порядка 0,5с, а вниз - 2с. Этого достаточно, чтоб голая "звезда" вот вот начинала "раскачиваться" при токе в пару ампер (мучил китайские 1W). Понятное дело что так издеваться врятли кто будет...
Код:
;--------------------------------------------------------------------
;Температура

	ldi	R29,	5		;Пропустить 5 семплов АЦП
lpttmp:	clt
lptmp:	brtc	lptmp
	dec	R29
	breq	lptout
	sbi	ADCSRA,	6
	rjmp	lpttmp

lptout:	in	R23,	ADCL		;Записать данные АЦП в буфер
	in	R24,	ADCH
	ldi	R16,	0b10100111	;Измерение Iout
	out	ADMUX,	R16
	sbi	ADCSRA,	6

	ldi	ZH, HIGH(RAMEND-6)
	ldi	ZL, LOW(RAMEND-6)
	ld	R17,	Z+		;Загрузить tempmax

	clr	R16			;t=(t-tmax)*64
	sec				;+256
	ror	R17			;x64
	ror	R16
	lsr	R17
	ror	R16

	sub	R23,	R16		;Подготовка значения АЦП
	sbc	R24,	R17
	brcc	subtok
	clr	R23
	clr	R24
subtok:	cpi	R24,	4
	brcc	ovrmul
	lsr	R23
	ror	R24
	ror	R23
	ror	R24
	ror	R23
	rjmp	multok
ovrmul:	ser	R24
	ser	R23

multok:	ld	R18,	Z+		;Загрузить температуру
	ld	R19,	Z+

	sbic	GPIOR2,	5		;пропустить сглаживание,
	rjmp	tdmpok			;если выборка первая
	sbi	GPIOR2,	5
	mov	R18,	R24
	mov	R19,	R23

tdmpok:	clr	R22
	cp	R24,	R18		;Сглаживание
	cpc	R23,	R19		;+/-
	breq	equalt
	brcc	moretd

	mov	R20,	R18		;?
	mov	R21,	R19
	sub	R20,	R24
	sbc	R21,	R23
	lsl	R20			;/128
	rol	R21
	brcc	okdnt1
	ser	R21
	rjmp	okdnt2
okdnt1:	brne	okdnt2
	inc	R21
okdnt2:	sub	R18,	R21
	sbc	R19,	R22
	rjmp	equalt

moretd:	sub	R24,	R18
	sbc	R23,	R19
	lsl	R24			;/32
	rol	R23
	rol	R24
	rol	R23
	rol	R24
	rol	R23
	rol	R24
	andi	R24,	0b00000111
	cp	R23,	R22
	cpc	R24,	R22
	brne	okupt2
	inc	R23
okupt2:	add	R18,	R23
	adc	R19,	R24

equalt:	st	-Z,	R19		;Записать температуру
	st	-Z,	R18


Защита от переразряда.
Та же ситуация - хочется плавного ограничения. Я вижу две скользкие ситуации. Первая - удерживание напряжения на пороге 3V, регулируя под него ток нагрузки. При достижении этого порога фонарь начнёт вести себя как китаец на батарейках - всё тусклее и тусклее светить, и конца этому нет... Для этой задачи достаточно ПИ-регулятора, т.к. изменения очень медленные и отследить их не проблема. Но есть и второй момент:
В момент включения нельзя допустить перезагрузку, если батарея дохлая или её выходное сопротивление слишком высокое и она даже при полном заряде проседает ниже плинтуса (2,7V, ниже МК рестартует аппаратно). У нас в программе реализован софт-старт (0,25с), поэтому скорость роста тока нормирована, благодаря чему возможен расчёт дифференциального звена, чтоб оно притормаживало скорость, если напряжение питания слишком быстро для ПИ-звена падает. Максимальная скорость нарастания тока - 31мА (0...500мА размазано на 16 ступенек). В худшем случае такой скачок увеличит потребление с батареи миллиампер на 70. И если мы возьмём максимальное гарантированное внутреннее сопротивление батареи в 1Ом, то получим 0,07V просадки на ступеньку. Д не должен допустить снижения напряжения ниже 2,8V, однако на более высоких значениях его усиление необходимо притуплять, чтоб он не мешал там, где такие моменты не страшны. Например ATX БП сильно шумит, этот шум прекрасно пролазит через это звено и "срёт в эфир" (серьёзно, у меня даже приёмник начинает шуметь). Чтоб шум АЦП не доставал при нормальной работе - придётся таки отсечь пару младших битов. Всё равно точность тут ненужна, это аварийный стоп-кран.
Код:
;--------------------------------------------------------------------
;Напряжение питания:

main:	ldi	R29,	10		;Пропустить 10 семплов АЦП
lptvcc:	clt
lpvcc:	brtc	lpvcc
	dec	R29
	breq	lpvout
	sbi	ADCSRA,	6
	rjmp	lptvcc

lpvout:	in	R23,	ADCL		;Записать данные АЦП в буфер
	in	R24,	ADCH
	ldi	R16,	0b10101111	;Измерение температуры
	out	ADMUX,	R16
	sbi	ADCSRA,	6


vccld:	ldi	ZH, HIGH(RAMEND-27)	;Дифференциальное звено
	ldi	ZL, LOW(RAMEND-27)
	ld	R19, -Z			;Загрузить VccLoad
	ld	R18, -Z
	ld	R17, -Z			;Загрузить VccDiffdmp
	ld	R16, -Z

	sbic	GPIOR2, 6		;Пропустить сглаживание,
	rjmp	diffok			;если выборка первая
	sbi	GPIOR2, 6
	mov	R16, R23
	mov	R17, R24

diffok:	clr	R0
	cp	R16, R23		;Сглаживание
	cpc	R17, R24		;+/-
	breq	dmotvj
	brcc	morevd

	mov	R20, R23		;VccLoad+=(ADC-VccDiffdmp-256)*2/1...8
	mov	R21, R24
	sub	R20, R16
	sbc	R21, R17
	subi	R21, 2			;Порог LSB
	brcs	advlok
	lsl	R20			;Коэффициент
	rol	R21
	cpi	R24, 0x58		;Порог 3,2V
	brcc	lower1
	lsr	R21			;/2
	ror	R20
lower1:	cpi	R24, 0x4E		;Порог 3,6V
	brcc	lower2
	lsr	R21			;/4
	ror	R20
lower2:	cpi	R24, 0x40		;Порог 4,4V
	brcc	lower3
	lsr	R21			;/8
	ror	R20
lower3:	add	R18, R20
	adc	R19, R21
	brcc	advlok
	ser	R18
	ser	R19

advlok:	mov	R20, R23		;VccDiffdmp+=(ADC-VccDiffdmp)/32
	mov	R21, R24
	sub	R20, R16
	sbc	R21, R17
	lsl	R20
	rol	R21
	rol	R20
	rol	R21
	rol	R20
	rol	R21
	rol	R20
	andi	R20, 0b00000111
	cp	R21, R0
	cpc	R20, R0
	brne	okdnvd
	inc	R21
okdnvd:	add	R16, R21
	adc	R17, R20
dmotvj:	rjmp	dmoutv


morevd:	mov	R20, R16		;VccLoad-=(VccDiffdmp-ADC-256)*2/1...8
	mov	R21, R17
	sub	R20, R23
	sbc	R21, R24
	subi	R21, 2			;Порог LSB
	brcs	sbvlok
	lsl	R20			;Коэффициент
	rol	R21
	cpi	R24, 0x58		;Порог 3,2V
	brcc	lower4
	lsr	R21			;/2
	ror	R20
lower4:	cpi	R24, 0x4E		;Порог 3,6V
	brcc	lower5
	lsr	R21			;/4
	ror	R20
lower5:	cpi	R24, 0x40		;Порог 4,4V
	brcc	lower6
	lsr	R21			;/8
	ror	R20
lower6:	sub	R18, R20
	sbc	R19, R21
	brcc	sbvlok
	clr	R18
	clr	R19

sbvlok:	mov	R20, R16		;VccDiffdmp-=(VccDiffdmp-ADC)/32
	mov	R21, R17
	sub	R20, R23
	sbc	R21, R24
	lsl	R20
	rol	R21
	rol	R20
	rol	R21
	rol	R20
	rol	R21
	rol	R20
	andi	R20, 0b00000111
	cp	R21, R0
	cpc	R20, R0
	brne	okupvd
	inc	R21
okupvd:	sub	R16, R21
	sbc	R17, R20

dmoutv:	st	Z+, R16			;Записать VccDiffdmp
	st	Z+, R17


	ldi	R20, 0xC0		;ПИ-звено
	ldi	R21, 0x5D		;Порог 3V

	cp	R20, R23
	cpc	R21, R24
	brcc	morevl			;+/-

	sub	R23, R20		;VccLoad+=(ADC-Vccmin)/32
	sbc	R24, R21
	lsl	R23
	rol	R24
	rol	R23
	rol	R24
	rol	R23
	rol	R24
	rol	R23
	andi	R23, 0b00000111
	cp	R24, R0
	cpc	R23, R0
	brne	modupv
	inc	R24
modupv:	add	R18, R24
	adc	R19, R23
	brcc	vpiout
	ser	R18
	ser	R19
	rjmp	vpiout

morevl:	sub	R20, R23		;VccLoad-=(Vccmin-ADC)/32
	sbc	R21, R24
	lsl	R20
	rol	R21
	rol	R20
	rol	R21
	rol	R20
	rol	R21
	rol	R20
	andi	R20, 0b00000111
	cp	R21, R0
	cpc	R20, R0
	brne	moddnv
	inc	R21
moddnv:	sub	R18, R21
	sbc	R19, R20
	brcc	vpiout
	clr	R18
	clr	R19

vpiout:	st	Z+, R18			;Записать VccLoad
	st	Z+, R19


Остальное.
А что делать, когда напряжение уже не держится на 3,0V и продолжает падать? Ток к этому моменту будет минимален, запустится таймер, посчитает до 10-ти (секунд) и если за это время состояние не улучшится - уйдёт в Power-down. Задержка необходима на случай, если произойдёт перерегулирование. Драйвер ещё может выйти на режим, поэтому сразу же отключать не стоит. Этот же механизм сработает, если перегретое устройство не успеет остыть за это время. Может возникнуть ситуация, когда драйвер всё таки возбудился, или же когда не хватает напряжения питания, чтоб опустить напряжение на выходе до требуемого значения (к примеру КЗ при питании 3V). В такой ситуации драйвер засыпает немедленно.
Очень полезный механизм, которого тут не хватает - не дающий ОС уйти в насыщение, когда преобразователь по тем или иным причинам не может выдать требуемый ток. Актуально для лазеров, ибо в таком состоянии ОС пропустит выброс, если преобразователь ВНЕЗАПНО осилит то, что от него требуют. Но я пока не придумал адекватного механизма. В голову приходит только модуляция тока, с проверкой реальной амплитуды, возможно реализую...
Всякие феньки, свистелки, перделки и т.п. я тут не рассматриваю, т.к. они не вызывают проблем у программистов. Скажу только что "та странная фиговина, торчащая на схеме как аппендицит" - электромагнитный привод коллиматора, поэтому и буква "s" в названии - special. Заточенная под конкретную конструкцию система. Другой вариант имеет подстроечник и ещё ряд фенек, но из-за полукоммерческой основы я им светить не могу...

Вот весь код. Забыл свалить в общую кучу переменные в ОЗУ. Код достался по наследству от Indigo 4.0 и переделывался выпиливанием всего лишнего. Пооставались дырки в памяти...
Код:
;Драйвер на связке ATiny25 (45) и TPS63030 (20), версия с переключателем фокуса

	.INCLUDE "tn25def.inc"

;Векторы прерываний

	rjmp	RESET
	reti
	reti
	reti
	reti
	set				;Over0
;/*
;Расширитель разрядности с компенсацией ("прямая связь"):

	cp	R5,	R3		;Компенсация RC-цепи (T=1,024ms)
	cpc	R6,	R4
	brcs	locap			;Выбор знака (псевдознаковая арифметика)

	mov	R18,	R5		;Ton=C-(C-FB)*32
	mov	R19,	R6
	sub	R18,	R3
	sbc	R19,	R4
	cpi	R19,	8
	brcc	xmin
	lsr	R18
	ror	R19
	ror	R18
	ror	R19
	ror	R18
	ror	R19
	ror	R18
	mov	R16,	R5
	mov	R17,	R6	
	sub	R16,	R19
	sbc	R17,	R18
	brcc	xok1
xmin:	clr	R16
	clr	R17

xok1:	mov	R0,	R17
	add	R2,	R16
	adc	R0,	R1
	out	OCR1A,	R0

	mov	R18,	R5		;C-=(C-Ton)/32
	mov	R19,	R6
	sub	R18,	R16
	sbc	R19,	R17
	lsl	R18
	rol	R19
	rol	R18
	rol	R19
	rol	R18
	rol	R19
	rol	R18
	andi	R18, 0b00000111
	sub	R5,	R19
	sbc	R6,	R18
	reti


locap:	mov	R16,	R3		;Ton=(FB-C)*32+C
	mov	R17,	R4
	sub	R16,	R5
	sbc	R17,	R6
	cpi	R17,	8
	brcc	xmax
	lsr	R16
	ror	R17
	ror	R16
	ror	R17
	ror	R16
	ror	R17
	ror	R16
	add	R17,	R5
	adc	R16,	R6
	brcs	xmax
	cpi	R16,	0xFF
	brcs	xok2
xmax:	ser	R16
	clr	R17

xok2:	mov	R0,	R16
	add	R2,	R17
	adc	R0,	R1
	out	OCR1A,	R0

	sub	R17,	R5		;C+=(Ton-C)/32
	sbc	R16,	R6
	lsl	R17
	rol	R16
	rol	R17
	rol	R16
	rol	R17
	rol	R16
	rol	R17
	andi	R17, 0b00000111
	add	R5,	R16
	adc	R6,	R17
	reti
;*/
/*
	mov	R0,	R4		;Расширение разрядности ШИМ (16 бит, без компенсации)
	add	R2,	R3
	adc	R0,	R1
	out	OCR1A,	R0
	reti
*/

;====================================================================
;Конфигурация:

RESET:	;Ldi	R16,	HIGH(RAMEND-34)	;инициализация стека
	;out	SPH,	R16
	Ldi	R16,	LOW(RAMEND-34)
	out	SPL,	R16

	ldi	R16,	0b00100110	;Подтягивание
	out	PORTB,	R16
	ldi	R16,	0b00000111	;Выходы
	out	DDRB,	R16

	ldi	R16,	0b10000000	;Отключить аналоговый компаратор
	out	ACSR,	R16
	ldi	R16,	0b00011000	;Выключить цифровые входные буферы
	out	DIDR0,	R16

	ldi	R16,	0b00000010	;Запустить ФАПЧ
	out	PLLCSR,	R16

	ldi	R16, 	0b10000111	;Измерение Ioffset
	out	ADMUX,	R16
	ldi	R16,	0b11000011	;ADEN, ADSC, тактовая clk/8
	out	ADCSRA,	R16

	clr	R1
	clr	R2
	clr	R3
	clr	R4
	ser	R16
	mov	R5,	R16
	mov	R6,	R16
	clr	R7
	clr	R8
	clr	R27

	ldi	ZH, HIGH(RAMEND+1)	;Очистить ОЗУ
	ldi	ZL, LOW(RAMEND+1)
	ldi	R16,	34		;Количество очищаемых ячеек
upclr:	st	-Z,	R3
	dec	R16
	brne	upclr


	ldi	R16,	0x80		;5mA min
	ldi	R17,	0x02
	ldi	ZH, HIGH(RAMEND-10)
	ldi	ZL, LOW(RAMEND-10)
	st	Z+,	R16		;Записать Irefdamped
	st	Z+,	R17

	ldi	ZH, HIGH(RAMEND-6)
	ldi	ZL, LOW(RAMEND-6)
tnordy:	sbic	EECR,	EEPE
	rjmp	tnordy
	ldi	R16,	119		;Загрузить порог температуры
	out	EEARL,	R16
	sbi	EECR,	EERE
	in	R16,	EEDR
	cpi	R16,	120		;Проверка на диапазон (40...95гр.)
	brcs	tmaxok
	ldi	R16,	120
tmaxok:	cpi	R16,	57
	brcc	tminok
	ldi	R16,	57
tminok:	st	Z+,	R16		;Записать tempmax


;--------------------------------------------------------------------
;Задняя кнопка:

	clr	R16
	in	R21,	MCUSR
	out	MCUSR,	R16		;Очистить MCUSR
	sbrs	R21,	PORF		;Не переключать, если PORF очищен
	ser	R21

	clr	R18			;Поиск активного байта (хоть какого-нибудь рабочего)
	rjmp	eeloop
rdeelp:	inc	R18
	cpi	R18,	EEPROMEND-8	;Конец памяти кнопки
	brcs	eeloop
	clr	R18			;Альтернативная память
	mov	R16,	R28
	sbi	GPIOR0, 0		;Флаг альтернативного режима
	rjmp	eeend
eeloop:	out	EEARL,	R18		;Прочитать байт из EEPROM
	sbi	EECR,	EERE
	in	R16,	EEDR
	cpi	R16,	0x00
	breq	rdeelp			;Прочитать следующий, если 0x00

eeend:	cpi	R16,	0b11111111	;Декодирование активного байта
	breq	pwr1
	cpi	R16,	0b01111111
	breq	pwr2
	cpi	R16,	0b00111111
	breq	pwr3
	cpi	R16,	0b00011111
	breq	pwr4
	cpi	R16,	0b00001111
	breq	pwr1
	cpi	R16,	0b00000111
	breq	pwr2
	cpi	R16,	0b00000011
	breq	pwr3
	cpi	R16,	0b00000001
	breq	pwr4
	sbis	GPIOR0,	0
	rjmp	rdeelp			;Прочитать следующий при ошибке
	ser	R16			;Первый режим при ошибке в альтернативном режиме

pwr1:	sbrc	R21,	EXTRF		;Установка текущего режима
	rjmp	pwr1ld
	rcall	pwrup
	rjmp	pwr2ld
pwr1ld:	ldi	R16,	EEPROMEND-7
	rjmp	pwrout

pwr2:	sbrc	R21,	EXTRF
	rjmp	pwr2ld
	rcall	pwrup
	rjmp	pwr3ld
pwr2ld:	ldi	R16,	EEPROMEND-5
	rjmp	pwrout

pwr3:	sbrc	R21,	EXTRF
	rjmp	pwr3ld
	rcall	pwrup
	rjmp	pwr4ld
pwr3ld:	ldi	R16,	EEPROMEND-3
	ldi	R27,	12		;Переключить фокус на перетяжку
	rjmp	pwrout

pwr4:	sbrc	R21,	EXTRF
	rjmp	pwr4ld
	rcall	pwrup
	rjmp	pwr1ld
pwr4ld:	ldi	R16,	EEPROMEND-1
	ldi	R27,	12		;Переключить фокус на перетяжку
	rjmp	pwrout


pwrup:	lsr	R16			;Сохранить следующий режим (хоть куда-нибудь)
	mov	R28,	R16
	clr	R19
	ldi	R17,	0b00100100	;Write Only, EEMPE
newrt:	out	EEDR,	R16
	out	EEARL,	R18
	out	EECR,	R17
	sbi	EECR,	EEPE
pwrlp:	sbic	EECR,	EEPE
	rjmp	pwrlp
	sbi	EECR,	EERE
	in	R17,	EEDR
	cp	R17,	R16
	brne	pwrer
	tst	R16
	breq	eeclr
	ret
pwrer:	ldi	R17,	0b00000100	;Erase and Write, EEMPE
	clr	R20
	out	EEDR,	R20
	out	EECR,	R17
	sbi	EECR,	EEPE
pwrlp1:	sbic	EECR,	EEPE
	rjmp	pwrlp1
	rjmp	adrinc
eeclr:	ser	R16
	ldi	R17,	0b00010100	;Erase Only, EEMPE
adrinc:	cpi	R19,	EEPROMEND-8	;Счётчик количества байт
	brcs	ewlpok
	ret
ewlpok:	inc	R18
	inc	R19
	cpi	R18,	EEPROMEND-8	;Конец памяти кнопки
	brcs	newrt
	clr	R18
	rjmp	newrt


pwrout:	ldi	ZH, HIGH(RAMEND-8)	;Загрузка выбранного режима
	ldi	ZL, LOW(RAMEND-8)
	ld	R22,	-Z		;Загрузить Irefdamped
	ld	R21,	-Z
	out	EEARL,	R16
	sbi	EECR,	EERE
	in	R17,	EEDR
	inc	R16
	out	EEARL,	R16
	sbi	EECR,	EERE
	in	R18,	EEDR
	ldi	R19,	0x80		;5mA min
	ldi	R20,	0x02
	cp	R17,	R19
	cpc	R18,	R20
	brcc	cmaxok
	mov	R17,	R19
	mov	R18,	R20
cmaxok:	ldi	R19,	0xC0		;Макс значение 0,5A
	ldi	R20,	0xEF
	cp	R19,	R17
	cpc	R20,	R18
	brcc	cminok
	mov	R17,	R19
	mov	R18,	R20
cminok:	st	-Z,	R18		;Записать Irefmax
	st	-Z,	R17
	cp	R17,	R21
	cpc	R18,	R22
	brcc	moresp
	sub	R21,	R17
	sbc	R22,	R18
	mov	R17,	R21
	mov	R18,	R22
	rjmp	spdiv
moresp:	sub	R17,	R21
	sbc	R18,	R22
spdiv:	swap	R17			;Irefmax/16
	swap	R18
	mov	R19,	R18
	andi	R17,	0b00001111
	andi	R18,	0b00001111
	andi	R19,	0b11110000
	or	R17,	R19
	st	-Z,	R18		;Записать speed_soft_start
	st	-Z,	R17


plloop:	in	R16,	PLLCSR		;Ждём стабилизацию ФАПЧ
	sbrs	R16,	PLOCK
	rjmp	plloop
	ldi	R16,	0b00000001	;Запуск таймера0, clk/1
	out	TCCR0B,	R16
	ldi	R16,	0b00000010	;Включение Over0
	out	TIMSK,	R16
	ldi	R16,	0b00000111	;Подключить ФАПЧ к таймеру
	out	PLLCSR,	R16
	ldi	R16,	0b01110001	;Fast PWM inverting mode, clk/1
	out	TCCR1,	R16
	sei				;Разрешить прерываниЯ

;С этого момента софт синхронизирован с ШИМ.

	ldi	R29,	128		;Ждём 4мс (128 циклов), пока зарядится RC-фильтр
lptstr:	clt				;И выйдет на режим АЦП
lpstr:	brtc	lpstr			;Тупим в цикле синхронизации (ждём флаг T)
	sbi	ADCSRA, 6		;Запустить измерение следующего семпла
	dec	R29
	brne	lptstr


	ldi	R29,	64		;Калибровка токового шунта
	clr	R23
	clr	R24
offset:	clt
lpofst:	brtc	lpofst
	in	R16,	ADCL		;Записать данные АЦП в буфер
	in	R17,	ADCH
	sbi	ADCSRA,	6
	add	R23,	R16		;Интегрирование семплов
	adc	R24,	R17
	dec	R29
	brne	offset
	ldi	ZH, HIGH(RAMEND-25)
	ldi	ZL, LOW(RAMEND-25)
	st	Z+,	R23		;Записать Ioffset
	st	Z+,	R24
	ldi	R16, 	0b00101100	;Измерение Vcc
	out	ADMUX,	R16
	sbi	ADCSRA,	6

	sbi	PORTB,	0		;Запустить преобразователь

;====================================================================

	;Глобальные переменные

	;R1		- Zero
	;R2		- Ton_error
	;R4:R3		- Ton
	;R6:R5		- Ton_comp
	;R7		- PIcur_error
	;R8		- Dcur_error
	;R27		- Таймер переключателя фокуса
	;R28		- Резервная память режимов
	;R29		- Main Loop Counter

	;RAMEND-5	- temperature
	;RAMEND-6	- tempmax

	;RAMEND-10	- Irefdamped
	;RAMEND-12	- Irefmax
	;RAMEND-14	- Speed_soft_start

	;RAMEND-21	- IrefDiffdmp
	;RAMEND-23	- Iref
	;RAMEND-25	- Ioffset
	;RAMEND-27	- timeout

	;RAMEND-29	- VccLoad
	;RAMEND-31	- VccDiffdmp



;--------------------------------------------------------------------
;Напряжение питания:

main:	ldi	R29,	10		;Пропустить 10 семплов АЦП
lptvcc:	clt
lpvcc:	brtc	lpvcc
	dec	R29
	breq	lpvout
	sbi	ADCSRA,	6
	rjmp	lptvcc

lpvout:	in	R23,	ADCL		;Записать данные АЦП в буфер
	in	R24,	ADCH
	ldi	R16,	0b10101111	;Измерение температуры
	out	ADMUX,	R16
	sbi	ADCSRA,	6


vccld:	ldi	ZH, HIGH(RAMEND-27)	;Дифференциальное звено
	ldi	ZL, LOW(RAMEND-27)
	ld	R19, -Z			;Загрузить VccLoad
	ld	R18, -Z
	ld	R17, -Z			;Загрузить VccDiffdmp
	ld	R16, -Z

	sbic	GPIOR2, 6		;Пропустить сглаживание,
	rjmp	diffok			;если выборка первая
	sbi	GPIOR2, 6
	mov	R16, R23
	mov	R17, R24

diffok:	clr	R0
	cp	R16, R23		;Сглаживание
	cpc	R17, R24		;+/-
	breq	dmotvj
	brcc	morevd

	mov	R20, R23		;VccLoad+=(ADC-VccDiffdmp-256)*2/1...8
	mov	R21, R24
	sub	R20, R16
	sbc	R21, R17
	subi	R21, 2			;Порог LSB
	brcs	advlok
	lsl	R20			;Коэффициент
	rol	R21
	cpi	R24, 0x58		;Порог 3,2V
	brcc	lower1
	lsr	R21			;/2
	ror	R20
lower1:	cpi	R24, 0x4E		;Порог 3,6V
	brcc	lower2
	lsr	R21			;/4
	ror	R20
lower2:	cpi	R24, 0x40		;Порог 4,4V
	brcc	lower3
	lsr	R21			;/8
	ror	R20
lower3:	add	R18, R20
	adc	R19, R21
	brcc	advlok
	ser	R18
	ser	R19

advlok:	mov	R20, R23		;VccDiffdmp+=(ADC-VccDiffdmp)/32
	mov	R21, R24
	sub	R20, R16
	sbc	R21, R17
	lsl	R20
	rol	R21
	rol	R20
	rol	R21
	rol	R20
	rol	R21
	rol	R20
	andi	R20, 0b00000111
	cp	R21, R0
	cpc	R20, R0
	brne	okdnvd
	inc	R21
okdnvd:	add	R16, R21
	adc	R17, R20
dmotvj:	rjmp	dmoutv


morevd:	mov	R20, R16		;VccLoad-=(VccDiffdmp-ADC-256)*2/1...8
	mov	R21, R17
	sub	R20, R23
	sbc	R21, R24
	subi	R21, 2			;Порог LSB
	brcs	sbvlok
	lsl	R20			;Коэффициент
	rol	R21
	cpi	R24, 0x58		;Порог 3,2V
	brcc	lower4
	lsr	R21			;/2
	ror	R20
lower4:	cpi	R24, 0x4E		;Порог 3,6V
	brcc	lower5
	lsr	R21			;/4
	ror	R20
lower5:	cpi	R24, 0x40		;Порог 4,4V
	brcc	lower6
	lsr	R21			;/8
	ror	R20
lower6:	sub	R18, R20
	sbc	R19, R21
	brcc	sbvlok
	clr	R18
	clr	R19

sbvlok:	mov	R20, R16		;VccDiffdmp-=(VccDiffdmp-ADC)/32
	mov	R21, R17
	sub	R20, R23
	sbc	R21, R24
	lsl	R20
	rol	R21
	rol	R20
	rol	R21
	rol	R20
	rol	R21
	rol	R20
	andi	R20, 0b00000111
	cp	R21, R0
	cpc	R20, R0
	brne	okupvd
	inc	R21
okupvd:	sub	R16, R21
	sbc	R17, R20

dmoutv:	st	Z+, R16			;Записать VccDiffdmp
	st	Z+, R17


	ldi	R20, 0xC0		;ПИ-звено
	ldi	R21, 0x5D		;Порог 3V

	cp	R20, R23
	cpc	R21, R24
	brcc	morevl			;+/-

	sub	R23, R20		;VccLoad+=(ADC-Vccmin)/32
	sbc	R24, R21
	lsl	R23
	rol	R24
	rol	R23
	rol	R24
	rol	R23
	rol	R24
	rol	R23
	andi	R23, 0b00000111
	cp	R24, R0
	cpc	R23, R0
	brne	modupv
	inc	R24
modupv:	add	R18, R24
	adc	R19, R23
	brcc	vpiout
	ser	R18
	ser	R19
	rjmp	vpiout

morevl:	sub	R20, R23		;VccLoad-=(Vccmin-ADC)/32
	sbc	R21, R24
	lsl	R20
	rol	R21
	rol	R20
	rol	R21
	rol	R20
	rol	R21
	rol	R20
	andi	R20, 0b00000111
	cp	R21, R0
	cpc	R20, R0
	brne	moddnv
	inc	R21
moddnv:	sub	R18, R21
	sbc	R19, R20
	brcc	vpiout
	clr	R18
	clr	R19

vpiout:	st	Z+, R18			;Записать VccLoad
	st	Z+, R19



;--------------------------------------------------------------------
;Температура

	ldi	R29,	5		;Пропустить 5 семплов АЦП
lpttmp:	clt
lptmp:	brtc	lptmp
	dec	R29
	breq	lptout
	sbi	ADCSRA,	6
	rjmp	lpttmp

lptout:	in	R23,	ADCL		;Записать данные АЦП в буфер
	in	R24,	ADCH
	ldi	R16,	0b10100111	;Измерение Iout
	out	ADMUX,	R16
	sbi	ADCSRA,	6

	ldi	ZH, HIGH(RAMEND-6)
	ldi	ZL, LOW(RAMEND-6)
	ld	R17,	Z+		;Загрузить tempmax

	clr	R16			;t=(t-tmax)*64
	sec				;+256
	ror	R17			;x64
	ror	R16
	lsr	R17
	ror	R16

	sub	R23,	R16		;Подготовка значения АЦП
	sbc	R24,	R17
	brcc	subtok
	clr	R23
	clr	R24
subtok:	cpi	R24,	4
	brcc	ovrmul
	lsr	R23
	ror	R24
	ror	R23
	ror	R24
	ror	R23
	rjmp	multok
ovrmul:	ser	R24
	ser	R23

multok:	ld	R18,	Z+		;Загрузить температуру
	ld	R19,	Z+

	sbic	GPIOR2,	5		;пропустить сглаживание,
	rjmp	tdmpok			;если выборка первая
	sbi	GPIOR2,	5
	mov	R18,	R24
	mov	R19,	R23

tdmpok:	clr	R22
	cp	R24,	R18		;Сглаживание
	cpc	R23,	R19		;+/-
	breq	equalt
	brcc	moretd

	mov	R20,	R18		;?
	mov	R21,	R19
	sub	R20,	R24
	sbc	R21,	R23
	lsl	R20			;/128
	rol	R21
	brcc	okdnt1
	ser	R21
	rjmp	okdnt2
okdnt1:	brne	okdnt2
	inc	R21
okdnt2:	sub	R18,	R21
	sbc	R19,	R22
	rjmp	equalt

moretd:	sub	R24,	R18
	sbc	R23,	R19
	lsl	R24			;/32
	rol	R23
	rol	R24
	rol	R23
	rol	R24
	rol	R23
	rol	R24
	andi	R24,	0b00000111
	cp	R23,	R22
	cpc	R24,	R22
	brne	okupt2
	inc	R23
okupt2:	add	R18,	R23
	adc	R19,	R24

equalt:	st	-Z,	R19		;Записать температуру
	st	-Z,	R18



;--------------------------------------------------------------------
;Сглаживание Irefmax, защиты и фокус

	clt
lpcdmp:	brtc	lpcdmp
	sbi	ADCSRA,	6

	ldi	ZH, HIGH(RAMEND-14)	;Плавный пуск/выключение
	ldi	ZL, LOW(RAMEND-14)
	ld	R16,	Z+		;Загрузить speed_soft_start
	ld	R17,	Z+
	ld	R18,	Z+		;Загрузить Irefmax
	ld	R19,	Z+
	ld	R20,	Z+		;Загрузить Irefdamped
	ld	R21,	Z+

	cp	R18,	R20		;+/-
	cpc	R19,	R21
	brcs	refdwn

	add	R20,	R16
	adc	R21,	R17
	brcs	dmpov1
	cp	R18,	R20
	cpc	R19,	R21
	brcc	rfupok
dmpov1:	mov	R20,	R18
	mov	R21,	R19
	rjmp	rfupok

refdwn:	sub	R20,	R16
	sbc	R21,	R17
	brcs	overok
	cp	R20,	R18
	cpc	R21,	R19
	brcc	rfupok
overok:	mov	R20,	R18
	mov	R21,	R19

rfupok:	st	-Z,	R21		;Записать Irefdamped
	st	-Z,	R20

;/*
	ldi	ZH, HIGH(RAMEND-29)	;Ограничение по напряжению питания
	ldi	ZL, LOW(RAMEND-29)
	ld	R18,	Z+		;Загрузить VccLoad
	ld	R19,	Z+
	clr	R16
	cp	R18,	R16
	cpc	R19,	R16
	breq	vrfok
	sub	R20,	R18		;Iref-=VccLoad
	sbc	R21,	R19
	brcc	vrfok
	clr	R20
	clr	R21

vrfok:	ldi	ZH, HIGH(RAMEND-5)	;Ограничение по температуре
	ldi	ZL, LOW(RAMEND-5)
	ld	R16,	Z+		;Загрузить температуру
	ld	R17,	Z+
	ser	R18
	ser	R19
	sub	R18,	R16
	sbc	R19,	R17
	cp	R18,	R20
	cpc	R19,	R21
	brcc	trfok
	mov	R20,	R18
	mov	R21,	R19
;*/
trfok:	ldi	ZH, HIGH(RAMEND-25)	;Таймаут
	ldi	ZL, LOW(RAMEND-25)
	ld	R19,	-Z		;Загрузить timeout
	ld	R18,	-Z
	ldi	R16,	0x80		;5mA min
	ldi	R17,	0x02
	cp	R20,	R16
	cpc	R21,	R17
	brcc	mrfok
	mov	R20,	R16
	mov	R21,	R17
	ldi	R16,	1
	clr	R17
	add	R18,	R16
	adc	R19,	R17
	ldi	R16,	0x58		;Задержка перед выключением (10s)
	ldi	R17,	0x02
	cp	R18,	R16
	cpc	R19,	R17
	brcs	timout
	rjmp	pwroff			;Выключение при таймауте
	mov	R18,	R16
	mov	R19,	R17
	rjmp	timout
mrfok:	clr	R18
	clr	R19
timout:	st	Z+,	R18		;Записать timeout
	st	Z+,	R19

/*
	sbic	GPIOR2,	7		;Модулятор тока (для отлаживания)
	rjmp	fulcur
	sbi	GPIOR2,	7
	rjmp	modout
fulcur:	cbi	GPIOR2,	7
	lsr	R21
	ror	R20
modout:
*/

	ld	R18,	Z+		;Загрузить Ioffset
	ld	R19,	Z+
	add	R20,	R18		;Калибровка
	adc	R21,	R19
	brcc	crnorm
	rjmp	pwroff			;Выключение при переполнении
crnorm:	st	Z+,	R20		;Записать Iref
	st	Z+,	R21

	sbi	GPIOR0, 1		;512 семплов стабилизации тока
	ser	R29

	tst	R27			;Таймер переключателя фокуса
	breq	currfb
	dec	R27
	brne	currfb
	sbi	PINB,	2		;Инвертировать состояние



;--------------------------------------------------------------------
;ОС по макс. току:

currfb:	clt
lpcur:	brtc	lpcur

	in	R23,	ADCL		;Записать данные АЦП в буфер
	in	R24,	ADCH
	sbi	ADCSRA,	6
curfb1:	sbic	PINB,	0		;CТАБИЛИЗАЦИЯ
	rjmp	pwmon			;Сбросить прогресс,
	clr	R3			;если преобразователь отключен
	clr	R4
	rjmp	iout1


pwmon:	ldi	ZH, HIGH(RAMEND-23)	;Дифференциальное звено
	ldi	ZL, LOW(RAMEND-23)
	ld	R16,	Z+		;Загрузить Iref
	ld	R17,	Z+
;/*
	ld	R18,	Z+		;Загрузить IrefDiffdmp
	ld	R19,	Z+

	cp	R18,	R23		;Сглаживание
	cpc	R19,	R24		;+/-
	breq	dmoutc
	brcc	morecd

	mov	R20,	R23		;X=(Iout-IrefDiffdmp)/512
	mov	R21,	R24
	sub	R20,	R18
	sbc	R21,	R19
	lsr	R21
	ror	R20
	adc	R8,	R20		;Интегратор остатка от деления
	adc	R21,	R1
	add	R18,	R21		;IrefDiffdmp+=X
	adc	R19,	R1
	sub	R3,	R21		;Tonnom-=X
	sbc	R4,	R1
	brcc	dmoutc
	clr	R3
	clr	R4
	rjmp	dmoutc


morecd:	mov	R20,	R18		;X=(IrefDiffdmp-Iout)/512
	mov	R21,	R19
	sub	R20,	R23
	sbc	R21,	R24
	lsr	R21
	ror	R20
	adc	R8,	R20		;Интегратор остатка от деления
	adc	R21,	R1
	sub	R18,	R21		;IrefDiffdmp-=X
	sbc	R19,	R1
	add	R3,	R21		;Tonnom+=X
	adc	R4,	R1
	brcc	dmoutc
	ser	R20
	mov	R3,	R20
	mov	R4,	R20

dmoutc:	st	-Z,	R19		;Записать IrefDiffdmp
	st	-Z,	R18
;*/


	cp	R23,	R16		;ПИ-звено
	cpc	R24,	R17		;+/-
	brcs	loTon

	sub	R23,	R16		;Tonnom-=(Iout-Iref)/512
	sbc	R24,	R17
	lsr	R24
	ror	R23
	adc	R7,	R23		;Интегратор остатка от деления
	adc	R24,	R1
	sub	R3,	R24
	sbc	R4,	R1
	brcc	iout1			;Клиппинг ОС (КЗ)
/*
	clr	R3			Отключение защиты от КЗ (для отлаживания)
	clr	R4
	rjmp	iout1
*/
pwroff:	cli				;Выключение при сбое
	clr	R16
	out	TCCR1,	R16		;Вырубить ШИМ
	out	PLLCSR,	R16		;Остановить ФАПЧ
	out	ADCSRA,	R16		;Выключить АЦП
	out	PORTB,	R16		;Сбросить порт
	ldi	R17,	0b10110000
	ldi	R16,	0b10110100
lpwoff:	out	MCUCR,	R16		;BOD Sleep, Sleep, режим Power-down, BOD Sleep Enable
	out	MCUCR,	R17		;BOD Sleep, Sleep, режим Power-down
	SLEEP				;Вечный сон...
	rjmp	lpwoff


loTon:	sub	R16,	R23		;Tonnom+=(Iref-Iout)/512
	sbc	R17,	R24
	lsr	R17
	ror	R16
	adc	R7,	R16		;Интегратор остатка от деления
	adc	R17,	R1
	add	R3,	R17
	adc	R4,	R1
	brcc	iout1
	ser	R16			;Клиппинг ОС (перегрузка)
	mov	R3,	R16
	mov	R4,	R16

iout1:	dec	R29
	brne	crmxlp
	sbic	GPIOR0,	1	
	rjmp	clrbt1
	rjmp	main

clrbt1:	cbi	GPIOR0, 1
crmxlp:	clt
lpcur2:	brtc	lpcur2
	in	R23,	ADCL		;Записать данные АЦП в буфер
	in	R24,	ADCH
	cpi	R29,	1
	brne	llcmax
	sbic	GPIOR0,	1	
	rjmp	llcmax
	ldi	R16,	0b00101100	;Измерение Vcc
	out	ADMUX,	R16
llcmax:	sbi	ADCSRA,	6
	rjmp	curfb1





	.eseg				;EEPROM
	.org	EEPROMEND-8

	.db	85			;Температура 60гр. (44LSB=25гр., 0,857гр. LSB)
	.db	0x00,0x13		;Ток 1 40mA	(0,525mA LSB x64 L,H)
	.db	0x40,0xD6		;Ток 2 450mA
	.db	0x00,0x13		;Ток 3 40mA	(с фокусом)
	.db	0x40,0xD6		;Ток 4 450mA	(с фокусом)

Вот Архив.rar. Тут и исходники, и хексы, и схема, и плата...
Этот драйвер можно завести на полевике вместо преобразователя (что-то вроде форумного драйвера), на частоте 2...4МГц. Изначально мишуры было гораздо больше ("передняя" умная кнопка, подстроечник, программирующий все режимы, модуляция тока, няшный индикатор и т.п.) но всё это было попилено...

Да, забыл же осциллограммы результата показать:
Нажмите на изображение для увеличения
Название: P4144467.JPG
Просмотров: 745
Размер:	86.7 Кб
ID:	72819
Переменная составляющая напряжения на выходе (под нагрузкой), 10мВ/Дел. По виду там в среднем 5мВ пульсаций, посмотрим по-ближе:
Нажмите на изображение для увеличения
Название: P4144466.JPG
Просмотров: 954
Размер:	90.0 Кб
ID:	72820
Тут просматривается пила самого преобразователя на частоте в пару мегагерц, а если отойти по-дальше - видно пилу самого ШИМ МК (жирная линия такая прорисовываться на фоне мелкой пилы). Как видно сам МК вклад вносит незначительный, хоть по-идее и ШИМ там хреновый, и АЦП шумит, и вообще МК гавно... Поэтому я и говорю что поднять частоту ШИМ можно до 2МГц без ухудшения результата. Выручит плотностно-импульсная модуляция его последнего бита. АЦП таки может хорошо работать, попросить просто надо. А арифметика если использует деление - остаток не выбрасывайте, складывайте где-то в кучку, а когда мелочи соберётся достаточно - меняйте на рубль (LSB) и вперёд. Не впишется в один семпл, так хоть размажется по нескольким...
Кстати, как ни странно - рассчитанный ток попадает метко. Зашил в EEPROM 450мА - получил 449...451мА. На 40мА получаю 39...41мА. Подстроечником так фиг настроишь. Были проблемы с калибровкой смещения, почему-то на 25-х постоянно замечаю не хилый offset. Тут он занизил ток на 16мА (порядка +30LSB к показаниям АЦП), а вот на 44-х вообще не актуален. Поэтому тинька сначала калибрует шунт при запуске, ток в этот момент через него течь не должен, а уже затем запускает преобразователь...

По поводу чисто программной реализации драйвера (пример - "форумный" драйвер) VS полуаппаратной (такой, как тут на схеме) - Сначала я не любил программные реализации из-за неумения достаточно эффектно писать. Связку АЦП+ШИМ у AVR ещё попробуй заставь работать с качеством микрофонного усилителя... Затем я всё таки начал предпринимать попытки, но из-за огородности решений выбрал управление готовым преобразователем. Один чип вместо жмени компонентов, который может и повышать, и понижать. Ещё и частота у него запредельная по меркам МК - >2МГц, и защиты свои собственные, домашние... ОС там тоже шустрая, АЦП просто не сможет так эффективно давить помехи выше десятка килогерц. Теперь же меня прижимают ограничения таких решений. Годные преобразователи пересчитать можно на пальцах, а иногда ведь хочется чего-то не совсем шаблонного. Например какую-нибудь повышалку для трипла/квадрипла, или понижалку с питанием от 10...30V. Тут уже снова напрашивается дискретный вариант. Чисто программный, на рассыпухе так сказать. Но внезапно для себя я обнаружил, что те же самые драйверы с полевиками, которыми в норме должен дёргать ШИМ МК, можно заставить работать самостоятельно. Вводится ПОС на ВЧ, и ООС на НЧ, и всё. Имеем мультивибратор или усилитель класса D. Деталей ненамного больше, но обвес живёт своей жизнью как готовый преобразователь, со всеми его преимуществами...

P.S. Если кого смущает странная арифметика в коде, на месте которой знаковая смотрелась бы куда удобнее и понятнее - я не вкурил эту многобайтную знаковую арифметику на ассемблере. Для 8-ми разрядной арифметики всё понятно и работает, но вот с переносами беда, даже Си там такого огородит, что для одной только токовой ОС не хватило бы ресурсов всего камня - ПРИМЕР. Вот и приходится выкручиваться. Или тратить по 10 тактов на банальное сложение, или один раз потратить 3...4 такта на определение знака и дальше тратить по паре тактов на подобные операции. Если знаковая арифметика таки может работать эффективнее - я с радостью посмотрю как это сделать...
Вообще же ассемблер меня давно достал, но к сожалению для AVR альтернативы нет, а для ниши, в которой у меня сидят тиньки - альтернативы нет им, вот и приходится мучатся...

[Исправлено: INFERION, 18.04.2013 в 22:58]
INFERION вне форума   Ответить с цитированием Вверх
Поблагодарили: 16 раз(а)
Admin (15.04.2013), Artik555 (24.11.2020), Corvax (25.09.2013), DooMmen (30.04.2014), fonpuh (08.06.2013), galex (15.04.2013), kruvas (15.04.2013), ksan (25.12.2020), LEV-UA (15.04.2013), lonish (15.04.2013), Memorized (13.02.2016), MOHAPX (15.04.2013), Rime (01.08.2013), shurko_3 (15.04.2013), togico (15.04.2013), Volosaty (13.01.2014)
Старый 15.04.2013, 11:17   2
AVSel
Консультант

 
Аватар для AVSel
 
Регистрация: 15.11.2010
Последняя активность: 27.01.2024 20:53
Адрес: Москва
Сообщений: 8206
Сказал(а) спасибо: 1077
Поблагодарили: 1713 раз(а) в 912 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

INFERION, спасибо, интересно было почитать.
Правда мне кажется проблема с EEPROM сильно надумана. Если давить на кнопку питания фонаря по 10 раз в сутки (что соответствует достаточно суровой эксплуатации фонаря), EEPROM хватит на 100000/10/365=27лет А реально еще больше, т.к. 100 000 циклов записи производитель гарантирует, а отработать может и 150000 циклов записи.
AVSel вне форума   Ответить с цитированием Вверх
Старый 15.04.2013, 11:22 Автор темы   3
INFERION

 
Аватар для INFERION
 
Регистрация: 07.04.2013
Последняя активность: 13.06.2023 02:24
Адрес: Украина, Полтава
Сообщений: 5774
Сказал(а) спасибо: 340
Поблагодарили: 8154 раз(а) в 2385 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

EEPROM можно угробить за несколько минут ошибкой в коде, можно засрать до отказа дохлой батареей (проходили уже) и т.п. Да и не все же жмут 10 раз в сутки? Я рассчитываю лет на пять непрерывного клацанья, если ресурсы позволяют - почему бы не реализовать? Один китаец с убитой EEPROM мне уже знаком, какой-то топовый, но линейный. Сдох за пол года эксплуатации. Стало быть внимания этому моменту уделяют недостаточно...
INFERION вне форума   Ответить с цитированием Вверх
Старый 15.04.2013, 13:51   4
mephisto-nv
Увлеченный
 
Регистрация: 03.03.2011
Последняя активность: 08.10.2015 05:27
Сообщений: 186
Сказал(а) спасибо: 3
Поблагодарили: 26 раз(а) в 18 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

про загубленный еепром возможно могу подтвердить. фонарей есть ужо цельный ящик(как у многих тут). пользуюсь парой на протяжении лет наверное 2-3. трастфаер ст-50 обхмеленный и щадоу вг-20. пользуюсь активно (говорила мама - иди на повара учиться. дак не же - лепездричество мне нравиться... таперь вот по подвалям и чердакам лазию - всяческую тепловую кибернетику ломаю, щоб людям в квартирах тепло було блин. раньше нас трубочистами звали). если не сказать оченно активно. на обоих или у обоев - драйвера менялись. после тыщеразных матюков в темном мля подвале с зажигалкой в руке (ну вот непокупается пачамута наклющник) и тыщеразной же переборкой оных. ибо алгоритм работы их менялся на совершенно загадочный плод внеземного разума.
зы ждемс почтовых голубей с драйверками.
ззы зерно уже на подоконнике рассыпал. (на соседском естесстно - нэхай радуются гандурасы ночному пению птиц).
засим прощаюсь с вами - уважаемые читатели. с уважением ваш вечно лукавый искрящийся призрак ночи.

[Исправлено: mephisto-nv, 15.04.2013 в 13:52]
mephisto-nv вне форума   Ответить с цитированием Вверх
Старый 19.05.2013, 19:50 Автор темы   5
INFERION

 
Аватар для INFERION
 
Регистрация: 07.04.2013
Последняя активность: 13.06.2023 02:24
Адрес: Украина, Полтава
Сообщений: 5774
Сказал(а) спасибо: 340
Поблагодарили: 8154 раз(а) в 2385 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

у 25-й тиньки (наверняка и у более жирных представителей её семейства) очень плохо работает ёмкость на RESET'е. Когда 44-й микрофарада хватает на 20 секунд (приходится мегаомный резистор допаивать) - 25-й ёмкость подобрать нереально. 2мкФ хватает лишь на очень короткий удар по кнопке, а 220мкФ долго удерживает RESET при запуске. Пришлось программировать фьюз "RSTDIBL" и цеплять на PB5 (ADC0) АЦП. При запуске меряем напряжение и только затем подтягиваем. Теоретически утечка происходит через какой-нибудь P-N переход в линию питания, когда оно опускается ниже плинтуса (хотя мультиметр показал бесконечность). Поэтому при напряжениях ниже 0,6...0,3V конденсатор может работать нормально. Исходя из этого я выбрал порог в 0,1V (cpi ADCH, 23 с ADLAR и ИОН на 1,1V) и получил такой вот практический результат: с микрофарадом сопротивление в 100...200k (параллельно ёмкости) даёт паузу около секунды. Оптимальный (на мой взгляд) результат получается при сопротивлении 68k. Без резистора держит десятки секунд, первые 5 семплов надо пропустить.

Пришлось рискнуть и залить не отлаженный вариант с АЦП и отключить RESET. Хорошо что с первого раза завелось, а-то пришлось бы выпаивать МК в QFN корпусе, не зацепив и не поджарив соседей...
Нажмите на изображение для увеличения
Название: P5184497.jpg
Просмотров: 775
Размер:	77.5 Кб
ID:	75767
Хоть и для 12х Blu-ray предназначен, однако им должно быть удобно питать "наключники". Пол ампера вытянет. В нонижающем режиме обещают вообще 800мА, но программа стабилит в диапазоне 5...500мА. 4 настраиваемых режима, на всякие феньки вроде индикации заряда и т.п. памяти не хватило. Температурное ограничение фиксировано и заточено под лазерные диоды - 60...70 градусов. Кнопка поумнела, теперь при сбое (перезагрузке из-за попытки подключить критически севшую батарею) она выискивает режим с током по-меньше текущего, но максимально близкий к нему. Если перезагрузка произошла с и так уже минимальным режимом - уходит спать. Но всё это костыль, т.к. не требуется в теории, если основной механизм ограничения тока под напряжение питания работает достаточно быстро.
При успешной же загрузке заводится механизм ограничения тока под минимальное напряжение питания, как и раньше. Т.е. на батарее удерживается ровно 3V, а ток продолжает падать. При достижении 5мА запускается таймер и через 10с драйвер уходит спать...

[Исправлено: INFERION, 19.05.2013 в 20:06]
INFERION вне форума   Ответить с цитированием Вверх
Старый 01.08.2013, 11:21   6
Tamagotchi

 
Аватар для Tamagotchi
 
Регистрация: 07.09.2011
Последняя активность: 04.08.2023 18:59
Адрес: Волгоградская обл.
Сообщений: 13705
Сказал(а) спасибо: 3333
Поблагодарили: 7886 раз(а) в 3523 сообщениях

Отправить сообщение для Tamagotchi с помощью Skype™
По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

А как лучше поступить после переключения с замера тока на замер напряжения? Пропустить первый результат?
Tamagotchi вне форума   Ответить с цитированием Вверх
Старый 01.08.2013, 14:22 Автор темы   7
INFERION

 
Аватар для INFERION
 
Регистрация: 07.04.2013
Последняя активность: 13.06.2023 02:24
Адрес: Украина, Полтава
Сообщений: 5774
Сказал(а) спасибо: 340
Поблагодарили: 8154 раз(а) в 2385 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

Если ИОН не переключается, то хватит и одного семпла, иначе 5 семплов (0,16мс) при переключении на внутренний ИОН, и 10 семплов (0,32мс) при переключении на Vcc в качестве ИОН. Это минимум, что я нащупал.

P.S. Сейчас я по-другому работаю с АЦП. Он запускается аппаратно, компаратором на каком-нибудь таймере. Причём момент запуска с каждым семплом смещается на 1 такт, и так гуляет между значениями в компараторе 8...40 или -24...40. Т.е. ползает по одному или двум целым периодам ШИМ (32 такта), это уменьшает влияние его заполнения на статическую ошибку (шум изначально задавлен жесткой синхронизацией).

[Исправлено: INFERION, 01.08.2013 в 16:47]
INFERION вне форума   Ответить с цитированием Вверх
Поблагодарили: 1 раз
Tamagotchi (01.08.2013)
Старый 01.08.2013, 15:56   8
Tamagotchi

 
Аватар для Tamagotchi
 
Регистрация: 07.09.2011
Последняя активность: 04.08.2023 18:59
Адрес: Волгоградская обл.
Сообщений: 13705
Сказал(а) спасибо: 3333
Поблагодарили: 7886 раз(а) в 3523 сообщениях

Отправить сообщение для Tamagotchi с помощью Skype™
По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

нашел затык в программе. частота выборок была маленькая. Бросил старую прогу и написал тестовую с нуля. Стало значительно лучше, примерно 15 mA работают стабильно на шунте 0.05Om. Сейчас буду по новому все переписывать. Спасибо за Ваши советы!
Tamagotchi вне форума   Ответить с цитированием Вверх
Старый 24.11.2020, 01:25   9
Artik555
Увлеченный
 
Регистрация: 07.03.2020
Последняя активность: 18.06.2021 20:15
Сообщений: 302
Сказал(а) спасибо: 54
Поблагодарили: 5 раз(а) в 5 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

INFERION, пока у меня всё ещё теплится внутри надежда сделать тёплый ламповый простенький фулл-аналог, так сказать спрошу-вы пробывали прикручивать ОУ к tps63020? Экспериментировали с таким? Получается всё не хорошо?
А то в защиту надежды всплыло воспоминание что алиэкспресс завален дешёвыми модулями имульсными со стабилизацией тока, в которых всё ну совсем просто-самая банальная lm358 и вот вам стабильзация тока, и работает всё ну очень хорошо
Правда микросхема очень древняя и кпд низкий.
Ну и частота у неё не маленькая, но и не мегагерцная как в tps, 340кГц вроде.
Как в них всё работает? За счёт чего?
Я как посмотрел, как всё просто, как переделывается стабилизатор напряжения в стабилизатор тока, на примере этих китайских поделий, а потом начал разбираться и отрадовался обратно.
Или при 340кГц всё легко и хорошо, и ухудшается по экспоненте при приближении к 2МГц?
Типа таких модули:
https://m.aliexpress.ru/ite...

*тут и ОУ, и крутящийся патенциометр о котором вы говорили, что с ним вообще беда будет в высокочастотных схемах

[Исправлено: Artik555, 24.11.2020 в 01:28]
Artik555 вне форума   Ответить с цитированием Вверх
Старый 24.11.2020, 01:40   10
Artik555
Увлеченный
 
Регистрация: 07.03.2020
Последняя активность: 18.06.2021 20:15
Сообщений: 302
Сказал(а) спасибо: 54
Поблагодарили: 5 раз(а) в 5 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

Цитата:
Посмотреть сообщение Сообщение от INFERION :
Задача - построить стабилизатор тока на ATtiny25/45/85 с блекджеком и
Попадаются утверждения, что у низкочастотных схем с большой индуктивностью лучше КПД должен быть, по крайней мере потенциально, ну и по логике оно вроде так.
Однако по обзорам и читая даташиты-самые высокие КПД у самых высокочастотных микросхем преобразователей. Почему так?

Цитата:
Посмотреть сообщение Сообщение от INFERION :
Задача - построить стабилизатор тока на ATtiny25/45/85 с блекджеком и
Ну и применительно к ATtiny-почему бы сразу не сделать импульсный стабилизатор тока исключительно на атини? И ток на шунте им мерить, и частосту с продолжительностью импульсов согласно ему ати'ней и изменять. И сделать всему этому небольшую частоту работы(импульсов на индуктивность), для стабильности.

Не удастся выжать хорошие (как у мегагерцных заводских схем) КПД? Почему?
Artik555 вне форума   Ответить с цитированием Вверх
Старый 24.11.2020, 01:50   11
Artik555
Увлеченный
 
Регистрация: 07.03.2020
Последняя активность: 18.06.2021 20:15
Сообщений: 302
Сказал(а) спасибо: 54
Поблагодарили: 5 раз(а) в 5 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

Ну и 3-й финальный:
Что посоветуете с учётом максимального сохранения изначальной концепции(tps63020+ОУ+регуляция тока патенциометром+высокий кпд и на низких токах порядка 20мА)-т.е. максимальной простоты, но чтобы работало хорошо:
tps63020+Атини+цифровой переменный резистор?
Атини измерять ток, им же щёлкать переменный цифровой резистор встроенный в стандартный делитель напряжения обратной связи tps, и патенциометр на входы атини для управления?
Artik555 вне форума   Ответить с цитированием Вверх
Старый 24.11.2020, 01:53 Автор темы   12
INFERION

 
Аватар для INFERION
 
Регистрация: 07.04.2013
Последняя активность: 13.06.2023 02:24
Адрес: Украина, Полтава
Сообщений: 5774
Сказал(а) спасибо: 340
Поблагодарили: 8154 раз(а) в 2385 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

Цитата:
Посмотреть сообщение Сообщение от Artik555 :
вы пробывали прикручивать ОУ к tps63020?
https://forum.fonarevka.ru/...
Цитата:
Посмотреть сообщение Сообщение от INFERION :
завести сигнал с токового монитора прямиком на FB пытались многие, и я тоже - хрень выходит, возбуждается легко чуть что.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Как в них всё работает? За счёт чего?
Тупая дубовая ОС, которая терпит такие издевательства, плюс конские индуктивности и ёмкости - так и работает. Низкая частота работы уже подразумевает низкие скорости работы и самой ОС.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
как всё просто, как переделывается стабилизатор напряжения в стабилизатор тока
Ага, просто оно с виду, а возбуд ловит даже LM317 со штатной схемой из даташита. Есть вот такая штука во всех этих регуляторах: http://www.gaw.ru/html.cgi/...
Эта и следующая страницы. Вот если разобраться, то выходит не всё так просто...
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
тут и ОУ, и крутящийся патенциометр о котором вы говорили, что с ним вообще беда будет в высокочастотных схемах
Тут потенциометр без длинных соплей, и сам мелкий. Да, хуже парочки 0603 резисторов у самого ОУ, но не катастрофа. Вот если проводами выносить переменник куда-нибудь в корпусе под регулировку руками... Но и это всё можно сделать, если понимать как и что компенсировать.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Или при 340кГц всё легко и хорошо, и ухудшается по экспоненте при приближении к 2МГц?
Почему по экспоненте? Просто есть вот задержка в контуре регулирования. Она определяется много чем, но в основном LC фильтром в преобразователе. И вот нужно чтоб ОС давала усиление ошибки ниже 1 на частотах, где эта задержка двигает фазу более чем на 90...120 градусов - всё. Под это дело её нужно частотно корректировать. Снизить усиление по переменному току в ОУ не сложно, но я помню что TPS63020 так просто не сдавался. Деталей не помню. Может, сейчас бы с текущим опытом и знаниями - поборол бы.

[Исправлено: INFERION, 24.11.2020 в 02:11]
INFERION вне форума   Ответить с цитированием Вверх
Поблагодарили: 1 раз
Artik555 (24.11.2020)
Старый 24.11.2020, 02:08 Автор темы   13
INFERION

 
Аватар для INFERION
 
Регистрация: 07.04.2013
Последняя активность: 13.06.2023 02:24
Адрес: Украина, Полтава
Сообщений: 5774
Сказал(а) спасибо: 340
Поблагодарили: 8154 раз(а) в 2385 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Попадаются утверждения, что у низкочастотных схем с большой индуктивностью лучше КПД должен быть, по крайней мере потенциально, ну и по логике оно вроде так.
Однако по обзорам и читая даташиты-самые высокие КПД у самых высокочастотных микросхем преобразователей. Почему так?
Не встречал низкочастотных схем, требующих такие же мелкие индукторы как высокочастотные. А в индукторе обычно куча потерь и его сопротивление напрямую зависит от индуктивности. Да и низкочастотные обычно ж самые примитивные с асинхронным выпрямителем, тогда как высокочастотные обычно наоборот.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Ну и применительно к ATtiny-почему бы сразу не сделать импульсный стабилизатор тока исключительно на атини?
Делал уже не раз: Indigo 5.0, и не только я. Тут этим почти все занимаются. Или вот пример, ставший культовым: https://forum.fonarevka.ru/...
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Не удастся выжать хорошие (как у мегагерцных заводских схем) КПД? Почему?
Всё удаётся и давно уже делается. Просто темы нужно читать не настолько избирательно . Я вот сейчас только программные преобразователи и делаю. Даже в мощных сетевых импульсниках к усилителям. Да и сами усилители (звуковые) у меня уже тоже - цифра (https://forum.fonarevka.ru/...). Это всё хороший путь, но и самый сложный. Ну и если нужна сверхэкономичность на малых токах - тут потребление МК значительно больше чем у аппаратных преобразователей.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
tps63020+Атини+цифровой переменный резистор?
Наверное. Это самое простое из рабочего у "ардуинщиков" (людей с низким порогом вхождения в это всё дело), и одновременно с этим МК позволит поиграться с более сложными вещами. Например, логарифмировать регулировочную характеристику органа управления, прикрутить кнопки, индикатор заряда и т.п.

[Исправлено: INFERION, 24.11.2020 в 02:22]
INFERION вне форума   Ответить с цитированием Вверх
Старый 24.11.2020, 02:09   14
Artik555
Увлеченный
 
Регистрация: 07.03.2020
Последняя активность: 18.06.2021 20:15
Сообщений: 302
Сказал(а) спасибо: 54
Поблагодарили: 5 раз(а) в 5 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

Цитата:
Посмотреть сообщение Сообщение от INFERION :
Почему по экспоненте?
Думал из-за усиления наводок от работы самой схемы на высоких частотах, думал фонить намного сильнее они начинают на высоких частотах работы, не линейный рост фона от частоты думал.
Ну и из-за "частоты единичного усиления" операционников думал сложно им по экспоненте с высокими частотами работать.
Artik555 вне форума   Ответить с цитированием Вверх
Старый 24.11.2020, 02:22   15
Artik555
Увлеченный
 
Регистрация: 07.03.2020
Последняя активность: 18.06.2021 20:15
Сообщений: 302
Сказал(а) спасибо: 54
Поблагодарили: 5 раз(а) в 5 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

Цитата:
Посмотреть сообщение Сообщение от INFERION :
Не встречал низкочастотных схем, требующих такие же мелкие индукторы как высокочастотные. А в индукторе обычно куча потерь и его сопротивление напрямую зависит от индуктивности.
С большими индуктивностям естественно, а не такими же.
Я просто думал что чем больше индуктивность тем меньше потери-толстым проводом намотал-и потери меньше
Думал в нём именно потери только по длине как в проводнике.
Ну и в фон уходящие, на высоких частотах, если он всё-таки не линейно усиливается от увеличения частоты, пока так и не разобрался.


Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Всё удаётся и давно уже делается.
Прям вплоть до 96+% как в лучших представителях заводских аналоговых преобразователей?
Просто мы по тонкому льду ходим Немного туда-немного сюда кпд, а там и глядишь линейные 81% рядом...

Не выйдет ли так, что как бы проще реализовать на микроконтроллере одном только драйвер, чем заставлять хорошо стабильно работать аналоговую микросхему у которой с завода 96% кпд,
но вот дотянуть самодельный преобразователь на микроконтроллере до тех же 96% потребует опять жёстких исследований и погружения в едрёную теорию на долгие месяцы безвылазно...

Вот в чём вопрос


за ссылку спасибо, почитаю про индиго 5.0, с навигацией по сайту было сложно, находил только через гугл темы по фразам из них по памяти, в которые раньше также случайно из гугла попадал
сейчас вроде разобрался

[Исправлено: Artik555, 24.11.2020 в 02:26]
Artik555 вне форума   Ответить с цитированием Вверх
Старый 24.11.2020, 02:31 Автор темы   16
INFERION

 
Аватар для INFERION
 
Регистрация: 07.04.2013
Последняя активность: 13.06.2023 02:24
Адрес: Украина, Полтава
Сообщений: 5774
Сказал(а) спасибо: 340
Поблагодарили: 8154 раз(а) в 2385 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Думал из-за усиления наводок от работы самой схемы на высоких частотах, думал фонить намного сильнее они начинают на высоких частотах работы, не линейный рост фона от частоты думал.
Я не замечал проблем из-за этого. Это ж не СВЧ, где всё нужно проектировать с учётом волновых сопротивлений проводников. Тут нужно сильно косячить в дизайне, чтоб это вылезло. Но накосячить можно на любой частоте.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Ну и из-за "частоты единичного усиления" операционников думал сложно им по экспоненте с высокими частотами работать.
От этой частоты только зависит глубина местной ОС, т.е. точность работы этого ОУ на конкретной частоте, и всё. Есть ещё второй лимит - скорость нарастания выходного напряжения. Если в оба этих параметра вписываемся - ОУ уже может выполнять свою задачу, а какой там вклад в общее усиление вносит его внешняя цепь ООС - вторично. Вспомнилась простая понятная статейка от Аудиокиллера: https://electroclub.info/ar...
И да, ОС в преобразователях работает на десятках-сотнях килогерц. Много ниже за частоту преобразования.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Я просто думал что чем больше индуктивность тем меньше потери-толстым проводом намотал-и потери меньше
А то что провод намного длиннее и при этом материал сердечника имеет бОльшую массу (и бОльшие потери на гистерезис и вихревые токи при прочих равных)? Достаточно глянуть на Rdc обмоток используемых там дросселей...
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Ну и в фон уходящие, на высоких частотах
Да нету там такого. Это ж не радио. Если что-то уходит в фон - нарушается электромагнитная совместимость и это говорит о косяках схемотехники. Значит где-то звенит какой-то паразитный контур на плате, и его или убирать, или если это невозможно - замедлять ключи и снижать КПД уже динамическими потерями в них (а не на вещание в эфир).
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Прям вплоть до 96+% как в лучших представителях заводских аналоговых преобразователей?
Можно и выше. Смотря какая задача. Аналоговые преобразователи имеют ту же самую силовую часть что и цифровые.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Не выйдет ли так, что как бы проще реализовать на микроконтроллере одном только драйвер, чем заставлять хорошо стабильно работать аналоговую микросхему у которой с завода 96% кпд,
но вот дотянуть самодельный преобразователь на микроконтроллере до тех же 96% потребует опять жёстких исследований и погружения в едрёную теорию на долгие месяцы безвылазно...
На МК давно собирают мощную высокоэффективную силовуху, вроде контроллеров двигателей (т.н. частотники) и прочих контроллеров PMSM с резольверами во всяких дорогущих ЧПУ - и ничего. Целые семейства МК существуют и развиваются. Есть даже со встроенными затворными драйверами на 3 полумоста (3 фазы) и DC-DC для собственного питания с силовых линий. Пример: https://www.st.com/resource...
На таком можно сразу собирать мультифазный преобразователь хоть для питания какого-нибудь процессора на материнке. КПД мультифазников выше однофазных преобразователей, и пульсации меньше. Или использовать фазы как три независимых канала.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Вот в чём вопрос
Ответ в том, что такие вещи мало кто осиливает...

[Исправлено: INFERION, 24.11.2020 в 02:55]
INFERION вне форума   Ответить с цитированием Вверх
Поблагодарили: 1 раз
Artik555 (24.11.2020)
Старый 24.11.2020, 12:17   17
Artik555
Увлеченный
 
Регистрация: 07.03.2020
Последняя активность: 18.06.2021 20:15
Сообщений: 302
Сказал(а) спасибо: 54
Поблагодарили: 5 раз(а) в 5 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

Цитата:
Посмотреть сообщение Сообщение от INFERION :
Тупая дубовая ОС, которая терпит такие издевательства, плюс конские индуктивности и ёмкости - так и работает
Какую именно дубовость ОС вы имеете ввиду? Дубовость ОС в самой микросхеме, или дубовость ОС в виде системы шунт-ОУ, т.е. с большим падением напряжения, и большими потерями-низким кпд, но что позволяет на фоне большого напряжения падения не замечать много шумов и помех, типа пульсаций, напряжения смещения и т.д.?

А большая индуктивность как тут влияет положительно? Добавляет большую инерцию системы?


Если совсем не стоит вопрос компактности конечной платы, может получится по простому/по тупому заставить нормально работать связку tps+ОУ с помощью больших ёмкостей?
Или не прокатит и такой путь безрезультатный?
Artik555 вне форума   Ответить с цитированием Вверх
Старый 24.11.2020, 14:48 Автор темы   18
INFERION

 
Аватар для INFERION
 
Регистрация: 07.04.2013
Последняя активность: 13.06.2023 02:24
Адрес: Украина, Полтава
Сообщений: 5774
Сказал(а) спасибо: 340
Поблагодарили: 8154 раз(а) в 2385 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Дубовость ОС в самой микросхеме
Да.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
дубовость ОС в виде системы шунт-ОУ, т.е. с большим падением напряжения, и большими потерями-низким кпд, но что позволяет на фоне большого напряжения падения не замечать много шумов и помех
Не замечал проблемы из-за каких-то шумов ОС. Она же всё равно интегрирует среднее значение. А большое падение на шунте повышает дифференциальное сопротивление нагрузки, тем самым снижая усиление ошибки, вот и всё.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
А большая индуктивность как тут влияет положительно? Добавляет большую инерцию системы?
Да. Замедляет реакцию системы на воздействие ОС - это снижает уровень ошибки регулирования (почти то же, что снижение её усиления). При этом не ухудшает стабильность на переходных процессах в нагрузке, т.к. то что не успевает регулятор - берёт на себя пассивный фильтр. Но это если ОС классическая на обычном усилителе ошибки.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
может получится по простому/по тупому заставить нормально работать связку tps+ОУ с помощью больших ёмкостей?
Может и получится, но это нужно грамотно проверять и отлаживать.
INFERION вне форума   Ответить с цитированием Вверх
Поблагодарили: 1 раз
Artik555 (24.11.2020)
Старый 06.12.2020, 20:20   19
Artik555
Увлеченный
 
Регистрация: 07.03.2020
Последняя активность: 18.06.2021 20:15
Сообщений: 302
Сказал(а) спасибо: 54
Поблагодарили: 5 раз(а) в 5 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

INFERION, назрело пару вопросов которые моими методами не гуглятся
Насколько непрерывное и равномерное напряжение на выходу у ЦАП? Допустим при плавном изменении с 0.5 до 1 вольта за 1 секунду, что будет на выходе если смотреть осциллографом который по характеристикам всё происходящее точно показать?
Какое сопротивление у цифрового переменного резистора между переключениями? На долю секунды во время переключения он в обрыв уходит или как?

И совсем оффтоп для этой темы, но всё же,
не могу никак понять, система "стабилизатор напряжения" + "шунт" + "оу" ну и + конденсаторы на выходе, это система стремящаяся к самозатуханию колебаний, к усилению колебаний или к бесконечному продолжению колебаний на одном уровне?
Т.е. вот изменили усиление на выходе ОУ, он подал меньшее напряжение на пин обратной связи микросхемы, она увеличила напряжение на выходе, увеличился ток через нагрузку и через шунт соответственно, ОУ подал бОльшее напряжение на пин обратной связи микросхемы, она уменьшила напряжение на выходе, уменьшился ток...
и пошло-поехало
Не нужен ли тут какой-то аналоговый компонент, который будет вычитать какую-то величину из управляющего сигнала, по времени и/или в зависимости от величины управляющего сигнала, для затухания колебаний как в ПИД-регуляторах программа делает?
Artik555 вне форума   Ответить с цитированием Вверх
Старый 07.12.2020, 13:35 Автор темы   20
INFERION

 
Аватар для INFERION
 
Регистрация: 07.04.2013
Последняя активность: 13.06.2023 02:24
Адрес: Украина, Полтава
Сообщений: 5774
Сказал(а) спасибо: 340
Поблагодарили: 8154 раз(а) в 2385 сообщениях

По умолчанию Re: Программная реализация драйвера на примере Indigo 3.0s

Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Насколько непрерывное и равномерное напряжение на выходу у ЦАП?
У какого? Они тоже разные ведь бывают. Дельта-Сигма? Ну там вполне себе аналоговый сигнал с каким-то количеством шума. SAR, R-2R, ШИМ, цифровой потенциометр? Ну тогда у голого ЦАП (без реконструкции сигнала) будут ступеньки, линейность ниже, но скорость выше. У ШИМ ещё и пульсации.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
что будет на выходе если смотреть осциллографом который по характеристикам всё происходящее точно показать?
В первом посте этой же темы есть вот это:
Пила преобразователя и где-то вон в ней спряталась более низкочастотная пила ШИМ. Это выход всего драйвера.

Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Какое сопротивление у цифрового переменного резистора между переключениями?
Смотря ж какого? Читать даташит на конкретный чип. Там ещё и время этого переключения будет указано. Но обычно такими вещами пренебрегают, насколько мне известно. Сам я цифровые потенциометры ещё ни разу не использовал.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
не могу никак понять, система "стабилизатор напряжения" + "шунт" + "оу" ну и + конденсаторы на выходе, это система стремящаяся к самозатуханию колебаний, к усилению колебаний или к бесконечному продолжению колебаний на одном уровне?
Поддерживать колебания на одном уровне - задача вообще сложная, и есть такая проблема в генераторах синуса на ОУ (там и лампочки обычные ставят для стабилизации амплитуды). А вот будет затухать или наоборот - зависит от этих самых ""стабилизатор напряжения" + "шунт" + "оу" ну и + конденсаторы на выходе". Обратную связь делят на положительную (ПОС) и отрицательную (ООС). Пока она отрицательная - имеем затухание, а когда становится положительной (из-за задержки сигнала во времени разворачивается фаза) - возбуд. Если нам не нужен возбуд - на его частотах усиление должно быть меньше единицы, чтоб эта ПОС просто не приводила к усилению колебаний. Вот и крутишь частотную коррекцию, обеспечивая требуемое снижение усиления на ВЧ. Чем сильнее снизишь - тем устойчивее ОС, но и тем она медленнее.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Т.е. вот изменили усиление на выходе ОУ, он подал меньшее напряжение на пин обратной связи микросхемы, она увеличила напряжение на выходе, увеличился ток через нагрузку и через шунт соответственно, ОУ подал бОльшее напряжение на пин обратной связи микросхемы, она уменьшила напряжение на выходе, уменьшился ток...
Вот если ОУ подаст больше чем нужно "микросхеме" - будет возбуд. Внутри микросхемы штатная ОС всегда немного недорегулирует, поэтому на условые 0.1А отклонения "микросхема" отреагирует только условными 0.07А. А затем на оставшиеся 0.03А отреагирует изменив ещё на 0.03*0.7=0.021А, и так пока не выйдет на режим. Тут имеем усиление ошибки 0.7. Если оно будет >2 - "микросхема" начнёт промахиваться больше, чем было до этого. Вместо стабилизации получим генерацию. При усилении 1...2 - будет заметен звон - затухающие колебания.
Цитата:
Посмотреть сообщение Сообщение от Artik555 :
Не нужен ли тут какой-то аналоговый компонент, который будет вычитать какую-то величину из управляющего сигнала, по времени
Нужен - частотной коррекцией называется. Уже есть в "микросхеме", есть в ОУ, и есть в "конденсаторах на выходе".
INFERION вне форума   Ответить с цитированием Вверх
Поблагодарили: 1 раз
Artik555 (07.12.2020)
Ответ  Создать новую тему
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск





Copyright ©2007 - 2024, FONAREVKA.RU

Powered by vBulletin®
Copyright ©2000 - 2022, Jelsoft Enterprises Ltd. Перевод: zCarot

Правила форума | Отказ от ответственности
Время генерации страницы 0.28702 секунды с 19 запросами