Семисегментный LED-индикатор. Эффекты анимации

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
ChipCard
Открыл глаза
Сообщения: 42
Зарегистрирован: Чт июл 23, 2020 20:59:01
Откуда: СевКавТВ

Семисегментный LED-индикатор. Эффекты анимации

Сообщение ChipCard »

Хотелось бы поэкспериментировать с этим индикатором в плане эффектов. Для начала решил написать вот такого вида, бегущий прочерк по часовой стрелке. Для отображения на индикаторе взял код (прерывание по Таймеру0) один из доступных в сети.

Код: Выделить всё

 - - - - -
|          |
 - - - - -
В общем всё взлетело, только код получился, как мне кажется очень кривой и громоздкий. И ещё появился один косяк. Яркость индикатора упала в два раза от оригинала ( таймера с которого я взял код обработки прерывания для динамической индикации). И не придумал, как можно обойтись одни таймером. И можно ли вообще одним только? Выслушаю все замечания и рекомендации.
Спойлер

Код: Выделить всё

#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>


#define  CHISLO PORTD
#define  RAZRIAD PORTB

unsigned int Razrad1 = 0, Razrad2 = 0, Razrad3 = 0, Razrad4 = 0;
unsigned char bc547 = 1;
ISR (TIMER0_OVF_vect)
{     
	 asm("cli"); 
	if (bc547 == 1) {RAZRIAD = 0b00001000; CHISLO = Razrad1;} //включаем 1-й разряд, остальные выключаем
	if (bc547 == 2) {RAZRIAD = 0b00000100; CHISLO = Razrad2;} //включаем 2-й разряд, остальные выключаем
	if (bc547 == 3) {RAZRIAD = 0b00000010; CHISLO = Razrad3;} //включаем 3-й разряд, остальные выключаем
	if (bc547 == 4) {RAZRIAD = 0b00000001; CHISLO = Razrad4;} //включаем 4-й разряд, остальные выключаем
	bc547++; // добавляем к переменной BC547 единицу
	if (bc547 > 4) bc547 = 1; // отслеживаем переменную BC547, чтобы она не превысила значение 4
	
}


ISR(TIMER1_COMPA_vect)
{
	static unsigned char Razrad;
	Razrad++;
	switch (Razrad)
	{
		case 1:
		Razrad1 = 0b00110001;
		Razrad2 = 0b00001001;
		Razrad3 = 0b00001001;
		Razrad4 = 0b00001111;
		break;
		case 2:
		Razrad1 = 0b00101001;
		Razrad2 = 0b00001001;
		Razrad3 = 0b00001001;
		Razrad4 = 0b00001111;
		break;
		case 3:
		Razrad1 = 0b00011001;
		Razrad2 = 0b00001001;
		Razrad3 = 0b00001001;
		Razrad4 = 0b00001111;
		break;
		case 4:
		Razrad1 = 0b00111000;
		Razrad2 = 0b00001001;
		Razrad3 = 0b00001001;
		Razrad4 = 0b00001111;
		break;
		case 5:
		Razrad1 = 0b00111001;
		Razrad2 = 0b00001000;
		Razrad3 = 0b00001001;
		Razrad4 = 0b00001111;
		break;
		case 6:
		Razrad1 = 0b00111001;
		Razrad2 = 0b00001001;
		Razrad3 = 0b00001000;
		Razrad4 = 0b00001111;
		break;
		case 7:
		Razrad1 = 0b00111001;
		Razrad2 = 0b00001001;
		Razrad3 = 0b00001001;
		Razrad4 = 0b00001110;
		break;

		case 8:
		Razrad1 = 0b00111001;
		Razrad2 = 0b00001001;
		Razrad3 = 0b00001001;
		Razrad4 = 0b00001101;
		break;
		case 9:
		Razrad1 = 0b00111001;
		Razrad2 = 0b00001001;
		Razrad3 = 0b00001001;
		Razrad4 = 0b00001011;
		break;
		case 10:
		Razrad1 = 0b00111001;
		Razrad2 = 0b00001001;
		Razrad3 = 0b00001001;
		Razrad4 = 0b00000111;
		break;

		case 11:
		Razrad1 = 0b00111001;
		Razrad2 = 0b00001001;
		Razrad3 = 0b00000001;
		Razrad4 = 0b00001111;
		break;
		case 12:
		Razrad1 = 0b00111001;
		Razrad2 = 0b00000001;
		Razrad3 = 0b00001001;
		Razrad4 = 0b00001111;
		Razrad = 0;
		break;
	}
}



int main(void)
{
	TCCR1B &= ~(1<<CS12);
	TCCR1B |= (1<<CS11) | (1<<CS10); // деление частоты на 64 = 15625
	TIMSK |= (1<<OCIE1A); // разрешаем прерывание при совпадении
	OCR1AH = 0b00000110;
	OCR1AL = 0b00001001; // регистр сравнения 
	TCNT1 = 0;
	TCCR1B |= (1<<WGM12); // сброс при совпадении



	TCCR0 |= (1<<1); 
    TCCR0 &= ~((1<<0) | (1<<2)); // f/8 
	TIMSK |= (1<<0);
	TCNT0 = 0;
	sei ();
	
	
    while(1)
    {
        //TODO:: Please write your application code 
    }
}
Последний раз редактировалось ChipCard Сб авг 22, 2020 18:17:40, всего редактировалось 1 раз.
Реклама
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение BlackKilkennyCat »

