7seg на hc595 4digit

Обсуждаем контроллеры компании Atmel.
Ответить
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32

Сообщение Martian »

схема не соответствует коду

изменение:

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

void TM74HC595Display::timerIsr()
{
  send(0x70);
  send(_DATA[0]);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH);
  send(0xd0);
  send(_DATA[1]);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH);
  send(0xb0);
  send(_DATA[2]);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH);
  send(0xe0);
  send(_DATA[3]);
  digitalWrite(_RCLK, LOW);
  digitalWrite(_RCLK, HIGH);
}
я думал, там какая-то волшебная библиотека, но увы, там ардуино прям так и лезет...

Добавлено after 13 minutes 35 seconds:
ох, там ещё и в send() сдвиг влево...

подправил.
Возможно, порядок разрядов нарушен, тогда поменять местами 0x70 и 0xe0, 0xd0 и 0xb0
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3793
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

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

Сообщение BOB51 »

Схемы с динамической индикацией на том же кристалле, что выполняет и сновную программу да еще под Си в ардуино шатука очень неблагодарная.
Но зато чисто "из спортивного интереса" полезная для тренировки мозга.
В принципе... для АВРок под ассемблером вторым независимым потоком вполне удачно решаемая задача даже на аттини 2313. Но "в рамках референса" ардуино и при такой схеме... Надо еще извернуться, чтоб красиво работало.
8)
С применением спецконтроллеров конечно много проще опрос решается.
8)
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32

Сообщение Martian »

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

Что же касается I2C, то не стоит забывать, что его реализация далеко не пару строк кода занимает. Рискну утверждать, что такой дисплей с I2C будет выгоден/удобен только если I2C уже используется, или жизненно важно обойтись двумя лапами.
Кроме того, как уже говорил выше, 595-ый можно считать примитивным спецконтроллером для SPI. Работа с SPI значительно проще, чем c I2C.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Сообщения: 1943
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария

Сообщение veso74 »

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

Сообщение Ser60 »

[uquote="Martian",url="/forum/viewtopic.php?p=4542990#p4542990"]Работа с SPI значительно проще, чем c I2C.[/uquote]Я так не сказал-бы. У каждого производителя в его среде разработки имеются (или должны иметься?) библиотеки работы с обоими интерфейсами для их семейства микроконтроллеров и программировать их заново не требуется. С этой точки зрения пересылка массива байтов из одного устройства в другое сводится буквально к 1 строчке кода на С.
Реклама
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32

Сообщение Martian »

Это для высокоуровневого программиста одна строчка кода, а у меня 8 кБ флэш
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 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 КБ) 66 скачиваний
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32

Сообщение Martian »

[uquote="olegue",url="/forum/viewtopic.php?p=4543054#p4543054"]И пришлось еще устранить одно необъяснимое явление. Пришлось unsigned char const led_table[] = {0x06,0x9f,0xa2,0x92,0x1b,0x52,0x42,0x9e,0x02,0x12} отобразить зеркально.[/uquote] Это потому что в этой библиотеке сдвиг байта налево используется, а у меня направо
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 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 байт.
Друг Кота
Сообщения: 9446
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

olegue писал(а):ардуинка на Атмега8 уже показывает температуру...
простейший вариант - добавить вторую ардуину на Атмега8... и пачку резисторов... и больше ничего не нужно))
остальноё всё делается программно...
но мы же не ищем лёгких путей))
:tea:
[uquote="roman.com",url="/forum/viewtopic.php?p=4542905#p4542905"]лучше добавить к LED индикатору буфер... типа D-триггер... и писать в буфер...[/uquote]
простейший D-триггер... любителем рассыпухи... и сложных путей))
Screenshot_1.jpg
(5.36 КБ) 62 скачивания
:))
Друг Кота
Аватара пользователя
Сообщения: 15734
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Нацарапал прожку с "движком" на прерывании и примитив-тестом (для ардуино-нано на меге328)...
К сожалению НЕ ПРОВЕРЕНО на железе (т.е. возможны и ошибки, особенно в позиционных номерах выходных линий регистров). Исходил из предположения, что время исполнения функции shiftOut (по Гайверу) равно 117 микросекунд...
После компиляции:
"Скетч использует 1846 байт (6%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 46 байт (2%) динамической памяти, оставляя 2002 байт для локальных переменных. Максимум: 2048 байт."...
disp4a.zip
(4.14 КБ) 69 скачиваний
:roll:
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

BOB51,


Изображение Изображение


бежит счетчит, только вот 0 незначащий не рисует, может так и задумывалось?

Добавлено after 5 minutes 6 seconds:
Изображение


