Сообщество - Сообщество Ремонтёров

Сообщество Ремонтёров

8 097 постов 44 152 подписчика

Популярные теги в сообществе:

110

Диагностика и ремонт ноутбука ASUS N56V. Необходимые условия старта материнской платы.

Необходимые условия старта это все понятно


1. Когда основной биос и EC-биос 100% рабочий.

2. Когда есть питание мульта, его кварц работает и мульт биос вычитывает (смотреть обмен данными на флешке биоса осциллографом).

3. Когда ACIN = 3.3V

4. Когда LID_SW# = 3.3V

5. Когда мульт снимет ресет с юга, т.е. EC_RSMRST# = 3.3V

6. Когда при нажатии кнопки включения сигнал ON/OFFBTN# опускается до нуля и этот же сигнал транслируется в PBTN_OUT#

7. Когда с юга сигналы PM_SLP_S3# и SLP_S5# будут сброшены, т.е. напряжение на них составит 3.3V.

При этих условиях мульт должен дать команду на запуск.

Показать полностью 1
47

Выполняем замену выгоревшего разъема питания ноутбука

Для начала удаляем эпоксидную смолу, которую нанес владелец ноутбука. Оттягивание ремонта привело к тому, что из-за плохого контакта дорожки просто выгорели.

Перед началом ремонта очистим дорожки изопропиловым спиртом от нагара.

Теперь мы можем приступать к нанесению флюса. Подойдет даже канифоль. В тех случаях когда на контактах имеется сильная коррозия и обычный флюс не справляется нужно использовать активный флюс это Ф-38Н, не забудьте очистить плату после окончания пайки.

Добавляем на контакты немного свинцового припоя, это поможет снизить температуру плавления.

Далее вставляет в отверстие разъема пинцет. Теперь необходимо взять паяльник с толстым жалом и поочередно прогревать все контакты в то же время оказывая небольшое усилие пинцетом на разъем. Ни в коем случае не давите сильно, можно испортить плату.

На фото слева видим выгоревшую контактную площадку и справа, то какой она должна быть.

Пробуем прозвонить и видим короткое замыкание.

Чтобы Dы понимали на сколько температура была высокой так выглядит плата которая находилась в нескольких миллиметрах.

Слева мы видим испорченный разъем с выгоревшим выводом.

Справа разъем с донора, я припаял к нему провод и изолировал контакт термоусадкой.

Перед установкой разъема необходимо очистить контакты от припоя медной оплеткой. Так выглядит плата с уже с установленным разъемом.

Сняв все элементы которые были соединены с замкнутым контактом я в первую очередь их проверил, все оказались в рабочем состоянии. А значит можно приступать к следующему этапу. Берем небольшой кусочек платы, немного уменьшаем ее толщину. И приклеиваем на эпоксидную смолу.

Теперь можно приступать к установке снятых элементов. Так же было решено оставить кусочек провода для того, чтобы механическое воздействие на разъем не передавалось на маленькую плату. Сборке корпуса плата и провод не мешают.

Приступаем к проверке.

На видео вы сможете увидеть процесс более наглядно.

Показать полностью 12 1
136

Ликбез по зарядкам Samsung 30 pin (N8000 P5100 P3100 P6200 N5100 P7500 и т.д.) или "как выбрать зарядку, которая будет заряжать планшет"

Пришлось перечинить много N8000 P5100 N5100 и т.д. с проблемами выхода из строя микросхем памяти. Подробные статьи тут:

https://pikabu.ru/story/samsung_n5100_zamena_emmc_5412825

https://pikabu.ru/story/samsung_n8000_zamena_emmc_bez_boksa_...

https://pikabu.ru/story/samsung_p7500_zamena_emmc_5565558


И их продолжают нести со всей России, что приятно. ) Но так же встречаются и сопутствующие проблемы. Одна из проблем - проблема с зарядкой.


В данном посте пойдет речь про проблемы с зарядкой у планшетов Samsung с разъемами 30 pin (это примерно такой же разъем как на iPhone 3g/gs/4/4s, но другой. ) Вот такой:

Соответственно под словом "планшет" в данном случае будем подразумевать планшет Samsung с разъемом зарядки 30 pin (все из названия поста + аналогичные аппараты Samsung).


Под словами "не заряжается" будем подразумевать, что аппарат не заряжается как положено. Т.е. "заряжается за двое суток" = "не заряжается".


Вся информация собрана из различных источников в интернете, а так же на собственном опыте работы с такими планшетами.


С N8000 и P5100 в комплекте идёт вот точно такой зарядник из трёх частей: вилка, блок и кабель.

Вроде как на другие модели попадались более компактные блоки питания, но сути это не меняет. Будем исходить из этого.


Многие пользователи через годы работы получают проблемы с зарядкой планшетов. Как правило, проявляется это тем, что планшет перестаёт заряжаться нормально: во включенном состоянии рисует крест на АКБ, а в выключенном может заряжаться 2-3 суток. Или же вобще перестаёт заряжаться. Люди покупают новые кабеля, новые зарядники, но всё тщетно. Даже некоторые мастера впадают в ступор, начинают копать плату, хотя часто всё гораздо проще.