В массив "кадров" оформить было бы удобнее. И даже, возможно, экономичнее. Если подумать, то часть эффектов можно описать формулами.
Одним таймером обойтись можно, да и ненужно больше-то.
Например, так:
массив размерностью 4 - там храним значение каждого разряда. назовем Digs[]
i = 0
В бесконечном цикле main:
Port = Digs
if i >3 i= 0

ну а по таймеру меняем содержимое Digs[]
Это не единственный вариант, да и не самый лучший - может плавать яркость, так как будет отвлечение на прерывания то там то сям.
Можно наоборот - переключение свечения разрядов переложить на таймер, а смену кадров в main, по некоему флагу счетчику, который накапливается в том таймере.

Вообще, если "кадры" загнать в массивы, то таймера необязательны, даже один. Можно бесконечно прокручивать в майне.

Яркость падает - индикация динамическая же, разряд (или сегменты - смотря на что опирается динамика) светятся лишь некий процент времени. В некоторых пределах лечится увеличением тока.
Реклама
Аватара пользователя
ChipCard
Открыл глаза
Сообщения: 42
Зарегистрирован: Чт июл 23, 2020 20:59:01
Откуда: СевКавТВ

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение ChipCard »

Я изначально размышлял про массив, но что-то мысль не пошла :). Надо попробовать по вашему рецепту. А про яркость, я пробовал изменить частоту и добавил запрет всех прерываний, чтоб контроллер не отвлекался при выполнении кода вывода на индикатор. Не помогло. Ток увеличивать не хотелось бы, решить программно.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15556
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение BOB51 »

Анимацию закладываем в параметры динамической индикации.
Собственно там, при хорошо проработанном алгоритме, никаких потерь яркости не должно быть - только другая картинка на определенное время замещает текущую.
Как вариант - попеременный вывод из двух массивов - основная видеопамять и буфер предобработки данных.
Один выводится, другой в это время обрабатывается.
Обработка дисплея делается автономной "прозрачной" - вывод очередного шага развертки и обработка счетчиков шагов по прерыванию (от чего удобнее - или по таймеру /ассемблер-Си/ или через спецприем для адуринки).
Остальное время - работает основная программа с буферами предподготовки и по спецфлагам содержимое тех буферов пересылается в основную видеопамять дисплея в момент "темного периода" (перед началом очередного цикла развертки).
8)
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение Ivanoff-iv »

а зачем темный период? использовал буфер и работай с ним, а драйвер экрана будет брать из него по потребности
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Реклама
Аватара пользователя
ChipCard
Открыл глаза
Сообщения: 42
Зарегистрирован: Чт июл 23, 2020 20:59:01
Откуда: СевКавТВ

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение ChipCard »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3882347#p3882347"]а зачем темный период?[/uquote]

Что конкретно имеется в виду?
Реклама
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15556
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение BOB51 »

Специальный участок в конце развертки для служебных операций с погашенным экраном.
В принципе не всегда обязателен в явном виде - часто используется интервал индикации знакоместа.
Просто с тем "темным знакоместом" начинающему проще. Да и дополнительные операции также время занимают (кнопы или еще чего к дисплею привязанного - перезагрузка счетчиков, указателей, проверка флагов и прочая рутина)...
Я в основном на ассемблере с динамикой возился - там интервалы обработки удобнее просчитываются.
Под Си - или ассемблерные вставки или следим за тем, во что наши задумки компилятор превращает - лучше чтоб запас времени был.
8)
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение BlackKilkennyCat »

Мне кажется, в данном случае это излишне. Всё прекрасно успеет обработаться пока светится разряд.
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение Ivanoff-iv »

зачем мучаться?
настраиваешь таймер, и ловишь его переполнения
в них
1- гасишь разряд
2- обновляешь сегменты из массива элементов дисплея
3- зажигаешь разряд.
все операции занимают одинаковое количество команд (из цикла в цикл) => экран не мерцает
а если вынести гашение разряда в прерывание по совпадению этого же таймера, то можно и яркость регулировать...
а пересчитывать массив и опрашивать кнопки можно, например, после вывода 1го разряда...
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение BlackKilkennyCat »

Верно. Поправлю только, что пересчитывать и опрашивать можно всё остальное время.
Аватара пользователя
ChipCard
Открыл глаза
Сообщения: 42
Зарегистрирован: Чт июл 23, 2020 20:59:01
Откуда: СевКавТВ

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение ChipCard »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3882391#p3882391"]зачем мучаться?
1- гасишь разряд
2- обновляешь сегменты из массива элементов дисплея
3- зажигаешь разряд.[/uquote]
А обязательно именно так поступать, ведь при обычных частотах обновления экрана всё равно не будет заметно появление новых значений? В том коде, который я использую таже не так, верно?

Код: Выделить всё

 if (bc547 == 2) {RAZRIAD = 0b00000100; CHISLO = Razrad2;} //включаем 2-й разряд, остальные выключаем
Меняется номер разряда и сразу выводится новое значение. Я спрашиваю из соображения, как делать правильно и при этом не наращивать объём кода.

