сайт для палких паяльників

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

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

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

  1. Для управления таким дисплеем требуется много выводов микроконтроллера, по одному на каждый сегмент. Для 3 разрядного индикатора 24 вывода.
  2. Контрастность может падать, если постоянное напряжение приложено в течение долгого времени. В этом случае жидкокристаллическая структура деградирует из-за миграции ионов.

Для решения этой проблемы применяется изменение полярности напряжения. Короче говоря, если надо засветить сегмент, нельзя на общий вывод подать 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

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

  • nsl2004 говорить:

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

  • Дмитрий говорить:

    Подскажите, а есть ли такой пример подключения к микроконтроллеру AVR?

    • admin говорить:

      Это и есть пример подключения к ATmega8

      • Дмитрий говорить:

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

  • Дмитрий говорить:

    И еще с использованием динамической индикации

Translate
Архіви

© 2011-2019 Андрій Корягін, Кременчук - Київ, Україна