-Музыка

Нестандартные скорости UART MSCOMM32

Дневник

Воскресенье, 18 Июня 2017 г. 17:06 + в цитатник

Удалось связаться с AVR по UART через MSCOMM32.OCX на скорости 250000 бод. Частота кварца избыточная - 16 МГц. Действительно и для Arduino. Как? Подсказка на VBForums, используем Win32 API SetCommState и GetCommState из Kernel32. Немного костылей в выборе менюшки скоростей, т.е. для галочки открываем порт на допустимой стандартной скорости 115200, а затем уже задаём любую, вплоть до 2МБит.


AVR software uart 250000 baud (452x115, 5Kb)
MSComm 250000baud (206x172, 13Kb)

Сразу оговорюсь, что UART со стороны AVR программный, поэтому скорость такая низкая. Схемотехнически у меня программный RX/TX висит на свободных ногах ATMega328P, потому как аппаратный занят шиной данных с NAND флешкой.



Итак, управляющая программа на VB6 использует компонент MSComm и разрешает из коробки подключаться только на следующих скоростях (бит/с, бод): 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200, 128000, 256000. Успехом увенчалась попытка подключения на 128000, а 256000 уже не приводила к желанному результату увидеть ответ устройства по UART. Возможно, дело в том, что если для аппаратного приёмопередатчика UART можно запросто подобрать скорость UART в зависимоти от частоты задающего генератора, то для программного, который зависит от кучи прерываний и лагов обработчика, высокие частоты упираются уже не в последнюю милю кабеля и разводку с экранировкой, а в специфику работы программного UART. Боюсь предположить, но аппаратный UART на AVR в теории может давать бодрейт до 2 МБит/с, т.е. 2000000. Разумеется, со стороны компьютера я ловлю его не через родной COM-порт материнки, а через преобразователь CH340G, который стоит в каждой ардуине, и его предел аппаратных возможностей с подобающей обвязкой по даташиту заканчивается как раз таки на 2 Mbps. Это ограничение уже упирается в физическую реализацию последней мили - длину проводов USB, разводку на плате, конденсаторы и качество кабеля.



Что я получил на скоростях 250 КБит/с? Чтение блока с флешки (135168 байт) за 6,16 секунд. Запись, правда, до сих пор ограничивается скоростью в 135168 байт за 35,9 сек, что обусловлено моей осторожностью и программными задержками при записи в NAND flash. Однако мой любимый дисплейчик ❤️️ LCD 160x128 16 битного цвета заполняется из флешки полностью картинкой за 215 мс, то есть можно глядеть кино с FPS ~5 кадров/сек., что я считаю пределом для 16 МГц, софтварном SPI через дрыганье ногами и попутном чтении с флешки, то смею предположить, что видеобуфер (ОЗУ дисплея) составляет 40 960 байт, и по UART напрямую при скорости 250 КБит заполнится за 2 секунды. Всё равно медленно, чтение флешки размером в 1 ГБ (NAND flash K9K8G08U0M-PIB0) займёт 14 часов.


Однако команда CLS, оформленная AVR-ASM просто дёрганьем CLK дисплея при постоянной единице на шине DATA очищает 160х128 за 0,105 сек, то есть за 105 мс., что как бы намекает на непредельность скорости. То есть используя полупрограммный-полуаппаратный SPI из-за того, что 9-й бит приходится дёргать вручную, остальные 8 будет слать аппаратный SPI, при быстром ОЗУ контроллера я бы смог добиться скорости вывода одного экрана (не пустого) за 105 мс при скорости UART в 1,5...2 МБит. Без промежуточной флешки, а картинку бы формировал на стороне компьютера. Тогда и кино в 10 FPS можно было бы крутить.


AVR Parallel output for Nokia 1616 LCD (700x451, 108Kb)

А самым забавным решением было бы применение внешнего аппаратного SPI, который из параллельной шины делает последовательную, и клок дёргать вручную. Однако это то же самое, что и полупрограммный SPI, потому как совсем блокируется возможность передавать данные в обратную сторону от дисплея (читать ОЗУ дисплея, SPFD54124B это позволяет). Но это уже больная фантазия.

Рубрики:  этот удивительный мир вокруг нас

Метки:  

