Програмна реалізація інтерфейсу управління TM1640 на ATmega
Мікросхема TM1640 фірми Titan Micro Electronics представляє собою драйвер управління 8-сегментними світлодіодними індикаторами в кількості до 16 штук (Рис.1). Зв'язок з цією мікросхемою здійснюється по двопровідній шині даних, схожій за протоколом на I2C, але не сумісній з нею.
Рис.1 Мікросхема TM1640
Призначення у виводів мікросхеми таке: SEG1-SEG8 - вибір сегментів індикатора (високий рівень на виводі запалює сегмент, низький - гасить), GRID1-16 - вибір індикатора (низький рівень на виводі вибирає індикатор, високий - скасовує вибір). VDD - живлення 5+-0,5В і VSS - земля. DIN і SCLK - відповідно лінія даних і лінія синхронізації. Ці виводи потрібно підключати до живлення через резистори 10 кОм (Рис.2).
Рис.2 Принцип підключення сегментних індикаторів до TM1640
Розглянемо протокол цієї двопровідної шини. Коли повідомлення не передаються, на обох проводах має бути високий рівень. Будь-яке повідомлення починається зі стану Start (при високому рівні на SCLK відбувається перехід на DIN з високого рівня на низький), а закінчується станом Stop (при високому рівні на SCLK відбувається перехід на DIN з низького рівня на високий). Кожен біт, що передається по лінії DIN, супроводжується імпульсом на тактовій лінії SCLK. На рис.3 показана структура відправки повідомлення - команди. Вони мають довжину 8 біт і передаються від молодшого біта до старшого. У повідомленнях не вказується адреса пристрою, до якого вони призначені. Тому по двом проводам можливо підключити до мікроконтролера один єдиний TM1640.
Рис.3 Структура передачі повідомлення-команди.
Мікросхема сприймає команди трьох типів:
1-й тип. Вказівка способу прийому даних. Можливий прийом даних з автоматичним інкрементом адреси індикатора (цей режим встановлено за замовчуванням, найбільш оптимальний), з фіксованим адресом, а також нормальний і тестовий режими.
2-й тип. Встановлення адреси індикатора, в який буде здійснюватися запис даних. У цьому ж повідомленні надсилаються дані на сегментні індикатори. Довжина такої команди становить не менше 16 біт і кратна 8 бітам (Рис.4).
Рис.4 Приклад відправки повідомлень в TM1640: Command1 - вибір способу передачі даних, Command2 - вибір адреси індикатора, з якого буде здійснюватися запис, data1-dataN - пакет даних на індикатори, Command3 - встановлення яскравості індикаторного дисплея.
3-й тип. Встановлення яскравості індикаторного дисплея. Мікросхема управляє індикаторами в динамічному режимі. Коєфіцієнт заповнення ШІМ може бути вибраний від 1/16 до 14/16 за таблицею з даташита. Також індикатори можна просто погасити.
Розглянемо просту програмну реалізацію інтерфейсу зв'язку з TM1640, яка буде підходити для всіх мікроконтролерів Atmel серії Atmega:
Зробимо визначення для задання виводів, які використовуються як SCLK і DIN (тут вивід PA6 визначено як SCLK, а PA7 як DIN):
//Задання виводів SCLK і DIN і визначення їх на вихід #define SCLK_DIN_to_output DDRA|=(1<<6)|(1<<7) #define SCLK_LOW PORTA&=~(1<<6)//Низький рівень на SCLK #define SCLK_HIGH PORTA|=(1<<6)//Високий рівень на SCLK #define DIN_LOW PORTA&=~(1<<7)//Низький рівень на DIN #define DIN_HIGH PORTA|=(1<<7)//Високий рівень на DIN
В тексті основної програми обов'язково ініціалізуємо вибрані виводи для роботи з шиною і встановимо на них високий рівень:
//Визначення на вихід виводів SCLK і DIN SCLK_DIN_to_output //Підтягування виводів SCLK і DIN SCLK_HIGH; DIN_HIGH;
Сформуємо стан Start: здійснимо перехід рівня на DIN з високого на низький, а слідом такий же перехід на SCLK. Часову затримку між командами можна не ставити навіть для максимальної частоти тактування мікроконтролера в 16 МГц. Для коректної роботи цієї установки на обох лініях має бути встановлений високий рівень.
//Установка стану старт voidTM1640_Message_Start(void) { DIN_LOW; SCLK_LOW; }
Тепер стан Stop: в даташиті цей стан називається "End", але звичніше використовувати більш правильний антонім. Для коректної роботи цієї установки на обох лініях має бути низький рівень. Здійснимо перехід рівня на DIN з низького на високий, потім такий же перехід здійснимо на SCLK)
//Установка стану стоп voidTM1640_Message_Stop(void) { SCLK_HIGH; DIN_HIGH; }
Розглянемо відправку байта, яка за вимогою протоколу повинна здійснюватися з молодшого біта: Встановлюємо потрібне значення біта даних і формуємо синхроімпульс. Навіть для частоти тактування мікроконтролера в 16МГц, без використання функції затримки, тривалість синхроімпульсу становитиме більше 125нс (виміряно логічним аналізатором Saleae Logic). Це перевищує вимагане мінімальне час встановлення біта даних на 25нс. Не забуваємо скинути DIN в нуль.
//Відправка байта voidTM1640_Message_Sendbyte(unsigned char byte) { //Побітна запис з молодшого біта for(signedchari=0;i<8;i++) { if(byte&(1<<i))DIN_HIGH;//Записати біт 1 else DIN_LOW;//Записати біт 0 SCLK_HIGH;//Встановлюємо синхроімпульс SCLK_LOW;//Знімаємо синхроімпульс DIN_LOW;//Скидаємо DIN в "0" } }
У цій функції, відповідно до таблиці 9 даташита, здійснюється відправка адреси індикатора від 0 до 15.
//Встановлення позиції, куди буде здійснюватися запис voidTM1640_SetPos(char i) { TM1640_Message_Sendbyte(0b11000000+i); }
Щоб за допомогою наведеної функції на індикаторах відображалися потрібні символи, необхідно задати наступний масив і зробити визначення для символів 16-бітного коду.
char str[12];//Масив для виводу результату на дисплей //Масив цифр 0 1 2 3 4 5 6 7 8 9 A char led[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, // B C D E F 0x7C, 0x39, 0x5E, 0x79, 0x71}; //Визначення символів 16-річної системи числення #define A 10 #define B 11 #define C 12 #define D 13 #define E 14 #define F 15
Функція встановлення яскравості зроблена відповідно до таблиці 10 даташита. У ній здійснюється відправка команди з потрібною яскравістю індикаторів від 0 (погасити індикатори) до 8 (максимальна яскравість).
//Встановлення яскравості світлодіодів voidTM1640_LED_Bright(chari) { TM1640_Message_Start(); if(i!=0)TM1640_Message_Sendbyte(0b10001000+i-1); elseTM1640_Message_Sendbyte(0b10000000); TM1640_Message_Stop(); }
Іноді зручно повністю стерти всі дані, відправлені на індикаторний дисплей. Для цього використовуємо таку функцію:
//Повна очистка світлодіодного індикатора void TM1640_clear(void) { TM1640_Message_Start(); TM1640_SetPos(0); for(char j=0;j<16;j++)TM1640_Message_Sendbyte(0x00); TM1640_Message_Stop(); }
Тут наведено приклад поетапної відправки символів 16-розрядного коду з подальшим поступовим гасінням індикаторів.
//Відправка символів 16-розрядного коду з 0 до F TM1640_Message_Start(); TM1640_SetPos(0); for(j=0;j<16;j++) { TM1640_Message_Sendbyte(led[j]);// _delay_ms(200); } TM1640_Message_Stop();//Постепенне гасіння індикаторного дисплея for(j=0;j<9;j++) { TM1640_LED_Bright(9-j); _delay_ms(200); }
Нижче представлена фотографія макета на основі TM1640, зібраного за схемою рис.2 (але з використанням усіх виводів GRID), під управлінням мікроконтролера Atmega32. Відео роботи схеми, вихідний код і "даташит" на мікросхему є в додатку до статті.
Прикреплені файли:
- tm1640.pdf (404 Кб)