Добавлено after 1 minute 19 seconds:
[uquote="BOB51",url="/forum/viewtopic.php?p=3882376#p3882376"]Специальный участок в конце развертки для служебных операций с погашенным экраном.[/uquote]
Так в моём случае его же и нет. Разве не так?
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение BlackKilkennyCat »

если не гасить перед обновлением - риск появления ложной засветки
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение Ivanoff-iv »

конкретно в твоем случае ничего страшного не произойдёт, разве что в протеусе дисплей может завыкобениваться и начнёт всякую ерунду показывать.
но:
если тактовая у мк небольшая или частота переключения разрядов высокая или светодиоды в сегментах яркие или дисплей крупный, а в усилителях стоят медленные транзисторы, то эффект паразитной засветки соседних тазрядов может быть весьма ощутимым.
или если пришлось разместить сегменты на разные порты, то ты их не сможешь переключить за один такт => если их переключать при включенном разряде, то у них будет различаться время свечения и, значит, и яркость...
А посмотри на свой дисплей в темноте - может и ты паразитную засветку заметишь (особенно заметно на потушенном разряде)

Добавлено after 14 minutes:
BlackKilkennyCat, да, можно считать и опрашивать всё остальное время, но, если нужно связаться с часовой микросхемой или с датчиком температуры - то лучше не тянуть, т.к. только сразу после переключения разряда есть гарантированный вагон времени для связи, при которой ни ей никто не помешает, ни она никому...
только мы уже совсем отвлеклись от темы топика...

Добавлено after 7 minutes 57 seconds:
к теме - делал меню со спецэффектами перехода -
разместил всё меню в 2мерный массив (все подпункты одного пункта шли какбы одной строкой) текущее положение и цель перемещения задаввлась координатами в этом массиве (задавались координаты первого символа, остальные брались последующие от него в строке)
также для смягчения эффекта перехода был предусмотрен анимированный сдвиг по вертикали и/или горизонтали.

Добавлено after 2 minutes 36 seconds:
благодаря этоау меню легко ложится в топографичевкую память и становится удобным в обращении
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
ChipCard
Открыл глаза
Сообщения: 42
Зарегистрирован: Чт июл 23, 2020 20:59:01
Откуда: СевКавТВ

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение ChipCard »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3882460#p3882460"]А посмотри на свой дисплей в темноте - может и ты паразитную засветку заметишь (особенно заметно на потушенном разряде)[/uquote]

Так и есть ))
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение Demiurg »

В качестве примера.

seven_segm_led_ind.h
Спойлер

Код: Выделить всё

//==================
#ifndef SEVEN_SEGM_LED_IND_H

#define SEVEN_SEGM_LED_IND_H

#include "seven_segm_led_ind.h"
//==================

//==================
#include "main_def_func.h"
//==================

//==================
//#define __COMMON_METHOD_ONE__
#define __COMMON_METHOD_ZERO__

//#define __SEGMENT_METHOD_ONE__
#define __SEGMENT_METHOD_ZERO__
//==================

//==================
#define LEDS_IND_PORT           PORTC
#define LEDS_IND_PIN            PINC
#define LEDS_IND_DDR            DDRC

#define LEDS_IND                PC7
#define LEDS_IND_BIT            1<<LEDS_IND
//------------------------------------------------------------------------
#define SEVEN_SEGM_IND_1_PORT   PORTA
#define SEVEN_SEGM_IND_1_PIN    PINA
#define SEVEN_SEGM_IND_1_DDR    DDRA

#define SEVEN_SEGM_IND_1        PA0
#define SEVEN_SEGM_IND_1_BIT    1<<SEVEN_SEGM_IND_1
//------------------------------------------------------------------------
#define SEVEN_SEGM_IND_2_PORT   PORTA
#define SEVEN_SEGM_IND_2_PIN    PINA
#define SEVEN_SEGM_IND_2_DDR    DDRA

#define SEVEN_SEGM_IND_2        PA1
#define SEVEN_SEGM_IND_2_BIT    1<<SEVEN_SEGM_IND_2
//------------------------------------------------------------------------
#define SEVEN_SEGM_IND_3_PORT   PORTA
#define SEVEN_SEGM_IND_3_PIN    PINA
#define SEVEN_SEGM_IND_3_DDR    DDRA

#define SEVEN_SEGM_IND_3        PA2
#define SEVEN_SEGM_IND_3_BIT    1<<SEVEN_SEGM_IND_3
//------------------------------------------------------------------------
#define SEVEN_SEGM_IND_4_PORT   PORTA
#define SEVEN_SEGM_IND_4_PIN    PINA
#define SEVEN_SEGM_IND_4_DDR    DDRA

#define SEVEN_SEGM_IND_4        PA3
#define SEVEN_SEGM_IND_4_BIT    1<<SEVEN_SEGM_IND_4
//------------------------------------------------------------------------
#define SEVEN_SEGM_IND_5_PORT   PORTA
#define SEVEN_SEGM_IND_5_PIN    PINA
#define SEVEN_SEGM_IND_5_DDR    DDRA

#define SEVEN_SEGM_IND_5        PA4
#define SEVEN_SEGM_IND_5_BIT    1<<SEVEN_SEGM_IND_5
//------------------------------------------------------------------------
#define SEVEN_SEGM_IND_6_PORT   PORTA
#define SEVEN_SEGM_IND_6_PIN    PINA
#define SEVEN_SEGM_IND_6_DDR    DDRA