Успеть сохранить в EEPROM при сбросе питания

Дневник

Воскресенье, 04 Июня 2017 г. 23:56 + в цитатник

Дело и предыстория такая: решил я таки перебрать счётчик Микрон СЭО-1.10.1 на базе AD7755 и прикрутить к нему цветастый TFT LCD дисплей, чтобы видеть как денежка утекает в пустоту🤑 и отражается на цене изделия, выскакивающего из-под станка.


Микрон СЭО-1.10.1 AD7755 и ATMega8 (700x525, 95Kb)

Поскольку станок потребляет множество разных напряжений по разным проводам, от +3,3В до +50В, единственным разумным решением считаю прикрутить счётчик на 220В переменного тока возле входа в розетку. По сути, у счётчика есть импульсный выход, который даже на колодку выведен, 2 клеммы, которые нормально разомкнуты, однако импульс инверсный, и размыкаются они только при прохождении импульса от AD7755. Таким образом, как и в проводной сигнализации, злоумышленник не сможет оборвать сигнальную цепь. Оборвав её, он обречёт вечно повисший импульс в нуле застрять в глубинах централизованной считалки в подвале, что сразу же будет обнаружено. Клемма безопасная - размыкание происходит через оптрон, поэтому я мог и не разбирать счётчик, а лишь подключиться к этим контактам. Но рука чесалась, и я встроил в корпус счётчика USB-зарядку с Aliexpress за 49₽, которая даёт +5В, достаточных для запитки моей платы микроконтроллера с цветным дисплеем.



Однако тем и хороша логика работы механического счётчика, что импульс дёргает катушку счётчика и передвигает колесо при каждом импульсе, при отключении питания «данные», показания уже сохранены физически. Электрически же мы можем держать их в ОЗУ до момента сброса питания, или записывать каждый импульс в EEPROM. Однако ресурс EEPROM сильно ограничен - лишь 100 000 циклов перезаписи. Если счётчик выдаёт 4000 импульсов на 1 кВт, то для одного байта EEPROM ресурс исчерпается за 25 кВт. Это меньше месячного потребления, а чтобы сохранять хотя бы годовые показания, нужен DWORD (32 бита, 4 байта). Но даже если устроить некоторый TRIM, как у SSD для ячеек EEPROM, распределять износ, всего объёма EEPROM (512 байт у ATMega8, по 4 байта на 1 показание) хватит лишь на ((512/4)*100 000)/4000=3 200 кВт⋅ч. Это лишь год и контроллер можно выпаивать и выбрасывать. Тут ещё умные мужики на хабрах пишут, что мол EEPROM внутри ATMega имеет не побайтную адресацию, а тоже WORD или DWORD -
тоже можно было бы учесть, чтоб не перезаписывать лишний раз, но это уже крохоборство будет .


Как сэкономить ресурс энергонезависимой памяти EEPROM при условии непредсказуемого пропадания питания? Чтобы не запоминать каждый импульс? Как не износить ресурс EEPROM AVR?


У устройств с батарейным питанием момент сохранения состояния реализован проще - опрос напряжения батареи/АКБ с помощью АЦП, и при падении до минималки 3,7В мы просто сохраняем и уходим в глухой сон, отключаем периферию, компараторы и не реагируем на внешние прерывания. При этом у схемы вполне хватает сил и энергии сохранить в EEPROM ещё вагон информации.


Но при непредсказуемом питании на помощь также придёт встроенный АЦП. Просто воспользуемся вредным советом отделить шину питания контроллера диодом от основной шины питания, которую через делитель (R1, R2) заведём на АЦП (PC0). Для демонстрации можно понавешать светодиодов на обе шины питания🎄.



Сохранить EEPROM при сбросе питания (640x323, 19Kb)

Итак, на всю схему приходит +5В от зарядки с Aliexpress, которая встроена в счётчик (и тоже учитывается), они же через делитель приходят на АЦП, а сам контроллер запитан чуть более низким напряжением +4,2В из-за падения на диоде. Ничего страшного. Я взял первый попавшийся диод 2Д106А, и он заработал. После диода ставим конские конденсаторы 2 шт. по 1000 мкФ, можно больше, однако смотрите, чтобы блок питания выдержал при пуске и потребление контроллера, и зарядку конденсаторов. Ну и конечно, не забываем об обвязке-фильтрах для АЦП (AVCC, AREF).