и на Атмеге8 не хочет работать, нет регистра
disp4a:180:29: error: 'OCIE0A' was not declared in this scope
OCR0A = 100; TIMSK0 |= (1<<OCIE0A);
^~~~~~
C:\Users\KDFX Modes\AppData\Local\Temp\Rar$DIa7032.24454\disp4a\disp4a.ino:180:29: note: suggested alternative: 'OCIE1A'
OCR0A = 100; TIMSK0 |= (1<<OCIE0A);
^~~~~~
OCIE1A
exit status 1
'OCR0A' was not declared in this scope
Можно сделать универсально?
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32

Сообщение Martian »

а разве byte znak(byte tetr) менее затратно, чем работа с массивом?

мне пришёл в голову варварский вариант: создаём массив со всеми возможными числами в диапазоне 0...9999 (включая варианты с одной и двумя цифрами после запятой), а потом просто обращаемся: crazy_total_array_7seg[value]; и всё, никаких конвертаций, очень быстро :)
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 15734
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

А во втором разряде другие циферки высвечиваются?
Там по тесту счетчик от 0 до 9999 - должны все цифирьки на табло высвечиваться.
Частота регенерации 62,5 Гц.
:roll:
Насчет массива и знакогенератора - там всего-то 16 позиций. Добавлять progmem смысла нету - "кейсы" по такому же принципу работают.
Однако ежли там будут не только 0-F, то уже надо без зкогенератора обходиться - это уже "часть теста"(прикладной программы) решать должна.
8)
Чуток тестовый фрагмент подправил (на скору руку)
disp4a.zip
(4.15 КБ) 69 скачиваний
:roll:
Последний раз редактировалось BOB51 Ср фев 14, 2024 20:32:34, всего редактировалось 1 раз.
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

[uquote="BOB51",url="/forum/viewtopic.php?p=4543511#p4543511"]А во втором разряде другие циферки высвечиваются?[/uquote]
конечно, все ок, кроме нулей
Друг Кота
Аватара пользователя
Сообщения: 15734
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Нулями заведует фрагмент теста (преобразование из двоичного в двоично-десятичный):
Спойлер

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

// обработка текущего значения Dcnt и
  // вывод двоично-десятичных значений в массив TrmDat
 temp = Dcnt;
 if (temp == 0)
  { for (byte m = 0; m <= 3; m++){ TrmDat[m] = fnt_0; } }
 else 
  { if (temp >= 1000)
     { TrmDat[0] = temp / 1000; temp = temp % 1000; }
    else if(temp < 1000){ TrmDat[0] = fnt_0; }
    if (temp >= 100)
     { TrmDat[1] = temp / 100; temp = temp % 100; }
    else if(temp < 100){ TrmDat[1] = fnt_0; }
    if (temp >= 10)
     { TrmDat[2] = temp / 10; temp = temp % 10; }
    else if(temp < 10){ TrmDat[2] = fnt_0; }
    TrmDat[3] = temp;
  }
  // перекодировка в сегментный код
  for (byte m = 0; m <= 3; m++)
   { TrmDat[m] = znak(TrmDat[m]); }
  // если флаг запроса сброшен
  // выставить флаг запроса на обноление данных на индикаторе
  if (!QtVrLd){ QtVrLd = 1; }
  // выждать время удержания изображения
  delay (200);
  // приращение демосчетчика Dcnt
  Dcnt++;
  if (Dcnt >= 10000){ Dcnt = 0; }
}
Это уже подправленный вариант.
:roll:
Насчет фокуса с прерыванием по OCR0A - Это поддерживается в 48й, 88й и 328й мегах.
Есть и другой вариант - через TONE и INT1/INT0.
Или смотрим начинку МК и не задействованный в основной программе таймер (функции ШИМ и чего еще может быть). надо вчитываться в документацию и по МК и по IDE...
Друг Кота
Аватара пользователя
Сообщения: 3793
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

BOB51 - а ради интереса, можете проверить сколько места занимает библиотечная (или какая иная) реализация I2C протокола ориентированная на аппаратный драйвер (т.е., без "ногодрыга") на таком МК?
Друг Кота
Аватара пользователя
Сообщения: 15734
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Библиотеки ориентированы на аппаратные модули с жесткой привязкой к выводам МК.
А вот shiftIn/shiftOut - это встроенные программной реализации функции, работающие с любыми цифровыми выводами МК (по сути вариант протокола SPI).
Касательно библиотек I2C и SPI - я ими пока не пользовался (из-за неудобства по разводке выводов и оставил для тех устройств, где применение оправдано/обязательно) ... Делал только собственный вариант программного I2C для RTC да использовал часть библиотеки OneWire и Adafruit_NeoPixel - их не обойти (быстродействие).
Может когда посмотрю чего там...
:roll:
Кстати... Можете на сайте у Гайвера (https://alexgyver.ru/lessons/)обзоры глянуть - там попадаются довольно неплохие описания и характеристики функционала IDE в дополнение к "референсу" (https://docs.arduino.cc/programming/)...
8)
Собутыльник Кота
Аватара пользователя
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Сообщение olegue »

