采用软件写IIC通讯,硬件写IIC是采用的特定的接口写的,但是软件的IIC就是采用的是任意两个引脚SCL和SDA引脚模拟IIC通讯
第一步先定义初始化的引脚
//初始化软件IIC
void IIC_Init()
{
GPIO_InitTypeDef GPIO_Init_IIC;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_Init_IIC.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init_IIC.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_Init_IIC.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_Init_IIC);
SCL_IIC_Set(); //SCL为1
SDA_IIC_Set(); //SDA为1
}
初始化写完了就写启动IIC和停止IIC我们根据有IIC的时序写
//开启IIC
void IIC_Start(void)
{
SCL_IIC_Set();
SDA_IIC_Set();
delay_us(1);
SDA_IIC_Reset();
delay_us(1);
SCL_IIC_Reset();
delay_us(1);
}
//关闭IIC
void IIC_Stop(void)
{
SDA_IIC_Reset();
delay_us(1);
SCL_IIC_Set();
delay_us(1);
SDA_IIC_Set();
delay_us(1);
}
下一步就是写应答重占的应答,一定要记住为1是没有应答,也是看时序写程序
unsigned char IIC_Ack(void)
{
unsigned char Ack = 0;
SCL_IIC_Reset();
delay_us(1);
SDA_IIC_Set();
delay_us(1);
SCL_IIC_Set();
delay_us(1);
if(SDA_IIC_ACK())//读取SDA有没有应答
{
Ack = IIC_ACK;
}
else
{
Ack = IIC_NO_ACK;
}
SCL_IIC_Reset();
delay_us(1);
return Ack;
}
下面写读取函数根据以下时序写,注意写命令是0x00,写数据是0x40。
//IIC读取一个字节
void IIC_Read_Byte(unsigned char Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
SCL_IIC_Reset();
delay_us(1);
if(Byte&0x80)
{
SDA_IIC_Set();
}
else
{
SDA_IIC_Reset();
}
delay_us(1);
SCL_IIC_Reset();
delay_us(1);
Byte<<=1;
}
SCL_IIC_Reset();
delay_us(1);
IIC_Ack();
}
//IIC写命令
void IIC_Write_Byte(unsigned char IIC_Cmd)
{
IIC_Start();
IIC_Read_Byte(0x78);
IIC_Read_Byte(0x00);
IIC_Read_Byte(IIC_Cmd);
IIC_Stop();
}
//IIC写数据
void IIC_Write_Data(unsigned char Data)
{
IIC_Start();
IIC_Read_Byte(0x78);
IIC_Read_Byte(0x40);
IIC_Read_Byte(Data);
IIC_Stop();
}