From df75af19c25bfb81befe3b886ec66af9d0e74b37 Mon Sep 17 00:00:00 2001 From: zloihach <72695485+zloihach@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:16:59 +0300 Subject: [PATCH] upd --- CMakeLists.txt | 13 ++++++ Wire.h | 40 ------------------ i2c.c | 48 +++++++++++++++++++++ i2c.h | 111 ------------------------------------------------- main.c | 98 ++++++++++++++++++++++++++++++++++++++++++- pwm.c | 29 +++++++++++++ pwm.h | 70 ------------------------------- test.c | 75 --------------------------------- 8 files changed, 186 insertions(+), 298 deletions(-) delete mode 100644 Wire.h create mode 100644 i2c.c delete mode 100644 i2c.h create mode 100644 pwm.c delete mode 100644 pwm.h delete mode 100644 test.c diff --git a/CMakeLists.txt b/CMakeLists.txt index e69de29..6a6f9a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.22) +project(untitled2 C) + +set(CMAKE_C_STANDARD 17) + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR avr) +set(CMAKE_C_COMPILER avr-gcc) +set(CMAKE_CXX_COMPILER avr-g++) +set(CMAKE_C_FLAGS "-mmcu=atmega328p") +set(CMAKE_CXX_FLAGS "-mmcu=atmega328p") + +add_executable(8.PMW main.c i2c.h pwm.h) diff --git a/Wire.h b/Wire.h deleted file mode 100644 index 2c0373f..0000000 --- a/Wire.h +++ /dev/null @@ -1,40 +0,0 @@ -#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_endTransmission() { - TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); // Отправка условия STOP -} - -void i2c_write(uint8_t data) { - TWDR = data; // Запись данных - TWCR = (1 << TWINT) | (1 << TWEN); // Отправка данных - while (!(TWCR & (1 << TWINT))); // Ожидание завершения передачи данных -} - -void i2c_read(uint8_t *data, uint8_t ack) { - if (ack) { - TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); // Отправка ACK - } else { - TWCR = (1 << TWINT) | (1 << TWEN); // Отправка NACK - } - while (!(TWCR & (1 << TWINT))); // Ожидание завершения приема данных - *data = TWDR; // Чтение данных -} \ No newline at end of file diff --git a/i2c.c b/i2c.c new file mode 100644 index 0000000..e3a3322 --- /dev/null +++ b/i2c.c @@ -0,0 +1,48 @@ +#include "i2c.h" + +#define F_CPU 16000000UL +#define F_SCL 100000UL + +#define I2C_READ 1 +#define I2C_WRITE 0 + +#define SCL_CLOCK ((F_CPU/F_SCL)-16)/2 + +void i2c_init(void) +{ + TWBR = (uint8_t)SCL_CLOCK; +} + +void i2c_start(void) +{ + // transmit START condition + TWCR = (1<speed) - 16) / 2; - TWAR = (i2c->address << 1); -} - -void i2c_beginTransmission(i2c_device_t *i2c, uint8_t address){ - TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); - while (!(TWCR & (1 << TWINT))); - - TWDR = (address << 1); - TWCR = (1 << TWINT) | (1 << TWEN); - while (!(TWCR & (1 << TWINT))); - i2c->address = address; -} - -void i2c_write(i2c_device_t *i2c, uint8_t data){ - TWDR = data; - TWCR = (1 << TWINT) | (1 << TWEN); - while (!(TWCR & (1 << TWINT))); -} - -void i2c_read(i2c_device_t *i2c, uint8_t *data, uint8_t ack){ - if (ack){ - TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); - } else { - TWCR = (1 << TWINT) | (1 << TWEN); - } - while (!(TWCR & (1 << TWINT))); - *data = TWDR; -} - -void i2c_endTransmission(i2c_device_t *i2c){ - TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); -} - -void i2c_sendByte(i2c_device_t *i2c, uint8_t address, uint8_t data){ - i2c_beginTransmission(i2c, address); - i2c_write(i2c, data); - i2c_endTransmission(i2c); -} - - - -#endif //INC_8_PMW_I2C_H - -//void i2c_begin(I2C *i2c) { -// TWBR = ((F_CPU / i2c->speed) - 16) / 2; -// TWAR = (i2c->address << 1); -//} -// -//void i2c_beginTransmission(I2C *i2c, uint8_t address) { -// TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); -// while (!(TWCR & (1 << TWINT))); -// -// TWDR = (address << 1); -// TWCR = (1 << TWINT) | (1 << TWEN); -// while (!(TWCR & (1 << TWINT))); -// i2c->address = address; -//} -// -//void i2c_write(I2C *i2c, uint8_t data) { -// TWDR = data; -// TWCR = (1 << TWINT) | (1 << TWEN); -// while (!(TWCR & (1 << TWINT))); -//} -// -//void i2c_read(I2C *i2c, uint8_t *data, uint8_t ack) { -// if (ack) { -// TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); -// } else { -// TWCR = (1 << TWINT) | (1 << TWEN); -// } -// while (!(TWCR & (1 << TWINT))); -// *data = TWDR; -//} -// -//void i2c_endTransmission(I2C *i2c) { -// TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); -//} -// -//void sendByte(uint8_t data) { -// sendByteRaw(data); -// _writes++; -// if (_writes >= 16) { -// endTransm(); -// beginData(); -// } -//} -// -//void sendByteRaw(uint8_t data) { -// i2c_write(data); -//} -// -//void sendCommand(uint8_t cmd1) { -// beginOneCommand(); -// sendByteRaw(cmd1); -// i2c_endTransmission(); -//} diff --git a/main.c b/main.c index 482d356..88db5bd 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,99 @@ -#define I2C_FREQ 100000UL +#include #include "i2c.h" -#include "pmw.h" +#include "pwm.h" +#define I2C_ADDRESS 0x20 +void send_data(void) +{ + // read state of PWM from master and send to slave + i2c_start(); + i2c_write_byte(I2C_ADDRESS | I2C_WRITE); + i2c_write_byte(0x00); + i2c_start(); + i2c_write_byte(I2C_ADDRESS | I2C_READ); + uint8_t state = i2c_read_byte(0); + i2c_stop(); + // set PWM state + if (state) { + TCCR1B |= (1< 1.0) ? 1.0 : frequency; + set_frequency(frequency); +} + +void decrease_frequency(void) +{ + // decrease PWM frequency by 20% + float frequency = ICR1 * 0.8 / PWM_MAX_FREQ; + set_frequency(frequency); +} + +void set_duty_cycle(float duty_cycle) +{ + // set PWM duty cycle + pwm_set_duty_cycle(duty_cycle); +} + +void increase_duty_cycle(void) +{ + // increase PWM duty cycle by 10% + float duty_cycle = OCR1A * 1.1 / ICR1; + duty_cycle = (duty_cycle > 1.0) ? 1.0 : duty_cycle; + set_duty_cycle(duty_cycle); +} + +void decrease_duty_cycle(void) +{ + // decrease PWM duty cycle by 10% + float duty_cycle = OCR1A * 0.9 / ICR1; + set_duty_cycle(duty_cycle); +} + +int main(void) +{ + // initialize I2C and PWM + i2c_init(); + pwm_init(); + // set default PWM frequency and duty cycle + set_frequency(1000); + set_duty_cycle(0.5); + // main loop + while (1) { + send_data(); + // read buttons and execute actions + if (!(PIND & (1< 0xffff) ? 0xffff : top; + // set timer 1 TOP value + ICR1 = top; +} + +void pwm_set_duty_cycle(float duty_cycle) +{ + // calculate OCR1A value from duty cycle + uint16_t ocr = (uint16_t)(duty_cycle * ICR1); + ocr = (ocr > ICR1) ? ICR1 : ocr; + // set OCR1A value + OCR1A = ocr; +} \ No newline at end of file diff --git a/pwm.h b/pwm.h deleted file mode 100644 index 83ab59d..0000000 --- a/pwm.h +++ /dev/null @@ -1,70 +0,0 @@ -// -// Created by FSB-PC on 22.05.2023. -// - -#ifndef INC_8_PMW_PMW_H -#define INC_8_PMW_PMW_H - - -struct PWM { - uint8_t pin; // номер пина - uint16_t frequency; // частота ШИМ сигнала - uint8_t duty_cycle; // коэффициент заполнения -}; - -void pwm_begin(struct PWM *pwm) { - TCCR0A = (1 << COM0A1) | (1 << WGM00) | (1 << WGM01); - TCCR0B = (1 << CS00) | (1 << CS01); - OCR0A = 0; - pwm->duty_cycle = 0; -} - -void pwm_set_duty_cycle(struct PWM *pwm, uint8_t duty_cycle) { - pwm->duty_cycle = duty_cycle; - OCR0A = (duty_cycle * 255) / 100; -} - -void pwm_increase_speed(struct PWM *pwm) { - pwm->duty_cycle += 25; - TCCR0B = (1 << CS00) | (1 << CS01); -} - -void pwm_decrease_speed(struct PWM *pwm) { - pwm->duty_cycle -= 20; - TCCR0B = (1 << CS00) | (1 << CS01); -} - -void pwm_end(struct PWM *pwm) { - TCCR0B = 0; -} - - - -//void pmw_begin(PMW *pmw) { -// TCCR0A = (1 << COM0A1) | (1 << WGM00) | (1 << WGM01); -// TCCR0B = (1 << CS00) | (1 << CS01); -// OCR0A = 0; -// pmw->speed = 0; -// pmw->duty_cycle = 0; -//} -// -//void pmw_set_duty_cycle(PMW *pmw, uint8_t duty_cycle) { -// pmw->duty_cycle = duty_cycle; -// OCR0A = (duty_cycle * 255) / 100; -//} -// -//void pmw_increase_speed(PMW *pmw) { -// pmw->speed += 25; -// TCCR0B = (1 << CS00) | (1 << CS01); -//} -// -//void pmw_decrease_speed(PMW *pmw) { -// pmw->speed -= 20; -// TCCR0B = (1 << CS00) | (1 << CS01); -//} -// -//void pmw_end(PMW *pmw) { -// TCCR0B = 0; -//} - -#endif //INC_8_PMW_PMW_H \ No newline at end of file diff --git a/test.c b/test.c deleted file mode 100644 index 452fa1f..0000000 --- a/test.c +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#define F_CPU 8000000UL -#define I2C_FREQ 100000UL - -#include "i2c.h" - -#define PWM_ADDRESS 0x50 -#define BUTTONS_ADDRESS 0x40 - -#define PWM_ENABLE_CMD 0x0001 -#define PWM_DISABLE_CMD 0x0002 -#define PWM_INCREASE_FREQ_CMD 0x0011 -#define PWM_DECREASE_FREQ_CMD 0x0012 -#define PWM_INCREASE_DUTY_CYCLE_CMD 0x0021 -#define PWM_DECREASE_DUTY_CYCLE_CMD 0x0022 - -struct PWM pwm; -struct I2C buttons_i2c; - -void setup() { - i2c_begin(&buttons_i2c); - i2c_beginTransmission(&buttons_i2c, BUTTONS_ADDRESS); - i2c_write(&buttons_i2c, 0x00); - i2c_endTransmission(&buttons_i2c); - - pwm.pin = PB3; - pwm.frequency = 1000; - pwm_begin(&pwm); -} - -void loop() { - i2c_beginTransmission(&buttons_i2c, BUTTONS_ADDRESS); - i2c_read(&buttons_i2c, buttons_i2c.data, 1); - i2c_endTransmission(&buttons_i2c); - - uint16_t command = ((uint16_t)(buttons_i2c.data[0]) << 8) | buttons_i2c.data[1]; - - if (command == PWM_ENABLE_CMD) { - pwm_increase_speed(&pwm); - i2c_sendByte(&buttons_i2c, PWM_ADDRESS, 1); - } else if (command == PWM_DISABLE_CMD) { - pwm_decrease_speed(&pwm); - i2c_sendByte(&buttons_i2c, PWM_ADDRESS, 0); - } else if (command == PWM_INCREASE_FREQ_CMD) { - pwm.frequency += round(pwm.frequency * 0.25); - pwm_set_frequency(&pwm, pwm.frequency); - i2c_sendByte(&buttons_i2c, PWM_ADDRESS, 1); - } else if (command == PWM_DECREASE_FREQ_CMD) { - pwm.frequency -= round(pwm.frequency * 0.2); - pwm_set_frequency(&pwm, pwm.frequency); - i2c_sendByte(&buttons_i2c, PWM_ADDRESS, 0); - } else if (command == PWM_INCREASE_DUTY_CYCLE_CMD) { - pwm_increase_duty_cycle(&pwm); - i2c_sendByte(&buttons_i2c, PWM_ADDRESS, 1); - } else if (command == PWM_DECREASE_DUTY_CYCLE_CMD) { - pwm_decrease_duty_cycle(&pwm); - i2c_sendByte(&buttons_i2c, PWM_ADDRESS, 0); - } - - _delay_ms(100); -} - -int main() { - setup(); - while (true) { - loop(); - } - return 0; -} \ No newline at end of file