STM32 – Частина 3: Підключення та управління дисплеєм TM1650

28.05.2025 2 хвилин Автор: animator404

STM32 та TM1650 — надійне поєднання для керування 7-сегментними LED-дисплеями в проєктах з мікроконтролерами. У цій частині серії ми покажемо, як підключити TM1650 до STM32, налаштувати обмін даними через I2C-подібний інтерфейс та виводити потрібну інформацію на дисплей.

TM1650​

У певний момент з’явилася ідея запустити 7-сегментний LED-дисплей за допомогою наддешевої мікросхеми TM1650. Станом на кінець 2024 року, коли курс долара складав приблизно 42 гривні за одиницю, середня вартість TM1650 у вітчизняних магазинах становила близько 6 гривень, а на міжнародних майданчиках — у 1.5–2 рази дешевше.

З огляду на функціональні можливості, така ціна є майже символічною. TM1650 підтримує мультиплексування, що дозволяє збільшити кількість використовуваних входів або виходів у схемі. Це дає змогу, наприклад, керувати стандартним 7-сегментним дисплеєм (фактично підтримується 4 знаки по 8 сегментів), або зчитувати дані одночасно з 28 кнопок.

Керування мікросхемою здійснюється або через інтерфейс I2C, або шляхом прямого формування сигналів із GPIO-виводів — шляхом імітації шини даних і тактової шини.

 Протокол керування

Для реалізації проєкту було обрано найпростіший варіант — використання інтерфейсу I2C. Однак згодом з’ясувалося, що повноцінної підтримки I2C у TM1650 фактично не передбачено. Принаймні, у даташиті відсутні прямі згадки про цей інтерфейс.

Разом з тим, аналіз протоколу комунікації, наведений у технічній документації, демонструє характерні риси, властиві саме I2C. У структурі переданих даних чітко простежуються такі елементи як адресація, біти підтвердження (ACK), а також сигнали початку та завершення передачі — START і STOP.

Хоча виробник мікросхеми — китайська компанія Titan Microelectronics — прямо не декларує підтримку інтерфейсу I2C, на практиці TM1650 все ж може бути керована за допомогою I2C-периферії мікроконтролера. Водночас є важливий нюанс: мікросхема не має єдиної фіксованої адреси, як це характерно для класичних I2C-пристроїв.

Натомість для кожної окремої операції передбачено свою власну адресу. Тобто, кількість допустимих операцій безпосередньо визначає кількість адрес. Це означає, що для стабільної роботи з TM1650 рекомендується використовувати окрему I2C-шину або повністю емулювати обмін даними через вільні GPIO-виводи мікроконтролера.

Нижче наведено список адрес, які відповідають конкретним операціям, що виконуються з LED-дисплеєм:

  • 0x68 – задати значення в 1-ий символ дисплею.

  • 0x6A – задати значення в 2-ий символ дисплею.

  • 0x6C – задати значення в 3-ий символ дисплею.

  • 0x6E – задати значення в 4-ий символ дисплею.

  • 0x48 – керування дисплеєм: увімкн/вимкн дисплей, змінити яскравість, увімкн/вимкн підтримку 8-го сегменту — десяткової коми.

​Виведення символів

Задати символ на дисплеї дуже просто: на потрібну адресу потрібно відправити значення. Значення формується на основі того, які сегменти потрібно увімкнути.

Для того, щоб на першій позиції 7-сегментного дисплея з’явилася цифра 7, необхідно надіслати байт 0b00000111 (тобто 0x07) на адресу 0x68. Це значення активує сегменти a, b та c, які відповідають за форму цифри 7. Активними мають бути три найменш значущі біти (LSB), що й формує відповідний шаблон.

Інший приклад — відображення цифри 0. Для цього необхідно активувати сегменти a, b, c, d, e та f, що формує двійковий шаблон 0b00111111, або в шістнадцятковому представленні — 0x3F.

