109 lines
2.7 KiB
C++
109 lines
2.7 KiB
C++
|
#include "iic.h"
|
||
|
|
||
|
static inline void iic_Start(SW_Dev_IIC dev) {
|
||
|
dev.SDA_MODE(OUT);
|
||
|
dev.SDA_SET(HIGH);
|
||
|
dev.CLK_SET(HIGH);DELAY1US();
|
||
|
dev.SDA_SET(LOW);DELAY1US();
|
||
|
dev.CLK_SET(LOW);
|
||
|
}
|
||
|
|
||
|
//结束信号
|
||
|
static inline void iic_Stop(SW_Dev_IIC dev) {
|
||
|
dev.SDA_MODE(OUT);
|
||
|
dev.CLK_SET(LOW);
|
||
|
dev.SDA_SET(LOW);DELAY1US();
|
||
|
dev.CLK_SET(HIGH);
|
||
|
dev.SDA_SET(HIGH);
|
||
|
}
|
||
|
|
||
|
//等待信号响应
|
||
|
static inline uint8_t iic_WaitAck(SW_Dev_IIC dev, uint16_t timeout) {
|
||
|
uint16_t time = 0;
|
||
|
dev.SDA_MODE(IN);
|
||
|
dev.SDA_SET(HIGH);DELAY1US();
|
||
|
dev.CLK_SET(HIGH);DELAY1US();
|
||
|
while (dev.SDA()) {
|
||
|
time++;DELAY1US();
|
||
|
if (time > timeout) {
|
||
|
iic_Stop(dev);
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
dev.CLK_SET(LOW);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static inline void iic_Ack(SW_Dev_IIC dev) {
|
||
|
dev.CLK_SET(LOW);
|
||
|
dev.SDA_MODE(OUT);
|
||
|
dev.SDA_SET(LOW);DELAY1US();DELAY1US();
|
||
|
dev.CLK_SET(HIGH);DELAY1US();DELAY1US();
|
||
|
dev.CLK_SET(LOW);
|
||
|
}
|
||
|
|
||
|
static inline void iic_NAck(SW_Dev_IIC dev) {
|
||
|
dev.CLK_SET(LOW);
|
||
|
dev.SDA_MODE(OUT);
|
||
|
dev.SDA_SET(HIGH);DELAY1US();DELAY1US();
|
||
|
dev.CLK_SET(HIGH);DELAY1US();DELAY1US();
|
||
|
dev.CLK_SET(LOW);
|
||
|
}
|
||
|
|
||
|
//写入一个字节
|
||
|
static inline void iic_W(SW_Dev_IIC dev, uint8_t date) {
|
||
|
dev.SDA_MODE(OUT);
|
||
|
uint8_t i;
|
||
|
for (i = 0; i < 8; i++) {
|
||
|
dev.CLK_SET(LOW);
|
||
|
if (date & 0x80) {
|
||
|
dev.SDA_SET(HIGH);
|
||
|
} else {
|
||
|
dev.SDA_SET(LOW);
|
||
|
}DELAY1US();DELAY1US();
|
||
|
dev.CLK_SET(HIGH);DELAY1US();DELAY1US();
|
||
|
dev.CLK_SET(LOW);DELAY1US();DELAY1US();
|
||
|
date <<= 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static inline uint8_t iic_R(SW_Dev_IIC dev, uint8_t ack) {
|
||
|
unsigned char i, read = 0;
|
||
|
dev.SDA_MODE(IN);
|
||
|
for (i = 0; i < 8; i++) {
|
||
|
dev.CLK_SET(LOW);DELAY1US();DELAY1US();
|
||
|
dev.CLK_SET(HIGH);
|
||
|
read <<= 1;
|
||
|
if (dev.SDA())read++;DELAY1US();
|
||
|
}
|
||
|
if (ack)
|
||
|
iic_Ack(dev); //发送ACK
|
||
|
else
|
||
|
iic_NAck(dev); //发送NACK
|
||
|
return read;
|
||
|
}
|
||
|
|
||
|
void SW_IIC_WL(SW_Dev_IIC Dev, uint8_t InternalAddress, uint8_t *Write_Data, uint32_t Len) {
|
||
|
iic_Start(Dev);
|
||
|
iic_W(Dev, Dev.ADD);
|
||
|
iic_WaitAck(Dev, 200);
|
||
|
iic_W(Dev, InternalAddress);
|
||
|
iic_WaitAck(Dev, 200);
|
||
|
for (uint32_t i = 0; i < Len; i++) {
|
||
|
iic_W(Dev, Write_Data[i]);
|
||
|
iic_WaitAck(Dev, 200);
|
||
|
}
|
||
|
iic_Stop(Dev);
|
||
|
}
|
||
|
|
||
|
void SW_IIC_RL(SW_Dev_IIC Dev, uint8_t InternalAddress, uint8_t *Read_Data, uint32_t Len, uint8_t Ack) {
|
||
|
iic_Start(Dev);
|
||
|
iic_W(Dev, Dev.ADD);
|
||
|
iic_WaitAck(Dev, 200);
|
||
|
iic_W(Dev, InternalAddress);
|
||
|
iic_WaitAck(Dev, 200);
|
||
|
for (uint32_t i = 0; i < Len; i++) {
|
||
|
Read_Data[i] = iic_R(Dev, Ack);
|
||
|
}
|
||
|
iic_Stop(Dev);
|
||
|
}
|