From f3a480bd870738e67724108ec45188cf6ae28c4c Mon Sep 17 00:00:00 2001 From: zloihach <72695485+zloihach@users.noreply.github.com> Date: Mon, 22 May 2023 08:08:40 +0300 Subject: [PATCH] Update codebase, without i2c commands --- .gitignore | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Wire.h | 30 ++++++++++ main.c | 161 +++++++++++++++++++++++++++-------------------------- 3 files changed, 270 insertions(+), 79 deletions(-) create mode 100644 .gitignore create mode 100644 Wire.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d50fdb7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,158 @@ +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### CLion+all template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + diff --git a/Wire.h b/Wire.h new file mode 100644 index 0000000..9b6c5a8 --- /dev/null +++ b/Wire.h @@ -0,0 +1,30 @@ +// ========== I2C ========== +#define I2C_FREQ 100000UL + +void i2c_begin(uint8_t address) +{ + TWBR = ((F_CPU / I2C_FREQ) - 16) / 2; // Расчет предделителя для заданной частоты + TWAR = (address << 1); // Установка адреса устройства +} + +void i2c_endTransaction() +{ + TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); // Отправка условия STOP +} + +void i2c_beginTransmission(uint8_t address) +{ + TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // Отправка условия START + while (!(TWCR & (1 << TWINT))); // Ожидание завершения START + + TWDR = (address << 1); // Отправка адреса устройства + TWCR = (1 << TWINT) | (1 << TWEN); // Отправка адреса + while (!(TWCR & (1 << TWINT))); // Ожидание завершения передачи адреса +} + +void i2c_write(uint8_t data) +{ + TWDR = data; // Запись данных + TWCR = (1 << TWINT) | (1 << TWEN); // Отправка данных + while (!(TWCR & (1 << TWINT))); // Ожидание завершения передачи данных +} \ No newline at end of file diff --git a/main.c b/main.c index 7f26efc..fafbccf 100644 --- a/main.c +++ b/main.c @@ -1,90 +1,93 @@ -#include -#include -#include +#include +#define I2C_FREQ 100000UL -#define I2C_ADDRESS 0x20 +// Адрес устройства из задания 7 +const int deviceAddress = 8; -#define BUTTON1_PIN 2 -#define BUTTON2_PIN 3 -#define BUTTON3_PIN 4 -#define BUTTON4_PIN 5 -#define BUTTON5_PIN 6 -#define BUTTON6_PIN 7 - -int frequency = 1000; // Начальная частота ШИМ -int dutyCycle = 50; // Начальная скважность ШИМ -int pwmEnabled = 0; // ШИМ выключен по умолчанию - -void i2cInit() { - TWSR = 0; // Установка предделителя TWPS в 0 - TWBR = ((F_CPU / 100000UL) - 16) / 2; // Установка скорости передачи 100 кГц - TWCR = (1 << TWEN) | (1 << TWEA) | (1 << TWIE); // Включение TWI и прерываний -} - -void i2cWaitForComplete() { - while (!(TWCR & (1 << TWINT))); // Ожидание завершения передачи данных -} - -void i2cSendByte(uint8_t data) { - TWDR = data; - TWCR = (1 << TWINT) | (1 << TWEN); -} - -void i2cSendData(uint8_t address, uint8_t* data, uint8_t length) { - TWCR = (1 << TWSTA) | (1 << TWEN) | (1 << TWINT); // Генерация START - i2cWaitForComplete(); - i2cSendByte((address << 1) | TW_WRITE); // Отправка адреса устройства - i2cWaitForComplete(); - for (uint8_t i = 0; i < length; i++) { // Отправка данных - i2cSendByte(data[i]); - i2cWaitForComplete(); - } - TWCR = (1 << TWSTO) | (1 << TWINT) | (1 << TWEN); // Генерация STOP -} - -void setPwmFrequency(int frequency) { - TCCR1A = (1 << COM1A1) | (1 << WGM11); // Включение режима Fast PWM и установка нормального режима работы на выводе OC1A - TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); // Установка предделителя на 8, чтобы получить частоту - OCR1A = (F_CPU / (2 * 8 * frequency)) - 1; // Рассчет значения регистра OCR1A для заданной частоты -} - -void setPwmDutyCycle(int dutyCycle) { - OCR1B = (dutyCycle * OCR1A) / 100; // Рассчет значения регистра OCR1B для заданной скважности -} - -void enablePwm() { - pwmEnabled = 1; - TCCR1B |= (1 << CS10); // Включение таймера -} - -void disablePwm() { - pwmEnabled = 0; - TCCR1B &= ~(1 << CS10); // Выключение таймера -} +// Регистры устройства +byte reg1 = 0; +byte reg2 = 0; void setup() { - i2cInit(); // Инициализация шины I2C - DDRB &= ~((1 << BUTTON1_PIN) | (1 << BUTTON2_PIN) | (1 << BUTTON3_PIN) | (1 << BUTTON4_PIN) | (1 << BUTTON5_PIN) | (1 << BUTTON6_PIN)); // Настройка пинов кнопок на вход - PORTB |= (1 << BUTTON1_PIN) | (1 << BUTTON2_PIN) | (1 << BUTTON3_PIN) | (1 << BUTTON4_PIN) | (1 << BUTTON5_PIN) | (1 << BUTTON6_PIN); // Включение внутренней подтяжки к питанию для пинов кнопок - DDRB |= (1 << PB1); // Настройка пина OC1A на выход - setPwmFrequency(frequency); // Установка начальной частоты ШИМ - setPwmDutyCycle(dutyCycle); // Установка начальной скважности ШИМ - enablePwm(); // Включение ШИМ - sei(); // Включение прерываний + // Инициализация I2C + i2c_begin(); + // Назначение функции-обработчика для приема данных по I2C + Wire.onReceive(receiveData); + + // Настройка пинов для кнопок + pinMode(2, INPUT_PULLUP); + pinMode(3, INPUT_PULLUP); + pinMode(4, INPUT_PULLUP); + pinMode(5, INPUT_PULLUP); + pinMode(6, INPUT_PULLUP); + pinMode(7, INPUT_PULLUP); } void loop() { -// Чтение состояния кнопок и отправка данных на устройство по шине I2C - uint8_t buttonState = (PINB >> BUTTON1_PIN) & 0x3F; // Чтение состояния кнопок - uint8_t data[] = {buttonState}; // Формирование массива данных для отправки - i2cSendData(I2C_ADDRESS, data, sizeof(data)); // Отправка данных на устройство - _delay_ms(10); // Задержка для стабилизации состояния кнопок + // Обработка нажатий кнопок + if (digitalRead(2) == LOW) { + // Включить ШИМ + reg1 |= 0b00000001; + sendData(); + } else if (digitalRead(3) == LOW) { + // Выключить ШИМ + reg1 &= 0b11111110; + sendData(); + } else if (digitalRead(4) == LOW) { + // Увеличить частоту на 25% + reg1 |= 0b00000010; + sendData(); + } else if (digitalRead(5) == LOW) { + // Уменьшить частоту на 20% + reg1 |= 0b00000100; + sendData(); + } else if (digitalRead(6) == LOW) { + // Увеличить скважность + reg2 |= 0b00000001; + sendData(); + } else if (digitalRead(7) == LOW) { + // Уменьшить скважность + reg2 &= 0b11111110; + sendData(); + } } -int main() { - setup(); - while (1) { - loop(); +// Функция-обработчик для приема данных по I2C +void receiveData(int byteCount) { + while (Wire.available()) { + byte reg = Wire.read(); + byte value = Wire.read(); + // Запись значения в соответствующий регистр + if (reg == 1) { + reg1 = value; + // Включение ШИМ + if (bitRead(reg1, 0) == 1) { + analogWrite(9, 128); + } else { + analogWrite(9, 0); + } + // Изменение частоты ШИМ + if (bitRead(reg1, 1) == 1) { + analogWriteFrequency(9, 25000); + } else if (bitRead(reg1, 2) == 1) { + analogWriteFrequency(9, 8000); + } + } else if (reg == 2) { + reg2 = value; + // Изменение скважности ШИМ + int dutyCycle = map(reg2, 0, 255, 0, 1023); + analogWrite(9, dutyCycle); + } } - return 0; +} + +// Функция для отправки данных по I2C +void sendData() { + Wire.beginTransmission(deviceAddress); + // Отправка значений регистров + Wire.write(1); + Wire.write(reg1); + Wire.write(2); + Wire.write(reg2); + Wire.endTransmission(); } \ No newline at end of file