Что происходит при отключении питания 220В? Напруга пропадает до диода моментально (светодиод тухнет сразу же), потому что в Aliexpress USB-зарядке конденсаторов кот наплакал, а вот после диода напруга снижается постепенно в течение 1,5...2 секунд. Этого времени более, чем достаточно, чтобы АЦП понял, что напруга упала и быстро записать 4 байта в EEPROM. Разумеется, все вышеприведённые цифры и номиналы подобраны на глаз экспериментально, у меня до диода ещё стоит CH340G USB-UART, а будет ещё подсветка дисплея. Питание дисплея будет висеть на шине питания контроллера. Вообще по логике работы целесообразно диод ампера на полтора поставить, чтобы всё, что напрямую подключено к контроллеру отключалось вместе с ним и не происходило подпитки схемы через ножки портов, что может спалить AVR.


В данном решении нашёл единственный косяк: пока работаю без Watchdog'а🐶, возможно, он снимет проблему кратковременного пропадания питания, когда контроллер уже ушёл в сон, но на конденсаторах ещё остался заряд в +1...2В, и при возвращении питания (AC back, DC back) не происходит RESET, контроллер не тактируется благодаря оператору END. А также одна неприятная мастырка - пин RESET не равнозначен сбросу питания СхЭ.


А теперь немного кода на скорую руку (BASCOM-AVR):





Config Pind.6 = Input ' Пока без прерываний, опрашиваем импульсный вход в цикле
Config Adc = Single , Prescaler = 16 , Reference = Internal 'Референс внутренний
' для перестраховки
Dim Currentcounts As Dword , Checkcounts As Dword , Emptydword As Dword
Dim Megacounts As Byte
Dim Eepromaddress As Byte ' Даём 256 байт (64 метки) от &H00 до &HFF адрес в ЕЕПРОМе
Dim Voltage As Word 'Отлов показания АЦП, падения напруги

Emptydword = &HFFFFFFFF 'Не умеет писать константу в ЕЕПРОМ!!!!!11
' Показания счётчика будут измеряться 32 битами (DWORD) (по адресам а также байтом
' по адресу &H104, который является началом следующего разряда после DWORD. Типа
' продолжение разрядности Megacounts

Readeeprom Megacounts , &H104
If Megacounts = &HFF Then 'Первый запуск, в ЕПРОМе пусто
Megacounts = 0
Writeeeprom Megacounts , &H104
Elseif Megacounts = &HFE Then
Print "Counter locked!" ' Иди беги за новым счётчиком!
End
' Блокируем счётчик при 4 294 967 295 * 255 импульсах = 1 095 216 660 225, что в
' киловаттах 274 877 906. Хватит на десятилетия промышленного и столетия бытового
' использования.
End If
' Теперь технология выравнивания износа для EEPROM (TRIM :)
' Найти крайнее нулевое значение в еепроме
' Сюда б добавить проверку нынешнего и последнего значения в EEPROM, чтобы не писать
' в две ячейки одно и то же значение.
For Eepromaddress = 0 To &HFF Step 4
Readeeprom Currentcounts , Eepromaddress
If Currentcounts = &HFFFFFFFF Then
Eepromaddress = Eepromaddress - 4
Readeeprom Currentcounts , Eepromaddress
Eepromaddress = Eepromaddress + 4
Exit For 'Нашёлся крайняя пустая ячейка
End If
Next Eepromaddress
' Если крайний адрес был последним, счётчик Eepromaddress скинулся в &H00, значит
' можно засейвить показания в ОЗУ и вытереть весь EEPROM. Операция ДЛИТЕЛЬНАЯ!
If Eepromaddress = &H00 Then
If Currentcounts <> &HFFFFFFFF Then
Print "Erasing EEPROM..."
For Eepromaddress = 0 To &HFF Step 4
Writeeeprom Emptydword , Eepromaddress
Next Eepromaddress
End If
End If
Print "Null place:" ; Hex(eepromaddress) ' Отладочная строка, что мол писать будем сюда
Print "Previous counts:" ; Hex(megacounts) ; " " ; Hex(currentcounts) 'И то, что
' было считано из предыдущей ячейки

