给个参考你
//______________________________________________________________
// IIC_Init
//______________________________________________________________
//
// IIC总线初始化
//
bit IIC_Init(void)
{
//调用之前需要初始化GPIO
//IIC_GpioInit();
//________________
// GPIO
//TICK_Delay(20);
//________________
// STD
SDA_1();
SDA_OUTPUT();
SCL_1();
IIC_DelayStd();
IIC_Stop();
if (1)
{
if (!AT24X_Init())
{
return 0;
}
}
return 1;
}
//______________________________________________________________
// IIC_Start
//______________________________________________________________
//
// I2C开始信号,注意结束时GPIO_I2C_SCL=0,GPIO_I2C_SDA=1
//
void IIC_Start(void)
{
SCL_0();
IIC_DelayStd();
SDA_1();
SDA_OUTPUT();
IIC_DelayStd();
SCL_1();
IIC_DelayStd();
SDA_0();
IIC_DelayStd();
SCL_0(); // SCL = 0, SDA = 1
IIC_DelayStd();
SDA_1();
}
//______________________________________________________________
// IIC_Stop
//______________________________________________________________
//
// I2C停止信号,结束时SDA=1,SCL=1,确保I2C总线在停止状态
//
void IIC_Stop(void)
{
SCL_0();
IIC_DelayStd();
SDA_0();
SDA_OUTPUT();
IIC_DelayStd();
SCL_1();
IIC_DelayStd();
SDA_1();
IIC_DelayStd();
}
//______________________________________________________________
// IIC_Send
//______________________________________________________________
//
// 发送一个字节,失败后会自动停止总线(发送stop)
// byte = 数据
// 返回: 0 = 失败, 1 = 成功
//
bit IIC_Send(u8 ucData)
{
SDA_OUTPUT();
u32 uiTmp = ucData;
for (u32 i=0; i<8; i++)
{
if (uiTmp & BIT7)
{
SDA_1();
}
else
{
SDA_0();
}
uiTmp <<= 1;
IIC_DelaySda();
SCL_1();
IIC_DelaySclHigh();
SCL_0();
//IIC_DelaySclLow();
}
SDA_INPUT();
IIC_DelaySda();
SCL_1();
IIC_DelayStd();
if (!SDA_VALUE)
{
SCL_0();
return 1;
}
else
{
__DEBUG();
}
//___________________________________
// 失败停止总线
IIC_Stop();
return 0;
}
//______________________________________________________________
// IIC_Receive
//______________________________________________________________
//
// 接收一个字节
// ack : 应答信号ACK或NACK
// 返回: 接收的字节
// 注: 软件模拟方式无法判断是否成功或失败,所以总是成功
//
u8 IIC_Receive(bit bAck)
{
SDA_INPUT();
u32 uiTmp = 0;
for (u32 i=0; i<8; i++)
{
uiTmp <<= 1;
SCL_1();
IIC_DelaySclHigh();
vu32 uiSda = SDA_VALUE;
SCL_0();
if (uiSda)
{
uiTmp++;
}
IIC_DelaySclLow();
}
//___________________________________
// 主机应答从机
SDA_OUTPUT();
SDA_OUT(bAck);
IIC_DelaySda();
SCL_1();
IIC_DelayStd();
SCL_0();
IIC_DelayStd();
SDA_1(); // 接收结束时GPIO_I2C_SDA=1
return uiTmp;
}
//______________________________________________________________
// IIC_SendSame
//______________________________________________________________
//
// 发送多个重复的字节(主要用于初始化).
//
bit IIC_SendSame(const u8 ucData, u32 uiNumber)
{
while (uiNumber--)
{
if (IIC_Send(ucData) == 0)
{
return 0;
}
}
IIC_Stop();
return 1;
}
//______________________________________________________________
// IIC_SendBuffer
//______________________________________________________________
//
// 发送多个字节
//
bit IIC_SendBuffer(void* pVoid, u32 uiNumber)
{
u8* pSrc = (u8*)pVoid;
while (uiNumber--)
{
if (IIC_Send(*pSrc++) == 0)
{
return 0;
}
}
IIC_Stop();
return 1;
}
//______________________________________________________________
// IIC_ReceiveBuffer
//______________________________________________________________
//
// 接收多个字节
//
bit IIC_ReceiveBuffer(void* pVoid, u32 uiNumber)
{
u8* pSrc = (u8*)pVoid;
u32 uiTmp = uiNumber -1;
while (uiTmp--)
{
*pSrc++ = IIC_Receive(I2C_ACK);
}
*pSrc = IIC_Receive(I2C_NACK);
IIC_Stop();
return 1;
}
//______________________________________________________________
// IIC_Query
//______________________________________________________________
//
// 查询IIC器件操作是否完成
// ucDevice = 器件选择(建议写操作,主机主动)
// uiTimeout = 超时间
// 返回: 0 = 未完成, 1 = 完成
//
// 注意: 可能不同的设备需要定制查询程序
//
bit IIC_Query(u8 ucDevice, const u32 uiTimeout)
{
//_______________________
// 简化算法
if (0)
{
TICK_Delay(uiTimeout);
return 1;
}
else
{
//_______________________
// 正常算法
u32 uiTmp = INT_GetTick();
while (1)
{
IIC_Start(); // !!!
if (IIC_Send(ucDevice) == 1)
{
IIC_Stop();
return 1;
}
else
{
//TICK_Delay(1ms);
if (TICK_IfTimeOut(uiTmp, uiTimeout))
{
return 0;
}
else
{
__DEBUG();
}
}
}
}
}
/*
//______________________________________________________________
// 函数延时方式
//______________________________________________________________
*/
#if cfg_I2C_DELAY_MODE != 0
//______________________________________________________________
// IIC_Delay
// IIC_DelayStd
// IIC_DelaySda
// IIC_DelaySclHigh
// IIC_DelaySclLow
//______________________________________________________________
//
// iic延时函数
//
static void IIC_Delay(void)
{
TVS_BasicDelay(1.25vs-10);
}
static void IIC_DelayStd(void)
{
IIC_Delay();
}
static void IIC_DelaySda(void)
{
TVS_BasicDelay(0.5vs);
}
static void IIC_DelaySclHigh(void)
{
IIC_Delay();
}
static void IIC_DelaySclLow(void)
{
IIC_Delay();
}
#endif
|