diff options
| author | vlapa <vlapa@ya.ru> | 2026-06-13 18:00:20 +0300 |
|---|---|---|
| committer | vlapa <vlapa@ya.ru> | 2026-06-13 18:00:20 +0300 |
| commit | 313fc4f591e59219382bc8a302b7b07e8dbaf918 (patch) | |
| tree | b6792694af032097f9dd2d7134a96e56cc78c9a9 | |
Firstmain
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | description | bin | 0 -> 64 bytes | |||
| -rw-r--r-- | platformio.ini | 19 | ||||
| -rw-r--r-- | src/main.cpp | 337 | ||||
| -rw-r--r-- | src/pin.cpp | 44 | ||||
| -rw-r--r-- | src/pin.h | 64 | ||||
| -rw-r--r-- | sync | 20 |
7 files changed, 486 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3b8da3a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.pio +.vscode
\ No newline at end of file diff --git a/description b/description Binary files differnew file mode 100644 index 0000000..2f3be81 --- /dev/null +++ b/description diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..93b1a58 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,19 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:attiny2313] +platform = atmelavr +board = attiny2313 +framework = arduino + +upload_speed = 115200 +monitor_speed = 115200 + +upload_protocol = usbasp
\ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..ab09cd5 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,337 @@ +/* =============================================== + Тахометр-мотометр - мои изыскания + 20250108 ... 20250206 + v.041 + + tiny2313, 16MHz, Общий Катод - ОК + + = FUSES = Low - 0xFF; High - 0xDB; Ext - 0xFF + +================================================== */ + +#include <avr/interrupt.h> +#include <util/delay.h> +#include <avr/eeprom.h> +#include <avr/wdt.h> +#include "pin.h" + +// ======================================= +// ОПРЕДЕЛЯЕМ КОНСТАНТЫ: +#define F_QUARTZ 16000000UL // частота кварца +#define DIVIDER 64 // делитель таймера T1, задается в инициализации Т1 +#define PART_SEC 60000000 / (1000000 / (F_QUARTZ / DIVIDER)) // часть секунды (для пересчета оборотов) + +// Количество импульсов на 1 оборот коленвала: +#define REV_RATED_POWER 3600 // обороты при номинальной мощности (введите свои) +#define COUNT_PULSE 1 // 4 - импульса на оборот; 2 - 2 импульса; 1 - 1 импульс + +// 8ми сегментный 4х разрядный индикатор: +#define LEVEL 0 // (1) - Общий Анод, (0) - Общий Катод +#define RAZR 4 // количество разрядов индикатора +#define BRIGHT 0x7F // яркость свечения сегментов (больше значение - ярче) + +// Минимальный учетный интервал Моточасов: +#define TIME 3600 // 3600=1минута; 216000=1час (60 * 60 * 60 (1сек * 1мин * 1час) +#define MEM_CELL 8 // начальная ячейка памяти в которой будут храниться моточасы +#define MEANING 0x0A0A0A0A // контрольное слово для проверки памяти +#define DELAY_VISIBLE 100 // пауза для визуального отображения +#define KOEFF 3 // коэффициент усреднения +#define TIME_RESET_MOTO 5000 // задержка сброса моточасов + +// ======================================= +// Рабочие переменные: +// Отображаемые на индикаторе символы: +uint8_t seg[19] = { + 0b11111100, // 0 + 0b01100000, // 1 + 0b11011010, // 2 + 0b11110010, // 3 + 0b01100110, // 4 + 0b10110110, // 5 + 0b10111110, // 6 + 0b11100000, // 7 + 0b11111110, // 8 + 0b11110110, // 9 + 0b11101110, // A + 0b00111110, // B + 0b00011010, // C + 0b01111010, // D + 0b10011110, // E + 0b10001110, // F + 0b00000000, // 16 - пусто + 0b00000010, // 17 - минус + 0b11000110, // 18 - градус +}; +uint8_t data[RAZR]; // ячейки данных разрядов индикатора +uint32_t countMoto = 0; // счетчик моточасов (накопитель оборотов) +uint16_t temp = 0; // счетчик оборотов +bool flagRev = false; // флаг для индикации +bool flagDot = false; // флаг для отображения точки в моточасах +uint16_t revOld = 0; // предыдущие обороты двигателя +uint32_t myMillis = 0; // счетчик миллисекунд +uint32_t myMillisOld = 0; // старый счетчик миллисекунд + +// ################################################################ +// Усредняем показания оборотов: +uint16_t filtr(uint16_t rev) +{ + static uint8_t a = pow(2, KOEFF) - 1; + (revOld > rev / KOEFF) ? revOld = (a * revOld + rev) >> KOEFF : revOld = rev; + return revOld; +} + +//================================================================ +// Инициализация прерываний: +void INTERRUPT_Init() +{ + // Инициализация T0: + TCCR0B |= (1 << CS01) | (1 << CS00); // делитель = 64 + OCR0A = BRIGHT; + OCR0B = 250; + TIMSK |= (1 << TOIE0) | (1 << OCIE0A); + // Инициализация T1: + TCCR1B |= (1 << CS11) | (1 << CS10); // делитель = 64 + // Инициализация INT0: + MCUCR |= (1 << ISC01) | (1 << ISC00); //-по фронту//(1 << ISC01);//-по спаду // + GIMSK |= (1 << INT0); +} + +//================================================================ +// Включение сегментов: +void segWork(uint8_t sTem) +{ + uint8_t segments = seg[sTem]; + (LEVEL) ? segments = ~segments : segments = segments; + (segments & (1 << 7)) ? PORT_A |= (1 << SEG_A) : PORT_A &= ~(1 << SEG_A); + (segments & (1 << 6)) ? PORT_B |= (1 << SEG_B) : PORT_B &= ~(1 << SEG_B); + (segments & (1 << 5)) ? PORT_C |= (1 << SEG_C) : PORT_C &= ~(1 << SEG_C); + (segments & (1 << 4)) ? PORT_D |= (1 << SEG_D) : PORT_D &= ~(1 << SEG_D); + (segments & (1 << 3)) ? PORT_E |= (1 << SEG_E) : PORT_E &= ~(1 << SEG_E); + (segments & (1 << 2)) ? PORT_F |= (1 << SEG_F) : PORT_F &= ~(1 << SEG_F); + (segments & (1 << 1)) ? PORT_G |= (1 << SEG_G) : PORT_G &= ~(1 << SEG_G); + (segments & (1 << 0)) ? PORT_H |= (1 << SEG_H) : PORT_H &= ~(1 << SEG_H); +} + +//================================================================ +// Гашение всех разрядов перед установкой сегментов: +ISR(TIMER0_COMPA_vect) +{ + (LEVEL) ? PORT_RAZ1 &= ~(1 << RAZ_1) : PORT_RAZ1 |= (1 << RAZ_1); + (LEVEL) ? PORT_RAZ2 &= ~(1 << RAZ_2) : PORT_RAZ2 |= (1 << RAZ_2); + (LEVEL) ? PORT_RAZ3 &= ~(1 << RAZ_3) : PORT_RAZ3 |= (1 << RAZ_3); + (LEVEL) ? PORT_RAZ4 &= ~(1 << RAZ_4) : PORT_RAZ4 |= (1 << RAZ_4); +} + +//================================================================ +// Основная индикация: +ISR(TIMER0_OVF_vect) +{ + static uint8_t s = 0; + + switch (s) + { + case 0: + segWork(data[0]); + (LEVEL) ? PORT_RAZ1 |= (1 << RAZ_1) : PORT_RAZ1 &= ~(1 << RAZ_1); + break; + + case 1: + segWork(data[1]); + (flagDot && !LEVEL) ? PORT_H |= (1 << SEG_H) : PORT_H &= ~(1 << SEG_H); + (LEVEL) ? PORT_RAZ2 |= (1 << RAZ_2) : PORT_RAZ2 &= ~(1 << RAZ_2); + break; + + case 2: + segWork(data[2]); + (LEVEL) ? PORT_RAZ3 |= (1 << RAZ_3) : PORT_RAZ3 &= ~(1 << RAZ_3); + break; + + case 3: + segWork(data[3]); + (LEVEL) ? PORT_RAZ4 |= (1 << RAZ_4) : PORT_RAZ4 &= ~(1 << RAZ_4); + break; + } + (s == 3) ? s = 0 : s++; // крутим активный разряд + + // почти = 1мс (976 мкс) + myMillis++; +} + +//================================================================ +// Запись данных в массив для отображения: +void visible(uint16_t vis) +{ + for (uint8_t c = 4; c > 0; c--) + { + data[c - 1] = vis % 10; + vis /= 10; + + // Гасим "левый" ноль: + if (data[0] == 0) + { + data[0] = 16; + } + } +} + +//=============================================================== +// Подсчет оборотов (по таймеру T1): +ISR(INT0_vect) +{ + temp = TCNT1 * COUNT_PULSE; + TCNT1 = 0; + temp = PART_SEC / temp; + countMoto += temp; + // flagRev = true; +} + +//=============================================================== +// Проверяем включено-ли зажигание: +void onIgnition() +{ + if (!(PIN_IGN_ON & (1 << IGN_ON))) + { + // если - нет, то сохраняем моточасы в EEPROM: + eeprom_update_dword((uint32_t *)MEM_CELL + 1, countMoto); + // и выключаемся: + while (1) + ; + } +} + +//=============================================================== +// Сброс моточасов: +void resEeprom() +{ + eeprom_update_dword((uint32_t *)MEM_CELL, MEANING); + eeprom_update_dword((uint32_t *)MEM_CELL + 1, 0); +} + +//=============================================================== +// Проверка нажатия кнопки сброса моточасов: +// void checkPinRes() +// { +// if (!(PIN_BTN & (1 << BTN))) +// { +// _delay_ms(5000); +// if (!(PIN_BTN & (1 << BTN))) +// { +// // если 3сек еще нажата, то сброс моточасов +// countMoto = 0; +// resEeprom(); +// } +// } +// } + +//=============================================================== +// Проверка нажатия кнопки сброса моточасов: +void checkPinMode() +{ + static bool pinCondition = false; + static bool flagResEeprom = true; + static uint32_t pinCount = 0; + if (!(PIN_BTN & (1 << BTN)) && !pinCondition) + { + flagRev = !flagRev; + pinCondition = 1; + pinCount = myMillis; + } + + if (!(PIN_BTN & (1 << BTN)) && pinCondition) + { + if (myMillis <= pinCount + TIME_RESET_MOTO) + { + pinCount++; + visible(pinCount); + } + else + { + countMoto = 0; + if (flagResEeprom) + { + resEeprom(); + } + else + { + flagResEeprom = false; + } + } + } + else + { + pinCondition = false; + pinCount = 0; + flagResEeprom = true; + } +} + +//=============================================================== +int main(void) +{ + wdt_reset(); + init_pin(); + + wdt_enable(WDTO_1S); + wdt_reset(); + + //--------------------------------------------------------- + // Читаем моточасы из EEPROM: + if (eeprom_read_dword((uint32_t *)MEM_CELL) == MEANING) + { + countMoto = eeprom_read_dword((uint32_t *)MEM_CELL + 1); + } + else + { + resEeprom(); + } + + // Инициализируем прерывания: + INTERRUPT_Init(); + // Разрешаем прерывания: + wdt_reset(); + sei(); + //--------------------------------------------------------- + while (1) + { + checkPinMode(); + // Если включен режим тахометра: + if (flagRev) + { + // то отображаем тахометр (и "убиваем" младший разряд) + visible(filtr(temp) / 10 * 10); + // flagRev = false; + flagDot = false; + myMillisOld = myMillis; + } + else + { + revOld = 0; + // если нет - отображаем моточасы + uint16_t data; + // Если меньше 100 мото/часов - отображаем с минутами: + if ((countMoto / REV_RATED_POWER / TIME) < 100) + { + data = countMoto / REV_RATED_POWER / TIME * 100; + data += countMoto / REV_RATED_POWER / (TIME / 60) % 60; + flagDot = true; + } + // если больше или равно 100 мото/часов - отображаем только часы: + else + { + data = countMoto / REV_RATED_POWER / TIME; + flagDot = false; + } + if ((countMoto / REV_RATED_POWER / TIME) >= 1000) + countMoto = 0; + visible(data); + myMillisOld = myMillis; + } + + // задержка для отображения цифр + while (myMillis <= myMillisOld + DELAY_VISIBLE) + { + onIgnition(); + wdt_reset(); + } + } +}
\ No newline at end of file diff --git a/src/pin.cpp b/src/pin.cpp new file mode 100644 index 0000000..d0e1e98 --- /dev/null +++ b/src/pin.cpp @@ -0,0 +1,44 @@ +#include <avr/io.h> +#include "pin.h" + +//=============================================================== +// Инициализация всех ПИНов: +void init_pin() +{ + DDR_A |= (1 << SEG_A); + PORT_A |= (1 << SEG_A); + DDR_B |= (1 << SEG_B); + PORT_B |= (1 << SEG_B); + DDR_C |= (1 << SEG_C); + PORT_C |= (1 << SEG_C); + DDR_D |= (1 << SEG_D); + PORT_D |= (1 << SEG_D); + DDR_E |= (1 << SEG_E); + PORT_E |= (1 << SEG_E); + DDR_F |= (1 << SEG_F); + PORT_F |= (1 << SEG_F); + DDR_G |= (1 << SEG_G); + PORT_G |= (1 << SEG_G); + DDR_H |= (1 << SEG_H); + PORT_H |= (1 << SEG_H); + + DDR_RAZ1 |= (1 << RAZ_1); + PORT_RAZ1 |= (1 << RAZ_1); + DDR_RAZ2 |= (1 << RAZ_2); + PORT_RAZ2 |= (1 << RAZ_2); + DDR_RAZ3 |= (1 << RAZ_3); + PORT_RAZ3 |= (1 << RAZ_3); + DDR_RAZ4 |= (1 << RAZ_4); + PORT_RAZ4 |= (1 << RAZ_4); + + DDR_TAHO &= ~(1 << BTN); + PORT_TAHO |= (1 << BTN); + + DDR_BTN &= ~(1 << BTN); + PORT_BTN |= (1 << BTN); + + DDR_IGN_ON &= ~(1 << IGN_ON); + PORT_IGN_ON |= (1 << IGN_ON); +} + +//=============================================================== diff --git a/src/pin.h b/src/pin.h new file mode 100644 index 0000000..5343e8c --- /dev/null +++ b/src/pin.h @@ -0,0 +1,64 @@ +#ifndef PIN_H_ +#define PIN_H_ + +// ЗАДАЕМ ИСПОЛЬЗУЕМЫЕ ПИНы: +// СЕГМЕНТЫ: +#define SEG_A PB3 +#define DDR_A DDRB +#define PORT_A PORTB +#define SEG_B PB7 +#define DDR_B DDRB +#define PORT_B PORTB +#define SEG_C PD6 +#define DDR_C DDRD +#define PORT_C PORTD +#define SEG_D PD4 +#define DDR_D DDRD +#define PORT_D PORTD +#define SEG_E PD5 +#define DDR_E DDRD +#define PORT_E PORTD +#define SEG_F PB4 +#define DDR_F DDRB +#define PORT_F PORTB +#define SEG_G PB0 +#define DDR_G DDRB +#define PORT_G PORTB +#define SEG_H PD3 +#define DDR_H DDRD +#define PORT_H PORTD +// РАЗРЯДЫ: +#define RAZ_1 PB2 +#define DDR_RAZ1 DDRB +#define PORT_RAZ1 PORTB +#define RAZ_2 PB5 +#define DDR_RAZ2 DDRB +#define PORT_RAZ2 PORTB +#define RAZ_3 PB6 +#define DDR_RAZ3 DDRB +#define PORT_RAZ3 PORTB +#define RAZ_4 PB1 +#define DDR_RAZ4 DDRB +#define PORT_RAZ4 PORTB + +// КНОПКА: +#define BTN PD0 +#define DDR_BTN DDRD +#define PORT_BTN PORTD +#define PIN_BTN PIND + +// ЗАЖИГАНИЕ: +#define IGN_ON PD1 +#define DDR_IGN_ON DDRD +#define PORT_IGN_ON PORTD +#define PIN_IGN_ON PIND + +// ВХОД ТАХОМЕТРА: +#define PIN_TAHO PD2 +#define DDR_TAHO DDRD +#define PORT_TAHO PORTD + +//----------------------------------- +void init_pin(void); + +#endif
\ No newline at end of file @@ -0,0 +1,20 @@ +#!/bin/bash + +echo "============================" +stat=`git status | grep "modified"` +if [ -n "$stat" ] +then +echo "GIT synhronization:" +read -p "Input COMMIT: " text +echo "============================" +#git add . +git commit -a -m "$text" +echo "============================" +git push +echo "============================" +git log --oneline -5 +echo "============================" +else +echo "Изменений нет !" +echo "============================" +fi |
