Например TDA7294

Форум РадиоКот • Просмотр темы - Работа с чарлиплексинговым индикатором.
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Вс июл 27, 2025 22:01:17

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Работа с чарлиплексинговым индикатором.
СообщениеДобавлено: Вт июл 02, 2024 12:55:03 
Электрический кот
Аватар пользователя

Карма: 2
Рейтинг сообщений: 47
Зарегистрирован: Вс мар 01, 2009 19:47:16
Сообщений: 1046
Откуда: Ростов-на-Дону
Рейтинг сообщения: 0
Комрады, прошу помощи. Попался мне в лапы интересный дисплейчик от электронной сигареты. Очень кстати он подходит мне в проект термостата для портативного холодильника, но есть один нюанс - я с подобным никогда не работал, так что пытаюсь его освоить. Суть вот в чем: у дисплея сегменты подключены по методу чарлиплексинга и выведены на 6 выводов. Таблицу соответствия выводов и полярностей для каждого сегмента я сделал и все расписал, так что с этим вопросом не обращаюсь, мне нужен совет по подключению этой музыки к МК и реализации работы программы. Как вижу это я: каждый сегмент дисплея кодируется 6-ю байтами и заносится в массив, еще один массив такого же размера будет хранить 6-ти байтовую маску выводов порта, которые должны быть включены на выход во время индикации сегмента. Занимаем 1 порт контроллера под дисплей, индикация динамическая. Для отображения сегмента пишем в регистр порта нули, переводим весь порт на вход, чтобы погасить весь индикатор, затем пишем в в порт соответствующий нужному сегменту байт из массива и включаем нужные ножки порта на вывод записью соответствующей маски сегмента в регистр направления порта. После задержки продолжаем вывод следующего сегмента по вышеописанному алгоритму. Правильно ли такое решение, или я где-то ошибаюсь? Будет ли работать в таком режиме порт ввода-вывода. Работать будем с AVR.

UPD: не приложил фото дисплея, исправляюсь.

Морда:
Изображение


Со стороны хвоста:
Изображение

_________________
Не важно чем все начнется. Важно чем кончится!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Работа с чарлиплексинговым индикатором.
СообщениеДобавлено: Вт июл 02, 2024 13:42:50 
Друг Кота

Карма: 2
Рейтинг сообщений: 67
Зарегистрирован: Вт мар 13, 2012 12:16:13
Сообщений: 8167
Откуда: .ru
Рейтинг сообщения: 0
подключаем согласно схеме...
Вложение:
Чарлиплексинг.jpg [50.54 KiB]
Скачиваний: 97

и быстро дёргаем ножками МК... ))

//DDRD.0=1; // лампа 0
//PORTD.0=0; // лампа 0
//DDRD.1=1; // лампа 1
//PORTD.1=0; // лампа 1
//DDRD.2=1; // лампа 2
//PORTD.2=0; // лампа 2
//DDRD.3=1; // лампа 3
//PORTD.3=0; // лампа 3
//DDRD.4=1; // лампа 4
//PORTD.4=0; // лампа 4
//DDRD.5=1; // лампа 5
//PORTD.5=0; // лампа 5
...
...
...
и т.д.

что сложного...
:))


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Работа с чарлиплексинговым индикатором.
СообщениеДобавлено: Вт июл 02, 2024 14:00:24 
Электрический кот
Аватар пользователя

Карма: 2
Рейтинг сообщений: 47
Зарегистрирован: Вс мар 01, 2009 19:47:16
Сообщений: 1046
Откуда: Ростов-на-Дону
Рейтинг сообщения: 0
roman.com, ну во первых начнем с того, что ваш пример кода не заработает как надо, а начнется полная ахинея. Во вторых предложение подключить по указанной схеме меня немного смущает: вы мне предлагаете дисплей расковырять и переразвести его? Он, как бы уже собран на заводе и его схема конечна и неизменна.
В третьих, расписывать такую простыню после исправления для каждого кадра как минимум неэтично.

_________________
Не важно чем все начнется. Важно чем кончится!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Работа с чарлиплексинговым индикатором.
СообщениеДобавлено: Вт июл 02, 2024 14:33:54 
Друг Кота

