Подключение семисегментных индикаторов с помощью сдвигового регистра 74HC164. Делаем простой вольтметр на Attiny13.

Рейтинг:  5 / 5

Звезда активнаЗвезда активнаЗвезда активнаЗвезда активнаЗвезда активна
 

Применение сдвиговых регистров таких как 74HC164 обусловлено возможностью управления большим количеством выходных линий с помощью 3-х линий управления, например эти регистры можно использовать для подключения гирлянд или матриц из светодиодов. Они широко используются в бытовой и промышленной аппаратуре для вывода данных на индикаторы или опросе матричной клавиатуры. Из управляющих входов в этой микросхеме есть: DATA, RESET, CLK и есть 8-выходов, получается эта микросхема преобразует последовательный код в параллельный. Вход RESET который сбрасывает установленные значения на выходе обычно не используется, так как занимает лишний вывод у микроконтроллера, он должен всегда быть поднятым к Vcc. Обнулять значения можно посылкой из 8бит логических единиц. Вход CLK продвигает значение по регистру. На вход DATA поступают данные в последовательном режиме.

Для заполнения регистра нужно выполнить такую последовательность:

1. Сравниваем старший бит передаваемого байта с нулем, если он равен нулю передаем в DATA ноль, если не равен передаем единицу;
2. Сдвигаем передаваемое значение на 1 разряд;
3. На тактовый вход CLK подаем ноль;
4. На тактовый вход CLK подаем единицу;
5. Проделываем эти операции пока не передадим весь байт нашего значения.

Подробнее со сдвиговым регистром разберемся на примере вольтметра постоянного напряжения до 50 Вольт. Микроконтроллер на этот раз будет Attiny13, так как у него всего 5 рабочих линий порта PB он как раз нам подходит. Работает он от внутреннего генератора частотой 4,8 MHz. АЦП настроен стандартно, вход ADC1. Каждый сегмент индикаторов подключается через резистор 220 Ом, индикаторы используются с общим катодом.  Для предотвращения мерцания сегментов индикаторов их общие катоды подключаются через транзистор, который включается только тогда, когда все значение будет передано в регистр. Схема вольтметра для индикаторов с общим катодом  показана ниже:

Подключение семисегментных индикаторов с помощью сдвигового регистра 74HC164

Исходный код примера для индикаторов с общим катодом с подробными комментариями:

// Управление семисегментными индикаторами через регистр сдвига 74HC164(ОК)
#include <avr/io.h>
#include <util/delay.h> 

// Массив значений для индикатора
unsigned char SEGMENTE[] = 
{
//0----1----2----3----4----5----6----7----8----9 
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F
};

unsigned int value;

// Функция сдвига
void write_byte(unsigned char data) 
{ 
  for(unsigned char i = 0; i < 8 ; i++) 
  { 
    if((data & 0x80) != 0) // Сравниваем 8-й бит с нулем 
    PORTB |= (1 << PB0); // DATA 1
    else 
    PORTB &= ~(1 << PB0); // DATA 0

    data = data << 1; // Сдвигаем биты
    PORTB |= (1 << PB1); // CLK 1
    PORTB &= ~(1 << PB1); // CLK 0
  }
} 

int main(void) 
{ 
DDRB |= (1 << PB3)|(1 << PB1)|(1 << PB0); 
PORTB = 0x00;

ADCSRA |= (1 << ADEN) // Разрешение АЦП
       |(1 << ADPS2)|(1 << ADPS1); // Предделитель на 64
ADMUX |= (1 << MUX0); // Вход ADC1

ACSR |= (1 << ACD); // Выключаем аналаговый компаратор
DIDR0 |= (1 << ADC1D); // Отключаем неиспользуемые цифровые входы

while(1)
{ 
ADCSRA |= (1 << ADSC); // Начинаем преобразование
while (ADCSRA & (1 << ADSC)){} // Ждем завершения преобразования
value = (ADC*27)/50; // Uin = 4,99*110k/10k = 54,89V
                     // k = 548/1023 = 0,54
		     // 0,54 = 27/50

PORTB &= ~(1 << PB3); // Выключаем индикатор
write_byte(SEGMENTE[value%10]); // Выводим 1 разряд
write_byte((SEGMENTE[value%100/10])|0x80); // Выводим 2 разряд
write_byte(SEGMENTE[value%1000/100]); // Выводим 3 разряд
PORTB |= (1 << PB3); // Включаем индикатор
_delay_ms(100);
}
}