#define SEVEN_SEGM_IND_6        PA5
#define SEVEN_SEGM_IND_6_BIT    1<<SEVEN_SEGM_IND_6
//------------------------------------------------------------------------
#define SEVEN_SEGM_IND_7_PORT   PORTA
#define SEVEN_SEGM_IND_7_PIN    PINA
#define SEVEN_SEGM_IND_7_DDR    DDRA

#define SEVEN_SEGM_IND_7        PA6
#define SEVEN_SEGM_IND_7_BIT    1<<SEVEN_SEGM_IND_7
//------------------------------------------------------------------------
#define SEVEN_SEGM_IND_8_PORT   PORTA
#define SEVEN_SEGM_IND_8_PIN    PINA
#define SEVEN_SEGM_IND_8_DDR    DDRA

#define SEVEN_SEGM_IND_8        PA7
#define SEVEN_SEGM_IND_8_BIT    1<<SEVEN_SEGM_IND_8
//==================

/*
//==================
#ifdef __COMMON_METHOD_ONE__
#define set_seven_segm_ind_1_on()  set_bit (SEVEN_SEGM_IND_1_PORT, SEVEN_SEGM_IND_1)
#define set_seven_segm_ind_2_on()  set_bit (SEVEN_SEGM_IND_2_PORT, SEVEN_SEGM_IND_2)
#define set_seven_segm_ind_3_on()  set_bit (SEVEN_SEGM_IND_3_PORT, SEVEN_SEGM_IND_3)
#define set_seven_segm_ind_4_on()  set_bit (SEVEN_SEGM_IND_4_PORT, SEVEN_SEGM_IND_4)
#define set_seven_segm_ind_5_on()  set_bit (SEVEN_SEGM_IND_5_PORT, SEVEN_SEGM_IND_5)
#define set_seven_segm_ind_6_on()  set_bit (SEVEN_SEGM_IND_6_PORT, SEVEN_SEGM_IND_6)
#define set_seven_segm_ind_7_on()  set_bit (SEVEN_SEGM_IND_7_PORT, SEVEN_SEGM_IND_7)
#define set_seven_segm_ind_8_on()  set_bit (SEVEN_SEGM_IND_8_PORT, SEVEN_SEGM_IND_8)

#define set_leds_ind_on()          set_bit (LEDS_IND_PORT, LEDS_IND)
//------------------------------------------------------------------------
#define set_seven_segm_ind_1_off() clr_bit (SEVEN_SEGM_IND_1_PORT, SEVEN_SEGM_IND_1)
#define set_seven_segm_ind_2_off() clr_bit (SEVEN_SEGM_IND_2_PORT, SEVEN_SEGM_IND_2)
#define set_seven_segm_ind_3_off() clr_bit (SEVEN_SEGM_IND_3_PORT, SEVEN_SEGM_IND_3)
#define set_seven_segm_ind_4_off() clr_bit (SEVEN_SEGM_IND_4_PORT, SEVEN_SEGM_IND_4)
#define set_seven_segm_ind_5_off() clr_bit (SEVEN_SEGM_IND_5_PORT, SEVEN_SEGM_IND_5)
#define set_seven_segm_ind_6_off() clr_bit (SEVEN_SEGM_IND_6_PORT, SEVEN_SEGM_IND_6)
#define set_seven_segm_ind_7_off() clr_bit (SEVEN_SEGM_IND_7_PORT, SEVEN_SEGM_IND_7)
#define set_seven_segm_ind_8_off() clr_bit (SEVEN_SEGM_IND_8_PORT, SEVEN_SEGM_IND_8)

#define set_leds_ind_off()         clr_bit (LEDS_IND_PORT, LEDS_IND)
#endif
//------------------------------------------------------------------------

//------------------------------------------------------------------------
#ifdef __COMMON_METHOD_ZERO__
#define set_seven_segm_ind_1_on()  clr_bit (SEVEN_SEGM_IND_1_PORT, SEVEN_SEGM_IND_1)
#define set_seven_segm_ind_2_on()  clr_bit (SEVEN_SEGM_IND_2_PORT, SEVEN_SEGM_IND_2)
#define set_seven_segm_ind_3_on()  clr_bit (SEVEN_SEGM_IND_3_PORT, SEVEN_SEGM_IND_3)
#define set_seven_segm_ind_4_on()  clr_bit (SEVEN_SEGM_IND_4_PORT, SEVEN_SEGM_IND_4)
#define set_seven_segm_ind_5_on()  clr_bit (SEVEN_SEGM_IND_5_PORT, SEVEN_SEGM_IND_5)
#define set_seven_segm_ind_6_on()  clr_bit (SEVEN_SEGM_IND_6_PORT, SEVEN_SEGM_IND_6)
#define set_seven_segm_ind_7_on()  clr_bit (SEVEN_SEGM_IND_7_PORT, SEVEN_SEGM_IND_7)
#define set_seven_segm_ind_8_on()  clr_bit (SEVEN_SEGM_IND_8_PORT, SEVEN_SEGM_IND_8)

#define set_leds_ind_on()          clr_bit (LEDS_IND_PORT, LEDS_IND)
//------------------------------------------------------------------------
#define set_seven_segm_ind_1_off() set_bit (SEVEN_SEGM_IND_1_PORT, SEVEN_SEGM_IND_1)
#define set_seven_segm_ind_2_off() set_bit (SEVEN_SEGM_IND_2_PORT, SEVEN_SEGM_IND_2)
#define set_seven_segm_ind_3_off() set_bit (SEVEN_SEGM_IND_3_PORT, SEVEN_SEGM_IND_3)
#define set_seven_segm_ind_4_off() set_bit (SEVEN_SEGM_IND_4_PORT, SEVEN_SEGM_IND_4)
#define set_seven_segm_ind_5_off() set_bit (SEVEN_SEGM_IND_5_PORT, SEVEN_SEGM_IND_5)
#define set_seven_segm_ind_6_off() set_bit (SEVEN_SEGM_IND_6_PORT, SEVEN_SEGM_IND_6)
#define set_seven_segm_ind_7_off() set_bit (SEVEN_SEGM_IND_7_PORT, SEVEN_SEGM_IND_7)
#define set_seven_segm_ind_8_off() set_bit (SEVEN_SEGM_IND_8_PORT, SEVEN_SEGM_IND_8)

#define set_leds_ind_off()         set_bit (LEDS_IND_PORT, LEDS_IND)
#endif
//==================
*/

