7seg на hc595 4digit

Обсуждаем контроллеры компании Atmel.
Ответить
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

Коллега Martian, с нашего форуму прислал мне платы на hc595 и индикаторы к ним.
ИзображениеНу вот не прошло и пару лет как мне захотелось собрать на них что-то полезное.
К сожалению, разводка индикаторов оказалась нескольько другой чем известные на алике аналоги, например, Tm74hc595. Но Martian так же прислал схему с примером для АВР где были указаны шестнадцатиричные коды цифр.
7seg-2.pdf
(301.86 КБ) 143 скачивания
Мне не удалось переделать библиотеку 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']); 

}


Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

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

Изображение

Добавлено after 1 minute 56 seconds:
идеально было бы конечно изменить библиотеку Гайвер, по моему, там можно даже бегущую строк замутить.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

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

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

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']); 

}

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

Сообщение BOB51 »

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

Сообщение BOB51 »

Вот в той "паразитке" и основное отличие от аппаратного SPI.
А поскольку управляющие линии регистров общие для обеих корпусов (и Z-состояние мы в схеме не используем) придется пойти на дополнительный изврат.
"паразитка" может не всегда слишком явно проявляться - но на нерву через время таки действует.
В принципе... Для начала скотчик обработчика с транспортным протоколом сделать надо. А уж затем его или в отдельный файл или библиотекой оформить.
Ежли не особо спешно - вполне можно поучаствовать...
8)
Реклама
Модератор
Аватара пользователя
Сообщения: 19101
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

BOB51 писал(а):Динамическая индикация предусматривает гашение отображаемой информации на время смены данных (по сегментным или по позиционным ключам). Это нужно для подавления паразитной подсветки дисплея.
зачем гасить? сначала загнали всю новую информацию в сдвиговые регистры, а потом одним импульсом переписали всё в выходные регистры. и никакой паразитки не будет
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

вот попытался поправить код Гайвера, заменил на свои цифры, кстати здесь 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 КБ) 112 скачиваний
Вымогатель припоя
Сообщения: 602
Зарегистрирован: Ср янв 06, 2010 10:01:46

Сообщение metan »

Starichok51 писал(а):никакой паразитки не будет
будет :)
Причина проста - операция смены сегментов (знак) производится вовсе не одновременно со сменой активного разряда.
Мы можем одномоментно сменить знак, но на крошечную долю времени (до смены разряда, для которой этот новый знак предназначен), на табло будет светиться неверный для разряда знак. Для очень ярких индикаторов и не очень высокой частоты динамики очень даже заметно.
Кстати, протеус у меня вообще какую-то дичь показывал, пока я перед сменой сегментов не выключал все разряды.
Модератор
Аватара пользователя
Сообщения: 19101
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

я с этими регистрами не работал, поэтому могу и ошибаться.
но по логике запись в сдвиговые регистры не влияет на выходные регистры.
и у меня протеус валял дурака даже при прямом управлении от МК 4-разрядным 7-сегментником без промежуточного гашения при переключении на другой разряд. ну, это похоже на глюк протеуса.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Друг Кота
Аватара пользователя
Сообщения: 15791
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

[uquote="Martian",url="/forum/viewtopic.php?p=4542165#p4542165"]BOB51, я что-то не улавливаю, чем поможет Z... и только сейчас увидел, что сброс выведен зря - вероятность его использования здесь стремится к нулю :)[/uquote]
Если бы активным уровнем что у сегментов, что у позиционных ключей был 0 (при принудительной блокировке их единицей), то перевод в Z-состояние однозначно блокировал бы индикацию. Собственно так дело с позиционными ключами на схеме. Да и сегменты от утечки по Z вряд-ли засветятся.
Относительно функционала перезаписи - он то почти одновременный, но время задержки включения и отключения как у транзисторных ключей, так и у светиков имеется. Возможно особо заметно подсвечивать не будет - но то на конкретной железяке проверять надо. В том числе и на конечном варианте (фон, светофильтр).
:roll:
Друг Кота
Аватара пользователя
Сообщения: 15791
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Тут уже что удобнее - или лишний цикл загрузки (расход времени) или лишняя лапка - расход выводов.
Да и с Z-состоянием можно без линии сброса обойтись (и случайного "все нули" при подаче питания избегаем)...
Пока морочу с тем, что уже нарисовано набросок прожки. Для начала примитив - там надо с видеопамятью погдядеть...
:roll: :write:
Это не хвост, это антенна
Сообщения: 1495
Зарегистрирован: Ср июн 25, 2008 15:19:44

Сообщение Demiurg »

Я сталкивался с "паразиткой" с ключами на ULN и на полевых транзисторах. Решил так: на сегменты и на общие подавал неактивный уровень. Время подбирал, пока засветка не исчезнет. Алгоритм: заходим, ставим неактивный уровень, задержка, вывод нужных значений.
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

