1.IIC的特点?
1.双向二线制总线
2.同步串行半双工通信
3.一条总线可以挂载多个IIC接口器件
2.如何配置IIC?
1.根据从机需求查看是否支持IIC通信
2.根据原理图查看具有支持IIC通信的IO口
3.IIC规则配置IIC具体时序
4. 写IO口初始化配置函数 起始信号函数 发送/接收数据函数 应答相关函数 停止位函数
3.IIC的时序帧是怎样的?各个阶段规则是怎样的?
时序帧有:起始信号 数据段 应答信号 停止信号
当拉高时钟线数据线产生下降沿时开始起始信号;当拉低时钟线,数据线交叉时可以发送数据写数据,当拉高时钟线,数据线平行时,这个时候可以读数据接收数据,这个就是数据段;拉高时钟线数据线保持低电平接收的是一位应答位,数据线保持高电平则接收的是一位不应答位;拉高时钟线,数据线产生上升沿产生停止信号
4.IIC通信使用的IO口是如何配置的,为什么这样配?
针对IIC通信有一根时钟线SCL,一根数据线SDA。时钟线配置为通用推挽输出,数据线 配 置 为 通用开漏输出;
时钟线是主机输出高低电平传送到从机所以配置为推挽输出,数据线既要发数据又要接收数 据既要输入又要输出所以配置为通用开漏输出;内部控制器直接输出0,当输出寄存器置1时 输出端会断开处于浮空状态通过IIC器件上的上拉电阻将它拉高从而输出1,同样置一的时候输 出路断开了从而可以切换为输入模式防止输出端干扰主机读外界进来的信号
中文手册:输出框图
/***********************************************
*函数名 :iic_star
*函数功能 :IIC起始信号函数
*函数参数 :无
*函数返回值:无
*函数描述 :
************************************************/
void iic_star(void)
{
//时钟线拉低 可以动数据线
IIC_SCL_L;
//数据线拉高 保证可以出现下降沿
IIC_SDA_OUT_H;
//时钟线拉高 起始信号的条件
IIC_SCL_H;
timer6_delay_us(5);
//数据线拉低 产生了起始信号
IIC_SDA_OUT_L;
timer6_delay_us(5);
IIC_SCL_L;//安全作用
}
/***********************************************
*函数名 :iic_stop
*函数功能 :IIC停止信号函数
*函数参数 :无
*函数返回值:无
*函数描述 :
************************************************/
void iic_stop(void)
{
IIC_SCL_L;
IIC_SDA_OUT_L;
IIC_SCL_H;
timer6_delay_us(5);
IIC_SDA_OUT_H;
timer6_delay_us(5);
}
/***********************************************
*函数名 :iic_send_ack
*函数功能 :IIC发送应答/不应答信号函数
*函数参数 :u8 ack
*函数返回值:无
*函数描述 :ack 传入 0 表示发送应答
ack 传入 1 表示发送不应答
************************************************/
void iic_send_ack(u8 ack)
{
IIC_SCL_L;
timer6_delay_us(5);
if(ack == 0) IIC_SDA_OUT_L;
else IIC_SDA_OUT_H;
timer6_delay_us(5);
IIC_SCL_H;
timer6_delay_us(5);
IIC_SCL_L;//安全作用
}
/***********************************************
*函数名 :iic_get_ack
*函数功能 :IIC检测应答/不应答信号函数
*函数参数 :无
*函数返回值:u8
*函数描述 :0 应答信号
1 不应答信号
************************************************/
u8 iic_get_ack(void)
{
u8 ack;
/*将数据线切换位输入模式*/
IIC_SCL_L;
IIC_SDA_OUT_H;
/*检测应答*/
IIC_SCL_L; //主机帮助从机把时钟线拉低,从机才可以自动改变数据线
timer6_delay_us(5);
IIC_SCL_H; //主机拉高时钟线才可以读数据线
timer6_delay_us(5);
if(IIC_SDA_IN) ack = 1; //不应答信号
else ack = 0; //应答信号
IIC_SCL_L; //安全作用
return ack;
}
/***********************************************
*函数名 :iic_send_byte
*函数功能 :IIC发送一个字节函数
*函数参数 :u8 data
*函数返回值:无
*函数描述 :
************************************************/
void iic_send_byte(u8 data)
{
u8 i;
for(i=0;i<8;i++)
{
IIC_SCL_L;
timer6_delay_us(5);
if(data & 0x80)
{
IIC_SDA_OUT_H;
}
else
{
IIC_SDA_OUT_L;
}
timer6_delay_us(5);
IIC_SCL_H; //帮助从机拉高时钟线,从机才可以读这一位数据
timer6_delay_us(5);
//下一位数据
data = data << 1;
}
IIC_SCL_L; //安全作用
}
/***********************************************
*函数名 :iic_rec_byte
*函数功能 :IIC接收一个字节函数
*函数参数 :无
*函数返回值:u8
*函数描述 :
************************************************/
u8 iic_rec_byte(void)
{
u8 i;
u8 data;
/*IO切换为输入模式*/
IIC_SCL_L;
IIC_SDA_OUT_H;
/*接收一个字节数据*/
for(i=0;i<8;i++)
{
IIC_SCL_L; //帮助从机拉低时钟线,从才会改变数据线
timer6_delay_us(5);
IIC_SCL_H; //主机可以读数据线
timer6_delay_us(5);
data = data << 1;
if(IIC_SDA_IN)
{
data |= 0x01;
}
}
IIC_SCL_L; //安全作用
return data;
}