Карма: 68
Рейтинг сообщений: 1961
Зарегистрирован: Сб дек 18, 2021 19:25:32
Сообщений: 12867
Рейтинг сообщения: 0
чарлиплексинг описывался на форуме не единожды


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Работа с чарлиплексинговым индикатором.
СообщениеДобавлено: Вт июл 02, 2024 16:47:39 
Электрический кот
Аватар пользователя

Карма: 2
Рейтинг сообщений: 47
Зарегистрирован: Вс мар 01, 2009 19:47:16
Сообщений: 1046
Откуда: Ростов-на-Дону
Рейтинг сообщения: 0
Martian, К сожалению только размытыми фразами. Я же задал конкретный вопрос, расписав алгоритм работы так, как вижу его сам, с просьбой посмотреть и поправить, если я в чем то неправ.

_________________
Не важно чем все начнется. Важно чем кончится!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Работа с чарлиплексинговым индикатором.
СообщениеДобавлено: Вт июл 02, 2024 16:56:48 
Друг Кота

Карма: 68
Рейтинг сообщений: 1961
Зарегистрирован: Сб дек 18, 2021 19:25:32
Сообщений: 12867
Рейтинг сообщения: 0
Не только размытыми, есть несколько статей, где всё полностью описано, с исходным кодом.

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


Вернуться наверх
 
Распродажа паяльного оборудования ATTEN!
Паяльные станции, паяльники и аксессуары по самой выгодной цене.

По промокоду radiokot скидка 10%
Не в сети
 Заголовок сообщения: Re: Работа с чарлиплексинговым индикатором.
СообщениеДобавлено: Вт июл 02, 2024 18:00:31 
Электрический кот
Аватар пользователя

Карма: 2
Рейтинг сообщений: 47
Зарегистрирован: Вс мар 01, 2009 19:47:16
Сообщений: 1046
Откуда: Ростов-на-Дону
Рейтинг сообщения: 0
Martian, ну реализую, видно будет. Насчет яркости думаю проблем не будет, это индикатор все же, а не новогодняя елка. Меня больше смущает другой вопрос: при выводе каждого сегмента сначала порт настраивается на высокоимпендансное состояние, то бишь на вход. По моей логике я сначала пишу в регистр PORTx требуемое значение, а потом по маске включаю порт на выход записью в регистр DDRx той самой маски. Правильная ли очередность, или сначала надо порт на выход, а потом писать в него? Свой метод я применяю, отталкиваясь от логики работы той же 74hc595.

_________________
Не важно чем все начнется. Важно чем кончится!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Работа с чарлиплексинговым индикатором.
СообщениеДобавлено: Вт июл 02, 2024 18:55:34 
Друг Кота

Карма: 68
Рейтинг сообщений: 1961
Зарегистрирован: Сб дек 18, 2021 19:25:32
Сообщений: 12867
Рейтинг сообщения: 0
Я не знаю устройства AVR, но попробовал бы так (запись в порт, а потом установка как выход). Если сначала на выход, а потом запись, то потом необходим сброс в ноль, лишняя операция, будет жаль, если так...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Работа с чарлиплексинговым индикатором.
СообщениеДобавлено: Чт июл 04, 2024 13:25:38 
Электрический кот
Аватар пользователя

Карма: 2
Рейтинг сообщений: 47
Зарегистрирован: Вс мар 01, 2009 19:47:16
Сообщений: 1046
Откуда: Ростов-на-Дону
Рейтинг сообщения: 0
Таки дисплей я осилил этот, пока допиливаю код на полноценную работу с ним, но вывод информации проблем не составил. Яркость при частоте обновления 50 Гц вполне неплохая. И да, на свой же вопрос нашел ответ - разницы в очередности записи в регистры порта в принципе нет - работает все в любом порядке. А дисплей, вот он:
Изображение

_________________
Не важно чем все начнется. Важно чем кончится!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Работа с чарлиплексинговым индикатором.
СообщениеДобавлено: Пт июл 05, 2024 16:17:13 
Электрический кот
Аватар пользователя

Карма: 2
Рейтинг сообщений: 47
Зарегистрирован: Вс мар 01, 2009 19:47:16
Сообщений: 1046
Откуда: Ростов-на-Дону
Рейтинг сообщения: 0
В общем я таки добил этот дисплей, работает неплохо. Писал в Arduino IDE - никак с нее слезть проклятой не могу. Замечания к коду и битье тапком по морде приветствуются, кто в программировании разбирается, прошу глянуть и натыкать мордой в глупости. Описание работы программы в шапке кода подробно разжевано.