Так давайте разберёмся с этим вопросом "по науке". На самом деле диагностика проста до безобразия и для этого понадобится всего два устройства:

цифровой вольтметр USB из китая за 5-6 долларов и адаптер P1000 to microUSB ценой менее доллара:

Особенность этого тестера является то, что он кроме напряжения собственно USB порта показывает так же напряжение на шинах данных. Это очень поможет нам в дальнейшем.


Итак, приступим. У нас на руках три железки:

1. Планшет

2. Кабель

3. Блок питания

И при этом планшет через этот кабель и блок питания или не заряжается вобще, или заряжается очень медленно.

Мы не знаем, что из них неисправно и что нужно заменить. Приступим к диагностике.

Начнём с конца.


Блок питания.

I. Согласно информации от производителя блок питания должен соответствовать следующим характеристикам: напряжение 5 вольт, постоянный ток 2 ампера.

Причем эти параметры пишут на самом устройстве в том или ином виде:

На оригинальной зарядке так же указано мелко среди прочего:

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

И из этого делаем вывод, что эти планшеты не заряжаются от компьютера. На батарее во включенном состоянии будет красный крест. Так всегда, это не является неисправностью.


Небольшое отступление:

Проверить выдерживает ли зарядка заявленные 2 ампера можно с помощью нагрузочного сопротивления. Вот такого типа (Могут отличаться внешне, не суть такая. Два резистора по 1 амперу. Бывает и больше, но нам не надо.)

Тоже в поднебесной покупается за пару мертвых американских президентов.


Во время тестирования нагрузочный резистор будет греться. И не говорите, что я вас не предупреждал. Соответственно ток будет примерно 2 ампера, а напряжение не должно падать ниже 5 вольт. Это будет свидетельствовать о том, что параметры зарядки в норме и она тянет заявленные характеристики.

Для оригинальной зарядки паровоз выглядит вот так:

Лишнюю информацию с дисплея я удалил. Ни к чему она.


II. Второй характеристикой оригинального зарядного устройства является потенциал на линиях D+/D-. Да-да, эти аппараты не будут заряжаться двумя проводниками, им нужно 4 проводника. Причем 4 хороших качественных проводника нормального сечения. Именно это и является первым подводным камнем.

Схематично выход зарядного устройства выглядит так (картинка стырена из интернета):

Т.е. мало того, что D+ и D- соединены между собой, так ещё есть подтяжка по питанию, которая формирует 1,25 вольта на шине данных.

Если такой развязки нет в вашем блоке питания, то планшет не будет от него заряжаться корректно. Он решит что он подключен к компьютеру и ограничит ток зарядки до 400-450 мА. И чтобы зарядиться таким током, потребуется 2-3 дня.

Проверить наличие развязки можно обычным мультиметром. Подлезть в USB разъем вряд ли получится, но порезать старый кабель и измерить - можно. Или же используя наш универсальный тестер посмотреть напряжение на шине данных.

Соответственно для правильного блока питания должно быть как-то так:

Итак, с блоком питания разобрались: 5V/2A + 1,25V на шине данных.


Кабель зарядки.

Он же кабель передачи данных.

Как и практически любой USB кабель он состоит из 4 проводников и экранирующей оплетки.

90% всех проблем с зарядкой этих планшетов - проблема с кабелем (владельцы айфонов поймут))) . Как правило проводники перекручиваются в одном из штекеров и обрываются, или соединяются между собой, что приводит к неработоспособности кабеля или устройства.

Если шина данных в обрыве, то или блок не передаёт 1,25 вольт по шине данных и планшет заряжается малым током как от USB.


Второй подводный камень: качество кабелей.

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

Идеальный вариант, если кабель у вас оригинальный, вы его бережёте и всё хорошо.

Если так случилось, что оригинального кабеля нет и вы пошли на его поиски и вам говорят, что вот это, вот прям ОРИГИНАЛ и ещё добавляют

то тут как повезёт. Встречаются на рынке кабеля более-менее сносные, а встречаются совсем шлак. Мне приходилось сталкиваться с двумя типами кабелей в своих краях:

1. прям копия оригинала, но в пакетике (самая низкая цена).

2. кабеля ISA в коробках.

Первые хоть и работают, но годятся только для подключения к ПК.

Вторые работают отлично во всех режимах.

Не знаю из чего китайцы делают дешевые кабеля, но они просто не пропускают нужны ток. Т.е. для планшета нужен ток зарядки до 2 ампер, а кабель пропускает только 0,8-0,9 и всё.

Позже будет фото с замерами.

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

Лайфхак: если через кабель планшет определяется компьютером, то шины данных целые. Но это ещё не значит, что аппарат будет заряжаться этим кабелем нормально: нужно смотреть ток зарядки через тестер USB.