//==================
void set_seven_segm_ind_1_on (void);
void set_seven_segm_ind_2_on (void);
void set_seven_segm_ind_3_on (void);
void set_seven_segm_ind_4_on (void);
void set_seven_segm_ind_5_on (void);
void set_seven_segm_ind_6_on (void);
void set_seven_segm_ind_7_on (void);
void set_seven_segm_ind_8_on (void);

void set_leds_ind_on (void);
//------------------------------------------------------------------------
void set_seven_segm_ind_1_off (void);
void set_seven_segm_ind_2_off (void);
void set_seven_segm_ind_3_off (void);
void set_seven_segm_ind_4_off (void);
void set_seven_segm_ind_5_off (void);
void set_seven_segm_ind_6_off (void);
void set_seven_segm_ind_7_off (void);
void set_seven_segm_ind_8_off (void);

void set_leds_ind_off (void);
//==================

//==================
#define SEG_A              b00000001 // 1<<0
#define SEG_B              b00000010 // 1<<1 //     A
#define SEG_C              b00000100 // 1<<2 //   F   B
#define SEG_D              b00001000 // 1<<3 //     G
#define SEG_E              b00010000 // 1<<4 //   E   C
#define SEG_F              b00100000 // 1<<5 //     D   H
#define SEG_G              b01000000 // 1<<6
#define SEG_H              b10000000 // 1<<7
//------------------------------------------------------------------------
typedef struct tab_char_7_segm_cod_t
{
   u08 Char;
   u08 seven_segm_cod;
} tab_char_7_segm_cod_t;

extern struct tab_char_7_segm_cod_t __flash tab_char_7_segm_cod [];
//==================

//==================
#define MAX_LED_INDS       8
//==================

//==================
extern u08 dsp_buf [];

void clr_dsp_buf (void);
//==================

//==================
void set_proc_7_segm_ind_on (void);
void set_proc_7_segm_ind_off (void);
void proc_7_segm_ind (void);

u08 recod_char_7_segm_cod (u08 data);

void all_indications_init (void);
void all_indications_off (void);
//==================

//==================
#endif
//==================
seven_segm_led_ind.с
Спойлер

Код: Выделить всё

//==================
#include "seven_segm_led_ind.h"
//==================