пытаюсь переделать код 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
Изображение

Как привязать эти выводы в данном коде. Или может я еще чего-то не вижу или не учитываю
Друг Кота
Сообщения: 9589
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Сообщение roman.com »

динамическая индикация...
фу... фу.. фу...
в глазах рябит))
:o
лучше добавить к LED индикатору буфер... типа D-триггер... и писать в буфер...
и добавить отдельный вывод "С" (запись в буфер)...
будет статическая индикация.
для глаз приятно))
:)
Друг Кота
Аватара пользователя
Сообщения: 3794
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

olegue - я понимаю, что сейчас Вы хотите задействовать имеющиеся в наличии детали. Тем не менее, советую посмотреть на 4-сегментные дисплеи с аппаратным драйвером на борту и I2C интерфейсом с МК типа, например, типа таких или таких. Большинство (если не все) обсуждаемые здесь Ваши проблемы, связанные с динамической индикацией, снимутся.
Друг Кота
Аватара пользователя
Сообщения: 15791
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Схемы с динамической индикацией на том же кристалле, что выполняет и сновную программу да еще под Си в ардуино шатука очень неблагодарная.
Но зато чисто "из спортивного интереса" полезная для тренировки мозга.
В принципе... для АВРок под ассемблером вторым независимым потоком вполне удачно решаемая задача даже на аттини 2313. Но "в рамках референса" ардуино и при такой схеме... Надо еще извернуться, чтоб красиво работало.
8)
С применением спецконтроллеров конечно много проще опрос решается.
8)
Поставщик валерьянки для Кота
Сообщения: 1974
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария

Сообщение veso74 »

olegue, платы изготовлены, красивые, индикаторы установлены, схема подключения есть. Подключите один индикатор, выберите схему подключения (аппаратный SPI, программный SPI) и пишите код. Это не так уж и сложно. Никаких роботов и внешних библиотек не требуется. Сначала с бумагой и карандашом: какой сигнал кем обнаруживается, в какое время, как они передаются через 74HC595 и т. д. Разбейте все решение будущего устройства на небольшие шаги, которые будете реализовывать по одному. Интересно все, собенно если пишете код самостоятельно. По ходу дела многое станет ясно.
Последний раз редактировалось veso74 Вт фев 13, 2024 20:31:37, всего редактировалось 1 раз.
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3794
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

[uquote="Martian",url="/forum/viewtopic.php?p=4542990#p4542990"]Работа с SPI значительно проще, чем c I2C.[/uquote]Я так не сказал-бы. У каждого производителя в его среде разработки имеются (или должны иметься?) библиотеки работы с обоими интерфейсами для их семейства микроконтроллеров и программировать их заново не требуется. С этой точки зрения пересылка массива байтов из одного устройства в другое сводится буквально к 1 строчке кода на С.
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

[uquote="Martian",url="/forum/viewtopic.php?p=4542910#p4542910"]подправил.
Возможно, порядок разрядов нарушен, тогда поменять местами 0x70 и 0xe0, 0xd0 и 0xb0[/uquote]

КонГениально! Так и есть! Порядок разрядов поменял на противоположный. И пришлось еще устранить одно необъяснимое явление. Пришлось unsigned char const led_table[] = {0x06,0x9f,0xa2,0x92,0x1b,0x52,0x42,0x9e,0x02,0x12} отобразить зеркально. Те добавил в библиотеку еще функцию
unsigned char TM74HC595Display::mirrorNumber(unsigned char number) {
unsigned char mirrored_number = 0; // переменная для хранения зеркального числа

// Проходим по каждому биту исходного числа и сдвигаем его влево, добавляя его к зеркальному числу
for (int i = 0; i < 8; ++i) {
mirrored_number <<= 1; // сдвигаем текущее зеркальное число на один бит влево
mirrored_number |= (number & 1); // добавляем младший бит исходного числа к зеркальному числу
number >>= 1; // сдвигаем исходное число на один бит вправо для обработки следующего бита
}

return mirrored_number; // возвращаем зеркальное число
}
В итоге сейчас доступны все функции библиотеки Гайвера на Вашем дисплее!
Вложения
TM74HC595_Gyver_Martian.zip
Библиотека Гайвера для дисплея Martian
(8.79 КБ) 73 скачивания
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

[uquote="Martian",url="/forum/viewtopic.php?p=4543078#p4543078"]Это потому что в этой библиотеке сдвиг байта налево используется, а у меня направо[/uquote]
Эта курьезный момент остановил меня не более чем на час.
В любом случае ардуинка на Атмега8 уже показывает температуру.

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

Скетч использует 3380 байт (43%) памяти устройства. Всего доступно 7808 байт.
Глобальные переменные используют 68 байт (6%) динамической памяти, оставляя 956 байт для локальных переменных. Максимум: 1024 байт.
Ответить

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