/*****************************
*
*IIC软件模拟
*
******************************/
#include "i2c.h"
void SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( GPIOB , &GPIO_InitStructure );
}
void SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init( GPIOB , &GPIO_InitStructure );
}
/************************************************
*
*IIC时钟及引脚初始化
*
**********************************************/
void I2C_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE);
GPIO_InitStructure.GPIO_Pin = IIC1_SDA | IIC1_SCL;//B6,B7为SDA,SDL
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;
GPIO_Init(IIC1_PORT, &GPIO_InitStructure);//port B初始化
GPIO_SetBits(IIC1_PORT,IIC1_SDA | IIC1_SCL);
}
void I2cReadDelayUs(unsigned int count)//ums
{
unsigned short j;
for(; count > 0; count--)
{
for(j = 0; j < 36; j++)//12
{
}
}
}
void I2cDelayUs(unsigned int count)//ums
{
unsigned short j;
for(; count > 0; count--)
{
for(j = 0; j < 144; j++)//12
{
}
}
}
void I2cDelayMs(unsigned int time)//nms
{
unsigned short i, j;
for(; time > 0; time--)
{
for(j = 0; j < 12; j++)
{
for(i = 0; i < 1000; i++);
}
}
}
unsigned char I2cAck(void)
{
uint16_t i;
i = 0;
SCL_H ;
I2cDelayUs(1);
while(READ_SDA&&(i<0x2b0))
{
i++;//应答超时计数
return 0;
}
SCL_L;
I2cDelayUs(1);
return 1;
}
//不产生ACK应答
void IIC_NAck(void)
{
SCL_L;
SDA_OUT();
SDA_H;
I2cDelayUs(1);
SCL_H;
I2cDelayUs(1);
SCL_L;
}
//发送应答位
void IIC_SendACK(void)
{
SCL_L;
SDA_OUT();
SDA_L;
I2cDelayUs(1);
SCL_H;
I2cDelayUs(1);
SCL_L;
SDA_IN();
}
//发送非应答位
void IIC_SendNOACK(void)
{
SDA_OUT();
SDA_H;
I2cDelayUs(1);
SCL_H;
I2cDelayUs(1);
SCL_L;
}
/********************************
*
*软件模拟开始位
*********************************/
void I2cStart(void)
{
SDA_OUT();
SDA_H;
I2cDelayUs(1);
SCL_H;
I2cDelayUs(1);
SDA_L;
I2cDelayUs(1);
}
/********************************
*
*软件模拟结束位
*********************************/
void I2cStop(void)
{
SDA_OUT();
SDA_L;
I2cDelayUs(1);
SCL_H;
I2cDelayUs(1);
SDA_H;
I2cDelayUs(1);
}
void I2cWriteByte(unsigned char byte)
{
uint16_t i;
SDA_OUT();
SCL_L;
I2cDelayUs(1);
for(i=0;i<8;i++)
{
if(byte&0x80)
SDA_H;
else
SDA_L;
byte=byte<<1;
SCL_H;
I2cDelayUs(1);
SCL_L;
I2cDelayUs(1);
}
SDA_IN();
}
void I2cWriteReg(unsigned char adr,unsigned char reg )
{
I2cStart();
I2cWriteByte(adr);
I2cAck();
I2cWriteByte(reg);
I2cAck();
I2cStop();
I2cDelayUs(10);
}
void I2cWriteData(unsigned char adr,unsigned char reg,unsigned char data)
{
I2cStart();
I2cWriteByte(adr);
I2cAck();
I2cWriteByte(reg);
I2cAck();
I2cWriteByte(data);
I2cAck();
I2cStop();
I2cDelayUs(10);
}
void I2cWriteBuffer(unsigned char adr,unsigned char reg, unsigned char arry[], unsigned char buffersize)
{
unsigned i;
I2cStart();
I2cWriteByte(adr);
I2cAck();
I2cWriteByte(reg);
I2cAck();
for(i=0; i<buffersize;i++)
{
I2cWriteByte(arry[i]);
I2cAck();
}
I2cStop();
I2cDelayUs(10);
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
unsigned char IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();
for(i=0;i<8;i++ )
{
receive<<=1;
SCL_L;
I2cDelayUs(2);
SCL_H;
if(READ_SDA)receive++;
I2cDelayUs(2);
}
SCL_L;
if (!ack)
{
IIC_SendNOACK();//发送nACK
}
else
{
IIC_SendACK();
}
return receive;
}
unsigned char IIC_Read_Reg(unsigned char adr,unsigned char reg)
{
unsigned char data;
data=255;
I2cStart();
I2cWriteByte(adr);//写寄存器地址
I2cAck();
I2cWriteByte(reg);
I2cAck();
I2cStart();
I2cWriteByte(adr+1);//读指令
if(I2cAck())
{
data=IIC_Read_Byte(1);
}
else
IIC_NAck();
I2cStop();
return data;
}
unsigned int IIC_Read_Reg_word(unsigned char adr,unsigned char reg)
{
unsigned int data;
I2cStart();
I2cWriteByte(adr);//写寄存器地址
I2cAck();
I2cWriteByte(reg);
I2cAck();
I2cStart();
I2cWriteByte(adr+1);//读指令
if(I2cAck())
{
data=IIC_Read_Byte(1)<<8;
data|=IIC_Read_Byte(0);
}
else
{//读取失败
IIC_NAck();
}
I2cStop();
return data;
}