8.Master_I2C_PWM/slave/slave_v2.c
2023-06-23 13:23:15 +03:00

145 lines
5.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by FSB-PC on 23.06.2023.
//
// #include <Wire.h>
// 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 <avr/io.h>
#include <avr/interrupt.h>
#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;
}
}