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

7seg на hc595 4digit

Вс фев 11, 2024 20:14:18

Коллега Martian, с нашего форуму прислал мне платы на hc595 и индикаторы к ним.
ИзображениеНу вот не прошло и пару лет как мне захотелось собрать на них что-то полезное.
К сожалению, разводка индикаторов оказалась нескольько другой чем известные на алике аналоги, например, Tm74hc595. Но Martian так же прислал схему с примером для АВР где были указаны шестнадцатиричные коды цифр.
7seg-2.pdf
(301.86 KiB) Скачиваний: 53

Мне не удалось переделать библиотеку https://alexgyver.ru/tm74hc595_display/ ... 4622313349 от Алекса Гайвера, чего-то не хватило, наверно ума.

Поэтому решил гугллением , интернет -примерами, и чатом GPT написать код , который заряжает эти дисплейи. Тот же чатГПТ, конечно, обладается огромной эрудицией, но в плане интеллекта, не сильно убежал вперед. Целый вечер я уговарил его написать функцию для вывода на этот модуль чисел с плаввающей точкой, но так и не добился от него толку. В итого написал сам условно рабочий достаточно костыльный код, в надежде что он поправит его и оптимизирует, но Чат наоборот изувечил его логику и сделал непригодным. Это достаточно странно, я то думал, что неверно ставлю задачу, но всего лишь повторить логику имеющегося кода, оптимизировав где надо - та что может быть проще.

Короче, получился вот такой код. Поэтому приглашаю энтизуастов обратить внимание на функцию displayFloatOnIndicators(float number) и может быть что-то подсказать. Допустим 25.10 выводится как 25.10, ахотелось бы как _25.1
Код:
const int DATA_PIN = 5; // Пин для данных (подключен к PADDR0)
const int CLK_PIN = 7;  // Пин для сигнала тактового импульса (подключен к PADDR1)
const int LATCH_PIN = 6; // Пин для сигнала защелкивания (подключен к PADDR3)

unsigned char const led_table[] = { // цифры без точки
  0b00000110,
  0b10011111,
  0b10100010,
  0b10010010,
  0b00011011,
  0b01010010,
  0b01000010,
  0b10011110,
  0b00000010,
  0b00010010
};

unsigned char const led_table_dot[] = {  // цифры с точкой (точка 1бит справа, он у всех 0)
  0b00000100,
  0b10011101,
  0b10100000,
  0b10010000,
  0b00011001,
  0b01010000,
  0b01000000,
  0b10011100,
  0b00000000,
  0b00010000
};

//unsigned char dot = 0x00;
// Массив состояние анодов (питания индикаторов)
unsigned char const dig_n[] = {0xfe,0xfb, 0xfd,0xf7 };
unsigned char x;

void d(unsigned char c) {
  for (x = 0; x < 8; x++) {
    digitalWrite(DATA_PIN, LOW);
    if (c & 0x01) digitalWrite(DATA_PIN, HIGH);
    c >>= 1;
    digitalWrite(CLK_PIN, HIGH);
    digitalWrite(CLK_PIN, LOW);
  }
}

void dig(unsigned char d1, unsigned char d2) {
  digitalWrite(LATCH_PIN, LOW);
  d(d1);
  d(d2);
  digitalWrite(LATCH_PIN, HIGH);
}

