3、参考代码 子函数文件 iic.c #include "myi2c.h"
void I2C_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = SCL_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SDA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void I2C_delay(void)
{
u8 i=10; //这里可以优化速度 ,经测试最低到5还能写入
while(i)
{
i--;
}
} void delay5ms(void)
{
int i=5000;
while(i)
{
i--;
}
}
uint16_t I2C_Start(void)
{
SDA_H;
SCL_H;
I2C_delay();
if(!SDA_read)return FALSE; //SDA线为低电平则总线忙,退出
SDA_L;
I2C_delay();
if(SDA_read) return FALSE; //SDA线为高电平则总线出错,退出
SDA_L;
I2C_delay();
return TRUE;
}
void I2C_Stop(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SDA_H;
I2C_delay();
}
void I2C_Ack(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
void I2C_NoAck(void)
{
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
uint16_t I2C_WaitAck(void) //返回为:=1有ACK,=0无ACK
{
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
if(SDA_read)
{
SCL_L;
I2C_delay();
return FALSE;
}
SCL_L;
I2C_delay();
return TRUE;
}
void I2C_SendByte(unsigned char SendByte) //数据从高位到低位//
{
u8 i=8;
while(i--)
{
SCL_L;
I2C_delay();
if(SendByte&0x80)
SDA_H;
else
SDA_L;
SendByte<<=1;
I2C_delay();
SCL_H;
I2C_delay();
}
SCL_L;
}
unsigned char I2C_RadeByte(void) //数据从高位到低位//
{
u8 i=8;
u8 ReceiveByte=0; SDA_H;
while(i--)
{
ReceiveByte<<=1;
SCL_L;
I2C_delay();
SCL_H;
I2C_delay();
if(SDA_read)
{
ReceiveByte|=0x01;
}
}
SCL_L;
return ReceiveByte;
}
//ZRX
//单字节写入***************************** uint16_t Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data) //void
{
if(!I2C_Start())return FALSE;
I2C_SendByte(SlaveAddress); //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}
I2C_SendByte(REG_Address ); //设置低起始地址
I2C_WaitAck();
I2C_SendByte(REG_data);
I2C_WaitAck();
I2C_Stop();
delay5ms();
return TRUE;
} //单字节读取****************************
unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address)
{ unsigned char REG_data;
if(!I2C_Start())return FALSE;
I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址
if(!I2C_WaitAck()){I2C_Stop();return FALSE;}
I2C_SendByte((u8) REG_Address); //设置低起始地址
I2C_WaitAck();
I2C_Start();
I2C_SendByte(SlaveAddress+1);
I2C_WaitAck(); REG_data= I2C_RadeByte();
I2C_NoAck();
I2C_Stop();
//return TRUE;
return REG_data; }
头文件 iic.h #ifndef __MYI2C_H__ #define __MYI2C_H__ #define FALSE 0 #define TRUE 1 #define SCL_PIN GPIO_Pin_6 #define SDA_PIN GPIO_Pin_7 #define SCL_H GPIOB->BSRR = SCL_PIN #define SCL_L GPIOB->BRR = SCL_PIN #define SDA_H GPIOB->BSRR = SDA_PIN #define SDA_L GPIOB->BRR = SDA_PIN #define SCL_read GPIOB->IDR & SCL_PIN #define SDA_read GPIOB->IDR & SDA_PIN void I2C_GPIO_Config(void); void I2C_delay(void); void delay5ms(void); uint16_t I2C_Start(void); void I2C_Stop(void); void I2C_Ack(void); void I2C_NoAck(void); uint16_t I2C_WaitAck(void); void I2C_SendByte(unsigned char SendByte); unsigned char I2C_RadeByte(void); uint16_t Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data); unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address); #endif // __MYI2C_H__
|