#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; }