Этот же тестер поможет подобрать кабель, который нормально пропускает ток.


Теперь возникает проблема: если мы в далёкой деревне, где днём с огем такой кабель не найдёшь, блок зарядный утащил медведь в берлогу и на 100 верст вокруг нет магазинов, то попробуем сварганить зарядку из более доступных материалов.

Тут мы вспоминаем про наш адаптер P1000 micro USB (легко ищется по этим словам на али).

Адаптер этот примитивен. Внутри всего два сопротивления, которые формируют те самые 1,25 вольта на шину данных. Таким образом используя ЛЮБОЙ USB блок на честные 5 вольт/2 ампера + microUSB кабель + адаптер P1000 micro USB мы сможем зарядить планшет, поскольку он будет "обманут" адаптером и считать, что он подключен к оригинальной зарядке.

Так же с помощью этого адаптера можно убедиться в том, что схема зарядки исправна (если аппарат через него заряжается, а через родной кабель нет, то значит проблема у нас или в блоке питания или в кабеле).

Я настоятельно не рекомендую использовать этот адаптер постоянно, поскольку на разъем планшета создаётся излишняя нагрузка и он достаточно быстро сломается.

По понятным причинам адаптер не способен передавать данные. Он только для зарядки.


Теперь фото с замерами слева направо:

1. Новый дешевый кабель.

2. Новый дорогой кабель ISA (так же и с оригиналом).

3. Кабель MicroUSB с адаптером (адаптер разобран).

Стоит иметь ввиду, что такие показатели характерны для аппаратов 10,1 дюйма, с большим АКБ и текущим процентом заряда менее 30%. По мере зарядки АКБ ток заряда падает. Аппараты 7-8 дюймов с маленьким АКБ потребляют примерно на 400-500мА меньше (да, для них может и дешевый кабель пойдёт).


В продаже существуют зарядки сборные, т.е. не отдельно блок и кабель, а собранное воедино зарядное устройство. Насколько я знаю, с ними проблем нет, хотя внутрь не лазил.


Собственно планшет.

Если ни одним из способов выше планшет не заряжается, но вы уверены, что он исправен, то причину надо искать уже в самом аппарате. Частенько отрывают разъем на N8000/P5100/P7500, поскольку разъем на шлейфе. Как правило восстановлению шлейф не подлежит, ибо дорожки все порваны и проще заменить. Но менять надо или на оригинал, или сразу проверять, поскольку китайцы тоже бывает чудят и шлейф тоже не пропускает нужный ток. Благо комплект для проверки умещается в карман.)

С планшетами 7-8 дюймов часто бывают проблемы с АКБ (там одна банка и она со временем перестаёт выдавать нужный ток, планшет не может даже загрузиться). Там где большие АКБ такое не встречалось, две банки всё же только емкость теряют.

Более сложные проблемы уже решаются с системной платой, но это совсем другая история.


Я в Саратове, координаты для связи можете найти в предыдущих постах.

Если есть какие-то вопросы, то спрашивайте в комментариях, постараюсь всем ответить.

Всем спасибо за внимание. Надеюсь, было интересно и познавательно.

Думаю, что в этом году постов уже не будет, так что всех с наступающим Новым Годом!

Показать полностью 12
335

Что делать со старым ресивером Триколор-ТВ

Ну собственно этот пост является продолжением вот этого: https://pikabu.ru/story/trikolortv_okonchatelno_blokiruet_st...


За последнюю неделю мне позвонило 3 человека что у них перестали работать старые ресиверы спутникового провайдера Триколор-ТВ. Пришлось людей огорчить.


Как показало общение со знакомыми, покупать за 5500 рублей они новый ресивер не хотят (это так называемый "обмен"), но и остаться на новогодние праздники без телика не хочется.


А так же помер один ресивер на работе.


Я его забрал домой и сделал небольшое видео, как можно продлить жизнь ресивера.


Показывать Триколоровские каналы он конечно уже никогда не будет, но я сделал небольшую видеоинструкцию как настроить на нём собственными силами открытые каналы, которые идут со спутника  Eutelsat W4.


Сразу скажу, я намеренно не включил в видео, настройку каналов всевозможных телемагазинов,  так как считаю их злом.

Кто хочет, пусть сам ищет их  частоты и настраивает по указанному мной алгоритму.


В открытом доступе я нашёл только 4 канала формата MPEG-2.
Если есть ещё, напишите пожалуйста в комментариях. 

Показать полностью 1
1002

Ещё один оборотень

К посту https://pikabu.ru/story/zhestkiy_disk__oboroten_5330704


Обратился тут ко мне клиент с проблемой. Мол купил на Ali аж за 1500 целковых внешний hdd на 500гб, а он не работает. Ok говорю, давай посмотрим (сразу вспомнил камрада q2andrey)

Итак вот наш пациент. Пока всё ok...

Вскрываем!

Стоп! Что это?! Следы оригинальной наклейки.

