51单片机(IO模拟IIC通信)

单片机作为主机

sbit SDA = P1^0;
sbit SCL = P1^1;

 

IIC数据操作:在iic总线上,数据伴随时钟脉冲,一位一位的传送的,数据位由高到低传送,每位数据占一个时钟脉冲。在时钟线(SCL)为高电平期间,数据线(SDA)的状态就表示要传送的数据;高电平为数据1,低电平为数据0;在数据传递时,SDA上数据的改变要在时钟先为低电平时完成,而时钟线(SCL)为高电平时,数据线(SDA)必须保持稳定;否则数据线(SDA)上的变化会被当作开始或结束信号终止数据传输。

 

总线空闲状态:数据线(SDA)和时钟线(SCL)都是高电平

IIC通信时序图:

51单片机(IO模拟IIC通信)_第1张图片

51单片机(IO模拟IIC通信)_第2张图片

 

 

51单片机(IO模拟IIC通信)_第3张图片

 

1. 起始信号:

51单片机(IO模拟IIC通信)_第4张图片

时钟线(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. 停止信号:

51单片机(IO模拟IIC通信)_第5张图片

时钟线(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)为高电平时才读取数据

51单片机(IO模拟IIC通信)_第6张图片

 

主机发送一个字节到 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.csdn.net/qq_38410730/article/details/80312357

 

你可能感兴趣的:(51单片机(IO模拟IIC通信))