为了加深对I2C总线的理解,用C语言模拟IIC总线,边看源代码边读波形:

如下图所示的写操作的时序图:

读时序的理解同理。对于时序不理解的朋友请参考“I2C总线之(二)---时序

完整的程序如下:

#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define write_ADD 0xa0
#define read_ADD 0xa1
uchar a;
sbit SDA=P2^;
sbit SCL=P2^;
void SomeNop();     //短延时
void init();    //初始化
void check_ACK(void);
void I2CStart(void);
void I2cStop(void);
void write_byte(uchar dat);//写字节
void delay(uint z);
uchar read_byte();     //读字节
void write(uchar addr,uchar dat);  //指定地址写
uchar read(uchar addr);       //指定地址读
bit flag;  //应答标志位
void main()
{
    init();
    write_add(,0xaa); //向地址5写入0xaa
    delay();      //延时,否则被坑呀!!!
     P1=read_add();      //读取地址5的值
     );
}

//***************************************************************************
void delay()//简单延时函数
{ ;; }
//***************************************************************************
void start()  //开始信号 SCL在高电平期间,SDA一个下降沿则表示启动信号
{
    sda=; //释放SDA总线
    delay();
    scl=;
    delay();
    sda=;
    delay();
}
//***************************************************************************
void stop()   //停止 SCL在高电平期间,SDA一个上升沿则表示停止信号
{
    sda=;
    delay();
    scl=;
    delay();
    sda=;
    delay();
}
//***************************************************************************
void respons()  //应答 SCL在高电平期间,SDA被从设备拉为低电平表示应答
{
    uchar i;
    scl=;
    delay();
    //至多等待250个CPU时钟周期
    )&&(i<))i++;
    scl=;
    delay();
}
//***************************************************************************
void init()//总线初始化 将总线都拉高一释放总线  发送启动信号前,要先初始化总线。即总有检测到总线空闲才开始发送启动信号
{
    sda=;
    delay();
    scl=;
    delay();
}
//***************************************************************************
void write_byte(uchar date) //写一个字节
{
    uchar i,temp;
    temp=date;  

    ;i<;i++)
    {
        temp=temp<<;
        scl=;//拉低SCL,因为只有在时钟信号为低电平期间按数据线上的高低电平状态才允许变化;并在此时和上一个循环的scl=1一起形成一个上升沿
        delay();
        sda=CY;
        delay();
        scl=;//拉高SCL,此时SDA上的数据稳定
        delay();
    }
    scl=;//拉低SCL,为下次数据传输做好准备
    delay();
    sda=;//释放SDA总线,接下来由从设备控制,比如从设备接收完数据后,在SCL为高时,拉低SDA作为应答信号
    delay();
}
//***************************************************************************
uchar read_byte()//读一个字节
{
    uchar i,k;
    scl=;
    delay();
    sda=;
    delay();
    ;i<;i++)
    {
        scl=;//上升沿时,IIC设备将数据放在sda线上,并在高电平期间数据已经稳定,可以接收啦
        delay();
        k=(k<<)|sda;
        scl=;//拉低SCL,使发送端可以把数据放在SDA上
        delay();
    }
    return k;
}
//***************************************************************************
void write_add(uchar address,uchar date)//任意地址写一个字节
{
    start();//启动
    write_byte(0xa0);//发送从设备地址
    respons();//等待从设备的响应
    write_byte(address);//发出芯片内地址
    respons();//等待从设备的响应
    write_byte(date);//发送数据
    respons();//等待从设备的响应
    stop();//停止
}
//***************************************************************************
uchar read_add(uchar address)//读取一个字节
{
    uchar date;
    start();//启动
    write_byte(0xa0);//发送发送从设备地址 写操作
    respons();//等待从设备的响应
    write_byte(address);//发送芯片内地址
    respons();//等待从设备的响应
    start();//启动
    write_byte(0xa1);//发送发送从设备地址 读操作
    respons();//等待从设备的响应
    date=read_byte();//获取数据
    stop();//停止
    return date;//返回数据
}