void setup() {
  pinMode(DATA_PIN, OUTPUT);
  pinMode(CLK_PIN, OUTPUT);
  pinMode(LATCH_PIN, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  static float currentNumber = 1.0; // Текущее значение для отображения
  static unsigned long lastDisplayTime = 0; // Переменная для отслеживания времени

  if (millis() - lastDisplayTime > 100) { // Обновляем значение каждые 500 мс
    currentNumber+= 0.01; // Увеличиваем текущее значение
    if (currentNumber > 9999) currentNumber = 0; // Сбрасываем, если достигнуто максимальное значение
    lastDisplayTime = millis(); // Обновляем время последнего обновления
  }

  //displayFourDigitNumber(currentNumber); // Отображаем текущее число
  displayFloatOnIndicators(currentNumber);
  //displayFloatOnIndicatorsII(25.3);
}

void displayFourDigitNumber(int number) {
  // Функция вывода целочисленных чисел
  // Переводим число в строку
  char buffer[5];
  sprintf(buffer, "%04d", number); // Форматируем число

  int startIndex = 0; // Сдвигаем в право, не выводим незначащие нули слева, например 25 выведется как __25, а не 25__
  while (buffer[startIndex] == '0') {
    startIndex++;}

  // Отображаем каждую цифру на соответствующем индикаторе
  for (int i = startIndex; i < 4; ++i) {
    char digit = buffer[i];
 
      dig(dig_n[i], led_table[digit - '0']); // Отображаем цифру
 
  }
}


void displayFloatOnIndicators(float number) {
  // Суть алгоритма. Вывести цифры, но без точки (берем из массива цифр) led_table[]
  // Определить позицию точки
  // Из массива цифр с точками led_table_dot[] вывести ПОВТОРНО цифру, но уже с точкой
  char bufferNoDot[10];  // Сюда положу цифры без точки
  char buffer[10];  // Здесь будут цифры с точкой
  dtostrf(number, 4, 3, buffer); // Преобразуем число типа float в строку с 3 знаками после запятой
  //dtostrf(number*1000, 4, 0, bufferNoDot); // Число без точки

  // Определяем позицию точки в строке
  int dotPosition = strchr(buffer, '.') - buffer;
  //
  dtostrf(number*pow(10,(4-dotPosition)), 4, 0, bufferNoDot); // тут я умножаю на степень 10 найденну по позиции точки что бы получить целое число (МФТИ, ФПМИ- простите ребята)
  int dotDigit=buffer[dotPosition-1]; // значение цифра за которой идет точка (в конце будет ее выводить)
 
   int startIndex = 0; // Здесь искал незначащие нули впереди( для вывода чисел int)
  while (bufferNoDot[startIndex] == '0') {
    startIndex++;}

  // Отображаем каждую цифру на соответствующем индикаторе из массива без точек bufferNoDot
  for (int i = startIndex; i < 4; ++i) {
    char digit = bufferNoDot[i];
 
      dig(dig_n[i], led_table[digit - '0']); // Отображаем цифру
 
  }
  // Когда все цифры выведены Отображаем цифру с точкой ПОВТОРНО
    dig(dig_n[dotPosition-1], led_table_dot[dotDigit - '0']);

}


Re: 7seg на hc595 4digit

Вс фев 11, 2024 20:42:03

Ну, я не ориентировался на какие-то другие библиотеки, вообще, преследовалось две цели - как можно проще сделать трассировку платы (этим объясняется некий хаос в сигналах на схеме) и получить максимум универсальности - то есть, вывести ещё дискретные светодиоды, в том числе по центру платы для двоеточия часов. К тому же, это было выдрано из другого моего проекта, где являлось частью панели управления. Такой вот история...

Но проблем быть не должно.
Существует всего два массива:
Код:
цифры {0x06,0x9f,0xa2,0x92,0x1b,0x52,0x42,0x9e,0x02,0x12}
и разряды {0xf7,0xfd,0xfb,0xfe}
, притом старшая тетрада разрядов - дополнительные выходы
и правило: сначала посылаем выбор разряда, затем цифру.
Чтобы отобразить точку, достаточно в цифре сбросить бит ( & 0xFD):
Код:
 dig(dig_n[i], led_table[digit - '0'] & 0xFD); // Отображаем цифру


Или, если где-то определено, в каком разряде должна быть точка (пусть это будет переменная dig_dot), то можно вывод записать так:
Код:
 dig(dig_n[i], led_table[digit - '0'] & (dig_dot == i ? 0xFD : 0xFF)); // Отображаем цифру

Куча вариантов, оптимальный зависит от общего кода. Но два массива (с точкой и без точки) создавать излишне.

Re: 7seg на hc595 4digit

Вс фев 11, 2024 21:01:28

да , я не знал про сбросить бит ( & 0xFD):
елси бы был более смышленым мог бы его вычислить. Но попался исходник с двумя массивами и я решил использовать этот вариант
Конечно, нужно переделать , и память освободится а тка наворотил тут на 5кб. А хочется в Атмегу 8 запихнуть на ардуиновском коде.

Изображение

Добавлено after 1 minute 56 seconds:
идеально было бы конечно изменить библиотеку Гайвер, по моему, там можно даже бегущую строк замутить.

Re: 7seg на hc595 4digit

Вс фев 11, 2024 21:03:33

и ещё небольшие замечания:
Код:
void displayFloatOnIndicators(float number)
эта функция постоянно выводит изображение на индикатор. Но помимо этого, онав ещё и форматирует currentNumber, переданный ей, для вывода. А если он не изменился? Тогда она постоянно делает лишнюю работу.
Я бы сделал следующее:
1) избавится от типа float, вряд ли он тут нужен, но ввёл бы буфер индикатора (он и так уже есть, но бесполезный);
2) форматировать только когда необходимо;
3) вывод на индикатор сделать в прерывании таймера (это необязательно);

