diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md index 34f0c59..a5cc6a5 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ ## Устройство представляет из себя I2C ведущее устройство. Управляет устройством из задания 7. Имеет 6 кнопок: -- **Включить ШИМ. -- **Выключить ШИМ. -- **Увеличить частоту на 25% от текущего. -- **Уменьшить частоту на 20% от текущего. -- **Увеличить скважность. -- **Уменьшить скважность. \ No newline at end of file +- #### Включить ШИМ. +- #### Выключить ШИМ. +- #### Увеличить частоту на 25% от текущего. +- #### Уменьшить частоту на 20% от текущего. +- #### Увеличить скважность. +- #### Уменьшить скважность. \ No newline at end of file diff --git a/main.c b/main.c new file mode 100644 index 0000000..7f26efc --- /dev/null +++ b/main.c @@ -0,0 +1,90 @@ +#include +#include +#include + +#define I2C_ADDRESS 0x20 + +#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); // Выключение таймера +} + +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(); // Включение прерываний +} + +void loop() { +// Чтение состояния кнопок и отправка данных на устройство по шине I2C + uint8_t buttonState = (PINB >> BUTTON1_PIN) & 0x3F; // Чтение состояния кнопок + uint8_t data[] = {buttonState}; // Формирование массива данных для отправки + i2cSendData(I2C_ADDRESS, data, sizeof(data)); // Отправка данных на устройство + _delay_ms(10); // Задержка для стабилизации состояния кнопок +} + +int main() { + setup(); + while (1) { + loop(); + } + return 0; +} \ No newline at end of file diff --git a/main.cpp b/main.cpp deleted file mode 100644 index 68e93e6..0000000 --- a/main.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// определяем пины, к которым подключена кнопка и ШИМ -#define BUTTON_PIN 2 -#define PWM_PIN 9 - -// определяем регистры ШИМ -#define TCCR1A_REG 0x80 -#define TCCR1B_REG 0x81 -#define OCR1A_REG 0x88 - -void setup() { - // настраиваем пин кнопки на вход с подтягивающим резистором - pinMode(BUTTON_PIN, INPUT_PULLUP); - - // настраиваем пин ШИМ на выход - pinMode(PWM_PIN, OUTPUT); - - // устанавливаем настройки ШИМа - TCCR1A = 0x82; // настройки регистра TCCR1A (включаем Fast PWM, устанавливаем режим non-inverting) - TCCR1B = 0x11; // настройки регистра TCCR1B (выбираем источник тактирования и устанавливаем prescaler) - OCR1A = 0x0000; // устанавливаем начальное значение ШИМа -} - -void loop() { - // считываем состояние кнопки - bool buttonState = digitalRead(BUTTON_PIN); - - // если кнопка нажата, включаем ШИМ - if (buttonState == LOW) { - // устанавливаем значение ШИМа - OCR1A = 0x0FFF; - } - // если кнопка не нажата, выключаем ШИМ - else { - // устанавливаем значение ШИМа в 0 - OCR1A = 0x0000; - } -} diff --git a/main.ino b/main.ino deleted file mode 100644 index 3fb9eb4..0000000 --- a/main.ino +++ /dev/null @@ -1,37 +0,0 @@ -//// определяем пины, к которым подключена кнопка и ШИМ -//#define BUTTON_PIN 2 -//#define PWM_PIN 9 -// -//// определяем регистры ШИМ -//#define TCCR1A_REG 0x80 -//#define TCCR1B_REG 0x81 -//#define OCR1A_REG 0x88 -// -//void setup() { -// // настраиваем пин кнопки на вход с подтягивающим резистором -// pinMode(BUTTON_PIN, INPUT_PULLUP); -// -// // настраиваем пин ШИМ на выход -// pinMode(PWM_PIN, OUTPUT); -// -// // устанавливаем настройки ШИМа -// TCCR1A = 0x82; // настройки регистра TCCR1A (включаем Fast PWM, устанавливаем режим non-inverting) -// TCCR1B = 0x11; // настройки регистра TCCR1B (выбираем источник тактирования и устанавливаем prescaler) -// OCR1A = 0x0000; // устанавливаем начальное значение ШИМа -//} -// -//void loop() { -// // считываем состояние кнопки -// bool buttonState = digitalRead(BUTTON_PIN); -// -// // если кнопка нажата, включаем ШИМ -// if (buttonState == LOW) { -// // устанавливаем значение ШИМа -// OCR1A = 0x0FFF; -// } -// // если кнопка не нажата, выключаем ШИМ -// else { -// // устанавливаем значение ШИМа в 0 -// OCR1A = 0x0000; -// } -//}