Files
JYF_STC15W4K_wireless_charge/Driver/iic.c

206 lines
3.7 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.

#include "iic.h"
// 延时函数1us
void
IIC_Delay (void)
{
// 软件延时
// _nop_();_nop_();_nop_();_nop_();_nop_();// 30个nop约1us@30MHz
// _nop_();_nop_();_nop_();..............
DelayUs (1);
}
void
IIC_Init (void)
{
// 配置P2.6和P2.7为开漏模式
P2M1 |= 0xC0; // 1100 0000
P2M0 |= 0xC0; // 开漏模式
SDA = 1;
SCL = 1;
}
void
IIC_Start (void)
{
SDA = 1;
SCL = 1;
IIC_Delay ();
SDA = 0;
IIC_Delay ();
SCL = 0;
}
void
IIC_Stop (void)
{
SDA = 0;
SCL = 1;
IIC_Delay ();
SDA = 1;
IIC_Delay ();
}
void
IIC_SendByte (u8 dat)
{
u8 i;
for (i = 0; i < 8; i++)
{
SDA = (dat & 0x80) ? 1 : 0;
dat <<= 1;
IIC_Delay ();
SCL = 1;
IIC_Delay ();
SCL = 0;
}
}
u8
IIC_RecvByte (void)
{
u8 i, dat = 0;
SDA = 1; // 释放数据线
for (i = 0; i < 8; i++)
{
dat <<= 1;
SCL = 1;
IIC_Delay ();
if (SDA)
dat |= 0x01;
SCL = 0;
IIC_Delay ();
}
return dat;
}
bit
IIC_WaitAck (void)
{
SDA = 1; // 主机释放SDA
IIC_Delay ();
SCL = 1;
IIC_Delay ();
if (SDA)
{ // 检测SDA状态
SCL = 0;
return 0; // 无ACK
}
else
{
SCL = 0;
return 1; // 收到ACK
}
}
void
IIC_SendAck (bit ack)
{
SDA = ack ? 0 : 1;
IIC_Delay ();
SCL = 1;
IIC_Delay ();
SCL = 0;
SDA = 1; // 释放SDA
}
/**
* @brief I²C连续写入多个字节数据
* @param devAddr : 从机地址7位地址左对齐
* @param regAddr : 寄存器地址
* @param pData : 待写入数据缓冲区
* @param len : 数据长度
* @retval 写入状态1-成功0-失败
*/
bit
IIC_WriteBytes (u8 devAddr, u8 regAddr, u8 *pData, u8 len)
{
IIC_Start (); // 启动I²C通信[6](@ref)
// 发送设备地址(写模式)
IIC_SendByte (devAddr & 0xFE); // 7位地址+写位(0)
if (!IIC_WaitAck ())
{ // 检测从机应答
IIC_Stop ();
return 0; // 无应答则终止[2](@ref)
}
// 发送寄存器地址
IIC_SendByte (regAddr);
if (!IIC_WaitAck ())
{
IIC_Stop ();
return 0; // 寄存器地址无应答
}
// 循环发送数据字节
while (len--)
{
IIC_SendByte (*pData++); // 发送当前字节
if (!IIC_WaitAck ())
{ // 检测数据应答
IIC_Stop ();
return 0; // 数据写入失败
}
}
IIC_Stop (); // 结束通信[6](@ref)
return 1; // 写入成功
}
/**
* @brief I²C连续读取多个字节数据
* @param devAddr : 从机地址7位地址左对齐
* @param regAddr : 寄存器地址
* @param pData : 接收数据缓冲区
* @param len : 数据长度
* @retval 读取状态1-成功0-失败
*/
bit
IIC_ReadBytes (u8 devAddr, u8 regAddr, u8 *pData, u8 len)
{
IIC_Start (); // 启动I²C通信
// 发送设备地址(写模式)
IIC_SendByte (devAddr & 0xFE); // 7位地址+写位(0)
if (!IIC_WaitAck ())
{ // 检测从机应答
IIC_Stop ();
return 0; // 无应答则终止
}
// 发送寄存器地址
IIC_SendByte (regAddr);
if (!IIC_WaitAck ())
{
IIC_Stop ();
return 0; // 寄存器地址无应答
}
// 重新启动I²C通信重复启动
IIC_Start ();
// 发送设备地址(读模式)
IIC_SendByte (devAddr | 0x01); // 7位地址+读位(1)
if (!IIC_WaitAck ())
{ // 检测从机应答
IIC_Stop ();
return 0; // 无应答则终止
}
// 循环读取数据字节
while (len--)
{
*pData++ = IIC_RecvByte (); // 接收当前字节
if (len > 0)
{
IIC_SendAck (1); // 发送ACK
}
else
{
IIC_SendAck (0); // 发送NACK
}
}
IIC_Stop (); // 结束通信
return 1; // 读取成功
}