新闻  |   论坛  |   博客  |   在线研讨会
备战蓝桥--对iic总线的学习认知
YuXi啊 | 2020-03-02 21:52:50    阅读:34871   发布文章

     哈喽 !大家好,YuXi小呆萌前来报到。被新冠病毒折磨在家中你们肯定也像我一样在家无聊的想yue(吐)吧,相信宅在家中的铁子们大都像我一样每天准时在钉钉打卡看直播(当然,肯定还有老铁刚做钉钉的全职主播)。做了两周铁子的我又想起今年的蓝桥杯备战,漫漫长夜无心睡眠,因此突发奇想想和大家分享一下对iic总线通信的学习,若有不足之处,还请各位道友多多指点

      


        在前段时间学习使用DS18B20温度传感器中,初次了解到通信协议,后来又在网上查了一下有关通信协议的内容,了解到了iic协议和SPI协议。刚开始看这些协议的时候,文章字数一大堆,看的脑壳疼,果断的放弃继续阅读,这不刚过几天,不想看也得看了 (脑壳疼)难搞哦!


        对于单总线的学习呢,一定要注意时序,遵守有借有还的原则。好了不跑题,跟大家简单的分享一下对iic总线的学习心得。


         IIc : 

     IIC 是多主设备的总线,只使用两条信号线—— ‘serial data’ (SDA) 和 ‘serial clock’ (SCL)。

     IIC协议规定:

    • 第一,每一支IIC设备都有一个唯一的七位设备地址;

    • 第二,数据帧大小为8位的字节;

    • 第三,数据(帧)中的某些数据位用于控制通信的开始、停止、方向(读写)和应答机制。

      IIC 数据传输速率有标准模式(100 kbps)、快速模式(400 kbps)和高速模式(3.4    Mbps),另外一些变种实现了低速模式(10 kbps)和快速+模式(1 Mbps)。  (此处就简单的跟大家分享一下,我也没了解太多

        IIC 通信过程其实也很简单,首先,主设备发一个START信号,这个信号就像对所有其它设备喊:请大家注意!然后其它设备开始监听总线以准备接收数据。接着,主设备发送一个7位设备地址加一位的读写操作的数据帧。当所设备接收数据后,比对地址自己是否目标设备。如果比对不符,设备进入等待状态,等待STOP信号的来临;如果比对相符,设备会发送一个应答信号——ACKNOWLEDGE作回应。(在此缅怀那些我们在教师上课的岁月)我们可以把通信的过程当做老师那万恶的点名(this is a joke),老师相当于我们这个教室的主设备,而学生就相当于接收设备,当老师叫到某个学生的名字(START信号),当老师叫到某个学生名字时,该同学会回答“到”表示自己已经接受到信号并给老师反馈,而那些没有被叫到名字的同学则会继续等待老师点自己名字,直到被老师点到名字,作出回应。(我们班上课可没有别的同学代答“到”O)
        当主设备收到应答后便开始传送或接收数据。数据帧大小为8位,尾随一位的应答信号。主设备发送数据,从设备应答;相反主设备接数据,主设备应答。当数据传送完毕,主设备发送一个STOP信号,向其它设备宣告释放总线,其它设备回到初始状态。

    基于IIC总线的物理结构,总线上的START和STOP信号必定是唯一的。另外,IIC总线标准规定SDA线的数据转换必须在SCL线的低电平期,在SCL线的高电平期,SDA线的上数据是稳定的。

66F[~H`0FV[}{)SZUW[DTC8.png



    就和大家分享那么多,相信这些足够大家备战蓝桥杯了,下面总结一下代码,有不足之处还请路过的大神多多指点。


void init()//总线初始化
{  
    sda=1;  
    delay();  
    scl=1;  
    delay();  
} 

/*===========================================================================================================*/

 void start ()  //开始信号 
{
    sda = 1;
    delay();
    scl = 1;
    delay();
    sda = 0;
    delay();
}

/*===========================================================================================================*/

void stop()    //停止 
{  
    sda=0;  
    delay();  
    scl=1;  
    delay();  
    sda=1;  
    delay();  
}

/*===========================================================================================================*/

void respons()  //应答 
{  
    uchar i;  
    scl=1;  
    delay(); //至多等待250个CPU时钟周期
    while((sda==1)&&(i<250))i++;
    scl=0;  
    delay();  
}  


/*===========================================================================================================*/

void write_byte(uchar date) //写一个字节 
{  
    uchar i,temp;  
    temp=date;  
  
  
    for(i=0;i<8;i++)  
    {  
        temp=temp<<1;  
        scl=0;//拉低SCL,因为只有在时钟信号为低电平期间按数据线上的高低电平状态才允许变化;并在此时和上一个循环的scl=1一起形成一个上升沿          delay();  
        sda=CY;  
        delay();  
        scl=1;//拉高SCL,此时SDA上的数据稳定 
        delay();  
    }  
    scl=0;//拉低SCL,为下次数据传输做好准备      
    delay();  
    sda=1;//释放SDA总线,接下来由从设备控制,比如从设备接收完数据后,在SCL为高时,拉低SDA作为应答信号      
    delay();  
} 

/*===========================================================================================================*/

uchar read_byte()//读一个字节  
{  
    uchar i,dat;  
    scl=0;  
    delay();  
    sda=1;  
    delay();  
    for(i=0;i<8;i++)  
    {  
        scl=1;          
        delay();      
        dat=(dat<<1)|sda;  
        scl=0;//拉低SCL,使发送端可以把数据放在SDA上          
        delay();      
    }  
    return dat;  
}  

/*===========================================================================================================*/

void write_add(uchar address,uchar date)//任意地址写一个字节

{  
    start();//启动  
    write_byte(0xa0);//发送从设备地址  
    respons();//等待从设备的响应  
    write_byte(address);//发出芯片内地址  
    respons();//等待从设备的响应  
    write_byte(date);//发送数据  
    respons();//等待从设备的响应  
    stop();//停止  
 }  

 /*===========================================================================================================*/

(这还没高数难


我的水平有限,很多重点的只是都没给大家分享出来,有兴趣的同学可以自己在网上查阅资料,希望大家都能养成自己去探索未知的习惯。  最后希望大家在这个疫情待家的时间里,合理安排自己的时间,找到自己的目标,加油!!!


*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客