[uquote="BOB51",url="/forum/viewtopic.php?p=4543525#p4543525"]Нулями заведует фрагмент теста (преобразование из двоичного в двоично-десятичный):
Спойлер

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

// обработка текущего значения Dcnt и
  // вывод двоично-десятичных значений в массив TrmDat
 temp = Dcnt;
 if (temp == 0)
  { for (byte m = 0; m <= 3; m++){ TrmDat[m] = fnt_0; } }
 else 
  { if (temp >= 1000)
     { TrmDat[0] = temp / 1000; temp = temp % 1000; }
    else if(temp < 1000){ TrmDat[0] = fnt_0; }
    if (temp >= 100)
     { TrmDat[1] = temp / 100; temp = temp % 100; }
    else if(temp < 100){ TrmDat[1] = fnt_0; }
    if (temp >= 10)
     { TrmDat[2] = temp / 10; temp = temp % 10; }
    else if(temp < 10){ TrmDat[2] = fnt_0; }
    TrmDat[3] = temp;
  }
  // перекодировка в сегментный код
  for (byte m = 0; m <= 3; m++)
   { TrmDat[m] = znak(TrmDat[m]); }
  // если флаг запроса сброшен
  // выставить флаг запроса на обноление данных на индикаторе
  if (!QtVrLd){ QtVrLd = 1; }
  // выждать время удержания изображения
  delay (200);
  // приращение демосчетчика Dcnt
  Dcnt++;
  if (Dcnt >= 10000){ Dcnt = 0; }
}
Это уже подправленный вариант.
:roll:[/uquote]

Не помогло. Все на месте. Нулей нет.

Добавлено after 20 minutes 3 seconds:
[uquote="Ser60",url="/forum/viewtopic.php?p=4543539#p4543539"]BOB51 - а ради интереса, можете проверить сколько места занимает библиотечная (или какая иная) реализация I2C протокола ориентированная на аппаратный драйвер (т.е., без "ногодрыга") на таком МК?[/uquote]

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

#include <OneWire.h>
/*------------------------------------------------*/
#define ONE_WIRE_BUS 4 // вывод, к которому подключён DS18B20
OneWire oneWire(ONE_WIRE_BUS);
void setup(){}
void loop(){}

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

Скетч использует 2068 байт (6%) памяти устройства. Всего доступно 32384 байт.
Глобальные переменные используют 46 байт (2%) динамической памяти, оставляя 2002 байт для локальных переменных. Максимум: 2048 байт.
Добавлено after 6 minutes 26 seconds:
[uquote="BOB51",url="/forum/viewtopic.php?p=4543525#p4543525"]Насчет фокуса с прерыванием по OCR0A - Это поддерживается в 48й, 88й и 328й мегах.
Есть и другой вариант - через TONE и INT1/INT0.
Или смотрим начинку МК и не задействованный в основной программе таймер (функции ШИМ и чего еще может быть). надо вчитываться в документацию и по МК и по IDE...[/uquote]

У гайвера на micros() сделано:

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

#include <GyverNTC.h>
GyverNTC therm(0, 10000, 3950);
//---- ПИНЫ ----
byte SCLK = 7;
byte RCLK = 6;
byte DIO = 5;
//---- ПИНЫ ----

#include <TM74HC595Display.h>
#include <TimerOne.h>
TM74HC595Display disp(SCLK, RCLK, DIO);
unsigned char SYM[18];
unsigned long dispIsrTimer, countTimer;
float value = 0.0;

void setup() {
  
}

void loop() {
  if (millis() - countTimer > 1000) {   // каждые 50 миллисекунд ("прозрачный" аналог delay)
    value += 0.01;                    // прибавить 0.01
  
  disp.float_dot(therm.getTemp(),1);
    countTimer = millis();            // сбросить таймер
  }

  disp_isr();                         // динамическая индикация
}

void disp_isr() {
  if (micros() - dispIsrTimer > 300) {       // таймер динамической индикации (по-русски: КОСТЫЛЬ!)
    disp.timerIsr();                         // "пнуть" дисплей
    dispIsrTimer = micros();                 // сбросить таймер
  }
}
void disp_isr() {
if (micros() - dispIsrTimer > 300) { // таймер динамической индикации (по-русски: КОСТЫЛЬ!)
disp.timerIsr(); // "пнуть" дисплей
dispIsrTimer = micros(); // сбросить таймер
}
Ответить

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