我有一個非常簡單的ATTINY85 I2C位打包庫。讀取I2C傳感器值(bit-banging)
#define PORT_SDA PB0
#define PORT_SCL PB2
#define SIGNAL_HIGH(PORT) PORTB |= (1 << PORT)
#define SIGNAL_LOW(PORT) PORTB &= ~(1 << PORT)
void LED_ON(void);
void LED_OFF(void);
void i2c_init(void);
void i2c_start(void);
void i2c_read(void);
void i2c_stop(void);
void i2c_write(uint8_t byte);
void i2c_init()
{
DDRB |= (1 << PORT_SDA);
DDRB |= (1 << PORT_SCL);
}
void LED_ON(void)
{
PORTB |= 0b00000010;
}
void LED_OFF(void)
{
PORTB &= 0b111111101;
}
void i2c_start(void)
{
SIGNAL_HIGH(PORT_SCL);
SIGNAL_HIGH(PORT_SDA);
SIGNAL_LOW( PORT_SDA);
SIGNAL_LOW( PORT_SCL);
}
void i2c_stop(void)
{
SIGNAL_LOW( PORT_SCL);
SIGNAL_LOW( PORT_SDA);
SIGNAL_HIGH(PORT_SCL);
SIGNAL_HIGH(PORT_SDA);
}
void i2c_write(uint8_t byte)
{
uint8_t bit;
for (bit = 0; bit < 0x08; bit++)
{
if((byte << bit) & 0x80)
SIGNAL_HIGH(PORT_SDA);
else
SIGNAL_LOW(PORT_SDA);
SIGNAL_HIGH(PORT_SCL);
SIGNAL_LOW(PORT_SCL);
}
SIGNAL_HIGH(PORT_SDA);
SIGNAL_HIGH(PORT_SCL);
SIGNAL_LOW(PORT_SCL);
}
我能夠成功寫入I2C,沒有任何問題。我已經用SSD1306和LC2404B測試了這個代碼,如果VCC設置爲4.2V,即使時序也一切正常。
i2c_init();
i2c_start();
i2c_write(0xA0);
i2c_write(0x01);
i2c_write(0x13);
i2c_stop();
雖然書面方式,完美的作品,我似乎無法能夠引起我的任何I2C模塊,ATTINY85回我,我以後可以讀取值。
我連接覆盆子和GY-521傳感器(因爲即使未設置內部地址,它也會返回值)。我可以檢測傳感器,並與覆盆子從中讀取的值通過以下方式:
i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
i2cget -y 1 0x68
0x02
這是示波器上的輸出:
我可以看到傳感器數據改變。問題是我似乎無法從ATTINY85向傳感器複製相同的請求。傳感器根本無法用該值做出響應。 我似乎無法理解,如果第一個字節的最後一位是ACK或'READ'指示位,所以我嘗試了不同的地址。
i2c_start();
i2c_write( 0b11010001); // address: 0xD1
i2c_start();
i2c_write( 0b11010000); // address: 0xD0
i2c_start();
i2c_write( 0b10100001); // address: 0xA1
i2c_start();
i2c_write( 0b10100000); // address: 0xA0
,但無論對我所用的地址,傳感器根本不迴應(在oscioloscope)和SDA線保持高之後我發送地址字節。我也嘗試在發送地址後追加另一個start()條件,但仍然沒有運氣。任何提示我要去哪裏錯?我只是想讓傳感器響應ATTINY85讀取請求,以便稍後可以讀取該值。謝謝!
「您還需要提供從設備用於輸出數據的時鐘。」就是這樣!非常感謝你! – Kristian