7-и сегментный ЖК-индикатор. Пример использования.
Cемисегментные ЖК дисплеи (индикаторы) очень древние существа. Но даже в мире символьных, графических и цветных дисплеев у них есть свое место. Они особо полезны для обеспечения отличной видимости при ярком освещении (на солнце). Имеют мизерное энергопотребление.
Дисплеи могут быть с электроникой и без. Именно о них (без электроники) и пойдет речь.
Как правило, у таких дисплеев один вывод общий, и по выводу на каждый сегмент. В управлении такими дисплеями нет ничего сложного. Но есть две особенности:
- Для управления таким дисплеем требуется много выводов микроконтроллера, по одному на каждый сегмент. Для 3 разрядного индикатора 24 вывода.
- Контрастность может падать, если постоянное напряжение приложено в течение долгого времени. В этом случае жидкокристаллическая структура деградирует из-за миграции ионов.
Для подключения 3-х разрядного семисегментного индикатора я использовал микросхемы сдвиговых регистров 74HC/HCT164. Это позволяет управлять любым количеством разрядов индикатора, задействовав только 3 ноги контроллера.
Схема для 3-х разрядного ЖКИ (LCD3.0-13):
Схему можно наращивать до нужного количества выводов добавляя микросхемы 74HC/HCT164. Эту схему можно использовать и для семисегментных светодиодных индикаторов и для работы с другими индикаторами, где требуется много ног.
Схема подключена к микроконтроллеру следующим образом:
DSA -> PINC5
CP -> PINC4
MR -> PINC3
Распиновка LCD3.0-13:
Теперь займемся программной частью.
#include "stdio.h";
#include "avr/io.h";
#include "util/delay.h";
// Настраиваем порты для DSA, DSA, RESET
#define LCD_DSA_PORT PORTC
#define LCD_DSA_PORT_DDR DDRC
#define LCD_DSA PINC5
#define LCD_CLK_PORT PORTC
#define LCD_CLK_PORT_DDR DDRC
#define LCD_CLK PINC4
#define LCD_RESET_PORT PORTC
#define LCD_RESET_PORT_DDR DDRC
#define LCD_RESET PINC3
uint8_t LCDFlag;
//1 - точка
//2 - нижний левый
//4 - нижний
//8 - нижний правый
//16 - верхний правый
//32 - верхний
//64 - верхний левый
//128- середина
#define LCD_NULL 0
#define LCD_DOT 1
#define LCD0 2+4+8+16+32+64
#define LCD1 8+16
#define LCD2 32+16+128+2+4
#define LCD3 32+16+128+8+4
#define LCD4 64+128+16+8
#define LCD5 32+64+128+8+4
#define LCD6 64+128+2+4+8+32
#define LCD7 32+16+8
#define LCD8 2+4+8+128+64+16+32
#define LCD9 64+32+16+128+8+4
const uint8_t NSymbol[] = {LCD0, LCD1, LCD2, LCD3, LCD4, LCD5, LCD6, LCD7, LCD8, LCD9};
// Функция выводит на семисегментный LCD целое число от 0 до 999
void LCD7_Show_Int(int value) {
uint8_t byte[3];
uint8_t b,n;
byte[2] = value/100;
byte[1] = (value-byte[2]*100)/10;
byte[0] = (value - byte[2]*100 - byte[1]*10);
// Сброс сдвиговых регистров
LCD_RESET_PORT &= ~(1< LCD_RESET_PORT |= (1< // Разряд 3
if (byte[2] > 0)
byte[2] = NSymbol[byte[2]];
else
byte[2] = LCD_NULL;
// Разряд 2
if ((byte[1] > 0) || (byte[2] > 0))
byte[1] = NSymbol[byte[1]];
else
byte[1] = LCD_NULL;
// Разряд 1
byte[0] = NSymbol[byte[0]];
// Переворачивает уровни для поддержания контрастности
if (LCDFlag == 0) {
byte[2] &= 254;
LCDFlag = 1;
}
else {
byte[0] = ~byte[0];
byte[1] = ~byte[1];
byte[2] = ~byte[2] | 1;
LCDFlag = 0;
}
// Задвигаем данные в сдвиговые регистры
for(b=0; b<3; b++) {
for(n=0; n<8; n++) {
if ((0x01 & (byte[b]>>n)) == 1)
LCD_DSA_PORT |= (1 << LCD_DSA);
else
LCD_DSA_PORT &= ~(1 << LCD_DSA);
LCD_CLK_PORT &= ~(1 << LCD_CLK);
LCD_CLK_PORT |= (1 << LCD_CLK);
}
}
}
int main( void )
{
// Настраиваем порты для DSA, DSA, RESET
LCD_DSA_PORT_DDR |= (1 << LCD_DSA);
LCD_CLK_PORT_DDR |= (1 << LCD_CLK);
LCD_RESET_PORT_DDR |= (1 << LCD_RESET);
while(1) {
LCD7_Show_Int(123); // Выводим значение от 0 до 999
_delay_us(100);
}
}
Печатную плату, схему и пример на GCC можно качайте здесь.
Смотри так же: Использование cимвольных жидкокристаллических LCD дисплеев. Пример на GCC (WinAVR) для Atmega 8
Спасибо за хорошую идею. Но есть небольшая просба для неопытных. Можно ли добавить статью следующими моментами. 1. Соответствие выводов регистров выводам дисплея. Например Q1-a1, Q2-b1. Хотя бы для одного сегмента. Потому как пока непонятно как его вообще подключить? Например с какой ноги регистра подается питание на общий вывод? 2. Описать логику работы - что бы можно было понимать как все-таки происходит засвечивание сегмента. Не совсем понятно - каким образом подается разнополярное питание и прочее. С какой частотой меняется полярность? Понимаю что вопросы может и простецкие, но думаю, что многие Вам их еще будут задавать. Заранее спасибо.
Подскажите, а есть ли такой пример подключения к микроконтроллеру AVR?
Это и есть пример подключения к ATmega8
А без использования сдвиговых регистров? Напрямую, к выводам микроконтроллера.
И еще с использованием динамической индикации
Недавні записи
- LCD Display ST7567S (IIC)
- Розпізнавання мови (Speech recognition)
- Selenium
- Комп'ютерний зір (Computer Vision)
- Деякі думки про точність вимірювань в електроприводі
- Датчики Холла 120/60 градусів
- Модуль драйверів напівмосту IGBT транзисторів
- Драйвер IGBT транзисторів на A316J
- AS5600. Варіант встановлення на BLDC мотор
- DC-DC для IGBT драйверів ізольований 2 W +15 -8 вольт
Tags
battery soldering java-script ngnix adc rs-232 flask esp8266 watchdog web exti solar mongodb rtc sms pwm usart books ethernet smd git websocket meteo css python dc-dc displays led ssd1306 eeprom gpio barometer max1674 mpx4115a brushless motor mpu-6050 timer sensors remap servo bldc atmega pmsm 3d-printer flash encoder examples dma raspberry-pi tim ssd1331 piezo mpu-9250 rfid eb-500 foc bme280 gps nvic dht11 bluetooth hih-4000 stm32 st-link docker uart avr html wifi bmp280 bkp nodemcu options usb lcd programmator i2c capture
Архіви