I2C总线之(三)---以C语言理解IIC的更多相关文章

  1. SPI、I2C、UART三种串行总线协议的区别

    第一个区别当然是名字: SPI(Serial Peripheral Interface:串行外设接口); I2C(INTER IC BUS) UART(Universal Asynchronous R ...

  2. SPI、I2C、UART三种串行总线协议的区别和SPI接口介绍(转)

    SPI.I2C.UART三种串行总线协议的区别 第一个区别当然是名字: SPI(Serial Peripheral Interface:串行外设接口); I2C(INTER IC BUS) UART( ...

  3. IIC - 【转载】对I2C总线的时钟同步和总线仲裁的深入理解

    对I2C总线的时钟同步和总线仲裁的深入理解 每一个IIC总线器件内部的SDA.SCL引脚电路结构都是一样的,引脚的输出驱动与输入缓冲连在一起.其中输出为漏极开路的场效应管.输入缓冲为一只高输入阻抗的同 ...

  4. i2c总线驱动,总线设备(适配器),从设备,从设备驱动的注册以及匹配

    常用链接 我的随笔 我的评论 我的参与 最新评论 我的标签 随笔分类 ARM裸机(13) C(8) C++(8) GNU-ARM汇编 Linux驱动(24) Linux应用编程(5) Makefile ...

  5. [I2C].I2C总线详解

    转自:https://www.cnblogs.com/BitArt/archive/2013/05/27/3101037.html 一. 基本信息 1. 概述 I²C 是Inter-Integrate ...

  6. Linux设备驱动模型之I2C总线

    一.I2C子系统总体架构 1.三大组成部分 (1)I2C核心(i2c-core):I2C核心提供了I2C总线驱动(适配器)和设备驱动的注册.注销方法,提供了与具体硬件无关的I2C读写函数. (2)I2 ...

  7. I2C总线和S5PV210的I2C总线控制器

    一.什么是I2C通信协议? 1.物理接口:SCL + SDA (1)SCL(serial clock):时钟线,传输CLK信号,一般是I2C主设备向从设备提供时钟的通道. (2)SDA(serial ...

  8. I2C总线驱动框架详解

    一.I2C子系统总体架构 1.三大组成部分 (1)I2C核心(i2c-core):I2C核心提供了I2C总线驱动(适配器)和设备驱动的注册.注销方法,I2C通信方法(”algorithm”)上层的,与 ...

  9. 关于具有I2C总线的TEA6320的使用

    现在先了解一下TEA6320,TEA6320是一个I2C总线控制音响应用的立体声放大器,,它的I2C协议和音量控制如下: 它的主要代码: void delay1ms(unsigned int Dela ...

随机推荐

  1. Android(java)学习笔记192:SQLite数据库(表)的创建 以及 SQLite数据库的升级

    一.数据库的创建 1.文件的创建      //引用,如果文件不存在是不会创建的   File  file = new File("haha.txt"):     //输出流写数据 ...

  2. JS实现图片宽高的等比缩放

    关于图片宽高的等比缩放,其实需求就是让图片自适应父容器的宽高,并且是等比缩放图片,使图片不变形. 例如,需要实现如下的效果: 要实现上面的效果,需要知道图片的宽高,父容器的宽高,然后计算缩放后的宽高. ...

  3. Customize the SharePoint 2013 search experience with a Content Enrichment web service

    Did you ever wish you had more control over how your content is indexed and presented as search resu ...

  4. IXListView的自我分析一

    XListView是一个很不错的用来刷新和加载的控件,下拉刷新和上拉加载.目前这个控件已经没有更新,这个不重要,重要的是它确实还不错,之后可能一直有人在用. android没有提供原生的这类控件,需要 ...

  5. 如何下载到最新的版本的Oracle Database

    其实这不是一个很困难的事情,但是发现好多同学都不知道,其实只需直接访问Oracle的官网就可以找到,鉴于Oracle经常改到下载面也我这里直接粘贴下载地址 http://www.oracle.com/ ...

  6. doj常用包

    dojo.raise               抛出一个异常 dojo.errorToString将异常转换为字符串 dojo.render      系统环境对象 dojo.hostenv. ...

  7. vc调用BCB的dll 参数传递 报错

    可能原因: 调用方式约定不一致. 函数调用约定如下: 1. __cdecl:C 和 C++ 程序的缺省调用规范. 2. __stdcall:标准调用约定(即WINAPI调用约定),也就是pascal调 ...

  8. 深入理解shared pool共享池之library cache的library cache lock系列四

    本文了解下等待事件library cache lock,进一步理解library cache,之前的文章请见:  深入理解shared pool共享池之library cache的library ca ...

  9. cocos2dx入门分析 hello world

    打开新建的"findmistress"项目,可以看到项目文件是由多个代码文件及文件夹组成的,其中 Hello World 的代码文件直接存放于该项目文件夹中.下面我们来详细介绍一下 ...

  10. java中的包装类

    每一个包装类都对应一种基本数据类型.包装类有:Integer.character.Byte.Short.Long.Floot.Double.Boolean这八种,分别对应的基本数据类型是:int.ch ...