typedef unsigned char u8;
#define I2C_Pin_SCL GPIO_Pin_4
#define I2C_Pin_SDA GPIO_Pin_5
#define SCL_H GPIOA_SetBits( I2C_Pin_SCL )
#define SCL_L GPIOA_ResetBits( I2C_Pin_SCL )
#define SDA_H GPIOA_SetBits( I2C_Pin_SDA )
#define SDA_L GPIOA_ResetBits( I2C_Pin_SDA )
#define SCL_read GPIOA_ReadPortPin( I2C_Pin_SCL )
#define SDA_read GPIOA_ReadPortPin( I2C_Pin_SDA )
#define SCL_out GPIOA_ModeCfg(I2C_Pin_SCL, GPIO_ModeOut_PP_5mA)
#define SCL_in GPIOA_ModeCfg(I2C_Pin_SCL, GPIO_ModeIN_PU)
#define SDA_out GPIOA_ModeCfg(I2C_Pin_SDA, GPIO_ModeOut_PP_5mA)
#define SDA_in GPIOA_ModeCfg(I2C_Pin_SDA, GPIO_ModeIN_PU)
void I2CInit(void);
int I2C_7bit_Single_Write(u8 SlaveAddress,u8 REG_data);
u8 I2C_7bit_Single_Read(u8 SlaveAddress);
int I2C_7bit_Mult_Read(u8 SlaveAddress,u8 * ptChar,u8 size);
int I2C_10bit_Single_Write(u8 SlaveAddress,u8 REG_Address,u8 REG_data);
u8 I2C_10bit_Single_Read(u8 SlaveAddress,u8 REG_Address);
int I2C_10bit_Mult_Read(u8 SlaveAddress,u8 REG_Address,u8 * ptChar,u8 size);
void I2C_delay(void);
int I2C_Start(void);
void I2C_Stop(void);
void I2C_Ack(void);
void I2C_NoAck(void);
int I2C_WaitAck(void); //返回为:=1有ACK,=0无ACK
void I2C_SendByte(u8 SendByte);
u8 I2C_ReadByte(void); //数据从高位到低位//
void I2CInit(void)
{
SCL_out;
SDA_out;
}
void I2C_delay(void)
{
mDelayuS(100);
}
int I2C_Start(void)
{
SDA_H;
SDA_out;
SCL_H;
I2C_delay();
if(!SDA_read)return 0; //SDA线为低电平则总线忙,退出
SDA_L;
I2C_delay();
if(SDA_read) return 0; //SDA线为高电平则总线出错,退出
SDA_L;
I2C_delay();
return 1;
}
void I2C_Stop(void)
{
SCL_L;
I2C_delay();
SDA_L;
SDA_out;
I2C_delay();
SCL_H;
I2C_delay();
SDA_H;
I2C_delay();
}
void I2C_Ack(void)
{
SCL_L;
I2C_delay();
SDA_L;
SDA_out;
I2C_delay();
SCL_H;
I2C_delay();
I2C_delay();
SCL_L;
I2C_delay();
}
void I2C_NoAck(void)
{
SCL_L;
I2C_delay();
SDA_H;
SDA_out;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
int I2C_WaitAck(void) //返回为:=1有ACK,=0无ACK
{
SCL_L;
I2C_delay();
I2C_delay();
SCL_H;
SDA_in;
I2C_delay();
I2C_delay();
if(SDA_read)
{
SCL_L;
return 0;
}
SCL_L;
return 1;
}
void I2C_SendByte(u8 SendByte) //数据从高位到低位//
{
u8 i=8;
SDA_out;
while(i--)
{
SCL_L;
I2C_delay();
if(SendByte&0x80)
SDA_H;
else
SDA_L;
SendByte<<=1;
I2C_delay();
SCL_H;
I2C_delay();
I2C_delay();
}
SCL_L;
}
u8 I2C_ReadByte(void) //数据从高位到低位//
{
u8 i=8;
u8 ReceiveByte=0;
SDA_H;
SDA_out;
while(i--)
{
ReceiveByte<<=1;
SCL_L;
I2C_delay();
I2C_delay();
SCL_H;
SDA_in;
I2C_delay();
I2C_delay();
if(SDA_read)
{
ReceiveByte|=0x01;
}
}
SCL_L;
return ReceiveByte;
}
//7bit地址单字节写入*******************************************
int I2C_7bit_Single_Write(u8 SlaveAddress, u8 REG_data)
{
if(!I2C_Start())return 0;
I2C_SendByte(SlaveAddress); //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck()){I2C_Stop(); return 0;}
I2C_SendByte(REG_data);
I2C_WaitAck();
I2C_Stop();
return 1;
}
//7bit地址单字节读取*****************************************
u8 I2C_7bit_Single_Read(u8 SlaveAddress)
{
unsigned char REG_data;
if(!I2C_Start())return 0;
I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck())
{
I2C_Stop();
return 0;
}
I2C_Start();
I2C_SendByte(SlaveAddress+1);
I2C_WaitAck();
REG_data= I2C_ReadByte();
I2C_NoAck();
I2C_Stop();
//return TRUE;
return REG_data;
}
//7bit地址多字节读取*****************************************
int I2C_7bit_Mult_Read(u8 SlaveAddress,u8 * ptChar,u8 size)
{
u8 i;
if(size < 1)
return 0;
if(!I2C_Start())
return 0;
I2C_SendByte(SlaveAddress);
if(!I2C_WaitAck())
{
I2C_Stop();
return 0;
}
I2C_Start();
I2C_SendByte(SlaveAddress+1);
I2C_WaitAck();
for(i=1;i<size; i++)
{
*ptChar++ = I2C_ReadByte();
I2C_Ack();
}
*ptChar++ = I2C_ReadByte();
I2C_NoAck();
I2C_Stop();
return 1;
}
//10bit地址单字节写入*******************************************
int I2C_10bit_Single_Write(u8 SlaveAddress,u8 REG_Address,u8 REG_data)
{
if(!I2C_Start())return 0;
I2C_SendByte(SlaveAddress); //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck()){I2C_Stop(); return 0;}
I2C_SendByte(REG_Address ); //设置低起始地址
I2C_WaitAck();
I2C_SendByte(REG_data);
I2C_WaitAck();
I2C_Stop();
return 1;
}
//10bit地址单字节读取*****************************************
u8 I2C_10bit_Single_Read(u8 SlaveAddress,u8 REG_Address)
{
unsigned char REG_data;
if(!I2C_Start())return 0;
I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck())
{
I2C_Stop();
return 0;
}
I2C_SendByte((u8) REG_Address); //设置低起始地址
I2C_WaitAck();
I2C_Start();
I2C_SendByte(SlaveAddress+1);
I2C_WaitAck();
REG_data= I2C_ReadByte();
I2C_NoAck();
I2C_Stop();
//return TRUE;
return REG_data;
}
//10bit地址多字节读取*****************************************
int I2C_10bit_Mult_Read(u8 SlaveAddress,u8 REG_Address,u8 * ptChar,u8 size)
{
u8 i;
if(size < 1)
return 0;
if(!I2C_Start())
return 0;
I2C_SendByte(SlaveAddress);
if(!I2C_WaitAck())
{
I2C_Stop();
return 0;
}
I2C_SendByte(REG_Address);
I2C_WaitAck();
I2C_Start();
I2C_SendByte(SlaveAddress+1);
I2C_WaitAck();
for(i=1;i<size; i++)
{
*ptChar++ = I2C_ReadByte();
I2C_Ack();
}
*ptChar++ = I2C_ReadByte();
I2C_NoAck();
I2C_Stop();
return 1;
}
单片机模拟iic(通用版)
于 2022-10-11 10:23:49 首次发布