Вс фев 11, 2024 20:14:18
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']);
}
Вс фев 11, 2024 20:42:03
цифры {0x06,0x9f,0xa2,0x92,0x1b,0x52,0x42,0x9e,0x02,0x12}
и разряды {0xf7,0xfd,0xfb,0xfe}
dig(dig_n[i], led_table[digit - '0'] & 0xFD); // Отображаем цифру
dig(dig_n[i], led_table[digit - '0'] & (dig_dot == i ? 0xFD : 0xFF)); // Отображаем цифру
Вс фев 11, 2024 21:01:28
Вс фев 11, 2024 21:03:33
void displayFloatOnIndicators(float number)
unsigned char buffer_indicator[4]; // "память дисплея"
...
void displayFloatOnIndicators()
{
for (int i = 0; i < 4; i++)
{
dig(dig_n[i], buffer_indicator[i]); // Отображаем цифру
}
}
Вс фев 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']);
}
Вс фев 11, 2024 23:35:33
Вс фев 11, 2024 23:49:01
Пн фев 12, 2024 00:00:49
Пн фев 12, 2024 00:21:33
Пн фев 12, 2024 07:45:25
зачем гасить? сначала загнали всю новую информацию в сдвиговые регистры, а потом одним импульсом переписали всё в выходные регистры. и никакой паразитки не будетBOB51 писал(а):Динамическая индикация предусматривает гашение отображаемой информации на время смены данных (по сегментным или по позиционным ключам). Это нужно для подавления паразитной подсветки дисплея.
Пн фев 12, 2024 09:01:15
/*
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); */
}
Пн фев 12, 2024 09:17:57
будетStarichok51 писал(а):никакой паразитки не будет
Пн фев 12, 2024 09:49:51
Пн фев 12, 2024 09:56:33
Именно так.Starichok51 писал(а):запись в сдвиговые регистры не влияет на выходные регистры.
Пн фев 12, 2024 11:39:41
Пн фев 12, 2024 12:09:41
Пн фев 12, 2024 15:06:58
Вт фев 13, 2024 04:13:32
Вт фев 13, 2024 14:03:40
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);
}
Вт фев 13, 2024 15:17:53