Якщо потрібно вивести нуль із десятковою крапкою, то активується ще й 8-й біт (DP — decimal point). У результаті формується шаблон 0b10111111, що відповідає значенню 0xBF.

Наведена таблиця зі значеннями для символів є неповною — за потреби можна створити власні шаблони для нових символів або скористатися прикладами з мережі. Наприклад, можливо вивести символи r, a, S, L, H, h тощо — з урахуванням обмежень 7-сегментної матриці.

Керування​

Керування дисплеєм здійснюється за адресою 0x48. Принцип той самий як і з виведенням символів: потрібно відправити 1 байт даних на цю адресу. Які біти за що відповідають можна дізнатися з цієї таблиці:

Для встановлення 4-го рівня яскравості при активному дисплеї, необхідно надіслати байт 0b01000001 (тобто 0x41) на адресу 0x48. Це значення активує дисплей і водночас задає бажаний рівень яскравості.

Для кращого розуміння процесу корисно проаналізувати реальний обмін даними за допомогою логічного аналізатора. На прикладі буде розглянуто, як виглядає передача байтів при виведенні цифри 1 (яку формують сегменти b і c, тобто 0b00000110 або 0x06) на першу позицію дисплея (адреса 0x68), а також — як виглядає передача налаштування яскравості (0x41) на адресу 0x48. Аналіз сигналів дозволяє детально побачити послідовність START, адреса, дані, ACK та STOP, що формують повноцінну транзакцію в умовно-I2C сумісному протоколі TM1650.

Отже, як видно вище, логічний аналізатор підтверджує все, що було раніше описано в цій статті.

Тестування​

В якості мікроконтролера використано один із найекономічніших варіантів — STM32G030 (тактова частота 64 МГц, 8 КБ оперативної пам’яті, 32 КБ флеш-пам’яті) від WeAct Studio, придбаний через AliExpress. При замовленні від п’яти штук, вартість становить приблизно 55 гривень за модуль, а вартість самого мікроконтролера (без плати) — близько 17 гривень, що робить його одним із найдоступніших у своєму класі.

Код було згенеровано у STM32CubeIDE, а збирання виконано в Visual Studio Code за допомогою розширення PlatformIO, яке автоматично підтягує потрібні залежності HAL для STM32G030. Окрім того, PlatformIO підтримує завантаження зібраного прошивальника на мікроконтролер через різні інтерфейси — тип інтерфейсу задається в конфігураційному файлі platformio.ini.

Під час роботи з цією серією виникла проблема, пов’язана з тим, що STM32G0 є відносно новою лінійкою, і PlatformIO досі використовує застарілу версію утиліти stm32flash, яка не підтримує цю серію мікроконтролерів. У файлі README.md до проєкту зазначено, де знайти актуальну версію утиліти stm32flash і як правильно її встановити вручну. Ймовірно, у системах на базі Linux ця проблема не проявляється.

int main(void)
{
  HAL_Init();           //Reset of all peripherals, Initializes the Flash interface and the Systick.
  SystemClock_Config(); //Configure the system clock
  MX_GPIO_Init();       //Initialize all configured peripherals
  MX_I2C2_Init();

  //Turn display on and set 4 (middle) brightness level
  uint8_t cfgDisplay = 0b00100001;
  HAL_I2C_Master_Transmit(&hi2c2, 0x24 << 1, &cfgDisplay, sizeof(cfgDisplay), HAL_MAX_DELAY);
  while (1)
  {
    //Set some random symbol #1
    uint8_t symbol = 0b01100011;
    HAL_I2C_Master_Transmit(&hi2c2, 0x34 << 1, &symbol, sizeof(symbol), HAL_MAX_DELAY);
    HAL_I2C_Master_Transmit(&hi2c2, 0x35 << 1, &symbol, sizeof(symbol), HAL_MAX_DELAY);
    HAL_I2C_Master_Transmit(&hi2c2, 0x36 << 1, &symbol, sizeof(symbol), HAL_MAX_DELAY);
    HAL_Delay(500);
    
    //Set some random symbol #2
    symbol = 0b11111111;
    HAL_I2C_Master_Transmit(&hi2c2, 0x34 << 1, &symbol, sizeof(symbol), HAL_MAX_DELAY);
    HAL_I2C_Master_Transmit(&hi2c2, 0x35 << 1, &symbol, sizeof(symbol), HAL_MAX_DELAY);
    HAL_I2C_Master_Transmit(&hi2c2, 0x36 << 1, &symbol, sizeof(symbol), HAL_MAX_DELAY);
    HAL_Delay(500);
  }
}

