单片机作为主机
sbit SDA = P1^0;
sbit SCL = P1^1;
IIC数据操作:在iic总线上,数据伴随时钟脉冲,一位一位的传送的,数据位由高到低传送,每位数据占一个时钟脉冲。在时钟线(SCL)为高电平期间,数据线(SDA)的状态就表示要传送的数据;高电平为数据1,低电平为数据0;在数据传递时,SDA上数据的改变要在时钟先为低电平时完成,而时钟线(SCL)为高电平时,数据线(SDA)必须保持稳定;否则数据线(SDA)上的变化会被当作开始或结束信号终止数据传输。
总线空闲状态:数据线(SDA)和时钟线(SCL)都是高电平
IIC通信时序图:
1. 起始信号:
时钟线(SCL)高电平,数据线(SDA)从高电平跳变到低电平, 这是一个电平跳变的过程
/***********************************
函数功能:IO模拟IIC起始信号
备注: 起始信号后时钟线和数据线全为低电平
SDA和SCL为单片机IO
************************************/
void iic_Start()
{
SDA = 1;
delay_us(10);
SCL = 1;
delay_us(10); //先保持数据线和时钟线高电平一段时间
SDA = 0;// 数据线向低电平跳变
delay_us(10);
SCL = 0;//拉低时钟线
delay_us(10);
}
2. 停止信号:
时钟线(SCL)在高电平期间,数据线(SDA)由低电平向高电平跳变 (数据线与开始信号相反)
/**************************************
函数功能:IIC停止信号
**************************************/
void iic_Stop()
{
SDA = 0;
delay_us(10);
SCL = 1;
delay_us(10);
SDA = 1;
delay_us(10);
}
3. 在时钟线(SCL)跳变读取期间, 要保持数据线(SDA)的稳定,只有在时钟线(SCL)为高电平时才读取数据
主机发送一个字节到 IIC 总线,
/**********************************************
函数功能:通过IIC发送一个字节
返回值: 0发送失败, 1发送成功
参数: 要写入的数据8位
**********************************************/
unsigned char iic_WriteByte(unsigned char dat)
{
unsigned char i = 0;
unsigned char j = 0;
for(i = 0; i < 8; i++)//要发送8位,从最高位开始
{
SDA = dat>>7;
dat = dat<<1;
SCL = 1;
delay_us(10);
SCL = 0;
delay_us(10);
}
SDA = 1;//释放总线
delay_ms(10);
SCL = 1;
while(SDA)
{
j++;
if(j>200)
{
SCL = 0;
delay_us(10);
return 0;
}
}
SCL = 0;
delay_us(10);
reeturn 1;
}
主机从IIC总线读取一个字节数据
/**************************************
函数功能:主机从IIC总线读取一个字节数据
返回值: 读取的一个字节
备注:在时钟线(SCL)位高电平时,读取数据状态
**************************************/
unsigned char iic_ReadByte()
{
unsigned char i = 0;
unsigned char dat = 0;
SDA = 1;//起始和发送一个字节之后SCL都是0
delay_us(10);
for(i = 0; i < 8; i++)//接收8个字节
{
SCL = 1;
delay_us(10);
dat<<=1;
dat|=SDA; //或运算, 读取数据是dat最低位
dealy_us(10);
SCL = 0;
delay_us(10);
}
return dat;
}
参考:https://blog.youkuaiyun.com/qq_38410730/article/details/80312357