Start Adc 'Начинаем слушать и быть начеку пропадания питания
Do
Voltage = Getadc(0) ' Да, тупо проверка в цикле. Надо бы прерываниями, но впадлу
' без платы, на макетке
If Pind.6 = 0 Then 'Отлавливаем сам импульс
While Pind.6 = 0 : Wend 'Ждём конца импульса. Неправильно с точки зрения
' вмешательства злоумышленника на длине проводов в 5 см =)
If Currentcounts = &HFFFFFFFF Then 'Пока невнятно, при первом же включении
' разряд будет увеличен. Но никто не мешает насильственно при прошивке и первом
' запуске в ЕЕПРОМ &H00 прописать четыре нуля!
Incr Megacounts
Writeeeprom Megacounts , &H100
Currentcounts = 0
Else
Incr Currentcounts ' Одна четырёхтысячная киловатта израсходована: 0,25Вт
End If
Print Hex(megacounts) ; " " ; Currentcounts ' Пока print, но буду здесь процедуру
' вывода на дисплей всовывать при каждом импульсе. Или нет.
End If
If Voltage < 450 Then 'Алярм! Падение напруги! Магическое число 450
' экспериментальное. Чтоб не случалось ложных срабатываний при просадке -0,5В.
Stop Adc 'Отключаем всю периферию в т.ч. дисплей и т.д. и т.п.
Disable Interrupts ' Которых ЕЩЁ нет
Repeatwrite: ' А вот это тупой кусок кода! Запись с перепроверкой ЕЕПРОМа
Writeeeprom Currentcounts , Eepromaddress
Readeeprom Checkcounts , Eepromaddress
If Currentcounts <> Checkcounts Then Goto Repeatwrite 'Интересно, как я буду
' уверен в том, что содержимое ОЗУ Checkcounts и Currentcounts не повредила
' деменция ввиду падения напруги???
Print "Saved " ; Hex(currentcounts) ' Надпись, которую никто не увидит при
' отключённой подсветке дисплея. Лучше маложрущий светодиод поставить, который
' скажет об успешной записи.
End ' Останавливаем тактирование.
End If
Loop
End ' До сюда обработчик не доберётся никогда.



В заключение, раз уж речь зашла о питании. Я тут недавно попал на 6 т.₽. тупо из-за того, что маляха заряжала эйфон через зарядку для люмии ширпотреба на Android. Сказать, что был зол - ничего не сказать, ибо был без волшебной бaрбитуpы и эмоциональная реакция как в игре от третьего лица, уплощена🙃. Вроде бы все зарядки одинаковые, все Travel форм-фактора зарядки, но оригинал Apple зарядка почему-то стоит почти 1 т.₽. и весит грамм 50, а просто microUSB под любой ширпотреб можно купить за 49₽ на Aliexpress. При всём этом iPhone 4S оказался куда более всеядным - он с удовольствием кушал любое питание, а iPhone 7 Plus требователен к питанию и напряжению. Для индексации оставлю эту фразу, чтобы население не подтирало дупу инструкцией, где русским по белому написано использовать только оригинальные аксессуары Apple Inc. При использовании левой зарядки через два месяца у айфона вылетает контроллер заряда U2, BGA-микросхема, замена которой стоит вот эти 6 т.₽., причём стоит справедливо. Я заканючил, сгримасничал, поставил крестик на этой микре чтобы её именно заменили, а не просто прогрели или сделали реболлинг, с этим может справиться и К. на своей инфракрасной паяльной станции. И действительно, из ремонта вернули ту самую отпаянную помеченную крестом микросхему U2 в скотче. Короче, это такой индексируемый аттеншн: ‼️iPhone ломается при зарядке от Android.‼️ 🔴Не заряжайте Apple левыми зарядками🔴 Кстати, вскрытие зарядок показало, что мало того, что андройдова зарядка даёт безумные пульсации, так ещё и напряжение +5,5В (компьютерный USB тоже не хорош) вместо положенных +5В, которые даёт родная эплова зарядка. После этого случая я даже в компе не оставляю телефон дольше, чем нужно для сброса фоток.

Рубрики:  этот удивительный мир вокруг нас

Метки:  

 Страницы: [1]