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

display_init(void); - инициализация дисплея

set_brightness(uint8_t b); - установка яркости от 0 до 100

shift_in(char c); - сдвиг символа на одну позицию справа-налево

set_char_at(char c, uint8_t offset); - вывод символа в определенное знакоместо

Например: set_char_at('A', 0); // вывод символа А в первое знакоместо
set_char_at(2, 2); // вывод цифры 2 в третье знакоместо

set_segments_at(uint8_t segments, uint8_t offset); - вывод сегмента в определенное знакоместо

Например: set_segments_at(2, 1); // вывод сегмента "b" во второе знакоместо

shift_in_segments(uint8_t segments); - сдвиг сегмента на одну позицию справа-налево

set_number(uint16_t num); - вывод четырехразрядной переменной

clear_screen(void); - очистить дисплей

set_time(uint8_t hour, uint8_t min, uint8_t sec); - вывод времени в формате "ЧЧ.ММ"

set_number_4(uint8_t num_0, uint8_t num_1, uint8_t num_2, uint8_t num_3, uint8_t offset); - вывод значений поразрядно, вывод точки в позицию 1..4, 0 - неактивна

Для создания своего проекта как обычно добавляем к нему два файла display.c и display.h. Принцип работы библиотеки рассмотрим на примере часов. Используем для этого микроконтроллер atmega8, который тактируется от внешнего кварца частотой 8 МГц. Внешний кварц выбран для более точного хода часов. Сегменты индикатора подключаем к порту D, кстати в  заголовочном файле display.h можно изменить конфигурацию подключения по своему желанию, если например, на печатной плате надо оптимизировать разводку дорожек. Общие аноды(катоды) подключаются к выводам  PB3-PB0. Настройка часов осуществляется с помощью двух кнопок "Часы+" и "Минуты+", при нажатии на которые увеличиваются часы и минуты соответственно. При нажатии на обе кнопки изменяется яркость дисплея.

Использование библиотеки для работы с семисегментным индикатором. Делаем простые часы.

В нашей программе используются два таймера Т0 и Т1. Восьмибитный таймер Т0 используется для динамической индикации, шестнадцатибитный таймер Т1 используется для создания интервала в 1 секунду, он используется для подсчета времени. Как только наступает прерывание по совпадению Т1 переменная "second" увеличивается на 1 секунду, если "second" будет больше 60, переменная "minute" увеличится на 1 минуту, если переменная "minute" будет больше 60, переменная "hour" увеличится на 1 час, и т.д по кругу. Полный текст программы представлен ниже:

// Использование библиотеки для работы с семисегментным индикатором
#include <avr/io.h> 
#include <util/delay.h>
#include <avr/interrupt.h>
#include "display.h"

volatile unsigned char second, minute, hour, level;

// Обработчик прерывания по совпадению Т1
ISR(TIMER1_COMPA_vect)
{                       
second++;				    // Увеличиваем секунды
if(second == 60)
{
second = 0;
minute++;                   // Увеличиваем минуты
  if(minute == 60)
  {
   minute = 0;
   hour++;                  // Увеличиваем часы
   if(hour == 24) hour = 0;
  }
}

set_time(hour,minute,second); // Выводим на дисплей
}

