Как вывести многозначное число на семисегментный индикатор?
Обновлено Редакция GAW
Индикатор показывает цифры, а в программе лежит двоичное число. Перевести одно в другое значит разложить число на десятичные цифры — по сути, получить его в двоично-десятичном коде, как это делает Microchip в AN557, переводя результат АЦП в три цифры BCD.
Разложение и гашение нулей
// Common-cathode segment codes, bit order DP G F E D C B A
const uint8_t SEG[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
uint8_t digits[4]; // digits[0] is the rightmost one
void showNumber(uint16_t n) { // 0..9999
for (uint8_t i = 0; i < 4; i++) {
digits[i] = SEG[n % 10]; // lowest decimal digit
n /= 10;
}
for (uint8_t i = 3; i > 0 && digits[i] == SEG[0]; i--) {
digits[i] = 0x00; // blank leading zeros, keep the last digit
}
}
Массив digits потом выводит динамическая индикация — по одному разряду за раз, как описано в статье «Семисегментный индикатор». Коды для общего анода — инверсия кодов общего катода; готовый массив для любого порядка битов сгенерирует калькулятор кодов индикатора.
| Число | Цифры после разложения | На индикаторе из 4 разрядов |
|---|---|---|
| 7 | 0, 0, 0, 7 | 7 |
| 305 | 0, 3, 0, 5 | 305 — ноль внутри числа остаётся |
| 2026 | 2, 0, 2, 6 | 2026 |
MAX7219: режим Code B
У MAX7219 есть встроенный дешифратор Code B. Запись 0xFF в регистр Decode Mode (адрес 0x09) включает его для всех восьми разрядов. После этого в регистр разряда пишут саму цифру 0–9, а символы задают кодами: 0x0A — минус, 0x0F — пустой разряд, бит D7 — точка (табл. 5 даташита).
// max7219Write(address, data): your SPI helper sending one 16-bit word
max7219Write(0x09, 0xFF); // Code B for digits 0..7
max7219Write(0x01, 5); // digit 0 shows "5"
max7219Write(0x04, 0x0F); // digit 3 blank (leading zero)
Гасить ведущие нули через регистр Scan Limit Maxim прямо не советует: яркость зависит от числа сканируемых разрядов, и индикатор станет ярче при коротких числах. Остальные регистры и подключение — на странице MAX7219. Похожий принцип у CD4511: ему подают цифру четырьмя битами BCD, а сегменты он зажигает сам.
Похожие вопросы
Как вывести отрицательное число?
Отдельно запомнить знак, разложить на цифры модуль числа и в старший свободный разряд записать «минус» — у индикатора это один сегмент G. В Code B у MAX7219 для минуса есть готовый код 0x0A.
Как показать десятичную точку, например 23.5?
Хранить число в десятых — 235 — и включить точку у второго разряда справа. В коде сегментов это восьмой бит DP; у MAX7219 в любом режиме точку включает бит D7 в регистре разряда.
Не проще ли использовать sprintf?
Можно: sprintf(buf, "%4d", n) даст строку с ведущими пробелами вместо нулей, и останется перевести символы в коды. Но тогда в прошивку попадёт форматный вывод vfprintf из avr-libc, а цикл деления на 10 обходится без него.
Источники
- Maxim Integrated (Analog Devices). MAX7219/MAX7221 Serially Interfaced, 8-Digit LED Display Drivers (19-4452, Rev 6, 8/21) — табл. 2: адреса — No-Op 0xX0, Digit 0…7 — 0xX1…0xX8, Decode Mode 0xX9, Intensity 0xXA, Scan Limit 0xXB, Shutdown 0xXC, Display Test 0xXF; табл. 4: Decode Mode 0xFF — Code B для всех разрядов, 0x00 — без декодирования; табл. 5, Code B: 0–9, «-» 0x0A, E 0x0B, H 0x0C, L 0x0D, P 0x0E, пусто 0x0F, точка — бит D7; Scan-Limit Register: яркость зависит от числа сканируемых разрядов, поэтому регистр не следует использовать для гашения части индикатора, например ведущих нулей
- Microchip. AN557: Four-Channel Digital Voltmeter with Display and Keyboard (DS00557D) — результат АЦП переводится из 8-битного двоичного числа в три десятичные цифры BCD и выводится на семисегментные индикаторы; счётчик времени хранит цифры полубайтами BCD, при обновлении каждого разряда соответствующий полубайт декодируется в код сегментов
Нашли ошибку?
Смотрите также
- Коды семисегментного индикатораСегменты, hex-коды для анода и катода, массив на C, дешифраторы
- Семисегментные индикаторыОбщий анод и катод, коды 0–F, резисторы, мультиплексирование разрядов
- MAX72198 разрядов или 64 светодиода: выводы, регистры, RSET, яркость, каскад
- Двоично-десятичный код (BCD)Каждая десятичная цифра — в своих четырёх битах
- CD4511BДешифратор BCD в 7 сегментов: выводы, LT, BL, LE, ток сегмента, резисторы