С обратной стороны видим какие-то подтёки и псевдогарантийку. Видно что диск сильно-сильно б/у.

К слову сказать, компьютером это китайское народное творчество определялось как ST500LM012 SATA1! SATA1, Карл!!! Это ж каких он годов...

Итого имеем древний диск с новыми наклейками и прошивкой под 500гб, расстроенного клиента и минус 1500 рррэ.


P.S. В общем аккуратней при покупке подозрительно дешёвых внешних Hdd. Похоже китайские друзья поставили это "дело" на поток.

Показать полностью 4
970

Отдам 6 кг "трупов" в прямые руки.

UPD: Телефоны готовятся к отправке.
Всем спасибо.
______________________________________________________________________________________________________

Доброго времени суток, пикабутяне! Есть 14кг умерших, древних мобилок. Может надо кому на запчасти? Думаю, что какой-нибудь Кулибин, возьмёт с них что-нибудь полезное. Могу отдать совершенно бесплатно и без корыстно. Вышлю первому, кто выйдет на связь.

По традиции - комменты для минусов внутри.

P.S. Лет 8 - 10 назад покупал их на запчасти по 50-100руб).

Показать полностью 4
106

STM32 от Булкина. Урок 2: Пишем библиотеку сами для STM32

Предисловие


Меня частенько упрекают, что я даю материал в слишком трудной манере и не по порядку. Спешу вас расстроить, я и дальше буду следовать этой логике.


Стерильно-приторных уроков “для чайников” по программированию МК, в том числе и по STM32, на просторах инета полно. Учат они чему-то? Не уверен. Они лишь дают возможность разобраться в какой-то функции, когда возникает потребность.


У меня цели другие: научить думать и пользоваться документацией. Это можно сделать только на живых и настоящих примерах. Только в бою, так сказать. Я стараюсь показывать не столько возможности, сколько путь от задумки до реализации. Стараюсь выстраивать логику процесса так, чтоб не дочитав до конца вы уже могли бы предположить, что получится или какие могут возникать проблемы.


Я практикующий радионженер. Я не занимаюсь DIY. Я стараюсь показывать вещи так, как их делать ПРАВИЛЬНО. Делать на совесть, а не тяп-ляп и так сойдёт. Одно дело, когда вы берёте чужую реализацию и не разбираясь суёте в свой проект. Другое дело, когда сами пишете библиотеку с настроением, мол, разбираться некогда. Как то работает и х** с ним. Это ужас ужасный!


Предыдущие статьи:


Настройка Sublime Text 3, SW4 и STM32CubeMX для разработки STM32 под Windows 10

Настройка Sublime Text 3, SW4 и STM32CubeMX для разработки STM32 под Linux

STM32 от Булкина. Урок 1: Вводный, где мы немножко похулиганим

STM32 от Булкина. Atmega и Arduino vs STM32 и HAL


Ладно, сегодня у нас интересная тема!


Пишем библиотеку сами для STM32


В комментах проскакивали панические настроения некоторых людей, что не хватает библиотек для каких-то вещей. И я, и некоторые читатели, пытались убедить, что ничего страшного в этом нет.


Написание библиотеки - это приятный и увлекательный процесс! Бывает нудноватым, когда приходится тупо копипастить какие-то значения из документации, но в целом, весь процесс даёт какой-то адреналин даже. Ну а когда ты с чувством удовлетворения взглянешь на свой труд - оргазм!


Я долго не мог придумать, что же такое взять в качестве примера из того, что у меня самого не реализовано. И с удивлением обнаружил, что у меня нет библиотеки для классического текстового LCD на Hitachi HD44780. Это 1-но, 2-х или 4-х строчные дисплеи до 20 символов на строку. Те самые, которые все так любят втыкать во все свои DIY.


Полазил по просторам и с ещё большим удивлением обнаружил, что все реализации для шины I2C основаны на дурацкой классической библиотеке Arduino LiquidCrystal_I2C. Ну, думаю, сам Бог велел!


Начнём с главного: чтения документации.


Как работает дисплей


Дисплей основан на старинном чипе от HITACHI HD44780. У него нет последовательного интерфейса, как, например, у ST7920. Тем не менее, он прост до безобразия.


Открываем даташит раздел “Interfacing to the MPU” и видим примерную диаграмму, как устроен обмен данными. Смотрим, смотрим и видим фигу. Но всё-таки что-то почерпнуть можно.

Базовый его режим 8-ми битный. Т.е. мы можем передавать ему 1 байт за раз. Для чего у него есть восемь ног DB0-DB7. Ещё у него используются 3 ноги:


E: выдаём строб (импульс), который сообщает дисплею, что на ногах DB0-DB7 выставлены нужные данные, мол, давай, считывай

RS: Сообщаем дисплею, что мы хотим передать или считать, команду или конфигурацию

R/W: Сообщаем дисплею, пишем мы данные или считываем


На схеме показывается 4-битный режим. Это когда мы используем 4 ноги DB4-DB7 вместо восьми и передаём два раза по 4 бита. Режим полезен там, где жалко отдавать лишние ноги у МК. Или для нашего расширителя портов на PCF8574.


