Pull to refresh

STM32 и LCD через I2C

Reading time4 min
Views132K

Для использования в дальнейшем понадобилось связать, используя I2C микроконтроллер STM32 с экраном 2004. Не найдя аналогичного решения в сети, публикую здесь. Данный рецепт подойдёт также для экранов 1602. Далее под катом. (Осторожно, картинки).

Игрушечная касса, купленная сыну, оказалось с дефектом, и работала через раз. Появилась идея переделать её внутренности, и момент выбора микроконтроллера совпал с публикацией статьи RaJa про STM32 [1]. Немного прикинув и сравнив цены: STM32+LCD2004+I2C = ArduinoMega (причина была в том, что нужно было реализовать клавиатуру, динамик, устройство ввода штрих-кода и экран, поэтому каждый вывод микроконтроллера на счету) я выбрал первый набор.

Были сделаны покупки, и наступило время ожидания. Для прошивки купил ещё USB-USART переходник.
Что и где покупалось.
  1. STM32F103C8T6
  2. 2004 LCD HD44780. Оказался без кириллицы. Обращайте внимание на данную особенность при поиске, если нужен русский язык на экране.
  3. IIC/I2C/TWI/SP​​I Serial Interface Board Module Port For Arduino 1602LCD Display По описанию совместим с 2004. Но думаю подойдёт любой аналогичный.
  4. USB to UART TTL CP2012 для прошивки и отладки. Можно воспользоваться и другими поддерживаемыми способами прошивки и отладки, но этот вариант самый дешевый.


Средства для программирования, прошивки и отладки, используемые мною:
  1. EmBlocks.
  2. Прошивальщик с оригинального сайта: STM32 and STM8 Flash loader demonstrator.
  3. Терминал для чтения сигналов от MK через USB2UART: Terminal v1.91b. Но подойдёт и Putty (Connection->Serial).

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

Первым опишу подключение. Странно, описывая использование STM32 мало где рисуют схемы, в основном код, сам догадайся, что и как подключить.
Подключение изображу на фотографии (по клику — крупнее).

Данное подключение актуально для STM32F103C8. Для других плат МК проверьте пины подключения I2C1 по даташиту.
USART переходник в USB. Тут понятно. Далее — USART подключаем к STM32 к выведенному около разъема miniUSB USART1. TX к RX и соответственно RX к TX. У меня на USART есть вывод 3v3, я от него и запитал МК. Землю я подключил отдельно, для удобного её отключения во время переключения режимов прошивки и работы. К экрану я припаял I2C (так же на ebay есть экраны с припаянными I2C). Питание для I2C и экрана берётся от 3v3 МК или 5В от USART. Ниже написал про настройку контраста при различном напряжении питании. Далее: SCL от I2C подключается к PB6, SDA от I2C к PB7. Притягивать SCL и SDA к питанию при использовании одного данного устройства нет необходимости.

Первыми граблями был USART. Его я использовал для отладки, в приведённом здесь коде строки работы с ним закомментированы. Но с ним проблему так и не решил. Такое впечатление, что нет синхронизации между компьютером и микроконтроллером до посылки первого символа. Причем если использовать код из примера [4] — то МК прекрасно дублирует получаемый текст, а сам писать не может. Я добился наиболее приемлемого для отладки вывода строк, добавив Delay(500) после каждого символа.

Потом попытался реализовать работу с I2C. Взял код из примера [3], обратил внимание на комментарии про подвисание МК, проанализировав исходники, увидел что как и автору комментариев, мне необходим сдвиг адреса устройства влево:

//http://microtechnics.ru/stm32-ispolzovanie-i2c/#comment-8109
I2C_Send7bitAddress(I2Cx, slaveAddress<<1, transmissionDirection);

Вставил код и попробовал запустить. Программа повисала на моменте ожидания освобождения шины:

while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

Тут грабли в адресе I2C устройства. Судя из описания продавца, у меня был адрес 0x20. Вот тут я и потерял 15 минут впустую, но вчитавшись в описание разных моделей I2C переходников, ссылку [6] на которое привёл в своей статье [5] romanvl, обратил внимание на последнюю модель и попробовал поменять адрес на 0x27. Всё заработало. Вывод такой: если у Вас на переходнике запаяны A0 A1 A2 — адрес 0x20, не запаяны — 0x27.
Сравните:

Далее — экран. Оказалось, что он прекрасно работает и от 3.3 Вольт, как и переходник I2C (в даташите микросхемы переходника — от 2.5 до 6 В). Но сначала я его проверял от 5В. И контраст был выкручен на максимум. В итоге в результате запуска программы экран был полностью заполнен. Я расстроился и продолжил ковырять код. Но спустя полчаса проснулся и подбежал виновник разработки, я ему показал экран и случайно увидел под углом сбоку, что там что-то написано. Причиной этому является неправильная регулировка контраста. (Извините, если описал тут очевидные вещи, может найдутся такие же, кто этого не знал.)
Ничего не видно
То же самое, но под углом

При 5В питания контраст нужно немного уменьшить. А при 3.3В поставить на максимум, на настройке от 5В ничего не видно. Результат представлен на первой картинке в посте. Мой оказался без русского языка, я это увидел, пролистав символы. Попробовал нарисовать кляксу, не зная, что максимум можно определить 8 своих символов, написал для кляксы 12. Подобрал похожие из китайских, вроде получилось.

Код представлен на гихабе, так как для достижения результата переписал библиотеку от Ардуины: STM32_LCD_I2C.

Использованные материалы:
  1. Причина выбора микроконтроллера: STM32 vs Arduino.
  2. Отсюда взял реализацию Delay: STM32 I2C EEPROM 24СXX.
  3. Cтатья про I2C STM32. Использование I2C.microtechnics.ru/stm32-ispolzovanie-i2c. Тут же комментарий про сдвиг, без которого я бы наверное так же поймал грабли что и обсуждающие.
  4. Пример работы с USART STM32. USART. Часть 4 — Финал.
  5. Уменьшаем количество проводов в Arduino — I2C LCD экран и RTC часы по двум проводам.
  6. LCD Displays (Blue and YELLOW) with I2C/TWI Interface.
  7. Для понимания логики работы STM32 с внешними устройствами Руководство к быстрому старту по работе с периферией STM32F10x.

Спасибо за внимание.
Tags:
Hubs:
+25
Comments22

Articles