А ну-ка вот этот еще код опробуй (попробуем всё-таки в одну ардуину “уложиться”
) :
#include <TM1637.h>
// Определяем пины для подключения дисплея TM1637
#define CLK 8
#define DIO 9
#define wheel_len 240
#define pt_pin A0
#define out1_pin 2
#define out2_pin 3
#define timeout 500
uint32_t tick_delay, FREQ = 5500; //rpm
uint32_t pt, mill;
volatile uint8_t index = 0;
// Создаем объект дисплея TM1637
TM1637 tm1637(CLK, DIO);
const char Table1[wheel_len] = {
0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
};
void setup() {
cli(); // Запрещаем прерывания
DDRD |= (1 << PD2);
DDRD |= (1 << PD3);
PORTD &= ~(1 << PD2);
PORTD &= ~(1 << PD3);
// Настройка режима CTC Timer1
TCCR1A &= ~((1 << WGM10) | (1 << WGM11));
TCCR1B &= ~((1 << WGM13));
TCCR1B |= (1 << WGM12);
// Настройка предделителя на 8 Timer1
TCCR1B |= (1 << CS11);
TCCR1B &= ~((1 << CS12) | (1 << CS10));
// Разрешаем прерывание по совпадению с OCR1A
TIMSK1 |= (1 << OCIE1A);
pt = analogRead(pt_pin);
FREQ = map(pt, 0, 1024, 300, 5500);
// Устанавливаем значение для сравнения
tick_delay = ((120000000UL / FREQ) / wheel_len) * 2;
OCR1A = tick_delay;
// Глобально разрешаем прерывания
sei();
}
void loop() {
if (millis() - mill > timeout) {
mill = millis();
pt = analogRead(pt_pin);
FREQ = map(pt, 0, 1024, 300, 5500);
tick_delay = ((120000000UL / FREQ) / wheel_len) * 2;
OCR1A = tick_delay;
// Разбиваем на отдельные цифры
int8_t digits[] = {0, 0, 0, 0};
digits[0] = FREQ / 1000; // тысячи (десятки км/ч)
digits[1] = (FREQ / 100) % 10; // сотни (единицы км/ч)
digits[2] = (FREQ / 10) % 10; // десятки (десятые км/ч)
digits[3] = FREQ % 10; // единицы (сотые км/ч)
// Отображаем скорость на дисплее
tm1637.point(false);
tm1637.display(0, digits[0]);
tm1637.point(false);
tm1637.display(1, digits[1]);
tm1637.point(false); // Включаем точку для разделения целой и дробной части
tm1637.display(2, digits[2]);
tm1637.point(false);
tm1637.display(3, digits[3]);
}
}
ISR(TIMER1_COMPA_vect) {
if (Table1[index] == 0) {
PORTD &= ~(1 << PD2);
PORTD |= (1 << PD3);
} else {
PORTD |= (1 << PD2);
PORTD &= ~(1 << PD3);
}
if (index++ >= wheel_len) {
index = 0;
}
}
Должен работать “как слива в ж…” (ну ты понял).
Генерацию я у себя проверил - идет. ТМ1637 у меня нет.
Но, конечно же, нужно с оборудованием проверить.
Работает по другому принципу - на прерывании Timer1 (16 бит). А значит генерации импульсов ничто из главного цикла (loop()) помешать не может )))
Мои данные компиляции (у меня Arduino Nano v2 на Atmega168):
Скетч использует 2450 байт (17%) памяти устройства. Всего доступно 14336 байт.
Глобальные переменные используют 370 байт (36%) динамической памяти, оставляя 654 байт для локальных переменных. Максимум: 1024 байт.