7-и сегментный ЖК-индикатор. Пример использования.


28.03.2011

Cемисегментные ЖК дисплеи (индикаторы) очень древние существа. Но даже в мире символьных, графических и цветных дисплеев у них есть свое место. Они особо полезны для обеспечения отличной видимости при ярком освещении (на солнце). Имеют мизерное энергопотребление.

Дисплеи могут быть с электроникой и без. Именно о них (без электроники) и пойдет речь.

Как правило, у таких дисплеев один вывод общий, и по выводу на каждый сегмент. В управлении такими дисплеями нет ничего сложного. Но есть две особенности:

  • Для управления таким дисплеем требуется много выводов микроконтроллера, по одному на каждый сегмент. Для 3 разрядного индикатора 24 вывода.
  • Контрастность может падать, если постоянное напряжение приложено в течение долгого времени. В этом случае жидкокристаллическая структура деградирует из-за миграции ионов.
Для решения этой проблемы применяется изменение полярности напряжения. Короче говоря, если надо засветить сегмент, нельзя на общий вывод подать 0, а на управляющий +. Нужно постоянно менять полярность, иначе контрастность падает.

Для подключения 3-х разрядного семисегментного индикатора я использовал микросхемы сдвиговых регистров 74HC/HCT164. Это позволяет управлять любым количеством разрядов индикатора, задействовав только 3 ноги контроллера.

Схема для 3-х разрядного ЖКИ (LCD3.0-13):

Схему можно наращивать до нужного количества выводов добавляя микросхемы 74HC/HCT164. Эту схему можно использовать и для семисегментных светодиодных индикаторов и для работы с другими индикаторами, где требуется много ног.

Схема подключена к микроконтроллеру следующим образом:

DSA -> PINC5
CP -> PINC4
MR -> PINC3

Распиновка LCD3.0-13:

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

Графический дисплей WG12864A

Схеми і прошивки
Коментарі:
nsl2004 говорить:
12.08.2011 09:02
Спасибо за хорошую идею. Но есть небольшая просба для неопытных. Можно ли добавить статью следующими моментами.
1. Соответствие выводов регистров выводам дисплея. Например Q1-a1, Q2-b1. Хотя бы для одного сегмента. Потому как пока непонятно как его вообще подключить? Например с какой ноги регистра подается питание на общий вывод?
2. Описать логику работы - что бы можно было понимать как все-таки происходит засвечивание сегмента. Не совсем понятно - каким образом подается разнополярное питание и прочее. С какой частотой меняется полярность? Понимаю что вопросы может и простецкие, но думаю, что многие Вам их еще будут задавать. Заранее спасибо.

Дмитрий говорить:
26.10.2012 17:33
Подскажите, а есть ли такой пример подключения к микроконтроллеру AVR?

admin говорить:
26.10.2012 20:45
Это и есть пример подключения к ATmega8

Дмитрий говорить:
22.11.2012 09:17
А без использования сдвиговых регистров? Напрямую, к выводам микроконтроллера.

Дмитрий говорить:
22.11.2012 09:18
И еще с использованием динамической индикации

Додати коментар
Code
* - обов'язкові поля

Архіви