То есть, функция вывода на индикатор упростилась бы до:
Код:
unsigned char buffer_indicator[4]; // "память дисплея"
...
void displayFloatOnIndicators()
{
  for (int i = 0; i < 4; i++)
  {
       dig(dig_n[i], buffer_indicator[i]); // Отображаем цифру
  }
}


А вот заполнение "памяти дисплея" только когда currentNumber изменился, и там же и точку формировать.

Добавлено after 42 seconds:
Бегущую строку и тут можно замутить, нет никаких ограничений.... просто надо написать :)

Re: 7seg на hc595 4digit

Вс фев 11, 2024 21:19:49

ок, пока только добавил точку и избавился от второго массив, который с точками:

Код:
void displayFloatOnIndicators(float number) {
  // Суть алгоритма. Вывести цифры, но без точки (берем из массива цифр) led_table[]
  // Определить позицию точки из массива с точкой
 
  char bufferNoDot[10];  // Сюда положу цифры без точки
  char buffer[10];  // Здесь будут цифры с точкой
  dtostrf(number, 4, 3, buffer); // Преобразуем число типа float в строку с 3 знаками после запятой
  //dtostrf(number*1000, 4, 0, bufferNoDot); // Число без точки

  // Определяем позицию точки в строке
  int dotPosition = strchr(buffer, '.') - buffer;
  //
  dtostrf(number*pow(10,(4-dotPosition)), 4, 0, bufferNoDot); // получить целое число и положить в массив
  int dotDigit=buffer[dotPosition-1]; // значение цифра за которой идет точка (в конце будет ее выводить)
 
   int startIndex = 0; // Здесь искал незначащие нули впереди( для вывода чисел int)
  while (bufferNoDot[startIndex] == '0') {
    startIndex++;}

  // Отображаем каждую цифру на соответствующем индикаторе из массива без точек bufferNoDot
  for (int i = startIndex; i < 4; ++i) {
    char digit = bufferNoDot[i];
      if (i==dotPosition-1) {dig(dig_n[i], led_table[digit - '0'] & 0xFD);}// Отображаем цифру c точкой
      else {      dig(dig_n[i], led_table[digit - '0']);} // Отображаем цифру
     
  }
  // Когда все цифры выведены Отображаем цифру с точкой ПОВТОРНО
   // dig(dig_n[dotPosition-1], led_table_dot[dotDigit - '0']);

}

Re: 7seg на hc595 4digit

Вс фев 11, 2024 23:35:33

