Files
Arduino/14041130/TestLCD/SoftI2C.cppppp
2026-02-19 06:17:44 +03:30

130 lines
2.2 KiB
Plaintext

#include "SoftI2C.h"
SoftI2C::SoftI2C(uint8_t sda, uint8_t scl, uint32_t freq) {
sda_pin = sda;
scl_pin = scl;
delay_us = 1000000 / (2 * freq); // نیم پریود
}
void SoftI2C::begin() {
pinMode(sda_pin, INPUT_PULLUP);
pinMode(scl_pin, INPUT_PULLUP);
delay(10);
}
void SoftI2C::end() {
stop_condition();
pinMode(sda_pin, INPUT);
pinMode(scl_pin, INPUT);
}
void SoftI2C::start_condition() {
pinMode(sda_pin, OUTPUT);
sda_high();
scl_high();
i2c_delay();
sda_low();
i2c_delay();
scl_low();
i2c_delay();
}
void SoftI2C::stop_condition() {
pinMode(sda_pin, OUTPUT);
sda_low();
i2c_delay();
scl_high();
i2c_delay();
sda_high();
i2c_delay();
pinMode(sda_pin, INPUT_PULLUP);
pinMode(scl_pin, INPUT_PULLUP);
}
bool SoftI2C::write_byte(uint8_t data) {
pinMode(sda_pin, OUTPUT);
for(int i = 7; i >= 0; i--) {
if(data & (1 << i)) {
sda_high();
} else {
sda_low();
}
i2c_delay();
scl_high();
i2c_delay();
scl_low();
i2c_delay();
}
// خواندن ACK
pinMode(sda_pin, INPUT_PULLUP);
i2c_delay();
scl_high();
i2c_delay();
bool ack = !read_sda();
scl_low();
i2c_delay();
return ack;
}
uint8_t SoftI2C::read_byte(bool ack) {
pinMode(sda_pin, INPUT_PULLUP);
uint8_t data = 0;
for(int i = 7; i >= 0; i--) {
scl_high();
i2c_delay();
if(read_sda()) {
data |= (1 << i);
}
scl_low();
i2c_delay();
}
// ارسال ACK/NACK
pinMode(sda_pin, OUTPUT);
if(ack) {
sda_low();
} else {
sda_high();
}
i2c_delay();
scl_high();
i2c_delay();
scl_low();
i2c_delay();
return data;
}
bool SoftI2C::begin_transmission(uint8_t addr) {
start_condition();
return write_byte(addr << 1); // آدرس + بیت write
}
bool SoftI2C::write(uint8_t data) {
return write_byte(data);
}
bool SoftI2C::end_transmission() {
stop_condition();
return true;
}
uint8_t SoftI2C::request_from(uint8_t addr, uint8_t count) {
start_condition();
if(!write_byte((addr << 1) | 1)) { // آدرس + بیت read
return 0;
}
return count;
}
uint8_t SoftI2C::read() {
return read_byte(true);
}
bool SoftI2C::available() {
return true;
}