Згідно з прикладом коду, першим кроком надсилається конфігураційний байт на адресу 0x48 (що відповідає зсуву 0x24 << 1), який активує дисплей та встановлює 4-й рівень яскравості. Після цього, у циклі while по черзі виводяться різні символи на дисплей.

Один із символів активує всі 8 доступних сегментів одночасно, демонструючи повну заповненість розряду. У продемонстрованому прикладі задіяно лише 3 позиції дисплея, оскільки у тестовій конфігурації використовувався тризначний 8-сегментний LED-дисплей. Зафіксоване на відео неприємне миготіння помітне лише через камеру — у реальних умовах для людського ока індикація виглядає стабільною та чіткою.

У більшості випадків встановлення конденсатора на пін живлення TM1650 є критично необхідним, оскільки без нього мікросхема має схильність до нестабільної роботи або повного зависання. Для умов середнього рівня яскравості ємності 100 мкФ зазвичай достатньо.

Це пояснюється тим, що TM1650 працює за принципом мультиплексування: драйвер надзвичайно швидко перемикає активні сегменти, і фактично в кожен момент часу світиться лише один символ. Проте завдяки високій частоті циклів для людського ока створюється враження, ніби всі символи світяться одночасно.

Таке швидке та постійне перемикання навантаження (LED) створює значні імпульсні просідання напруги, особливо при низькоомних джерелах живлення. Унаслідок цього декуплювальний конденсатор перестає бути просто рекомендованим елементом — він стає необхідною умовою стабільної роботи всієї системи.

​Проєкт на GitHub

Проєкт розміщений на GitHub. Для розробки використовувався VS Code + PlatformIO:

Висновок

TM1650 — це надзвичайно доступний драйвер для LED-дисплеїв, що ідеально підходить для використання в економ-сегменті пристроїв, де ключовими вимогами є мінімальна вартість та простота реалізації.

Попри свою низьку ціну, мікросхема має певні особливості, які слід враховувати при розробці. Серед них — нестандартна реалізація I2C-подібного інтерфейсу та відсутність універсальної адресації, через що кожна операція має окрему адресу. Це створює деякі незручності при інтеграції в складніші системи або при спільному використанні однієї I2C-шини з іншими пристроями.

Втім, у контексті співвідношення функціональність/вартість, TM1650 виглядає дуже привабливо. Для порівняння, HT16K33 — один із популярних альтернативних драйверів — має вартість у 5 разів вищу, а деякі інші аналоги — в десятки разів дорожчі.

З урахуванням усіх факторів TM1650 може стати відмінним вибором для бюджетних проектів, особливо коли необхідна проста індикація та не планується використання складної логіки взаємодії по шині. За умови правильного підключення, стабільного живлення та обробки специфіки протоколу — мікросхема демонструє стабільну роботу та хорошу сумісність із сімейством STM32.

Посилання на першоджерело: https://solderkid-blog.netlify.app/stm32/neopixel

Підписатися
Сповістити про
0 Коментарі
Найстаріші
Найновіше Найбільше голосів
Знайшли помилку?
Якщо ви знайшли помилку, зробіть скріншот і надішліть його боту.