From 9d65806d8b407837209cc857dcd232fc04a66fcf Mon Sep 17 00:00:00 2001 From: zloihach <72695485+zloihach@users.noreply.github.com> Date: Wed, 21 Jun 2023 03:02:25 +0300 Subject: [PATCH] c++ == .ino --- test.cpp | 5 + test.h | 678 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 683 insertions(+) create mode 100644 test.cpp create mode 100644 test.h diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..d53eaa1 --- /dev/null +++ b/test.cpp @@ -0,0 +1,5 @@ +// +// Created by FSB-PC on 21.06.2023. +// + +#include "test.h" diff --git a/test.h b/test.h new file mode 100644 index 0000000..d897af8 --- /dev/null +++ b/test.h @@ -0,0 +1,678 @@ +// #include + + +// void pwm_init() { +// TCCR1A |= (1 << COM1A1) | (1 << WGM11); // non-inverting mode, Fast PWM (mode 14) +// TCCR1B |= (1 << WGM12) | (1 << WGM13) | (1 << CS10); // Fast PWM (mode 14), prescaler = 1 +// DDRB |= (1 << PB1); // set pin PB1 as output +// } + +// void pwm_set_frequency(uint16_t frequency) { +// uint16_t prescaler = 1; +// uint32_t top = F_CPU / (prescaler * frequency) - 1; +// ICR1 = top; +// } + +// void pwm_set_duty_cycle(uint8_t dutyCycle) { +// uint16_t value = ICR1 * dutyCycle / 100.0; +// OCR1A = value; +// } + + +// void pwm_init(); +// void pwm_set_frequency(uint16_t frequency); +// void pwm_set_duty_cycle(uint8_t dutyCycle); + +// #define F_CPU 16000000UL +// #define I2C_FREQ 100000UL +// #define I2C_PRESCALER 1 +// #define I2C_BITRATE ((F_CPU / I2C_FREQ) - 16) / (2 * I2C_PRESCALER) + +// void i2c_init() { +// TWBR = I2C_BITRATE; +// } + +// void i2c_start() { +// // отправляем START bit +// TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); + +// // ожидаем пока START bit будет успешно отправлен +// while (!(TWCR & (1 << TWINT))); +// } + +// void i2c_stop() { +// // отправляем STOP bit +// TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); + +// // ожидаем пока STOP bit будет успешно отправлен +// while (TWCR & (1 << TWSTO)); +// } + +// void i2c_write(uint8_t data) { +// // загружаем данные в регистр TWDR +// TWDR = data; + +// // отправляем данные +// TWCR = (1 << TWINT) | (1 << TWEN); + +// // ожидаем пока данные будут успешно отправлены +// while (!(TWCR & (1 << TWINT))); +// } + +// uint8_t i2c_read_ack() { +// // разрешаем отправку ACK после прочтения байта +// TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); + +// // ожидаем пока данные будут успешно прочитаны +// while (!(TWCR & (1 << TWINT))); + +// // возвращаем прочитанный байт +// return TWDR; +// } + +// uint8_t i2c_read_nack() { +// // запрещаем отправку ACK после прочтения байта +// TWCR = (1 << TWINT) | (1 << TWEN); + +// // ожидаем пока данные будут успешно прочитаны +// while (!(TWCR & (1 << TWINT))); + +// // возвращаем прочитанный байт +// return TWDR; +// } + +// void i2c_init(); +// void i2c_start(); +// void i2c_stop(); +// void i2c_write(uint8_t data); +// uint8_t i2c_read_ack(); +// uint8_t i2c_read_nack(); + +// const uint8_t BUTTON_PIN[] = {0, 1, 2, 3, 4, 5}; +// const uint8_t PWM_SLAVE_ADDR = 9; + +// uint16_t command = 0x00; +// float frequency = 1000.0; +// float dutyCycle = 50.0; + +// void setup() { +// i2c_init(); +// pwm_init(); + +// // Инициализируем пины кнопок +// DDRC &= ~(1 << PINC0) & ~(1 << PINC1) & ~(1 << PINC2) & ~(1 << PINC3) & ~(1 << PINC4) & ~(1 << PINC5); // подключены кнопки на пинах А0, А1, А2, А3, А4, А5 +// PORTC |= (1 << PINC0) | (1 << PINC1) | (1 << PINC2) | (1 << PINC3) | (1 << PINC4) | (1 << PINC5); // включение подтягивающего резистора + +// Serial.begin(9600); // Инициализируем Serial монитор +// Serial.println("PWM Controller started!"); +// sendCommand(0x01, 0.0); // Включить ШИМ при запуске +// } + +// void loop() { +// // Обработка нажатий на кнопки +// checkButton(0, "Turn on PWM!", 0x01, 0.0); +// checkButton(1, "Turn off PWM!", 0x02, 0.0); +// checkButton(2, "Increase frequency!", 0x03, 1.25); +// checkButton(3, "Decrease frequency!", 0x04, 0.8); +// checkButton(4, "Increase duty cycle!", 0x05, 1.1); +// checkButton(5, "Decrease duty cycle!", 0x06, 0.9); +// } + +// void checkButton(uint8_t pin, const char* message, uint16_t cmd, float value) { +// if (bit_is_clear(PINC, pin)) { +// Serial.println(message); +// delay(500); +// sendCommand(cmd, value); +// if (cmd == 0x03) { +// frequency *= value; +// pwm_set_frequency(frequency); +// } else if (cmd == 0x04) { +// frequency *= value; +// pwm_set_frequency(frequency); +// } else if (cmd == 0x05) { +// dutyCycle *= value; +// pwm_set_duty_cycle(dutyCycle); +// } else if (cmd == 0x06) { +// dutyCycle *= value; +// pwm_set_duty_cycle(dutyCycle); +// } else if (cmd == 0x02) { +// pwm_set_duty_cycle(0); +// } else if (cmd == 0x01) { +// pwm_set_duty_cycle(dutyCycle); +// } +// command = cmd; +// } +// } + +// void sendCommand(uint16_t cmd, float value) { +// if (cmd != 0x01 && cmd != 0x02) { // если команда изменения параметров +// switch (cmd) { +// case 0x03: // Увеличить частоту на 25% от текущего. +// value = frequency; +// value *= 0.25; +// break; +// case 0x04: // Уменьшить частоту на 20% от текущего. +// value = frequency; +// value *= 0.2; +// break; +// case 0x05: // Увеличить скважность на 10% от текущего. +// value = dutyCycle; +// value *= 0.1; +// break; +// case 0x06: // Уменьшить скважность на 10% от текущего. +// value = dutyCycle; +// value *= 0.1; +// break; +// } +// } +// uint16_t data = (uint16_t)(value * 16.0); +// data |= cmd << 4; +// i2c_start(); +// i2c_write(PWM_SLAVE_ADDR << 1); +// i2c_write(data >> 8); +// i2c_write(data & 0xFF); +// i2c_stop(); +// Serial.print("Sent command: "); +// Serial.print(cmd, HEX); +// Serial.print(", value: "); +// Serial.println(value); +// } + + + + + + +//VERSION #2 +#include + + +void pwm_init() { + TCCR1A |= (1 << COM1A1) | (1 << WGM11); // non-inverting mode, Fast PWM (mode 14) + TCCR1B |= (1 << WGM12) | (1 << WGM13) | (1 << CS10); // Fast PWM (mode 14), prescaler = 1 + DDRB |= (1 << PB1); // set pin PB1 as output +} + +void pwm_set_frequency(uint16_t frequency) { + uint16_t prescaler = 1; + uint32_t top = F_CPU / (prescaler * frequency) - 1; + ICR1 = top; +} + +void pwm_set_duty_cycle(uint8_t dutyCycle) { + uint16_t value = ICR1 * dutyCycle / 100.0; + OCR1A = value; +} + +void pwm_enable() { + pwm_set_duty_cycle(50); // Начальная скважность +} + +void pwm_disable() { + pwm_set_duty_cycle(0); // Выключение ШИМ +} + +void pwm_init(); +void pwm_set_frequency(uint16_t frequency); +void pwm_set_duty_cycle(uint8_t dutyCycle); +void pwm_enable(); +void pwm_disable(); + +#define F_CPU 16000000UL +#define I2C_FREQ 100000UL +#define I2C_PRESCALER 1 +#define I2C_BITRATE ((F_CPU / I2C_FREQ) - 16) / (2 * I2C_PRESCALER) + +void i2c_init() { + TWBR = I2C_BITRATE; +} + +void i2c_start() { + // отправляем START bit + TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); + + // ожидаем пока START bit будет успешно отправлен + while (!(TWCR & (1 << TWINT))); +} + +void i2c_stop() { + // отправляем STOP bit + TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); + + // ожидаем пока STOP bit будет успешно отправлен + while (TWCR & (1 << TWSTO)); +} + +void i2c_write(uint8_t data) { + // загружаем данные в регистр TWDR + TWDR = data; + + // отправляем данные + TWCR = (1 << TWINT) | (1 << TWEN); + + // ожидаем пока данные будут успешно отправлены + while (!(TWCR & (1 << TWINT))); +} + +uint8_t i2c_read_ack() { + // разрешаем отправку ACK после прочтения байта + TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); + + // ожидаем пока данные будут успешно прочитаны + while (!(TWCR & (1 << TWINT))); + + // возвращаем прочитанный байт + return TWDR; +} + +uint8_t i2c_read_nack() { + // запрещаем отправку ACK после прочтения байта + TWCR = (1 << TWINT) | (1 << TWEN); + + // ожидаем пока данные будут успешно прочитаны + while (!(TWCR & (1 << TWINT))); + + // возвращаем прочитанный байт + return TWDR; +} + +void i2c_init(); +void i2c_start(); +void i2c_stop(); +void i2c_write(uint8_t data); +uint8_t i2c_read_ack(); +uint8_t i2c_read_nack(); + +const uint8_t BUTTON_PIN[] = {0, 1, 2, 3, 4, 5}; +const uint8_t PWM_SLAVE_ADDR = 9; + +uint16_t command = 0x00; +float frequency = 1000.0; +float dutyCycle = 50.0; + +void setup() { + i2c_init(); + pwm_init(); + pwm_enable(); // Включение ШИМ + + // Инициализируем пины кнопок + DDRC &= ~(1 << PINC0) & ~(1 << PINC1) & ~(1 << PINC2) & ~(1 << PINC3) & ~(1 << PINC4) & ~(1 << PINC5); // подключены кнопки на пинах А0, А1, А2, А3, А4, А5 + PORTC |= (1 << PINC0) | (1 << PINC1) | (1 << PINC2) | (1 << PINC3) | (1 << PINC4) | (1 << PINC5); // включение подтягивающего резистора + + Serial.begin(9600); // Инициализируем Serial монитор + Serial.println("PWM Controller started!"); + sendCommand(0x01, 0.0); // Включить ШИМ при запуске +} + +void loop() { + // Обработка нажатий на кнопки + checkButton(0, "Turn on PWM!", 0x01, 0.0); + checkButton(1, "Turn off PWM!", 0x02, 0.0); + checkButton(2, "Increase frequency!", 0x03, 1.25); + checkButton(3, "Decrease frequency!", 0x04, 0.8); + checkButton(4, "Increase duty cycle!", 0x05, 1.1); + checkButton(5, "Decrease duty cycle!", 0x06, 0.9); +} + +void checkButton(uint8_t pin, const char* message, uint16_t cmd, float value) { + if (bit_is_clear(PINC, pin)) { + Serial.println(message); + delay(500); + sendCommand(cmd, value); + if (cmd == 0x03) { + frequency *= value; + pwm_set_frequency(frequency); + } else if (cmd == 0x04) { + frequency *= value; + pwm_set_frequency(frequency); + } else if (cmd == 0x05) { + dutyCycle *= value; + pwm_set_duty_cycle(dutyCycle); + } else if (cmd == 0x06) { + dutyCycle *= value; + pwm_set_duty_cycle(dutyCycle); + } else if (cmd == 0x02) { + pwm_disable(); // Выключение ШИМ + } else if (cmd == 0x01) { + pwm_enable(); // Включение ШИМ + } + command = cmd; + } +} + +void sendCommand(uint16_t cmd, float value) { + if (cmd != 0x01 && cmd != 0x02) { // если команда изменения параметров + switch (cmd) { + case 0x03: // Увеличить частоту на 25% от текущего. + value = frequency; + value *= 0.25; + break; + case 0x04: // Уменьшить частоту на 20% от текущего. + value = frequency; + value *= 0.2; + break; + case 0x05: // Увеличить скважность на 10% от текущего. + value = dutyCycle; + value *= 0.1; + break; + case 0x06: // Уменьшить скважность на 10% от текущего. + value = dutyCycle; + value *= 0.1; + break; + } + } + uint16_t data = (uint16_t)(value * 16.0); + data |= cmd << 4; + i2c_start(); + i2c_write(PWM_SLAVE_ADDR << 1); + i2c_write(data >> 8); + i2c_write(data & 0xFF); + i2c_stop(); + Serial.print("Sent command: "); + Serial.print(cmd, HEX); + Serial.print(", value: "); + Serial.println(value); + + + + + + + +// uint16_t data = (uint16_t)(value * 16.0); +// data |= cmd << 4; +// i2c_start(); +// i2c_write(PWM_SLAVE_ADDR << 1); +// i2c_write(data >> 8); +// Serial.print("Sent byte 1: "); +// Serial.println(data >> 8, HEX); +// i2c_write(data & 0xFF); +// Serial.print("Sent byte 2: "); +// Serial.println(data & 0xFF, HEX); +// i2c_stop(); +// Serial.print("Sent command: "); +// Serial.print(cmd, HEX); +// Serial.print(", value: "); +// Serial.println(value); +} + + + + +//VERSION 3.x + + +// #include +// #include +// #include + + +// void i2c_init(); +// void i2c_start(); +// void i2c_stop(); +// void i2c_write(uint8_t data); +// uint8_t i2c_read_ack(); +// uint8_t i2c_read_nack(); + + + +// #define F_CPU 16000000UL +// #define I2C_FREQ 100000UL +// #define I2C_PRESCALER 1 +// #define I2C_BITRATE ((F_CPU / I2C_FREQ) - 16) / (2 * I2C_PRESCALER) + +// void i2c_init() { +// TWBR = I2C_BITRATE; +// } + +// void i2c_start() { +// // отправляем START bit +// TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); + +// // ожидаем пока START bit будет успешно отправлен +// while (!(TWCR & (1 << TWINT))); +// } + +// void i2c_stop() { +// // отправляем STOP bit +// TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); + +// // ожидаем пока STOP bit будет успешно отправлен +// while (TWCR & (1 << TWSTO)); +// } + +// void i2c_write(uint8_t data) { +// // загружаем данные в регистр TWDR +// TWDR = data; + +// // отправляем данные +// TWCR = (1 << TWINT) | (1 << TWEN); + +// // ожидаем пока данные будут успешно отправлены +// while (!(TWCR & (1 << TWINT))); +// } + +// uint8_t i2c_read_ack() { +// // разрешаем отправку ACK после прочтения байта +// TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); + +// // ожидаем пока данные будут успешно прочитаны +// while (!(TWCR & (1 << TWINT))); + +// // возвращаем прочитанный байт +// return TWDR; +// } + +// uint8_t i2c_read_nack() { +// // запрещаем отправку ACK после прочтения байта +// TWCR = (1 << TWINT) | (1 << TWEN); + +// // ожидаем пока данные будут успешно прочитаны +// while (!(TWCR & (1 << TWINT))); + +// // возвращаем прочитанный байт +// return TWDR; +// } + +// #ifndef PWM_H +// #define PWM_H + +// void pwm_init(); +// void pwm_set_frequency(uint16_t frequency); +// void pwm_set_duty_cycle(uint8_t dutyCycle); +// void pwm_enable(); +// void pwm_disable(); + +// #endif + + + +// void pwm_init() { +// TCCR1A |= (1 << COM1A1) | (1 << WGM11); // non-inverting mode, Fast PWM (mode 14) +// TCCR1B |= (1 << WGM12) | (1 << WGM13) | (1 << CS10); // Fast PWM (mode 14), prescaler = 1 +// DDRB |= (1 << PB1); // set pin PB1 as output +// } + +// void pwm_set_frequency(uint16_t frequency) { +// uint16_t prescaler = 1; +// uint32_t top = F_CPU / (prescaler * frequency) - 1; +// ICR1 = top; +// } + +// void pwm_set_duty_cycle(uint8_t dutyCycle) { +// uint16_t value = ICR1 * dutyCycle / 100.0; +// OCR1A = value; +// } + +// void pwm_enable() { +// pwm_set_duty_cycle(50); // Начальная скважность +// } + +// void pwm_disable() { +// pwm_set_duty_cycle(0); // Выключение ШИМ +// } + +// #define F_CPU 16000000UL +// #define I2C_FREQ 100000UL +// #define I2C_PRESCALER 1 +// #define I2C_BITRATE ((F_CPU / I2C_FREQ) - 16) / (2 * I2C_PRESCALER) + +// #define BUTTON_PIN_CNT 6 + +// const uint8_t BUTTON_PIN[] = {0, 1, 2, 3, 4, 5}; +// const uint8_t PWM_SLAVE_ADDR = 9; + +// uint16_t command = 0x00; +// float frequency = 1000.0; +// float dutyCycle = 50.0; + +// bool is_button_pressed(uint8_t pin); +// void process_button_press(uint8_t pin); +// void send_command(uint16_t cmd, float value); + +// int main(void) { +// i2c_init(); +// pwm_init(); +// pwm_enable(); // Включение ШИМ + +// for (uint8_t i = 0; i < BUTTON_PIN_CNT; i++) { +// DDRC &= ~(1 << BUTTON_PIN[i]); +// PORTC |= (1 << BUTTON_PIN[i]); +// } + +// Serial.begin(9600); // Инициализируем Serial монитор +// Serial.println("PWM Controller started!"); + +// send_command(0x01, 0.0); // Включить ШИМ при запуске + +// while (true) { +// for (uint8_t i = 0; i < BUTTON_PIN_CNT; i++) { +// if (is_button_pressed(BUTTON_PIN[i])) { +// process_button_press(BUTTON_PIN[i]); +// _delay_ms(500); +// } +// } +// } +// } + +// bool is_button_pressed(uint8_t pin) { +// return bit_is_clear(PINC, pin); +// } + +// void process_button_press(uint8_t pin) { +// switch (pin) { +// case 0: +// send_command(0x01, 0.0); +// Serial.println("Turn on PWM!"); +// break; +// case 1: +// send_command(0x02, 0.0); +// Serial.println("Turn off PWM!"); +// break; +// case 2: +// if (frequency * 1.25 < 10000) { +// frequency *= 1.25; +// pwm_set_frequency(frequency); +// send_command(0x03, 1.25); +// Serial.println("Increased frequency!"); +// } else { +// Serial.println("Maximum frequency reached!"); +// } +// break; +// case 3: +// if (frequency * 0.8 > 1) { +// frequency *= 0.8; +// pwm_set_frequency(frequency); +// send_command(0x04, 0.8); +// Serial.println("Decreased frequency!"); +// } else { +// Serial.println("Minimum frequency reached!"); +// } +// break; +// case 4: +// if (dutyCycle * 1.1 <= 100) { +// dutyCycle *= 1.1; +// pwm_set_duty_cycle(dutyCycle); +// send_command(0x05, 1.1); +// Serial.println("Increased duty cycle!"); +// } else { +// Serial.println("Maximum duty cycle reached!"); +// } +// break; +// case 5: +// if (dutyCycle * 0.9 >= 0) { +// dutyCycle *= 0.9; +// pwm_set_duty_cycle(dutyCycle); +// send_command(0x06, 0.9); +// Serial.println("Decreased duty cycle!"); +// } else { +// Serial.println("Minimum duty cycle reached!"); +// } +// break; +// default: +// break; +// } +// } + +// void send_command(uint16_t cmd, float value) { +// if (cmd != 0x01 && cmd != 0x02) { // если команда изменения параметров +// switch (cmd) { +// case 0x03: // Увеличить частоту на 25% от текущего. +// value = frequency; +// value *= 0.25; +// break; +// case 0x04: // Уменьшить частоту на 20% от текущего. +// value = frequency; +// value *= 0.2; +// break; +// case 0x05: // Увеличить скважность на 10% от текущего. +// value = dutyCycle; +// value *= 0.1; +// break; +// case 0x06: // Уменьшить скважность на 10% от текущего. +// value = dutyCycle; +// value *= 0.1; +// break; +// } +// } +// uint16_t data = (uint16_t)(value * 16.0); +// data |= cmd << 4; +// i2c_start(); +// i2c_write(PWM_SLAVE_ADDR << 1); +// i2c_write(data >> 8); +// i2c_write(data & 0xFF); +// i2c_stop(); +// Serial.print("Sent command: "); +// Serial.print(cmd, HEX); +// Serial.print(", value: "); +// Serial.println(value); +// } + + + + + + +///test +// #include + +// #define PWM_ADDR 9 // Адрес устройства на шине I2C + +// void setup() { +// Wire.begin(); +// Serial.begin(9600); +// Serial.println("PWM Master device started!"); +// Serial.println("I2C connection established"); +// } + +// void loop() { +// // Генерация случайного значения ШИМ-сигнала +// int pwmValue = random(256); +// // Отправка значения по шине I2C на адрес устройства PWM_ADDR +// Wire.beginTransmission(PWM_ADDR); +// Wire.write(pwmValue); +// Wire.endTransmission(); +// Serial.print("Sent PWM value: "); +// Serial.println(pwmValue); +// delay(1000); // Пауза между отправкой нового значения +// }