//==================
struct tab_char_7_segm_cod_t __flash tab_char_7_segm_cod [] =
{
#ifdef __SEGMENT_METHOD_ONE__
   {'0',   (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F)},                  // 0
   {'1',   (SEG_B | SEG_C)},                                                  // 1
   {'2',   (SEG_A | SEG_B | SEG_D | SEG_E | SEG_G)},                          // 2
   {'3',   (SEG_A | SEG_B | SEG_C | SEG_D | SEG_G)},                          // 3
   {'4',   (SEG_B | SEG_C | SEG_F | SEG_G)},                                  // 4
   {'5',   (SEG_A | SEG_C | SEG_D | SEG_F | SEG_G)},                          // 5
   {'6',   (SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)},                  // 6
   {'7',   (SEG_A | SEG_B | SEG_C)},                                          // 7
   {'8',   (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)},          // 8
   {'9',   (SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G)},                  // 9
   {'A',   (SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G)},                  // 10
   {'B',   (SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)},                          // 11
   {'C',   (SEG_A | SEG_D | SEG_E | SEG_F)},                                  // 12
   {'D',   (SEG_B | SEG_C | SEG_D | SEG_E | SEG_G)},                          // 13
   {'E',   (SEG_A | SEG_D | SEG_E | SEG_F | SEG_G)},                          // 14
   {'F',   (SEG_A | SEG_E | SEG_F | SEG_G)},                                  // 15
   {'G',   (SEG_A | SEG_C | SEG_D | SEG_E | SEG_F)},                          // 16
   {'H',   (SEG_B | SEG_C | SEG_E | SEG_F | SEG_G)},                          // 17
   {'L',   (SEG_D | SEG_E | SEG_F)},                                          // 18
   {'N',   (SEG_C | SEG_E | SEG_G)},                                          // 19
   {'O',   (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F)},                  // 20
   {'P',   (SEG_A | SEG_B | SEG_E | SEG_F | SEG_G)},                          // 21
   {'П',   (SEG_A | SEG_B | SEG_C | SEG_E | SEG_F)},                          // 22
   {'-',   (SEG_G)},                                                          // 23
   {' ',   0xFF},                                                             // 24
#endif

#ifdef __SEGMENT_METHOD_ZERO__
   {'0',   (0xFF ^ (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F))},         // 0
   {'1',   (0xFF ^ (SEG_B | SEG_C))},                                         // 1
   {'2',   (0xFF ^ (SEG_A | SEG_B | SEG_D | SEG_E | SEG_G))},                 // 2
   {'3',   (0xFF ^ (SEG_A | SEG_B | SEG_C | SEG_D | SEG_G))},                 // 3
   {'4',   (0xFF ^ (SEG_B | SEG_C | SEG_F | SEG_G))},                         // 4
   {'5',   (0xFF ^ (SEG_A | SEG_C | SEG_D | SEG_F | SEG_G))},                 // 5
   {'6',   (0xFF ^ (SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G))},         // 6
   {'7',   (0xFF ^ (SEG_A | SEG_B | SEG_C))},                                 // 7
   {'8',   (0xFF ^ (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G))}, // 8
   {'9',   (0xFF ^ (SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G))},         // 9
   {'A',   (0xFF ^ (SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G))},         // 10
   {'B',   (0xFF ^ (SEG_C | SEG_D | SEG_E | SEG_F | SEG_G))},                 // 11
   {'C',   (0xFF ^ (SEG_A | SEG_D | SEG_E | SEG_F))},                         // 12
   {'D',   (0xFF ^ (SEG_B | SEG_C | SEG_D | SEG_E | SEG_G))},                 // 13
   {'E',   (0xFF ^ (SEG_A | SEG_D | SEG_E | SEG_F | SEG_G))},                 // 14
   {'F',   (0xFF ^ (SEG_A | SEG_E | SEG_F | SEG_G))},                         // 15
   {'G',   (0xFF ^ (SEG_A | SEG_C | SEG_D | SEG_E | SEG_F))},                 // 16
   {'H',   (0xFF ^ (SEG_B | SEG_C | SEG_E | SEG_F | SEG_G))},                 // 17
   {'L',   (0xFF ^ (SEG_D | SEG_E | SEG_F))},                                 // 18
   {'N',   (0xFF ^ (SEG_C | SEG_E | SEG_G))},                                 // 19
   {'O',   (0xFF ^ (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F))},         // 20
   {'P',   (0xFF ^ (SEG_A | SEG_B | SEG_E | SEG_F | SEG_G))},                 // 21
   {'П',   (0xFF ^ (SEG_A | SEG_B | SEG_C | SEG_E | SEG_F))},                 // 22
   {'-',   (0xFF ^ (SEG_G))},                                                 // 23
   {' ',   0xFF},                                                             // 24
#endif

   {0xFF,   0xFF},
};
//==================

//==================
u08 dsp_buf [MAX_LED_INDS];
//------------------------------------------------------------------------
// Очистка буфера дисплея.

u08 dsp_buf [MAX_LED_INDS];

void clr_dsp_buf (void)
{
   for (u08 i = 0; i < MAX_LED_INDS; i++)
      dsp_buf [i] = ' ';
}
//==================

//==================
u08 recod_char_7_segm_cod (u08 data)
{
   struct tab_char_7_segm_cod_t __flash *ptr = tab_char_7_segm_cod;

   for (; ptr -> Char != 0xFF; ptr++)
   {
      if (ptr -> Char == data)
         return ptr -> seven_segm_cod;
   }

   return false;
}
//==================

//==================
__flash FUNC proc_7_segm_ind_func [9] =
{
   set_seven_segm_ind_1_on,
   set_seven_segm_ind_2_on,
   set_seven_segm_ind_3_on,
   set_seven_segm_ind_4_on,
   set_seven_segm_ind_5_on,
   set_seven_segm_ind_6_on,
   set_seven_segm_ind_7_on,
   set_seven_segm_ind_8_on,
   set_leds_ind_on,
};

static u08 _proc_7_segm_ind;

void set_proc_7_segm_ind_on (void)
{
   _proc_7_segm_ind = 1;
}

void set_proc_7_segm_ind_off (void)
{
   all_indications_off ();
   _74act164_transf (0xFF);

   _proc_7_segm_ind = 0;
}