Обычно есть два варианта:
1. сделать удобную для конкретных деталюшек схему, но усложнить создание программы к ней
2. сделать извратную схему, но предельно упростить задачу для программиста...
У нас, к сожалению, первый вариант...
Динамическая индикация предусматривает гашение отображаемой информации на время смены данных (по сегментным или по позиционным ключам). Это нужно для подавления паразитной подсветки дисплея.
Тут же или "холостой цикл" загрузки или игра с управляющими сигналами - оба варианта по самодельному протоколу загрузки данных в регистры делать придется.
Насчет массивов... вполне достаточно одного массива "видеопамяти" в ОЗУ да знакогенератора в ПЗУ с фрагментом программной перекодировки данных. Другое дело, как быть с преобразованием кодов для второго регистра (ключи знакомест + служебные индикаторы) - это уже еще одна дополнительная функция предподготовки данных (опять же "нестандартная"). Ну и сам сканер дисплея на отдельном тайм - интервале (у 328й меги просто, а вот для 8й ... повозиться надо).
"Запятая" это уже наиболее простое из выше перечисленного (особо, ежли имелся ввиду DS18x20).
:roll:
Посмотреть как то для 328й выглядит (с моего представления)... как учебный вариант...
:roll:
Последний раз редактировалось BOB51 Вс фев 11, 2024 23:52:21, всего редактировалось 1 раз.

Re: 7seg на hc595 4digit

Вс фев 11, 2024 23:49:01

BOB51, не к сожалению :)
Извратиться с программой для меня гораздо проще (тем более, что надо-то один раз), чем сверлить лишнее переходное отверстие, поэтому у меня приоритет очень часто отдаётся железяке.
Что же касается всего остального, то тут обычные сдвиговые регистры, и работа с ними ничем не отличается от каких-то иных проектов, хоть к SPI подключить, хоть так, к портам как выше...
Про паразитную подсветку верно. Я не помню, насколько она у меня сильно проявлялась, ток светодиодов достаточно небольшой, вроде, у себя я гашение не делал.
Последний раз редактировалось Martian Пн фев 12, 2024 09:43:40, всего редактировалось 1 раз.

Re: 7seg на hc595 4digit

Пн фев 12, 2024 00:00:49

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

Re: 7seg на hc595 4digit

Пн фев 12, 2024 00:21:33

BOB51, я что-то не улавливаю, чем поможет Z... и только сейчас увидел, что сброс выведен зря - вероятность его использования здесь стремится к нулю :)

Re: 7seg на hc595 4digit

Пн фев 12, 2024 07:45:25

BOB51 писал(а):Динамическая индикация предусматривает гашение отображаемой информации на время смены данных (по сегментным или по позиционным ключам). Это нужно для подавления паразитной подсветки дисплея.
зачем гасить? сначала загнали всю новую информацию в сдвиговые регистры, а потом одним импульсом переписали всё в выходные регистры. и никакой паразитки не будет

Re: 7seg на hc595 4digit

Пн фев 12, 2024 09:01:15

вот попытался поправить код Гайвера, заменил на свои цифры, кстати здесь 2 массива, с точкой и без. А вот где поправить переключение анодов пока не понятно

Спойлер
Код:
/*
  TM74HC595Display.cpp - Library
  Updated by AlexGyver 06.02.2017 (added float_dot and int_dot functions)
*/
 
#include "TM74HC595Display.h"
#include <Arduino.h>

unsigned char _LED_0F[20];
   