int main(void)
{
hour = 12;	// Начальная установка времени
minute = 0;
second = 0;

// Порты ввода/вывода
DDRB |= (0 << PB5)|(0 << PB4);
PORTB |= (1 << PB5)|(1 << PB4);
// Настройка Т1
TCCR1B |= (1 << WGM12)|(1 << CS12); // 8MHz/256/(1+31249)=1Hz
OCR1A = 31249;

sei(); // Глобально разрешам прерывания

set_brightness(80); // Начальная установка яркости дисплея
display_init(); // Инициализация дисплея
// Выводим бегущую строку "test display"
shift_in('t');
_delay_ms(100);
shift_in('E');
_delay_ms(100);
shift_in('s');
_delay_ms(100);
shift_in('t');
_delay_ms(100);
shift_in(' ');
_delay_ms(100);
shift_in('d');
_delay_ms(100);
shift_in('i');
_delay_ms(100);
shift_in('s');
_delay_ms(100);
shift_in('p');
_delay_ms(100);
shift_in('L');
_delay_ms(100);
shift_in('a');
_delay_ms(100);
shift_in('y');
_delay_ms(100);
shift_in(' ');
_delay_ms(100);
shift_in(' ');
_delay_ms(100);
shift_in(' ');
_delay_ms(100);
clear_screen();
_delay_ms(100);

TIMSK |= (1 << OCIE1A); // Разрешаем прерывание по совпадению Т1

while(1)
{	
unsigned char i, dr;
// Если кнопка Часы+ и Минуты+ нажаты увеличиваем яркость
if((PINB&(1 << PB4)) == 0 && (PINB&(1 << PB5)) == 0) 
{
dr = 0;
// Программный антидребезг контактов
for(i = 0; i < 10; i++)
  { 
   _delay_ms(5);
   if((PINB&(1 << PB4)) == 0 && (PINB&(1 << PB5)) == 0) 
   dr++;
  } 
if(dr > 5) 
  {
   if(level != 99) 
   level++;	// Увеличиваем яркость
   else level = 0;
   set_brightness(level);
  }
} 
// Если кнопка Часы+ нажата увеличиваем часы
if((PINB&(1 << PB4)) == 0 && PINB&(1 << PB5))
{
dr=0;
// Программный антидребезг контактов
for(i = 0; i < 10; i++)
  {
   _delay_ms(5);
   if((PINB&(1 << PB4)) == 0) 
   dr++;
  } 
if(dr > 5) 
  {
   if(hour != 23) hour++; // Увеличиваем часы
   else hour = 0;
   set_time(hour,minute,second); // Выводим на дисплей
  }
} 
// Если кнопка Минуты+ нажата увеличиваем минуты
if((PINB&(1 << PB5))==0 && PINB&(1 << PB4))
{
dr=0;
// Программный антидребезг контактов
for(i = 0; i < 10; i++)
  {
   _delay_ms(5);
   if((PINB&(1 << PB5)) == 0) 
   dr++;
  } 
if (dr > 5) 
  {
   if(minute != 59) minute++; // Увеличиваем минуты
   else minute = 0;
   set_time(hour,minute,second); // Выводим на дисплей
  }
}

}
}

Обсуждение статьи на форуме


Архив для статьи "Использование библиотеки для работы с семисегментным индикатором. Делаем простые часы."
Описание: Проект AVRStudio и Proteus
Размер файла: 64.41 KB Количество загрузок: 4 756 Скачать

Комментарии  

#1 foxhant 13.02.2013 03:22
Подскажите пожалуйста, как переделать код для вывода секунд, минут и часов на 6-значном индикаторе.
Ну не как с секундами не получается :cry:
#2 AntonChip 13.02.2013 08:25
Цитирую foxhant:
Подскажите пожалуйста, как переделать код для вывода секунд, минут и часов на 6-значном индикаторе.
Ну не как с секундами не получается :cry:

Только переделывать библиотеку, если смогу выложу код.
#3 foxhant 13.02.2013 16:06
Понимаю, что библиотеку,в том-то и шутка. Сдвинуть четыре символа на два разряда вправо, несложно, а задействовать все шесть индикаторов не могу додуматься как?
Буду очень благодарен за помощь, вот если еще и на Си.......... :-?
#4 AntonChip 14.02.2013 08:27
Цитирую foxhant:
Буду очень благодарен за помощь, вот если еще и на Си.......... :-?

Написал в форум radioparty.ru/forums/viewtopic.php?f=2&t=749
#5 foxhant 15.02.2013 17:16
Огромное спасибо! Ну очень классная штука!!
#6 Galy4a 18.03.2014 16:09
Как правильно подключить библиотеку? Какие файлы куда скинуть, что прописать в коде? У меня проблемы на этапе компиляции.
#7 foxhant 19.03.2014 11:36
Попробуй проще, сделай копию скачанного архива, разархивируй в папку и запускай файл 7seg_menu.aps при помощьи AVR Studio 4(на других версиях не пробовал)
+2 #8 Виктор-C 20.12.2014 11:42
А вывода числа из переменной, нет :cry:
#9 igor_yalta 15.03.2015 01:25
а как зажигать точку произвольно из вашей библиотеки ???
ели хочется вывести температуру например -15.2 14.82 ???
#10 AntonChip 15.03.2015 22:35
Цитирую Виктор-C:
А вывода числа из переменной, нет :cry:

set_number(1000 );
#11 AntonChip 16.03.2015 11:47
Цитирую igor_yalta:
а как зажигать точку произвольно из вашей библиотеки ???
ели хочется вывести температуру например -15.2 14.82 ???

