Files
JYF_STC15W4K_wireless_charge/Driver/iic.c

124 lines
2.6 KiB
C
Raw Normal View History

2025-03-18 19:34:19 +08:00
#include "iic.h"
// 延时函数2us
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; // 写入成功
}