TM74HC595Display::TM74HC595Display(int SCLK, int RCLK, int DIO)
{
  pinMode(SCLK, OUTPUT);
  pinMode(RCLK, OUTPUT);
  pinMode(DIO, OUTPUT);
   
  _SCLK = SCLK;
  _RCLK = RCLK;
  _DIO = DIO;
  /*  Оригинальные коды цифр
  _LED_0F[0] = 0xC0; //0
  _LED_0F[1] = 0xF9; //1
  _LED_0F[2] = 0xA4; //2
  _LED_0F[3] = 0xB0; //3
  _LED_0F[4] = 0x99; //4
  _LED_0F[5] = 0x92; //5
  _LED_0F[6] = 0x82; //6
  _LED_0F[7] = 0xF8; //7
  _LED_0F[8] = 0x80; //8
  _LED_0F[9] = 0x90; //9

  _LED_0F[10] = 0b01000000; //.0
  _LED_0F[11] = 0b01111001; //.1
  _LED_0F[12] = 0b00100100; //.2
  _LED_0F[13] = 0b00110000; //.3
  _LED_0F[14] = 0b00011001; //.4
  _LED_0F[15] = 0b00010010; //.5
  _LED_0F[16] = 0b00000010; //.6
  _LED_0F[17] = 0b01111000; //.7
  _LED_0F[18] = 0b00000000; //.8
  _LED_0F[19] = 0b00010000; //.9
  */
  // Далее идут коды цифры устройства от Martian
  _LED_0F[0] = 0b00000110; //0
  _LED_0F[1] = 0b10011111; //1
  _LED_0F[2] = 0b10100010; //2
  _LED_0F[3] = 0b10010010; //3
  _LED_0F[4] = 0b00011011; //4
  _LED_0F[5] = 0b01010010; //5
  _LED_0F[6] = 0b01000010; //6
  _LED_0F[7] = 0b10011110; //7
  _LED_0F[8] = 0b00000010; //8
  _LED_0F[9] = 0b00010010; //9

  _LED_0F[10] = 0b00000100; //.0
  _LED_0F[11] = 0b10011101; //.1
  _LED_0F[12] = 0b10100000; //.2
  _LED_0F[13] = 0b10010000; //.3
  _LED_0F[14] = 0b00011001; //.4
  _LED_0F[15] = 0b01010000; //.5
  _LED_0F[16] = 0b01000000; //.6
  _LED_0F[17] = 0b10011100; //.7
  _LED_0F[18] = 0b00000000; //.8
  _LED_0F[19] = 0b00010000; //.9
 
   clear();
}

void TM74HC595Display::timerIsr()
{
 
  send(_DATA[0]);
  send(0b0001);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH);
  send(_DATA[1]);
  send(0b0010);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH);
  send(_DATA[2]);
  send(0b0100);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH);
  send(_DATA[3]);
  send(0b1000);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH); */

 
}


void TM74HC595Display::send(unsigned char X)
{

  for (int i = 8; i >= 1; i--)
  {
    if (X & 0x80)
    {
      digitalWrite(_DIO, HIGH);
    }
    else
    {
      digitalWrite(_DIO, LOW);
    }
    X <<= 1;
    digitalWrite(_SCLK, LOW);
    digitalWrite(_SCLK, HIGH); 
  }
}

void TM74HC595Display::send(unsigned char X, unsigned char port)
{
  send(X);
  send(port);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH);
}

void TM74HC595Display::digit4(int n, bool showZero)
{
  int n1, n2, n3, n4;
  n1 = (int)  n % 10;
  n2 = (int) ((n % 100)-n1)/10;
  n3 = (int) ((n % 1000) - n2 - n1) / 100;
  n4 = (int) ((n % 10000) - n3 - n2 - n1) / 1000;

   set(_LED_0F[n1], 0);
    if(showZero | n>9)set(_LED_0F[n2], 1);
    if(showZero | n>99)set(_LED_0F[n3], 2);
    if(showZero | n>999)set(_LED_0F[n4], 3);
}

void TM74HC595Display::digit4(int n)
{
  digit4(n,false);
}

void TM74HC595Display::digit4showZero(int n)
{
   digit4(n, true);
}


void TM74HC595Display::digit2(int n, int port)
{
    int n1, n2;
  n1 = (int)  n % 10;
  n2 = (int) ((n % 100)-n1)/10;
 
   set(_LED_0F[n1], port);
   set(_LED_0F[n2], port+1);

}

