🚥 TM1650
Нещодавно мені стало цікаво запустити 7-сегментний LED дисплей від ультра-дешевої мікросхеми TM1650. На момент написання цієї статті (кінець 2024, 1$ = 42₴) вона коштує 6 гривень в наших магазинах і ще в 1.5-2 рази дешевше на Алі. Тобто можна сказати майже нічого, якщо відштовхуватися від того, що вона вміє. А вміє вона в мультиплексинг: можна збільшити собі кількість входів або виходів. Тобто можна наприклад драйвити і той самий 7-сегментний дисплей (насправді 8 х 4 знаки) або зчитувати показники з 28 кнопок. Керувати TM1650 можна з I2C інтерфейсу або ж просто з пінів, імітуючи шину даних і шину тактової генерації.
Протокол комунікації
Шлях, який я обрав був найпростіший — I2C. Але як виявилось, підтримки I2C в TM1650 насправді немає. Принаймні даташит нічого не говорить про цей інтерфейс. Але якщо поглянути в даташит на протокол комунікації, то неозброєним оком видно деякі атрибути I2C: адреса, ACK (acknowledgement) біт підтвердження, START/STOP сигнали.
Тобто хоч виробник (китайська Titan Microelectronics) цього і не документує, але TM1650 все-таки можна драйвити від I2C інтерфейсу Вашого мікроконтролера, але з нюансами. Нюанс полягає в тому, що TM1650 не має адреси як такої. Натомість кожна операція з цією мікросхемою має свою окрему адресу. По факту це означає — скільки можливих операцій стільки і адрес, з чого можна зробити висновок, що краще таку мікросхему підключати або до окремо виділеного I2C або взагалі емулювати комунікацію вільними GPIO. Як уже писав вище, я обрав I2C. Ось перелік операцій (і їх адрес), які можна виконати над LED дисплеєм:
0x68
- задати значення в 1-ий символ дисплею0x6A
- задати значення в 2-ий символ дисплею0x6C
- задати значення в 3-ий символ дисплею0x6E
- задати значення в 4-ий символ дисплею0x48
- управління дисплеєм: увімкн/вимкн дисплей, змінити яскравість, увімкн/вимкн підтримку 8-го сегменту — десяткової коми
🔢 Виведення символів
Задати символ на дисплеї дуже просто: на потрібну адресу потрібно відправити значення. Значення формується на основі того, які сегменти потрібно увімкнути.
Наприклад, щоб на першому символі вивести цифру 7, потрібно на адресу 0x68
відправити значення 0b00000111
. За цифру 7 відповідають сегменти a, b, c на малюнку вище. Тобто крайні праві (LSB) 3 біти потрібно увімкнути, що і дає нам 0b00000111
.
Інший приклад: виведемо нуль. Згідно малюнку вище нам треба увімкнути біти наступних сегментів: a, b, c, d, e, f. Отримуємо 0b00111111
(або ж 0x3F
). Якщо ми хочемо вивести нуль, але цього разу з десятковою комою, то треба ще додатково увімкнути 8-ий біт, отримуємо 0b10111111
(тобто 0xBF
). Звісно таблиця з можливими символами вище не повна і можна або придумати свої символи, або піддивитися в інтернеті, що ще можна вивести на 7-ми сегментах. Ну наприклад: r
, a
, S
, L
, H
, h
і т.д.
🎮 Управління
Управління дисплеєм здійснюється за адресою 0x48
. Принцип той самий як і з виведенням символів: потрібно відправити 1 байт даних на цю адресу.
Які біти за що відповідають можна дізнатися з цієї таблиці:
Тобто, якщо потрібно виставити 4-ий рівень яскравості і при цьому щоб дисплей залишався увімкненим потрібно відправити 0b01000001
на адресу 0x48
.
Для наглядності давайте скористаємось логічним аналізатором і подивимось як виглядає виведення числа 1 (0b00000110
- сегменти b і c) на перший символ (0x68
) і виставлення 4-го рівня яскравості (0b01000001
).
Отже, як видно вище, логічний аналізатор підтверджує все, що було раніше описано в цій статті.
📝 Тестування
В якості мікроконтролера я обрав також ультрабюджетний STM32G030 (64MHz, 8KB RAM, 32KB Flash) від WeAct Studio з Алі. Вартість від 5 штук — 55 грн. Вартість голого камінця 17 гривень (найдешевше, що знайшов).
Код згенерований за допомогою STM32CubeIDE, а збираю в VS Code за допомогою PlatformIO розширення, яке саме підтягне HAL залежності для STM32G030 МК. Також PlatformIO вміє завантажувати збілджену програму на МК через різні інтерфейси, просто оберіть потрібний інтерфейс в файлі platformio.ini
. У мене виникла проблема, з тим що G0 серія відносно нова і PlatformIO ще досі підтягує стару версію stm32flash утиліти, яка завантажує програму на МК. І вона не вміє працювати з G0 серією. В 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 символи дисплею, тому що на руках був лише 3-ох символьний 8-ми сегментний LED дисплей. Неприємне миготіння показане нижче видно тільки на камеру, в реальності все набагато краще.
Практично обов'язково потрібно додати конденсатор до пінів живлення TM1650 інакше він весь час буде зависати. 100 мкФ можливо буде достатньо на середній яскравості. Оскільки TM1650 це мультиплексор, вона дуже швидко перемикає світлодіоди, тому насправді одночасно завжди горить тільки один символ. А за рахунок швидкого перемикання здається як ніби — всі одночасно. Тому там, де є часте перемикання споживача струму (світлодіоди), там будуть проблеми з живленням, із-за чого конденсатор це не рекомендація, а практична необхідність.
🐙 Проєкт на GitHub
Проєкт розміщений на GitHub. Для розробки використовувався VS Code + PlatformIO:
🔚 Висновки
TM1650 це дуже дешева мікросхема, яку можна використовувати в недорогих пристроях. Вона має свої недоліки: нестандартне I2C, вимагає кілька адрес. Але якщо подивитись на конкурентів, наприклад HT16K33, то вони дорожчі в 5 і більше разів. А деякі — в десятки разів.
Дата публікації
2024.10.04