#define SDA_IN() {GPIOA->CRL&=0X0FFFFFFF;GPIOA->CRL|=(u32)8<<28;}
#define SDA_OUT() {GPIOA->CRL&=0X0FFFFFFF;GPIOA->CRL|=(u32)3<<28;}
#define IIC_SCK PAout(4)
#define IIC_SDA PAout(7)
#define READ_SDA PAin(7)
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能PORTA,PORTE时钟
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
IIC_SCK = 1;
IIC_SDA = 1;
}
void SDA_OUT_1(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void SDA_IN_1(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void IIC_Start(void)
{
SDA_OUT();
//SDA_OUT_1();
IIC_SDA = 1;
IIC_SCK = 1;
delay_us(4);
IIC_SDA = 0;
delay_us(4);
IIC_SCK=0;
}
void IIC_Stop(void)
{
SDA_OUT();
//SDA_OUT_1();
IIC_SCK = 0;
IIC_SDA = 0;
delay_us(4);
IIC_SCK = 1;
IIC_SDA = 1;
delay_us(4);
}
unsigned char IIC_ReadAck(void)
{
unsigned char i=0,uctemp=0;
SDA_IN();
//SDA_IN_1();
IIC_SDA = 1;
delay_us(1);
IIC_SCK = 1;
delay_us(1);
while(READ_SDA)
{
i++;
if(i > 250)
{
IIC_Stop();
return 0;
}
}
IIC_SCK = 0;
return 1;
}
void IIC_WriteByte(unsigned char ucByte)
{
unsigned char ucloop;
SDA_OUT();
//SDA_OUT_1();
IIC_SCK = 0;
for(ucloop=0;ucloop<8;ucloop++)
{
if((ucByte&0x80)>>7)
IIC_SDA = 1;
else
IIC_SDA = 0;
ucByte <<=1;
delay_us(2);
IIC_SCK = 1;
delay_us(2);
IIC_SCK = 0;
delay_us(2);
}
}
unsigned char IIC_ReadByte(void)
{
unsigned char uctemp=0;
unsigned char ucloop;
SDA_IN();
//SDA_IN_1();
IIC_SCK = 0;
for(ucloop=0;ucloop<8;ucloop++)
{
IIC_SCK = 0;
delay_us(2);
IIC_SCK = 1;
uctemp <<= 1;
if(READ_SDA)
uctemp++;
delay_us(1);
}
return (uctemp);
}
unsigned char CommandDataWrite(unsigned char ucCommand,unsigned char ucData)
{
unsigned char uctemp1,uctemp2;
IIC_Start();
IIC_WriteByte(ucCommand);
uctemp1 = IIC_ReadAck();
IIC_WriteByte(ucData);
uctemp2=IIC_ReadAck();
IIC_Stop();
if((uctemp1+uctemp2)>0)
return 1;
else
return 0;
}
unsigned char CommandDataRead(unsigned char ucCommand,unsigned char * pucData)
{
unsigned char uctemp1,uctemp2;
IIC_Start();
IIC_WriteByte(ucCommand);
uctemp1 = IIC_ReadAck();
*pucData = IIC_ReadByte(); //IIC_WriteByte(ucData);
uctemp2 = IIC_ReadAck();
IIC_Stop();
if((uctemp1+uctemp2)>0)
return 1;
else
return 0;
}
注意: 在SDA进行输入输出口切换时,使用寄存器操作!!!