void TM74HC595Display::set(unsigned char X, int port ){
   _DATA[port] = X;
}

void TM74HC595Display::clear(){
  _DATA[0]= 0xFF;
  _DATA[1]= 0xFF;
  _DATA[2]= 0xFF;
  _DATA[3]= 0xFF;
}

void TM74HC595Display::int_dot(int n, int pos) {
  int n1, n2, n3, n4;
  n1 = (int)  n % 10;
  n2 = (int) ((n % 100) - n1) / 10;
  n3 = (int) ((n % 1000) - n2 - n1) / 100;
  n4 = (int) ((n % 10000) - n3 - n2 - n1) / 1000;

  int dot1 = 0, dot2 = 0, dot3 = 0;
  switch (pos) {
    case 1: dot1 = 10; break;
    case 2: dot2 = 10; break;
    case 3: dot3 = 10; break;
  }

  set(_LED_0F[n1], 0); //вывод
  if (n > 9) set(_LED_0F[n2 + dot1], 1); //вывод
  if (n > 99) set(_LED_0F[n3 + dot2], 2); //вывод
  if (n > 999) set(_LED_0F[n4 + dot3], 3); //вывод
}

void TM74HC595Display::float_dot(float value, int pos) {
  int whole = floor(value);
  int fract = floor(((float)value - whole) * pow(10, pos));

  byte w1, w2, w3, w4;
  w1 = (int) whole % 10;
  w2 = (int) ((whole % 100) - w1) / 10;
  w3 = (int) ((whole % 1000) - w2 - w1) / 100;
  w4 = (int) ((whole % 10000) - w3 - w2 - w1) / 1000;

  byte f1, f2, f3, f4;
  f1 = (int) fract % 10;
  f2 = (int) ((fract % 100) - f1) / 10;
  f3 = (int) ((fract % 1000) - f2 - f1) / 100;
  f4 = (int) ((fract % 10000) - f3 - f2 - f1) / 1000;

  byte n0, n1, n2, n3;
  switch (pos) {
    case 0: n0 = w1; n1 = w2; n2 = w3; n3 = w4;
      break;
    case 1: n0 = f1; n1 = w1 + 10; n2 = w2; n3 = w3;
      break;
    case 2: n0 = f1; n1 = f2; n2 = w1 + 10; n3 = w2;
      break;
    case 3: n0 = f1; n1 = f2; n2 = f3; n3 = w1 + 10;
      break;
  }

  set(_LED_0F[n0], 0);
  if (!(n3 == 0 && n2 == 0 && n1 == 0)) set(_LED_0F[n1], 1);
  if (!(n3 == 0 && n2 == 0)) set(_LED_0F[n2], 2);
  if (n3 != 0) set(_LED_0F[n3], 3);
}


тут есть функция которая толкает байты. Возможно с ней нужно поработать:
Код:
void TM74HC595Display::timerIsr()
{
 
  send(_DATA[0]);
  send(0b0001);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH);
  send(_DATA[1]);
  send(0b0010);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH);
  send(_DATA[2]);
  send(0b0100);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH);
  send(_DATA[3]);
  send(0b1000);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH); */

 
}
Вложения
GyverLibs-TM74HC595_Gyver.zip
библиотека Гайвера в оригинале
(364.43 KiB) Скачиваний: 19

Re: 7seg на hc595 4digit

Пн фев 12, 2024 09:17:57

Starichok51 писал(а):никакой паразитки не будет
будет :)
Причина проста - операция смены сегментов (знак) производится вовсе не одновременно со сменой активного разряда.
Мы можем одномоментно сменить знак, но на крошечную долю времени (до смены разряда, для которой этот новый знак предназначен), на табло будет светиться неверный для разряда знак. Для очень ярких индикаторов и не очень высокой частоты динамики очень даже заметно.
Кстати, протеус у меня вообще какую-то дичь показывал, пока я перед сменой сегментов не выключал все разряды.