Пытливый ум заметит, что сначала мы передаём старшие 4 бита, потом младшие. Также обратит внимание, что для передачи данных на ноге R/W должен быть 0, а для чтения 1.


Итак, как же выглядит передача данных в 8-битном режиме:


Для передачи команды дисплею, на ноге RS мы выставляем 0. Если надо передать символ, выставляем 1;

Если мы передаем команду или данные, то выставляем 0 на ноге R/W;

На ногах DB0-DB7, мы выставляем значения побитово того, что хотим передать;

Выдаём строб (импульс) на ноге E;

Документация рекомендует после строба считывать готовность дисплея к приёму следующей команды.


Как же выглядит передача данных в 4-битном режиме:


Для передачи команды дисплею, на ноге RS мы выставляем 0. Если надо передать символ, выставляем 1;

Если мы передаем команду или данные, то выставляем 0 на ноге R/W;

На ногах D4-D7 дисплея, мы выставляем значения старших 4-х бит, что хотим передать;

Выдаём строб (импульс) на ноге E;

На ногах D4-D7 дисплея, мы выставляем значения младших 4-х бит, что хотим передать;

Выдаём строб (импульс) на ноге E;

Документация рекомендует после двух стробов считывать готовность дисплея к приёму следующей команды.


Я тут накидал диаграмку, как передаются данные в 4-х битном режиме. Передаём два байта 0xA6 и 0xE9.

Обратите внимание, нельзя вот просто так взять и щёлкнуть стробом. Нужно помнить, что ширина строба и пауза между ними должны соответствовать паспортным данным. Идём в даташит и ищем что-то похожее на delay, timeout, execution time и т.д. Обязательно даются такие данные. Находим табличку “Table 6: Instructions” и видим, что на исполнение команды требуется от 37мкс до 41мкс. На возврат курсора в начало экрана требуется 1.52мс. Также при хаотичном листании документа в поисках информации, какая же должна быть пауза, находим в диаграмме “Figure 24: 4-Bit Interface” это:


When BF is not checked, the waiting time between instructions is longer than the execution instuction time. (See Table 6.)

Т.е. если мы не проверяем флаг занятости дисплея (почему объясню позже), то пауза должна быть больше, чем время исполнения инструкции. Т.о. я указал на диаграмме ширину строба 50мкс, интервал между парными стробами тоже в 50мкс, а интервал между данными 60мкс, для гарантии (китайские микрухи такие китайские).


Сами символы хранятся в таблицах, которые бывают Японскими или Кириллическими. На Али кириллицу хрен купишь, поэтому мы можем только загрузить в дисплей 8 собственных символов. Полностью это алфавит не покроет, но хоть что-то.


Как с ними работать, будем смотреть позже. Сейчас нас волнует подключение и протокол.

Подключение дисплея к шине I2C


Но нам вот жалко отдавать 7 ног МК (в 4-битном режиме) на дисплей. И кто-то взял и придумал копеешный модуль, который цепляет дисплей к I2C и сохраняет старый протокол.


Основан он на расширителе портов PCF8574. Вещь простая до безобразия. У него есть 8 ног, на которых мы можем выставлять 0 или 1. По I2C мы тупо шлём один байт на него, где каждый бит соответствует ноге. Либо тупо считываем такой же байт с текущим состоянием этих самых ножек.


Так вот модуль подключен по аналогичной схеме (я реализовывал это у себя на плате года два назад):

Пытливый ум, глядя на эту схему, задастся вопросом: А как же строб выдавать? Да ещё тайминги соблюдать. Да и вообще, как дрыгать ножками RS да R/W, чтоб не мешать данным и не сводить с ума дисплей? А вот тут и начинается самое интересное.


Ход мыслей такой. Давайте сначала заглянем в документацию PCF8574 и поищем там диаграмму по обмену данными. Находим прекрасную картинку:

Внимательно смотрим и видим, что состояние на ногах меняется сразу по окончании приёма байта от МК. Т.е. нам нужно передать данные и выставить ногу P2 в высокий уровень чтобы включить строб. Потом передать данные и выставить P2 уже в ноль, т.е. строб мы выключаем. А для этого нам надо разобраться, что такое шина I2C и с чем её едят.


Шина I2C


Откровенно говоря, не люблю я её. Использую только там, где нет альтернативы. Скорость небольшая, ёмкость линии ограничена 400пФ, в результате длина линии очень маленькая. К тому же сама суть протокола имеет существенный недостаток, об этом позже. Для каждого готового устройства приходится вручную подбирать номиналы подтягивающих резисторов. В этом плане SPI гораздо удобнее и круче, хоть и требует минимум 3-х ног. Ладно, к сути.