void proc_7_segm_ind (void)
{
   static soft_timer ST_PROC_7_SEGM_IND;

   static u08 cnt_7_segm_ind;

   u08 segments;

   switch (_proc_7_segm_ind)
   {
      case 0:
         break;

      case 1:
         all_indications_init ();
         clr_dsp_buf ();
         cnt_7_segm_ind = 0;
         set_soft_timer (ST_PROC_7_SEGM_IND, 0, 1);
         _proc_7_segm_ind = 2;
         break;

      case 2:
         if (handle_soft_timer (ST_PROC_7_SEGM_IND))
         {
            all_indications_off ();

            if (cnt_7_segm_ind < MAX_LED_INDS)
            {
               segments = recod_char_7_segm_cod (dsp_buf [cnt_7_segm_ind]);

               if ((get_dp_flag () == true) && (cnt_7_segm_ind == 2))
               {
                  #ifdef __SEGMENT_METHOD_ONE__
                  segments |= SEG_H;
                  #endif

                  #ifdef __SEGMENT_METHOD_ZERO__
                  segments &= (0xFF ^ SEG_H);
                  #endif
               }

               _74act164_transf (segments);
            }
            else
               _74act164_transf (get_leds_buf ());

            proc_7_segm_ind_func [cnt_7_segm_ind] ();

            if (++cnt_7_segm_ind > 8)
               cnt_7_segm_ind = 0;
         }
         break;

      default:
         break;
   }
}
//==================

//==================
#ifdef __COMMON_METHOD_ONE__
void set_seven_segm_ind_1_on (void)
{
   set_bit (SEVEN_SEGM_IND_1_PORT, SEVEN_SEGM_IND_1);
}

void set_seven_segm_ind_2_on (void)
{
   set_bit (SEVEN_SEGM_IND_2_PORT, SEVEN_SEGM_IND_2);
}

void set_seven_segm_ind_3_on (void)
{
   set_bit (SEVEN_SEGM_IND_3_PORT, SEVEN_SEGM_IND_3);
}

void set_seven_segm_ind_4_on (void)
{
   set_bit (SEVEN_SEGM_IND_4_PORT, SEVEN_SEGM_IND_4);
}

void set_seven_segm_ind_5_on (void)
{
   set_bit (SEVEN_SEGM_IND_5_PORT, SEVEN_SEGM_IND_5);
}

void set_seven_segm_ind_6_on (void)
{
   set_bit (SEVEN_SEGM_IND_6_PORT, SEVEN_SEGM_IND_6);
}

void set_seven_segm_ind_7_on (void)
{
   set_bit (SEVEN_SEGM_IND_7_PORT, SEVEN_SEGM_IND_7);
}

void set_seven_segm_ind_8_on (void)
{
   set_bit (SEVEN_SEGM_IND_8_PORT, SEVEN_SEGM_IND_8);
}

void set_leds_ind_on (void)
{
   set_bit (LEDS_IND_PORT, LEDS_IND);
}
//------------------------------------------------------------------------
void set_seven_segm_ind_1_off (void)
{
   clr_bit (SEVEN_SEGM_IND_1_PORT, SEVEN_SEGM_IND_1);
}

void set_seven_segm_ind_2_off (void)
{
   clr_bit (SEVEN_SEGM_IND_2_PORT, SEVEN_SEGM_IND_2);
}

void set_seven_segm_ind_3_off (void)
{
   clr_bit (SEVEN_SEGM_IND_3_PORT, SEVEN_SEGM_IND_3);
}

void set_seven_segm_ind_4_off (void)
{
   clr_bit (SEVEN_SEGM_IND_4_PORT, SEVEN_SEGM_IND_4);
}

void set_seven_segm_ind_5_off (void)
{
   clr_bit (SEVEN_SEGM_IND_5_PORT, SEVEN_SEGM_IND_5);
}

void set_seven_segm_ind_6_off (void)
{
   clr_bit (SEVEN_SEGM_IND_6_PORT, SEVEN_SEGM_IND_6);
}

void set_seven_segm_ind_7_off (void)
{
   clr_bit (SEVEN_SEGM_IND_7_PORT, SEVEN_SEGM_IND_7);
}

void set_seven_segm_ind_8_off (void)
{
   clr_bit (SEVEN_SEGM_IND_8_PORT, SEVEN_SEGM_IND_8);
}

void set_leds_ind_off (void)
{
   clr_bit (LEDS_IND_PORT, LEDS_IND);
}
#endif
//------------------------------------------------------------------------

//------------------------------------------------------------------------
#ifdef __COMMON_METHOD_ZERO__
void set_seven_segm_ind_1_on (void)
{
   clr_bit (SEVEN_SEGM_IND_1_PORT, SEVEN_SEGM_IND_1);
}

void set_seven_segm_ind_2_on (void)
{
   clr_bit (SEVEN_SEGM_IND_2_PORT, SEVEN_SEGM_IND_2);
}

void set_seven_segm_ind_3_on (void)
{
   clr_bit (SEVEN_SEGM_IND_3_PORT, SEVEN_SEGM_IND_3);
}

void set_seven_segm_ind_4_on (void)
{
   clr_bit (SEVEN_SEGM_IND_4_PORT, SEVEN_SEGM_IND_4);
}

void set_seven_segm_ind_5_on (void)
{
   clr_bit (SEVEN_SEGM_IND_5_PORT, SEVEN_SEGM_IND_5);
}

void set_seven_segm_ind_6_on (void)
{
   clr_bit (SEVEN_SEGM_IND_6_PORT, SEVEN_SEGM_IND_6);
}

void set_seven_segm_ind_7_on (void)
{
   clr_bit (SEVEN_SEGM_IND_7_PORT, SEVEN_SEGM_IND_7);
}

void set_seven_segm_ind_8_on (void)
{
   clr_bit (SEVEN_SEGM_IND_8_PORT, SEVEN_SEGM_IND_8);
}