Как вариант добавить свою функцию типа этого
Код:
void set_themperature(uint16_t themperature, uint8_t dot_digit)
{
set_number(themperature);
sbi(dots, dot_digit); // set dot 1 on
}
+3 #12 vanya 29.04.2015 18:42
Автору респект! На диплом схема потянет!))
#13 mastech 18.05.2015 01:04
день добрый пытаюсь использовать вашу библиотеку, но выходит следующие: нужно вывести букву А в третий индикатор, код такой
Код:#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "display.h"

volatile unsigned char second, minute, hour, level;



int main(void)
{

//порты
DDRA |= (1<<PA7)|(1<<PA6)|(1<<PA5)|(1<<PA4)|(1<<PA3)|(1<<PA2)|(1<<PA1)|(1<<PA0);//катоды
PORTA |= (0<<PA7)|(0<<PA6)|(0<<PA5)|(0<<PA4)|(0<<PA3)|(0<<PA2)|(0<<PA1)|(0<<PA0);//индикатора

DDRD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4)|(1<<PD3)|(1<<PD2)|(1<<PD1)|(1<<PD0);
PORTD |= (0<<PD7)|(0<<PD6)|(0<<PD5)|(0<<PD4)|(0<<PD3)|(0<<PD2)|(0<<PD1)|(0<<PD0); //сегменты индикатора



display_init(); // инициализация дисплея
set_brightness(99); // начальная установка яркости дисплея

while(1)
{
set_char_at('A', 2);
}

}

получается что на все индикаторы выводится "А",а на третьем индикаторе сегменты еле подсвечиваются. Индикатор с общим катодом в библиотеке выставил катод.
#14 mastech 18.05.2015 01:08
дополню. контроллер Mega32, регистры таймера проверил все совпадает с мегой8.
#15 AntonChip 18.05.2015 11:54
Подключаете через транзисторные ключи или без них?
#16 mastech 18.05.2015 12:54
через ключи в катодах,порт настроены. без библиотеки цифры нормально выводятся
#17 AntonChip 18.05.2015 12:58
Цитирую mastech:
через ключи в катодах,порт настроены. без библиотеки цифры нормально выводятся

Библиотека не оптимизирована для работы с ключами, нужно будет немножко переделать исходник
#18 mastech 18.05.2015 17:44
в каком направлении копать?
#19 AntonChip 18.05.2015 18:14
Цитирую mastech:
в каком направлении копать?

Попробуйте так
Код:
// common cathode
#define SET_DIGIT sbi
#define CLEAR_DIGIT cbi
#define SET_SEGMENT sbi
#define CLEAR_SEGMENT cbi
#20 n.mikro 25.08.2017 11:34
Очень интересно,часы действительно простые, но по хорошему 4 транзистора требуется внести в схему к индикатору.
Использовать часовой кварц и корректировку секунд, с обычными кварцами 8-16 мегагерц ничего путного не выходит.
К томуже появится возможность усыплять контроллер с таймером работающим в асинхронном режиме на случай потери питания.
Библиотека кстати огонь здоровенная.
#21 Ання 15.11.2017 21:51
Возник маленький вопрос, как открыть библиотеки? можете их сюда написать, я от руки вобью их (заранее спасибо^^)
#22 Сергей123 22.02.2019 16:01
Здравствуйте, помогите пожалуйста совместить данный пример программы с программой "термометр" с ds18b20
#23 bashsat 24.02.2019 16:55
Здравствуйте! Хочу собрать часы с термометром. Использовал занятия с проектами на DS1307 и DS18b20 и библиотеку для работы с семисегментными индикаторами. Вывод часов отображается нормально, а вот вывести температуру через эту библиотеку не получается. Проверял и в схеме, и в Протеусе.
#24 AntonChip 26.02.2019 20:28
Цитирую bashsat:
Здравствуйте! Хочу собрать часы с термометром. Использовал занятия с проектами на DS1307 и DS18b20 и библиотеку для работы с семисегментными индикаторами. Вывод часов отображается нормально, а вот вывести температуру через эту библиотеку не получается. Проверял и в схеме, и в Протеусе.

Здравствуйте. Добавил в библиотеку функцию set_number_4, через нее вывел температуру, пример в файлах к этой статье
-1 #25 bashsat 26.02.2019 21:22
Спасибо огромное!!! Буду разбираться.

У Вас недостаточно прав для добавления комментариев. Возможно, Вам необходимо зарегистрироваться на сайте.