Кино про дисплей:
Спойлер


Код:
Спойлер
Код:
/*
Программа написана в среде Arduino IDE. Использован МК AtMega328 c внешним кварцем 16МГц.
                        _____
Подключение индикатора: |   1   |     2    |    3    |    4    |    5     |    6    |
                        |  PD0  |    PD1   |   PD2   |   PD3   |   PD4    |   PD5   |
                        ----------
Сегменты по банкам:
1) A, B, C, D, E, F, G;
0) A, B, C, D, E, F, G;

Символы в массиве:

0 - Капля красная, 1 - Капля зеленая, 2 - Капля белая, 3 - Знак %, 4 - Молния красная, 5 - Молния белая;

Логика работы программы следующая:
Для работы используется прерывание таймера 1. Контроль работы а так же порядок выполнения операций осуществляется посредством счетчика на инкрементируемой переменной dyncounter. Частота прерываний - 10КГц.
Для вывода данных на индикатор в данный момент используется 16-ти байтный буфер buff[16], представляющий из себя одномерный массив содержащий
информацию для каждого из 16 сегментов в виде [A2,B2,A1,B1,C1,D1,E1,F1,G1,A0,B0,C0,D0,E0,F0,G0]. При выводе на индикатор в соответствии со значением
 dyncounter в регистр данных порта PORTx записываются данные сегмента из ячейки буфера, а в регистр направления порта DDRx соответствующая
маска сегмента из массива segmentmask[16].

Функция buffops() занимается подготовкой выходных данных. Во время ее работы вывод информации на дисплей запрещен
чтобы отображаемые данные были достоверными. Исходное число val в десятичном формате разбивается на разряды функцией digdisass() и помещает его в переменную vals[2]. Всвязи с особенностью дисплея отображать
в старшем разряде только единицу? отображение этого разряда происходит по признаку val>=100. Если условие верное, показываем единичку, если нет, молчим в тряпочку. Она проверяет и в случае необходимости включает
 старший разряд индикатора, по очереди берет исходное число, разбитое на десятки и единицы  из массива vals[2] и по битовой маске числа, соответствующей необходимым сегментам на дисплее, заполняет буфер вывода по следующей
системе: переменной outseg1 присваивается значение битовой маски из массива segments1, где записаны битовые маски для чисел от 0 до 9.
путем сдвига на 1 влево обрезается ненужный старший бит, так как каждый символ кодируется только 7-ю битами.
в цикле каждый бит переменной segments1 сравнивается с маской digitmask, и  пишет в выходной буфер данные для каждого из сегментов. В случае совпадения в соответствующую
 ячейку буфера будет записано значение из массива segments1, где содержатся битовые маски для отображения сегментов первого разряда, в случае несовпадения будет записан
 0, означающий, что текущий сегмент зажигать не надо. Здесь же присутствует операция гашения незначащего разряда, если исходное число меньше 10. Заполнение осуществляется
 от сегмента A1 до сегмента G1. Далее таким же способом заполняется буфер для сегментов A0-G0, после чего снимается запрет на вывод дисплей и останавливается работа с буфером до полного обновления индикатора.

В программе присутствует переменная timecontr. Она нужна для автоинкремента исходного числа val в прерывании. Данная функция нужна для демонстрации работы программы.

Отображение символов пока не реализовано, оно ничем не отличается от отображения символов, необходимо увеличить обьем выходного буфера на 6 байт и дописать в функцию работы с буфером обработку символов.
мне, как истинному коту пока лень ))))

*/
byte digitmask = 0x80;
volatile byte outseg0 = 0;
volatile byte outseg1 = 0;
volatile unsigned int timecontr = 0;
volatile byte dyncounter = 0;
volatile bool buffupdate = 0;
volatile byte val = 0;
volatile byte vals[2] = { 0, 0 };
byte segments1[7] = { 0x08, 0x10, 0x20, 0x01, 0x04, 0x08, 0x10 };
byte segments0[7] = { 0x20, 0x01, 0x02, 0x08, 0x10, 0x20, 0x01 };
byte symbols[6] = { 0x10, 0x08, 0x02, 0x08, 0x20, 0x20 };
byte segmentsmask[16] = { 0x03, 0x05, 0x09, 0x11, 0x21, 0x03, 0x06, 0x0a, 0x12, 0x22, 0x05, 0x06, 0x0c, 0x14, 0x24, 0x09 };
byte cifraseg[10] = { 0x7e, 0x30, 0x6d, 0x79, 0x33, 0x5b, 0x5f, 0x70, 0x7f, 0x7b };
volatile byte outbuff[16];
void digdisass() {
  if (val >= 100) {
    vals[1] = (val - 100) / 10;
    vals[0] = val % 10;
  }
  if (val < 100) {
    vals[1] = val / 10;
    vals[0] = val % 10;
  }
}
void buffops() {
   if (buffupdate == 1) {
digdisass();
    if (val >= 100) {
      outbuff[0] = 0x02;
      outbuff[1] = 0x04;
    }
    if (val < 100) {
      outbuff[0] = 0x00;
      outbuff[1] = 0x00;
    }
    if (val < 10) {
      outseg1 = 0x00;
    } else {
      outseg1 = cifraseg[vals[1]];
    }
    outseg1 = outseg1 << 1;
    for (int i = 0; i <= 6; i++) {
      if ((outseg1 & digitmask) == digitmask) {
        outbuff[(i + 2)] = segments1[i];
      }
      if ((outseg1 & digitmask) != digitmask) {
        outbuff[i + 2] = 0x00;
      }
      outseg1 = outseg1 << 1;
    }
    outseg0 = cifraseg[vals[0]];
    outseg0 = outseg0 << 1;
    for (int i = 0; i <= 6; i++) {
      if ((outseg0 & digitmask) == digitmask) {
        outbuff[i + 9] = segments0[i];
      }
      if ((outseg0 & digitmask)!= digitmask) {
        outbuff[i + 9] = 0x00;
      }
      outseg0 = outseg0 << 1;
    }
    buffupdate = 0;
  }
}
void displayout() {
  PORTD = outbuff[dyncounter];
  DDRD = segmentsmask[dyncounter];
}
void setup() {
  // Заводим таймер1 в режим СТС на 10 КГц
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 24;
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS11) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  sei();
}
ISR(TIMER1_COMPA_vect) {
  if (buffupdate == 0) {
    displayout();
     }

  dyncounter += 1;
  if (dyncounter > 15) {
    buffupdate = 1;
    buffops();
    dyncounter = 0;
  }
  timecontr += 1;
  if (timecontr >= 1500) {
    val += 1;
    timecontr = 0;
  }
  if (val >= 200) {
    val = 0;
  }
}
void loop() {
}