Re: 7seg на hc595 4digit

Пн фев 12, 2024 09:49:51

я с этими регистрами не работал, поэтому могу и ошибаться.
но по логике запись в сдвиговые регистры не влияет на выходные регистры.
и у меня протеус валял дурака даже при прямом управлении от МК 4-разрядным 7-сегментником без промежуточного гашения при переключении на другой разряд. ну, это похоже на глюк протеуса.

Re: 7seg на hc595 4digit

Пн фев 12, 2024 09:56:33

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

Starichok51 писал(а):запись в сдвиговые регистры не влияет на выходные регистры.
Именно так.

Re: 7seg на hc595 4digit

Пн фев 12, 2024 11:39:41

BOB51, я что-то не улавливаю, чем поможет Z... и только сейчас увидел, что сброс выведен зря - вероятность его использования здесь стремится к нулю :)

Если бы активным уровнем что у сегментов, что у позиционных ключей был 0 (при принудительной блокировке их единицей), то перевод в Z-состояние однозначно блокировал бы индикацию. Собственно так дело с позиционными ключами на схеме. Да и сегменты от утечки по Z вряд-ли засветятся.
Относительно функционала перезаписи - он то почти одновременный, но время задержки включения и отключения как у транзисторных ключей, так и у светиков имеется. Возможно особо заметно подсвечивать не будет - но то на конкретной железяке проверять надо. В том числе и на конечном варианте (фон, светофильтр).
:roll:

Re: 7seg на hc595 4digit

Пн фев 12, 2024 12:09:41

Да, но всё равно ведь потребуется действие - перевод в Z, и на это сожрётся нога мк, что не всегда хорошо... Фактически, мы потратим вывод ради очень небольшого выигрыша в программе, если вообще будет выигрыш.

Re: 7seg на hc595 4digit

Пн фев 12, 2024 15:06:58

Тут уже что удобнее - или лишний цикл загрузки (расход времени) или лишняя лапка - расход выводов.
Да и с Z-состоянием можно без линии сброса обойтись (и случайного "все нули" при подаче питания избегаем)...
Пока морочу с тем, что уже нарисовано набросок прожки. Для начала примитив - там надо с видеопамятью погдядеть...
:roll: :write:

Re: 7seg на hc595 4digit

Вт фев 13, 2024 04:13:32

Я сталкивался с "паразиткой" с ключами на ULN и на полевых транзисторах. Решил так: на сегменты и на общие подавал неактивный уровень. Время подбирал, пока засветка не исчезнет. Алгоритм: заходим, ставим неактивный уровень, задержка, вывод нужных значений.

Re: 7seg на hc595 4digit

Вт фев 13, 2024 14:03:40

пытаюсь переделать код Gyver, уперся в выводы на сегменты.Вот код функции :
Код:
void TM74HC595Display::timerIsr()
{
  send(_DATA[0]);
  send(0b0001);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH);
  send(_DATA[1]);
  send(0b0010);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH);
  send(_DATA[2]);
  send(0b0100);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH);
  send(_DATA[3]);
  send(0b1000);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH);
}

и вот схема к которой, по всей вероятности применяется этот код (там зайдествованы выводы DA DB DC DD

Изображение

вот здесь уже схема Martian, где зайдествованы выводы DE DF DG DH
Изображение

Как привязать эти выводы в данном коде. Или может я еще чего-то не вижу или не учитываю

Re: 7seg на hc595 4digit

Вт фев 13, 2024 15:17:53

динамическая индикация...
фу... фу.. фу...
в глазах рябит))
:o
лучше добавить к LED индикатору буфер... типа D-триггер... и писать в буфер...
и добавить отдельный вывод "С" (запись в буфер)...
будет статическая индикация.
для глаз приятно))
:)
Ответить