void set_leds_ind_on (void)
{
   clr_bit (LEDS_IND_PORT, LEDS_IND);
}         
//------------------------------------------------------------------------
void set_seven_segm_ind_1_off (void)
{
   set_bit (SEVEN_SEGM_IND_1_PORT, SEVEN_SEGM_IND_1);
}

void set_seven_segm_ind_2_off (void)
{
   set_bit (SEVEN_SEGM_IND_2_PORT, SEVEN_SEGM_IND_2);
}

void set_seven_segm_ind_3_off (void)
{
   set_bit (SEVEN_SEGM_IND_3_PORT, SEVEN_SEGM_IND_3);
}

void set_seven_segm_ind_4_off (void)
{
   set_bit (SEVEN_SEGM_IND_4_PORT, SEVEN_SEGM_IND_4);
}

void set_seven_segm_ind_5_off (void)
{
   set_bit (SEVEN_SEGM_IND_5_PORT, SEVEN_SEGM_IND_5);
}

void set_seven_segm_ind_6_off (void)
{
   set_bit (SEVEN_SEGM_IND_6_PORT, SEVEN_SEGM_IND_6);
}

void set_seven_segm_ind_7_off (void)
{
   set_bit (SEVEN_SEGM_IND_7_PORT, SEVEN_SEGM_IND_7);
}

void set_seven_segm_ind_8_off (void)
{
   set_bit (SEVEN_SEGM_IND_8_PORT, SEVEN_SEGM_IND_8);
}

void set_leds_ind_off (void)
{
   set_bit (LEDS_IND_PORT, LEDS_IND);
}
#endif
//==================

//==================
void all_indications_init (void)
{
   _74act164_init ();

   set_bit (SEVEN_SEGM_IND_1_DDR, SEVEN_SEGM_IND_1);
   set_bit (SEVEN_SEGM_IND_2_DDR, SEVEN_SEGM_IND_2);
   set_bit (SEVEN_SEGM_IND_3_DDR, SEVEN_SEGM_IND_3);
   set_bit (SEVEN_SEGM_IND_4_DDR, SEVEN_SEGM_IND_4);
   set_bit (SEVEN_SEGM_IND_5_DDR, SEVEN_SEGM_IND_5);
   set_bit (SEVEN_SEGM_IND_6_DDR, SEVEN_SEGM_IND_6);
   set_bit (SEVEN_SEGM_IND_7_DDR, SEVEN_SEGM_IND_7);
   set_bit (SEVEN_SEGM_IND_8_DDR, SEVEN_SEGM_IND_8);

   set_bit (LEDS_IND_DDR, LEDS_IND);

   all_indications_off ();
   all_leds_off ();
}
//==================

//==================
void all_indications_off (void)
{
   set_seven_segm_ind_1_off ();
   set_seven_segm_ind_2_off ();
   set_seven_segm_ind_3_off ();
   set_seven_segm_ind_4_off ();
   set_seven_segm_ind_5_off ();
   set_seven_segm_ind_6_off ();
   set_seven_segm_ind_7_off ();
   set_seven_segm_ind_8_off ();

   set_bit (LEDS_IND_PORT, LEDS_IND);
}
//==================
Этот код был написан для проекта, в котором донором послужил прибор Термодат.
termodat.jpg
(8.08 КБ) 244 скачивания
Аватара пользователя
ChipCard
Открыл глаза
Сообщения: 42
Зарегистрирован: Чт июл 23, 2020 20:59:01
Откуда: СевКавТВ

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение ChipCard »

Буду разбираться...


ЗЫ к сожалению, плюсы на сегодня закончились )
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение BlackKilkennyCat »

Ivanoff-iv, ну, связываться-то со всякой периферией - это значительно быстрее, чем переключения индикаторов. Индикатор - десятки герц, тормознутая и2ц, например, сотни килогерц... так что, успеваем )) опять же, если еще и периферия хардварная, то вообще ещё и в слип уйти можно успеть :)

Добавлено after 1 hour 23 minutes 5 seconds:
Demiurg, к сожалению, это может быть лишь хорошим примером "Как нельзя программировать"
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение Demiurg »

Мою работу оценивают мои клиенты.
Ваше замечание - Это ваше личное мнение. Укажите причины и выкладывайте свой пример. Гляну... Что касается моего примера, динамическая индикация. Работает, читайте внимательно, в основном цикле.
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение BlackKilkennyCat »

Это работа для клиентов?! Час от часу не легче...
Причины указывать - да весь код сплошная причина. Невообразимое количество бесполезных дефайнов и практически бессмысленных функций.
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

Re: Семисегментный LED-индикатор. Эффекты анимации

Сообщение Demiurg »

Понятно. Мне параллельно на ваше мнение. Потому что вы даже не разобрались. Впрочем, как я уже написал, мне параллельно.
Я не видел ваших примеров. Итак, почему написано именно так. Первое, да, много дефайнов. И много писанины. Но зато, в дальнейшем, правка кода минимальна. Долго запрягаем, быстро едем. Второе. Я могу назначить любой пин мк. В одном месте. Есть и третье и так далее. Если я написал именно так, значит этому есть причина.
Жду вашего конструктивного ответа.
Последний раз редактировалось Demiurg Сб авг 22, 2020 20:57:30, всего редактировалось 1 раз.
Ответить

Вернуться в «AVR»