[cnblogs@WhenISeeYouAgain]模拟IIC协议时序

来源:互联网 发布:mac做win8启动盘 编辑:程序博客网 时间:2024/06/15 18:17
模拟IIC协议时序

IIC是飞利浦公司开发的两线式串行总线,主要应用在单片机和外围电子器件之间的数据通讯。

IIC总线优点是节约总线数,稳定,快速,是目前芯片制造上非常流行的一种总线,大多数单片机已经片内集成了IIC总线接口,无需用户自己模拟,只需配置相关寄存器即可使用,但是,为了更好地理解IIC总线协议,可以自行按照IIC时序图进行模拟,加深理解。

IIC总线有两条串行线,其一是时钟线SCK,其二是数据线SDA。

在寻常的应用之中,单片机常常作为主机,外围器件作为从机使用。

每一个从机器件都拥有唯一的一个地址,这个地址在芯片手册上会有详细的介绍,一般还需要自行配置芯片管脚上的高低电平,来实现确定从机地址的目的。

硬件设计上,SCK线和SDA线通过典型的4.7K电阻进行上拉,保证两条线空闲时保持高电平状态。

SDA上的数据在SCK高电平期间必须稳定,SDA上的数据在SCK期间才可以被更改。

IIC总线的时序分析:

起始信号:在SCK高电平期间,SDA一个下降沿,即构成了IIC的起始信号。

终止信号:在SCK高电平期间,SDA一个上升沿,即构成了IIC的终止信号。

程序上的模拟如下所示:

1->IIC起始信号模拟程序:

 

按 Ctrl+C 复制代码
void IIC_start(void)
{
    SCK=1;
    SDA=1;
    IIC_delay();
    SDA=0;
    IIC_delay();
    SCK=0;
    IIC_delay();
}
按 Ctrl+C 复制代码

 

2->IIC终止信号模拟程序:

按 Ctrl+C 复制代码
void IIC_end(void)
{
    SCK=0;
    SDA=0;
    IIC_delay();
    SCK=1;
    IIC_delay();
    SDA=1;
    IIC_delay();
}
按 Ctrl+C 复制代码

IIC发送数据:
在IIC一次发送8位数据,数据发送时,总是高位在前,分8次传送出去。

IIC发送数据模拟程序:

 

按 Ctrl+C 复制代码
void IIC_write(unsigned char dat)
{
    unsigned char temp;
    for(temp=0x80;temp!=0;temp>>=1)
    {
            if(temp&dat==0)
            {
                        SDA=0;
            }
            else
            {
                        SDA=1;
            }
            IIC_delay();
            SCK=1;
            IIC_delay();
            SCK=0;
    }
按 Ctrl+C 复制代码

 

IIC接收应答模拟程序:

 

按 Ctrl+C 复制代码
bit Get_IIC_ack(void)
{
        bit ack;
        SDA=1;        //释放数据线,准备接收应答
        SCK=1;
        if(SDA==1)
        {
                ack=0;//无应答信号
        }
        else
        {
                ack=1;//有应答信号
        }
        SCK=0;
        IIC_delay();
        return ack;
}
按 Ctrl+C 复制代码

 

IIC读取数据模拟程序:

复制代码
 1 unsigned char IIC_Read(void) 2 { 3         unsigned char temp; 4         unsigned char dat; 5         SDA=1; //释放总线准备接收 6         for(temp=0x80;temp!=0;temp>>=1) 7         { 8                 IIC_delay(); 9                 SCK=1;10                 if(SDA==1)11                 {12                         dat|=temp;13                 }14                 else15                 {16                         dat&=~temp;17                 }18                 SCK=0;19         }20         return dat;21 }
复制代码

IIC非应答信号模拟程序:

复制代码
void IIC_No_ack(void){        SDA=1;        SCK=1;        IIC_delay();        SCK=0;        IIC_delay();}
复制代码

IIC应答信号模拟程序:

复制代码
void IIC_ack(void){        SDA=0;        SCK=1;        IIC_delay();        SCK=0;        IIC_delay();        }