Обсуждаем контроллеры компании Atmel.
Ответить

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

Пт авг 21, 2020 20:00:54

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

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

Пт авг 21, 2020 23:44:59

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

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

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

Яркость падает - индикация динамическая же, разряд (или сегменты - смотря на что опирается динамика) светятся лишь некий процент времени. В некоторых пределах лечится увеличением тока.

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

Сб авг 22, 2020 09:19:51

Я изначально размышлял про массив, но что-то мысль не пошла :). Надо попробовать по вашему рецепту. А про яркость, я пробовал изменить частоту и добавил запрет всех прерываний, чтоб контроллер не отвлекался при выполнении кода вывода на индикатор. Не помогло. Ток увеличивать не хотелось бы, решить программно.

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

Сб авг 22, 2020 10:12:10

Анимацию закладываем в параметры динамической индикации.
Собственно там, при хорошо проработанном алгоритме, никаких потерь яркости не должно быть - только другая картинка на определенное время замещает текущую.
Как вариант - попеременный вывод из двух массивов - основная видеопамять и буфер предобработки данных.
Один выводится, другой в это время обрабатывается.
Обработка дисплея делается автономной "прозрачной" - вывод очередного шага развертки и обработка счетчиков шагов по прерыванию (от чего удобнее - или по таймеру /ассемблер-Си/ или через спецприем для адуринки).
Остальное время - работает основная программа с буферами предподготовки и по спецфлагам содержимое тех буферов пересылается в основную видеопамять дисплея в момент "темного периода" (перед началом очередного цикла развертки).
8)

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

Сб авг 22, 2020 11:41:19

а зачем темный период? использовал буфер и работай с ним, а драйвер экрана будет брать из него по потребности

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

Сб авг 22, 2020 11:57:04

а зачем темный период?


Что конкретно имеется в виду?

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

Сб авг 22, 2020 12:54:04

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

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

Сб авг 22, 2020 13:19:44

Мне кажется, в данном случае это излишне. Всё прекрасно успеет обработаться пока светится разряд.

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

Сб авг 22, 2020 13:28:30

зачем мучаться?
настраиваешь таймер, и ловишь его переполнения
в них
1- гасишь разряд
2- обновляешь сегменты из массива элементов дисплея
3- зажигаешь разряд.
все операции занимают одинаковое количество команд (из цикла в цикл) => экран не мерцает
а если вынести гашение разряда в прерывание по совпадению этого же таймера, то можно и яркость регулировать...
а пересчитывать массив и опрашивать кнопки можно, например, после вывода 1го разряда...

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

Сб авг 22, 2020 14:00:32

Верно. Поправлю только, что пересчитывать и опрашивать можно всё остальное время.

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

Сб авг 22, 2020 16:01:42

зачем мучаться?
1- гасишь разряд
2- обновляешь сегменты из массива элементов дисплея
3- зажигаешь разряд.

А обязательно именно так поступать, ведь при обычных частотах обновления экрана всё равно не будет заметно появление новых значений? В том коде, который я использую таже не так, верно?

Код:
 if (bc547 == 2) {RAZRIAD = 0b00000100; CHISLO = Razrad2;} //включаем 2-й разряд, остальные выключаем

Меняется номер разряда и сразу выводится новое значение. Я спрашиваю из соображения, как делать правильно и при этом не наращивать объём кода.

Добавлено after 1 minute 19 seconds:
Специальный участок в конце развертки для служебных операций с погашенным экраном.

Так в моём случае его же и нет. Разве не так?

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

Сб авг 22, 2020 16:34:47

если не гасить перед обновлением - риск появления ложной засветки

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

Сб авг 22, 2020 17:13:46

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

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

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

Добавлено after 2 minutes 36 seconds:
благодаря этоау меню легко ложится в топографичевкую память и становится удобным в обращении

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

Сб авг 22, 2020 17:54:28

А посмотри на свой дисплей в темноте - может и ты паразитную засветку заметишь (особенно заметно на потушенном разряде)


Так и есть ))

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

Сб авг 22, 2020 17:55:54

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

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 KiB) Скачиваний: 196

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

Сб авг 22, 2020 18:19:43

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


ЗЫ к сожалению, плюсы на сегодня закончились )

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

Сб авг 22, 2020 19:59:50

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

Добавлено after 1 hour 23 minutes 5 seconds:
Demiurg, к сожалению, это может быть лишь хорошим примером "Как нельзя программировать"

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

Сб авг 22, 2020 20:24:03

Мою работу оценивают мои клиенты.
Ваше замечание - Это ваше личное мнение. Укажите причины и выкладывайте свой пример. Гляну... Что касается моего примера, динамическая индикация. Работает, читайте внимательно, в основном цикле.

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

Сб авг 22, 2020 20:45:44

Это работа для клиентов?! Час от часу не легче...
Причины указывать - да весь код сплошная причина. Невообразимое количество бесполезных дефайнов и практически бессмысленных функций.

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

Сб авг 22, 2020 20:49:46

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