_________________
Не важно чем все начнется. Важно чем кончится!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Работа с чарлиплексинговым индикатором.
СообщениеДобавлено: Пт июл 05, 2024 17:18:58 
Друг Кота

Карма: 68
Рейтинг сообщений: 1961
Зарегистрирован: Сб дек 18, 2021 19:25:32
Сообщений: 12867
Рейтинг сообщения: 1
Всё-таки код надо комментировать в самом коде, а не только общим описанием...

dyncounter и buffupdate можно заменить какой-то одной, наверное.

И инкрементирование красивше выглядит как ++, притом не особо ухудшает читаемость, даже если префиксное:

Код:
ISR(TIMER1_COMPA_vect) {
  if (buffupdate == 0) {
    displayout();
  }

  if (++dyncounter > 15) {
    buffupdate = 1;
    buffops();
    dyncounter = 0;
  }

  if (++timecontr >= 1500) {
    if  (++val >= 200) {  // проверка только тогда, когда произошло приращение, а не всегда, выглядит более логичной
       val = 0;
    }
    timecontr = 0;
  }
}


Добавлено after 5 minutes 9 seconds:
outseg0 = outseg0 << 1;

Это тоже можно записать более лаконично: outseg0 <<= 1; - читается даже проще, а использование лишь одного идентификатора уменьшает вероятность опечатки

Добавлено after 6 minutes 39 seconds:
Код:
void digdisass() {
  if (val >= 100) {
    vals[1] = (val - 100) / 10;
    vals[0] = val % 10;
  }
  if (val < 100) {
    vals[1] = val / 10;
    vals[0] = val % 10;
  }
}


немного можно упростить:

Код:
void digdisass() {
  if (val >= 100) {
    vals[1] = (val - 100) / 10;
  }
  else {
     vals[1] = val / 10;
  }
  vals[0] = val % 10;
}