I2C - это асимметричная последовательная шина, использует две двунаправленные линии. Т.е. данные передаются последовательно в одном направлении. Обе линии подтянуты к питанию. Шина типа “Ведущий-Ведомый”. Теоретически возможно ситуация, когда хоть все устройства могут быть как ведущим, так и ведомым. На практике реализовать это почти невозможно.


Для понимания работы, надо сначала запомнить правила:


- Данные на линии SDA могут меняться только при низком уровне на линии SCL

- Пока на линии SCL высокий уровень, на линии SDA данные не меняются

- Утрируя, есть три состояния: СТАРТ, СТОП и передача данных.

- Формировать сигналы СТАРТ и СТОП может только ведущий, даже в случае приёма им данных от ведомого

- Адрес ведомого устройства состоит из 7-ми бит.


Сигнал СТАРТ - это перевод линии SDA в низкий уровень при высоком уровне линии SCL.


Сигнал СТОП - перевод линии SDA в высокий уровень также при высоком уровне SCL.


Т.о. для начала передачи данных ведомогу, ведущий формирует сигнал СТАРТ. Все ведомые устройства на линии начинают слушать. Затем ведущий выстреливает адрес ведомого, с которым он хочет поговорить и сажает SDA на ноль. Адрес этот, как видно по картинке выше, занимает старшие 7 бит, а последний бит задаёт читаем мы данные или пересылаем. Если устройство на линии есть, оно удержит линию SDA в низком уровне, это значит, что оно готово общаться. Тоже самое и по окончании приёма данных. По окончании передачи ведущий формирует сигнал СТОП.


Вот тут и кроется главная проблема шины I2C. После передачи данных, если ведомый занят, он может продолжать удерживать линию SDA. Ведомый также может удерживать и SCL, если он не успевает обрабатывать данные, т.е. ведомый может снижать скорость передачи данных. По стандарту, устройства должны управлять линиями по схеме Open Drain. И даже если какое-то устройство монопольно займёт линию, другое сможет её сбросить. Теоретически. На практике же, если, например, ведомый подвис и держит линию, а мы поднимаем её на ведущем, оживить ведомого порой можно только reset’ом. Там вообще такие бывают дичайшие комбинации, что однажды даже пришлось прокидывать отдельную линию RESET для ведомых устройств и периодически их дергать.


Итак. Более менее и в общих чертах мы разобрались с I2C. На wiki есть неплохая статья, да и вообще погуглите, шина непростая, я дал лишь общую информацию для понимания вопроса.

Приступаем к написанию библиотеки


Вот и настал момент, когда мы почти готовы написать первые строки кода. Давайте сначала посмотрим, как устроены другие библиотеки. Мы же ленивые и надеемся обойтись малой кровью.


Откроем классическую Arduino LiquidCrystal_I2C. Просто бегло пройдём по ней глазками. Не знаю, как у вас, у меня сразу глаз цепляется за несколько вещей:


- Используются аппаратные задержки

- Куча однотипных функций

- Нет никаких оптимизаций по экономии потребления памяти

- Нет контроля ошибок

- Нет вменяемых комментариев


Если мы просто пороемся на GitHub в поисках библиотек для STM32, почти все они будут на основе этой же LiquidCrystal_I2C. С теми же недостатками. Я не буду глубоко туда влезать, я просто сделаю всё по-своему.


Итак, составим требования к нашей библиотеке:


- Никаких аппаратных задержек

- Использовать DMA для передачи данных

- Минимум функций, максимально выносить всё в #define

- Максимально экономим память

- Каждое обращение к дисплею должно контролироваться


Создаём проект


Для начала надо создать проект. Я уже написал инструкцию, как правильно настроить STM32CubeMX у себя в блоге, не буду повторяться тут. Полностью проект с уроком доступен в моем репо на GitHUB.


Отмечу только, что урок написан для отладочной платы на STM32F303VC. У меня сейчас нет под рукой STM32F103C8, так что всё проверял на STM32F3DISCOVERY. Но адаптировать под любую другую плату можно без особых проблем.


Дальше, конечно, мы можете взять готовую библиотеку, я её выложил на GitHub. Я вкратце напишу, что я делал.


Создадим два файла:

Inc/lcd_hd44780_i2c.h
Src/lcd_hd44780_i2c.c

Для начала написания кода, нам бы вообще понять, что делать в реальности. Для этого нам надо сделать две вещи: включить дисплей и послать на него пару символов. Открываем даташит дисплея, ищем описание процедуры инициализации.

Отлично! Всё написано по шагам, с таймингами и даже биты указаны! Но мы любопытные и хотим сразу знать, что же битики значат, чтобы сразу заполнить заголовочный файл #define'ами. Вспоминаем про "Table 6: Instructions". Там прям идеально, с комментариями, расписаны все биты команд.


Открываем наш заголовочный файл и предварительно накидываем:

Это та самая нудная часть работы, о которой я говорил. Внимательно смотрим в табличку, двоичный код переводим в HEX. Поясню на примере:


Инструкция Display on/off control требует всегда выставленного бита DB3. Открываем калькулятор, вводим двоичное 1000 и получаем 0x08 HEX.