Схема вольтметра для индикаторов с общим анодом  показана ниже:

Исходный код примера для индикаторов с общим анодом с подробными комментариями:

// Управление семисегментными индикаторами через регистр сдвига 74HC164(ОА)
#include <avr/io.h>
#include <util/delay.h> 

// Массив значений для индикатора

unsigned char SEGMENTE[] = 
{
//0----1----2----3----4----5----6----7----8----9 
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F
};

unsigned int value;

// Функция сдвига
void write_byte(unsigned char data) 
{ 
  for(unsigned char i = 0; i < 8 ; i++) 
  { 
    if((data & 0x80) != 0) // Сравниваем 8-й бит с нулем 
    PORTB |= (1 << PB0); // DATA 1
    else 
    PORTB &= ~(1 << PB0); // DATA 0

    data = data << 1; // Сдвигаем биты
    PORTB |= (1 << PB1); // CLK 1
    PORTB &= ~(1 << PB1); // CLK 0
  }
} 

int main(void) 
{ 
DDRB |= (1 << PB3)|(1 << PB1)|(1 << PB0); 
PORTB = 0x00;

ADCSRA |= (1 << ADEN) // Разрешение АЦП
       |(1 << ADPS2)|(1 << ADPS1); // Предделитель на 64
ADMUX |= (1 << MUX0); // Вход ADC1

ACSR |= (1 << ACD); // Выключаем аналаговый компаратор
DIDR0 |= (1 << ADC1D); // Отключаем неиспользуемые цифровые входы

while(1)
{ 
ADCSRA |= (1 << ADSC); // Начинаем преобразование
while (ADCSRA & (1 << ADSC)){} // Ждем завершения преобразования
value = (ADC*27)/50; // Uin = 4,99*110k/10k = 54,89V
                     // k = 548/1023 = 0,54
		     // 0,54 = 27/50

PORTB |= (1 << PB3); // Выключаем индикатор
write_byte(~SEGMENTE[value%10]); // Выводим 1 разряд
write_byte(~((SEGMENTE[value%100/10])|0x80)); // Выводим 2 разряд
write_byte(~SEGMENTE[value%1000/100]); // Выводим 3 разряд
PORTB &= ~(1 << PB3); // Включаем индикатор
_delay_ms(100);
}
}


Архив для статьи "Подключение семисегментных индикаторов с помощью сдвигового регистра 74HC164"
Описание: Проект AVRStudio 4
Размер файла: 45.98 KB Количество загрузок: 869 Скачать

Метки: ATtiny13, Вольтметр, 74HC164

Печать E-mail

Комментарии  

0 #21 Warovarin 22.02.2018 12:23
Вот теперь всё заработало,спас ибо вам!! А чтоб запятую сместить вправо,надо сделать так:write_byte_ 3(~((SEGMENT[va lue%1000/100])| 0*80));?
Сообщить модератору
0 #22 Warovarin 22.02.2018 17:17
До 54-х v у меня работает,а при смене коэффициента на ADC/4 и изменении делителя 200k и 3.9k и смещении запятой,чтоб измеряло 260v ,после прошивки высвечивается 0 b. 5
Сообщить модератору
0 #23 AntonChip 22.02.2018 19:04
Цитирую Warovarin:
До 54-х v у меня работает,а при смене коэффициента на ADC/4 и изменении делителя 200k и 3.9k и смещении запятой,чтоб измеряло 260v ,после прошивки высвечивается 0 b. 5
а зачем запятая нужна, может ее вообще убрать, или у вас 4-х разрядный индикатор?
Сообщить модератору
0 #24 Warovarin 23.02.2018 06:10
Нет,3-х разрядный. Хотя да,вы правы,вообще убрать.
Сообщить модератору
0 #25 Warovarin 23.02.2018 16:30
Это в 20-й строке надо сделать изменения:
if data&=0;?
Сообщить модератору
0 #26 Warovarin 25.02.2018 16:23
Всё перепробовал точка либо не уходит,либо индикатор не светится.. Ну да ладно. Я хотел бы спросить: показания вольтметра подгоняются R1 при измерении - U,а вот при измерении~U через мостик,показани я разнятся. Как уравнить,чтоб измерять ~U ?
Сообщить модератору

Авторизация