99 lines
2.2 KiB
C
99 lines
2.2 KiB
C
#include <util/delay.h>
|
|
#include "i2c.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<<CS11);
|
|
} else {
|
|
TCCR1B &= ~(1<<CS11);
|
|
}
|
|
}
|
|
|
|
void set_frequency(float frequency)
|
|
{
|
|
// set PWM frequency
|
|
pwm_set_frequency(frequency);
|
|
}
|
|
|
|
void increase_frequency(void)
|
|
{
|
|
// increase PWM frequency by 25%
|
|
float frequency = ICR1 * 1.25 / PWM_MAX_FREQ;
|
|
frequency = (frequency > 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<<PD1))) { // increase frequency
|
|
increase_frequency();
|
|
}
|
|
if (!(PIND & (1<<PD2))) { // decrease frequency
|
|
decrease_frequency();
|
|
}
|
|
if (!(PIND & (1<<PD3))) { // increase duty cycle
|
|
increase_duty_cycle();
|
|
}
|
|
if (!(PIND & (1<<PD4))) { // decrease duty cycle
|
|
decrease_duty_cycle();
|
|
}
|
|
if (!(PIND & (1<<PD5))) { // turn on PWM
|
|
TCCR1B |= (1<<CS11);
|
|
}
|
|
if (!(PIND & (1<<PD6))) { // turn off PWM
|
|
TCCR1B &= ~(1<<CS11);
|
|
}
|
|
_delay_ms(50);
|
|
}
|
|
} |