diff --git a/slave/slave_v2.c b/slave/slave_v2.c new file mode 100644 index 0000000..13b4361 --- /dev/null +++ b/slave/slave_v2.c @@ -0,0 +1,144 @@ +// +// Created by FSB-PC on 23.06.2023. +// + +// #include + +// void setup() { +// Wire.begin(9); // Устанавливаем адрес слейва +// Wire.onReceive(receiveEvent); // Указываем функцию для обработки приема данных +// Serial.begin(9600); +// } + +// void loop() { +// // Здесь можно добавить другие действия слейва, если необходимо +// } + +// void receiveEvent(int numBytes) { +// while (Wire.available()) { +// uint8_t cmd = Wire.read(); +// uint8_t upper_byte = Wire.read(); +// uint8_t lower_byte = Wire.read(); + +// uint16_t cmd_value = (upper_byte << 8) | lower_byte; +// float value = cmd_value / 16.0; + +// Serial.print("Received command: 0x"); +// Serial.print(cmd, HEX); +// Serial.print(", value: "); +// Serial.print(value); + +// Serial.print(", data bytes: 0x"); +// Serial.print(upper_byte, HEX); +// Serial.print(" "); +// Serial.println(lower_byte, HEX); +// } +// } + + +#include +#include + +#define SLAVE_ADDRESS 9 // адрес устройства slave +#define COMMAND_1 0x01 //команда включения шим +#define COMMAND_2 0x02 //команда выключения шим +#define COMMAND_3 0x03 //команда изменения частоты шим +#define COMMAND_4 0x04 //команда изменения скважности шим + +uint16_t frequency = 1 << 4; +uint8_t dutycycle = 50; +uint8_t buffer[32]; // буфер для полученных данных +uint8_t cnt = 0; // счетчик байтов +bool tran_end = false; //флаг окончания передачи + +void i2c_init() { + TWAR = SLAVE_ADDRESS << 1; // задаем адрес устройства + TWSR = 0; // частота шины 100 кГц (скорость передачи) + TWCR = (1 << TWEN) | (1 << TWEA) | (1 << TWIE); // включаем slave reciever +} + +// обработчик прерывания TWI +ISR(TWI_vect) { + switch (TWSR) { + case 0x60: // SLA+W received, ACK returned + //cnt = 0; // сброс счетчика + //tran_end = false; + TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA) | (1 << TWIE); // включаем прерывание и устанавливаем бит ACK + break; + case 0x80: // data byte received, ACK returned + buffer[cnt++] = TWDR; // сохраняем принятые данные + TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA) | (1 << TWIE); + break; + case 0x88: // last data byte received, NACK returned + buffer[cnt++] = TWDR; // сохраняем последний байт данных + TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA) | (1 << TWIE); + break; + case 0xA0: // STOP or repeated START received + tran_end = true; + TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA) | (1 << TWIE); + break; + default: + TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA) | (1 << TWIE); + break; + } +} + +void timer1_init() { + PORTB = 0; + DDRB |= (1 << PORTB1); //OC1A + DDRB |= (1 << PORTB2); //OC1B + TCCR1A = 0; // обнуляем регистры управления + TCCR1B = 0; + TCNT1 = 0; // и счетный регистр +} + +//частота приходит в 16 раз больше +void timer1_on(uint16_t frequency, uint8_t dutycycle) { + // Неинверсный режим работы + TCCR1A |= (0 << COM1A1) | (0 << COM1A0) | (1 << COM1B1) | (0 << COM1B0); + + //Fast PWM (Быстрый ШИМ) + TCCR1A |= (1 << WGM11) | (1 << WGM10); + TCCR1B |= (1 << WGM13) | (1 << WGM12); + + //Предделитель - 1024 + TCCR1B |= (1 << CS12) | (0 << CS11) | (1 << CS10); + + //Частота + OCR1A = F_CPU / 1024 * 16 / frequency; + + //Скважность + OCR1B = (F_CPU / 1024 * 16 / frequency) * dutycycle / 100; +} + +void timer1_off() { + TCCR1A |= (0 << COM1A1) | (0 << COM1A0) | (0 << COM1B1) | (0 << COM1B0); //шим отключен, нормальная работа порта +} + +void setup(void) { + i2c_init(); //инициализация i2c + timer1_init(); + Serial.begin(9600); + Serial.println("PWM Slave started!"); + sei(); // включаем прерывания +} + +void loop() { + if (tran_end) { + tran_end = false; + if (buffer[0] == COMMAND_1) { + Serial.println(buffer[0]); + timer1_on(frequency, dutycycle); // Включение ШИМ + } else if (buffer[0] == COMMAND_2) { + Serial.println(buffer[0]); + timer1_off(); // Выключение ШИМ + } else if (buffer[0] == COMMAND_3) { + Serial.println(buffer[0]); + + frequency = (buffer[1] << 8) + buffer[2]; + } else if (buffer[0] == COMMAND_4) { + dutycycle = buffer[1]; + } + cnt = 0; + } +}