В самой инструкции есть три команды:


- Display on/off

- Cursor on/off

- Blinking of cursor position character


Калькулятором высчитываем их HEX и будем их потом суммировать с LCD_BIT_DISPLAY_CONTROL.


Биты RS, RW, E и Backlight относятся к PCF8574, так что не забываем прописать и их.


Позже аналогичным способом напишем и остальные #define.


Для тех, кто не знаком с таким стилем, не стоит пугаться, что различные названия с одним значением. На самом деле, вы как бы пишете ссылки для себя, которые удобно читать. Компилятор же подставит вместо этих названий их значения. Причем только те, которые вы реально используете в коде.


Но теперь мы задумались и пришли к выводу, что нам нужно где-то хранить те параметры, что мы уже отправляли на дисплей. Также надо хранить данные шины, параметры дисплея и прочее. Для этого мы создадим структуру:

Обратите внимание. В этом struct мы храним не саму структуру для I2C, а лишь указатель. Т.о. мы не дублируем данные и всегда под рукой их состояние.


Судя по алгоритму инициализации, первые этапы уникальны и можно реализовать их тупо отправляя данные через базовые функции HAL. Их мы реализуем в функции lcdInit().


Пора бы уже отправить какие-то данные на дисплей. Хорошим тоном будет сделать локальную низкоуровневую функцию, которая будет подготавливать данные для отправки и саму отправку. А мы лишь будем в неё закидывать состояние управляющих битов и байт данных.


Посмотрите реализацию в уже готовой библиотеке. В чём фишка. Для того, чтобы выдавать строб, мы дважды шлём первую партию 4-х бит. Третьим байтом шлём младшие 4-бит и закрываем строб.


И вот, что получается на деле:

При таком раскладе и скорости шины I2C в 100кбит, ширина строба ~180мкс, пауза между стробами ~90мкс, и пауза между парными стробами ~530мкс. По идее, и я так думал предварительно, можно не удлинять строб на два байта, обойтись одним. Но на деле оказалось, что 90мкс мало для ширины строба, но достаточно для паузы между стробами. Похоже, что кварц в дисплее работает на более низкой частоте, чем положено по даташиту. Как говорил - Китай такой Китай =( А может мой дисплей дурит.


Также можно сократить длинную паузу раза в два, для этого есть два способа:


- Использовать прерывания и циклом фигачить побайтово прямо в регистр. Но это постоянные прерывания с обработчиками, на больших данных будут блокировки. А я этого ой как не люблю. Я предпочитаю отправить данные через DMA и забыть о них. И начать заниматься другими делами, пусть МК сам разруливает.


- Либо создать большущий буфер на отправку, для 20 символьного дисплея это будет порядка 120 байт. Надо будет просто подготовить данные в буфере и отправить одним выстрелом в DMA. Но я решил экономить память.


Но нас интересует вопрос, я так ругал Ардуиновскую библиотеку, а есть ли выигрыш? А вот смотрите, что показывает LiquidCrystal_I2C:

Комментарии излишни. Но ведь я учу вас критическому мышлению, не так ли? Что если оптимизировать код библиотеки Ардуино? Да! И я уверен, получится значительно улучшить параметры передачи. Делайте, думаю стотыщпятьсот людей вам скажут спасибо. Ведь я к чему это всё говорю. К тому, что в этом и есть беда Ардуино - такой вот код, где никто не думает об оптимизациях. Причём ведь делает вид, что всё согласно даташиту. Например, зачем нужны задержки между передачами в 50мкс, если в реальности между стробами 500мкс??


У пытливого ума опять же возникает вопрос, а есть выигрыш на большой передаче? А вот смотрите, сверху STM32, а снизу LiquidCrystal_I2C, данные одинаковые, процедура инициализации тоже:

Итог: STM32 83мс, LiquidCrystal_I2C 122мс. Повторю, если использовать прерывания или готовый буфер вместо чистого DMA, можно получить ещё больший выигрыш, думаю вполне реально сократить это время до 60мс. Но надо ли? С таким дисплеем и его откликом это уже за гранью добра и зла =)


Что ещё интересного в библиотеке


Я написал одну единственную функцию, которая занимается командами. Это функция lcdCommand().


Она занимается как установкой параметров, так и снятием. В качестве входных параметров, у неё команда и флаг - снять или выставить команду. Оба параметра - это нумерованные списки LCDCommands и LCDParamsActions.


Обратите внимание, никаких if/else. Всё сделано на Switch/Case. Несмотря на то, что их аж три штуки и приходится как минимум дважды проверять команду, работает это невероятно быстро. И причина тому - Бинарное дерево, в которое компилятор транслирует наш код. По сути, там всего два узла, так что поиск происходит за несколько тактов.


Конечно, вы можете использовать и запись типа if (command == LCD_DISPLAY), это также будет откомпилировано в бинарное дерево, но такой код читается хуже.


В результате мы получили возможность через #define определить прототипы функций, с коротким написанием и удобным чтением:

