/*****************************IIC通信协议***************************/
#define _IIC11
#define _IIC20
#define IIC1_SCLPB6
#define IIC1_SDAPB7
#define IIC2_SCL PB10
#define IIC2_SDAPB11
#if _IIC1
#define SDA_IN(){GPIOB->CRL &= 0X0FFFFFFF; GPIOB->CRL |= (u32)8<<28;}
#define SDA_OUT(){GPIOB->CRL &= 0X0FFFFFFF; GPIOB->CRL |= (u32)3<<28;}
#endif
#if _IIC2
#define SDA_IN(){GPIOB->CRH &= 0XFFFF0FFF; GPIOB->CRH |= (u32)8<<12;}
#define SDA_OUT(){GPIOB->CRH &= 0XFFFF0FFF; GPIOB->CRH |= (u32)3<<12;}
#endif
#define IIC1_SCL_HighwriteGpioHigh(IIC1_SCL)
#define IIC1_SCL_LowwriteGpioLow(IIC1_SCL)
#define IIC1_SDA_HighwriteGpioHigh(IIC1_SDA)
#define IIC1_SDA_LowwriteGpioLow(IIC1_SDA)
#define IIC2_SCL_HighwriteGpioHigh(IIC2_SCL)
#define IIC2_SCL_LowwriteGpioLow(IIC2_SCL)
#define IIC2_SDA_HighwriteGpioHigh(IIC2_SDA)
#define IIC2_SDA_LowwriteGpioLow(IIC2_SDA)
void iicStart(void)
{
SDA_OUT(); //sda线输出
IIC1_SCL_High;
IIC1_SDA_High;
delayNop(2);
IIC1_SDA_Low;
delayNop(2);
IIC1_SCL_Low; //钳住I2C总线,准备发送或接收数据
}
void iicStop(void)
{
SDA_OUT(); //sda线输出
IIC1_SDA_Low;
IIC1_SCL_Low;
delayNop(2);
IIC1_SCL_High;
IIC1_SDA_High;
delayNop(2);
}
u8 iicWaitAck(void)
{
u8 errorAck = 0;
SDA_IN();
IIC1_SCL_High;
delayNop(2);
IIC1_SDA_High;
delayNop(2);
while( GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7) == Bit_SET )
{
errorAck++;
if(errorAck > 250)
{
iicStop();
return 0;
}
}
IIC1_SCL_Low;
return 1;
}
//产生应答
void iicACK(void)
{
IIC1_SCL_Low;
SDA_OUT();
IIC1_SDA_Low;
delayNop(2);
IIC1_SCL_High;
delayNop(2);
IIC1_SCL_Low;
}
void iicNOack(void)
{
IIC1_SCL_Low;
SDA_OUT();
IIC1_SDA_High;
delayNop(2);
IIC1_SCL_High;
delayNop(2);
IIC1_SCL_Low;
}
void iicWrite_Byte(u8 byte)
{
u8 i;
SDA_OUT();
IIC1_SCL_Low;
for(i = 0; i < 8; i++)
{
if( (byte&0x80) == 0x80 )
{
IIC1_SDA_High;
}
else
{
IIC1_SDA_Low;
}
byte <<= 1;
delayNop(2);
IIC1_SCL_High;
delayNop(2);
IIC1_SCL_Low;
delayNop(2);
}
}
//读1个字节(高位开始读),ack=1时,发送ACK,ack=0,发送nACK
//在C语言中x<<=1等于x=x<<1,是把x左移1位以后值保存回x里,x发生变化了
u8 iicRead_Byte(unsigned char ack)
{
u8 i;
u8 recvByte = 0;
SDA_IN();
for(i = 0; i < 8; i++)
{
IIC1_SCL_Low;
delayNop(2);
recvByte <<= 1;//高位开始读,所以左移
if( GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7) == Bit_SET )
{
recvByte |= 0x01;
}
delayNop(2);
}
if(ack)
{
iicACK();
}
else
{
iicNOack();
}
return recvByte;
}
//------- 延时子程序
//系统时钟为24M时
//count = 200时,时间约等于100us
void delayNop(u32 count)
{
while(count -- > 0)
{
__NOP();
}
}