Модуль индикации и управления на TM1638 предназначен для ввода-вывода информации: отображает информацию на восьмисегментном индикаторе, 8 светодиодах и позволяет вводить данные с 8 кнопок. Для управления используется последовательный интерфейс.
Управление индикаторами и определение нажатия кнопок выполняет микросхема TM1638. Она принимает и передает данные от микроконтроллера по уникальному последовательному интерфейсу из трех сигналов, близкому к интерфейсу SPI. Отличие от SPI состоит в объединении в одну линию двух линий приема и передачи. Названия сигналов отличные от принятых в SPI, но они хорошо узнаются.
Микросхема содержит внутренние регистры хранения состояния светодиодов и кнопок. Запись и чтение регистров происходит по командам приходящим по интерфейсу. После записи регистров микросхема автоматически формирует сигналы управления индикаторами и опроса кнопок.
Сигналы интерфейса TM1638:
- STB – сигнал стробирования;
- CLK – тактовый сигнал;
- DIO – двунаправленная линия данных.
Пример
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
const int strobe = 8; // STB to D8 const int clk = 9; // CLK to D9 const int dta = 10; // DIO to D10 void sendCommand(uint8_t value) { digitalWrite(strobe, LOW); shiftOut(dta, clk, LSBFIRST, value); digitalWrite(strobe, HIGH); } void reset() { sendCommand(0x40); // Set auto increment mode digitalWrite(strobe, LOW); shiftOut(dta, clk, LSBFIRST, 0xc0); // Set starting address to 0 for (uint8_t i = 0; i < 16; i++) { shiftOut(dta, clk, LSBFIRST, 0x00); } digitalWrite(strobe, HIGH); } void setup() { pinMode(strobe, OUTPUT); pinMode(clk, OUTPUT); pinMode(dta, OUTPUT); sendCommand(0x8f); // Set maximum display brightness reset(); } #define COUNTING_MODE 0 #define SCROLL_MODE 1 #define BUTTON_MODE 2 void loop() { static uint8_t mode = COUNTING_MODE; switch (mode) { case COUNTING_MODE: mode += counting(); delay(500); break; case SCROLL_MODE: mode += scroll(); break; case BUTTON_MODE: buttons(); break; } delay(200); } bool counting() { /*0*/ /*1*/ /*2*/ /*3*/ /*4*/ /*5*/ /*6*/ /*7*/ /*8*/ /*9*/ uint8_t digits[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f }; static uint8_t digit = 0; sendCommand(0x40); digitalWrite(strobe, LOW); shiftOut(dta, clk, LSBFIRST, 0xc0); for (uint8_t position = 0; position < 8; position++) { shiftOut(dta, clk, LSBFIRST, digits[digit]); shiftOut(dta, clk, LSBFIRST, 0x00); } digitalWrite(strobe, HIGH); digit = ++digit % 10; return digit == 0; } bool scroll() { uint8_t scrollText[] = { /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*H*/ /*E*/ /*L*/ /*L*/ /*O*/ /*.*/ /*.*/ /*.*/ 0x76, 0x79, 0x38, 0x38, 0x3f, 0x80, 0x80, 0x80, /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*H*/ /*E*/ /*L*/ /*L*/ /*O*/ /*.*/ /*.*/ /*.*/ 0x76, 0x79, 0x38, 0x38, 0x3f, 0x80, 0x80, 0x80, }; static uint8_t index = 0; uint8_t scrollLength = sizeof(scrollText); sendCommand(0x40); digitalWrite(strobe, LOW); shiftOut(dta, clk, LSBFIRST, 0xc0); for (int i = 0; i < 8; i++) { uint8_t c = scrollText[(index + i) % scrollLength]; shiftOut(dta, clk, LSBFIRST, c); shiftOut(dta, clk, LSBFIRST, c != 0 ? 1 : 0); } digitalWrite(strobe, HIGH); index = ++index % (scrollLength << 1); return index == 0; } void buttons() { uint8_t promptText[] = { /*P*/ /*r*/ /*E*/ /*S*/ /*S*/ /* */ /* */ /* */ 0x73, 0x50, 0x79, 0x6d, 0x6d, 0x00, 0x00, 0x00, /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*b*/ /*u*/ /*t*/ /*t*/ /*o*/ /*n*/ /*S*/ /* */ 0x7c, 0x1c, 0x78, 0x78, 0x5c, 0x54, 0x6d, 0x00, /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static uint8_t block = 0; uint8_t textStartPos = (block / 4) << 3; for (uint8_t position = 0; position < 8; position++) { sendCommand(0x44); digitalWrite(strobe, LOW); shiftOut(dta, clk, LSBFIRST, 0xC0 + (position << 1)); shiftOut(dta, clk, LSBFIRST, promptText[textStartPos + position]); digitalWrite(strobe, HIGH); } block = (block + 1) % 16; uint8_t buttons = readButtons(); for (uint8_t position = 0; position < 8; position++) { uint8_t mask = 0x1 << position; setLed(buttons & mask ? 1 : 0, position); } } uint8_t readButtons(void) { uint8_t buttons = 0; digitalWrite(strobe, LOW); shiftOut(dta, clk, LSBFIRST, 0x42); pinMode(dta, INPUT); for (uint8_t i = 0; i < 4; i++) { uint8_t v = shiftIn(dta, clk, LSBFIRST) << i; buttons |= v; } pinMode(dta, OUTPUT); digitalWrite(strobe, HIGH); return buttons; } void setLed(uint8_t value, uint8_t position) { pinMode(dta, OUTPUT); sendCommand(0x44); digitalWrite(strobe, LOW); shiftOut(dta, clk, LSBFIRST, 0xC1 + (position << 1)); shiftOut(dta, clk, LSBFIRST, value); digitalWrite(strobe, HIGH); } |