А вообще, совет. Там, где у вас чётко обозначенные варианты, использовать switch/case, там, где необходимо сравнивать величины, использовать if/else. И не стесняйтесь нумерованных списков enum - они занимают очень мало памяти. Компилятор сам подбирает тип, но всё также, как с обычными целочисленными переменными, чем больше список, тем больше разрядность.


Почему не проверяем готовность дисплея, как в даташите


А потому, мои дорогие, что в случае с I2C это лишено смысла. Посмотрите на реальную передачу. На один только запрос уходит минимум 1 байт плюс ещё байт на адрес. Итого 180мкс. Для проверки готовности мы сначала должны выставить R/W в 1, потом еще щелкать стробами и внутри 1-го строба проверять бит BF на ноге DB7. Посчитали? Это при том, что по документации занят дисплей от 37мкс до 1,52мс. Проще просто использовать трюк с I2C.


Что можно придумать с русскими символами


У нас есть только возможность загрузить своих 8 символов. Я с этим сталкивался и, скажу, это нелегкий выбор =) Для этого в дисплее есть доступный EPROM на 8 ячеек. Каждая в каждую ячейку можно записать символ из 8 строк по 5 точек в каждой. Соответственно, это массив из 8 байт, где младшие 5 бит и есть наши точки. На самом деле, последняя строка - это курсор, так что, если уж соответсвовать стандартам, на символ можно использовать 5х7 точек. Вот схема из даташита (Example of Correspondence between EPROM Address Data and Character Pattern (5 × 8 Dots)):

Например, символ Д в HEX будет такой:

uint8_t symD[8] = { 0x07, 0x09, 0x09, 0x09, 0x09, 0x1F, 0x11 }; // Д

Соответственно загружаем его в CGRAM функцией:

lcdLoadCustomChar(0, &symD);

и выводим функцией:

lcdPrintChar(0);



Ну а как просто вывести текст?


Это элементарно. Нужно просто выставить курсор и отправить код символа в дисплей. Он сдвинет курсор на следующую позицию автоматически, а мы следом шлём следующий символ. И т.д.


Код символа в C/С++ определяется, если взять его в одиночные кавычки, например, 'B'. Либо просто перебором берём из строки &data[i]. Реализацию можете посмотреть в исходнике.


В готовом виде это:

Обратите внимание. Мы отправляем в функцию не строку, а указатель на массив uint8_t. Т.е. мы, во-первых, создаём строку в памяти, во-вторых, преобразуем строку в unsigned int, в-третьих, отправляем указатель на неё. Это, конечно, вариант для примера. В боевых устройствах использовать такую запись плохой тон. Т.к. во-первых, мы используем динамическое выделение памяти, что само по себе в условиях крайне её ограниченности не айс. Лучше стараться заранее выделить память под некоторые переменные. А во-вторых, приходится вручную пересчитывать размер строки. Так что хорошим тоном будет примерно так:

Немного о комментариях в коде


Призываю не слушать тех, кто заявляет, что очевидный код не нуждается в комментировании. В этом есть здравое зерно, правда есть несколько суровых НО.


Конечно, глупо комментировать каждую строчку. Но хорошим тоном, по моему опыту, являются:


Перед каждой функцией писать стандартный заголовок с тегами brief и note. В них стоит описать что это за функция и как она работает. Там же дать описания переменных и что она возвращает. Во многих современных редакторах есть плагин типа Docblockr. Просто перед функцией пишете /** и плагин сам создаёт отформатированный заголовок, вам нужно только дописать ручками несколько строк.

Давать отсылки на переменные из других файлов и документацию

Если алгоритмов для реализации несколько, напишите, почему выбрали конкретный. Сильно упрости общение с другими в будущем.

Добавляйте комменты для выделения этапов и всяких неочевидных вещей

Я сейчас дописываю документацию к библиотеке, читать её можно будет тут.


Напоследок


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


Я постарался заострить внимание на ключевых моментах. Параллельно показать какие-то банальные фишки, которые многие боятся использовать. Например, указатели.


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

Показать полностью 15
79

Здравствуй, здравствуй, мастер бородастый.

Давно вас читаю и вот решил чуточку из рабочих будней добавить. Принесли как-то раз планшкет в ремонт. Вскрыв сие устройство в нем было обнаружено нечто. Нечто усатолапообразное. Сказать что испугался, значит ничего не сказать. Обосрался! Проведя кишечно-лёгочную реанимацию, признаков жизни обнаружено не было.

После чего погибший был доставлен под микроскоп.

А случилось это все по причине утерянного стилуса. Видимо в один из летних деньков оставили планшкет подышать свежим воздухом, а клопу-вонючке, не пришло в голову ничего лучше, кроме как покончить с жизнью в отверстии данного гаджета. Пусть Гэлакситаб ему будет пухом!
А планшет Я починил. Фоткал я. Тег мое.

Показать полностью 3
Отличная работа, все прочитано!