Ну и лаконичная запись:
Код:
void digdisass() {
  vals[1] = (val >= 100) ? (val - 100) / 10 : val / 10; // тернарный оператор "?". На мой взгляд, читается хуже.
  vals[0] = val % 10;
}


Добавлено after 3 minutes 37 seconds:
Код:
for (int i = 0; i <= 6; i++) {
      if ((outseg1 & digitmask) == digitmask) {
        outbuff[(i + 2)] = segments1[i];
      }
      if ((outseg1 & digitmask) != digitmask) {
        outbuff[i + 2] = 0x00;
      }
      outseg1 = outseg1 << 1;
    }


Здесь и в других местах почему-то не используется else, а пишется очередное сравнение. Зачем?

Добавлено after 4 minutes 9 seconds:
Ну, а вообще - круто, что заработало, поздравляю! :beer:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Работа с чарлиплексинговым индикатором.
СообщениеДобавлено: Пт июл 05, 2024 18:00:59 
Электрический кот
Аватар пользователя

Карма: 2
Рейтинг сообщений: 47
Зарегистрирован: Вс мар 01, 2009 19:47:16
Сообщений: 1046
Откуда: Ростов-на-Дону
Рейтинг сообщения: 4
Martian, Огромное спасибо за замечания. buffupdate можно вообще убрать, а вывод на индикатор ограничить значением счетчика dyncounter - надо было сразу так сделать, хорошо, что подсказали. Способ записи и проверки инкремента тоже утащил в уголок, буду теперь так делать. Со сдвигом битов я пока хреново дружу - сказывается обучение программированию с помощью ардуино - сейчас активно с него пытаюсь слезть. Я неправильно записывал выражения и они у меня просто не работали, поэтому пришлось извращаться. Например, вместо outseg0 <<=1; чукча писал outseg0 << 1; Внезапно это не работало :shock: , поэтому старым добрым железобетонным методом писал outseg0 = outseg0<<1. Это то работает. :))

Связка if()...else() у меня иногда выдает проблемы - неоднократно нарывался на неадекватно работающий код. Я же пока только учусь, вот уже и от delay и millis отучился вроде. :))

Добавлено after 13 minutes:
В моем решении есть еще один недочет, который надо будет исправить - я для управления 6-ти выводным индикатором полностью занимаю весь 8-ми битный порт целиком. Надо будет перекошачить немного код, добавить запись в порт по маске требуемых выводов, чтобы остальные не трогать. Будет время, переделаю, а то 2 пина вникуда. То есть на вход все время :))

Добавлено after 20 minutes 2 seconds:
Может это в виде статьи оформить и выложить тут же на сайте? Сам же информацию подробную недавно искал про такие индикаторы.

_________________
Не важно чем все начнется. Важно чем кончится!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Работа с чарлиплексинговым индикатором.
СообщениеДобавлено: Пт июл 05, 2024 18:20:40 
Друг Кота

Карма: 68
Рейтинг сообщений: 1961
Зарегистрирован: Сб дек 18, 2021 19:25:32
Сообщений: 12867
Рейтинг сообщения: 0
Может это в виде статьи оформить и выложить тут же на сайте? Сам же информацию подробную недавно искал про такие индикаторы.
Объяснение чарлиплексинга и описание практической реализации для Arduino будет полезным. Такие индикаторы встречаются всё чаще.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Работа с чарлиплексинговым индикатором.
СообщениеДобавлено: Пт июл 05, 2024 18:25:05 
Электрический кот
Аватар пользователя

Карма: 2
Рейтинг сообщений: 47
Зарегистрирован: Вс мар 01, 2009 19:47:16
Сообщений: 1046
Откуда: Ростов-на-Дону
Рейтинг сообщения: 5
Martian, тады вечерком добавлю управление символами и забузолю в статью. Спасибо за помощь, при написании статьи буду ссылаться на того, от кого получил знания. :beer:

_________________
Не важно чем все начнется. Важно чем кончится!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Работа с чарлиплексинговым индикатором.
СообщениеДобавлено: Пт июл 05, 2024 18:28:42 
Друг Кота

Карма: 68
Рейтинг сообщений: 1961
Зарегистрирован: Сб дек 18, 2021 19:25:32
Сообщений: 12867
Рейтинг сообщения: 0
Я ничем не помог, Вы всё сделали сами: работало и без меня, и все мои замечание не относятся непосредственно к чарлиплексингу.


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 15 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 20


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y