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
А без использования сдвиговых регистров? Напрямую, к выводам микроконтроллера.
И еще с использованием динамической индикации
Tags
web java-script bmp280 adc bldc stm32 rs-232 programmator 3d-printer flash pwm sms motor docker raspberry-pi meteo gps ngnix bme280 timer ssd1331 mpu-6050 bkp battery rfid st-link tim mpx4115a ssd1306 encoder atmega pmsm wifi options rtc examples nvic soldering mongodb esp8266 books lcd foc flask barometer bluetooth ethernet brushless uart watchdog servo gpio solar git remap dma usart eb-500 smd nodemcu sensors displays html python capture dht11 led i2c eeprom piezo exti websocket max1674 usb dc-dc avr hih-4000 css mpu-9250
Архіви

