1.I2C协议


1.I2C协议
  
   2条双向串行线,一条数据线SDA,一条时钟线SCL。
   SDA传输数据是大端传输,每次传输8bit,即一字节。
   支持多主控(multimastering),任何时间点只能有一个主控。
   总线上每个设备都有自己的一个addr,共7个bit,广播地址全0.
   系统中可能有多个同种芯片,为此addr分为固定部分和可编程部份,细节视芯片而定,看datasheet。

1.1 I2C位传输

   数据传输:SCL为高电平时,SDA线若保持稳定,那么SDA上是在传输数据bit;
             若SDA发生跳变,则用来表示一个会话的开始或结束(后面讲)
   数据改变:SCL为低电平时,SDA线才能改变传输的bit



1.2 I2C开始和结束信号
   
   开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
   结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。

  

1.3 I2C应答信号
   
   Master每发送完8bit数据后等待Slave的ACK。
   即在第9个clock,若从IC发ACK,SDA会被拉低。
   若没有ACK,SDA会被置高,这会引起Master发生RESTART或STOP流程,如下所示:



1.4 I2C写流程

写寄存器的标准流程为:
1.    Master发起START
2.    Master发送I2C addr(7bit)和w操作0(1bit),等待ACK
3.    Slave发送ACK
4.    Master发送reg addr(8bit),等待ACK
5.    Slave发送ACK
6.    Master发送data(8bit),即要写入寄存器中的数据,等待ACK
7.    Slave发送ACK
8.    第6步和第7步可以重复多次,即顺序写多个寄存器
9.    Master发起STOP

写一个寄存器




写多个寄存器

1.5 I2C读流程

读寄存器的标准流程为:
1.    Master发送I2C addr(7bit)和w操作1(1bit),等待ACK
2.    Slave发送ACK
3.    Master发送reg addr(8bit),等待ACK
4.    Slave发送ACK
5.    Master发起START
6.    Master发送I2C addr(7bit)和r操作1(1bit),等待ACK
7.    Slave发送ACK
8.    Slave发送data(8bit),即寄存器里的值
9.    Master发送ACK
10.    第8步和第9步可以重复多次,即顺序读多个寄存器

读一个寄存器


读多个寄存器



2. PowerPC的I2C实现

Mpc8560的CCSR中控制I2C的寄存器共有6个。




2.1 I2CADR 地址寄存器

CPU也可以是I2C的Slave,CPU的I2C地址有 I2CADR指定

 

2.2 I2CFDR 频率设置寄存器

The serial bit clock frequency of SCL is equal to the CCB clock divided by the divider.
用来设置I2C总线频率



2.3 I2CCR 控制寄存器



MEN: Module Enable.    置1时,I2C模块使能
MIEN:Module Interrupt Enable. 置1时,I2C中断使能。
MSTA:Master/slave mode. 1 Master mode,0 Slave mode.
        当1->0时,CPU发起STOP信号
        当0->1时,CPU发起START信号
MTX:Transmit/receive mode select.0 Receive mode,1 Transmit mode
TXAK:Transfer acknowledge. 置1时,CPU在9th clock发送ACK拉低SDA
RSTA:Repeat START. 置1时,CPU发送REPEAT START
BCST:置1,CPU接收广播信息(信息的slave addr为7个0)

2.4 I2CSR 状态寄存器




MCF:0  Byte transfer is in process
     1  Byte transfer is completed

MAAS:当CPU作为Slave时,若I2CDR与会话中Slaveaddr匹配,此bit被置1

MBB:0 I2C bus idle  
     1 I2C bus busy

MAL:若置1,表示仲裁失败
BCSTM:若置1,表示接收到广播信息

SRW:When MAAS is set, SRW indicates the value of the R/W command bit of the calling address, which is sent from the master.
   0 Slave receive, master writing to slave
   1 Slave transmit, master reading from slave

MIF:Module interrupt. The MIF bit is set when an interrupt is pending, causing a processor interrupt request(provided I2CCR[MIEN] is set)

RXAK:若置1,表示收到了ACK

2.5 I2CDR 数据寄存器



这个寄存器储存CPU将要传输的数据。


3. PPC-Linux中I2C的实现

 
  内核代码(linux-2.6.24)中,通过I2C总线存取寄存器的函数都在文件drivers/i2c/busses/i2c-mpc.c中
  最重要的函数是mpc_xfer.
  
  1. static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
  2. {
  3.     struct i2c_msg *pmsg;
  4.     int i;
  5.     int ret = 0;
  6.     unsigned long orig_jiffies = jiffies;
  7.     struct mpc_i2c *i2c = i2c_get_adapdata(adap);

  8.     mpc_i2c_start(i2c);    // 设置I2CCR[MEN], 使能I2C module 

  9.     /* Allow bus up to 1s to become not busy */
  10.     //一直读I2CSR[MBB],等待I2C总线空闲下来
  11.     while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) {
  12.         if (signal_pending(current)) {
  13.             pr_debug("I2C: Interrupted\n");
  14.             writeccr(i2c, 0);
  15.             return -EINTR;
  16.         }
  17.         if (time_after(jiffies, orig_jiffies + HZ)) {
  18.             pr_debug("I2C: timeout\n");
  19.             if (readb(i2c->base + MPC_I2C_SR) ==
  20.                 (CSR_MCF | CSR_MBB | CSR_RXAK))
  21.                 mpc_i2c_fixup(i2c);
  22.             return -EIO;
  23.         }
  24.         schedule();
  25.     }

  26.     for (= 0; ret >= 0 && i < num; i++) {
  27.         pmsg = &msgs[i];
  28.         pr_debug("Doing %s %d bytes to 0x%02x - %d of %d messages\n",
  29.              pmsg->flags & I2C_M_RD ? "read" : "write",
  30.              pmsg->len, pmsg->addr, i + 1, num);
  31.         //根据消息里的flag进行读操作或写操作
  32.         if (pmsg->flags & I2C_M_RD) 
  33.             ret = mpc_read(i2c, pmsg->addr, pmsg->buf, pmsg->len, i);
  34.         else
  35.             ret = mpc_write(i2c, pmsg->addr, pmsg->buf, pmsg->len, i);
  36.     }
  37.     mpc_i2c_stop(i2c);    //保证为I2CCSR[MSTA]为0,保证能触发STOP
  38.     return (ret < 0) ? ret : num;
  39. }


  1. static int mpc_write(struct mpc_i2c *i2c, int target,
  2.              const u8 * data, int length, int restart)
  3. {
  4.     int i;
  5.     unsigned timeout = i2c->adap.timeout;
  6.     u32 flags = restart ? CCR_RSTA : 0;

  7.     /* Start with MEN */    //以防万一,保证I2C模块使能起来
  8.     if (!restart)
  9.         writeccr(i2c, CCR_MEN);
  10.     /* Start as master */       //写了I2CCR[CCR_MSTA],触发CPU发起START信号
  11.     writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags);
  12.     /* Write target byte */     //CPU发送一个字节,slave I2C addr和0 (写操作bit) 
  13.     writeb((target << 1), i2c->base + MPC_I2C_DR);

  14.     if (i2c_wait(i2c, timeout, 1) < 0)    //等待slave 发ACK
  15.         return -1;

  16.     for (= 0; i < length; i++) {
  17.         /* Write data byte */
  18.         writeb(data[i], i2c->base + MPC_I2C_DR); //CPU接着发数据,包括reg addr和data

  19.         if (i2c_wait(i2c, timeout, 1) < 0)       //等待slave 发ACK
  20.             return -1;
  21.     }

  22.     return 0;
  23. }


  1. static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
  2. {
  3.     unsigned long orig_jiffies = jiffies;
  4.     u32 x;
  5.     int result = 0;

  6.     if (i2c->irq == 0)
  7.     {    //循环读I2CSR,直到I2CSR[MIF]置1
  8.         while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
  9.             schedule();
  10.             if (time_after(jiffies, orig_jiffies + timeout)) {
  11.                 pr_debug("I2C: timeout\n");
  12.                 writeccr(i2c, 0);
  13.                 result = -EIO;
  14.                 break;
  15.             }
  16.         }
  17.         x = readb(i2c->base + MPC_I2C_SR);
  18.         writeb(0, i2c->base + MPC_I2C_SR);
  19.     } else {
  20.         /* Interrupt mode */
  21.         result = wait_event_interruptible_timeout(i2c->queue,
  22.             (i2c->interrupt & CSR_MIF), timeout * HZ);

  23.         if (unlikely(result < 0)) {
  24.             pr_debug("I2C: wait interrupted\n");
  25.             writeccr(i2c, 0);
  26.         } else if (unlikely(!(i2c->interrupt & CSR_MIF))) {
  27.             pr_debug("I2C: wait timeout\n");
  28.             writeccr(i2c, 0);
  29.             result = -ETIMEDOUT;
  30.         }

  31.         x = i2c->interrupt;
  32.         i2c->interrupt = 0;
  33.     }

  34.     if (result < 0)
  35.         return result;

  36.     if (!(& CSR_MCF)) {
  37.         pr_debug("I2C: unfinished\n");
  38.         return -EIO;
  39.     }

  40.     if (& CSR_MAL) {    //仲裁失败
  41.         pr_debug("I2C: MAL\n");
  42.         return -EIO;
  43.     }

  44.     if (writing && (& CSR_RXAK)) {//写后没收到ACK
  45.         pr_debug("I2C: No RXAK\n");
  46.         /* generate stop */
  47.         writeccr(i2c, CCR_MEN);
  48.         return -EIO;
  49.     }
  50.     return 0;
  51. }

  1. static int mpc_read(struct mpc_i2c *i2c, int target,
  2.             u8 * data, int length, int restart)
  3. {
  4.     unsigned timeout = i2c->adap.timeout;
  5.     int i;
  6.     u32 flags = restart ? CCR_RSTA : 0;

  7.     /* Start with MEN */    //以防万一,保证I2C模块使能
  8.     if (!restart)
  9.         writeccr(i2c, CCR_MEN);
  10.     /* Switch to read - restart */
  11.     //注意这里,再次把CCR_MSTA置1,再触发 START 
  12.     writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags);


  13.     /* Write target address byte - this time with the read flag set */ 
  14.     //CPU发送slave I2C addr和读操作1
  15.     writeb((target << 1) | 1, i2c->base + MPC_I2C_DR);
      
     //等待Slave发ACK
  1.     if (i2c_wait(i2c, timeout, 1) < 0)
  2.         return -1;

  3.     if (length) {
  4.         if (length == 1)
  5.             writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_TXAK);
  6.         else //为什么不置 TXAK
  7.             writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA);
  8.         /* Dummy read */
  9.         readb(i2c->base + MPC_I2C_DR);
  10.     }

  11.     for (= 0; i < length; i++) {
  12.         if (i2c_wait(i2c, timeout, 0) < 0)
  13.             return -1;

  14.         /* Generate txack on next to last byte */
  15.         //注意这里TXAK置1,表示CPU每收到1byte数据后,会发送ACK
  16.         if (== length - 2) 
  17.             writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_TXAK);

  18.         /* Generate stop on last byte */
  19.         //注意这里CCR_MSTA [1->0] CPU会触发STOP
  20.         if (== length - 1)    
  21.             writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_TXAK);

  22.         data[i] = readb(i2c->base + MPC_I2C_DR);
  23.     }

  24.     return length;
  25. }







本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/253194.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图像--摄像头数据输出格式与传输接口

一、 数据输出格式 RAW data 格式: CMOS 在将光信号转换为电信号时的电平高低的原始记录&#xff0c;单纯地将没有进行任何处理的图像数据&#xff0c;即摄像元件直接得到的电信号进行数字化处理而得到的。 每个pixel只能感光R光或者B光或者G光&am…

怎么建立微信生态用户增长模型?

微信最新数据及中国网民最新数据概述截止到2018年&#xff0c;移动网民用户增长放缓&#xff0c;接近人口大盘。微信作为全国移动网民的一款超级应用&#xff0c;在移动网民的***率超过90%。微信最近一年的新增用户主要来自中老年用户群体和乡镇用户群体***。易观最新发布的8月…

图像-摄像头驱动流程

驱动架构 在Kernel层用camera的驱动将其驱动起来以后&#xff0c;将硬件驱动接口交给Hal&#xff1b; 上层的camera应用程序在andriod实时系统的虚拟机中&#xff0c;加载留给camera公用的库文 件&#xff0c;调用Hal层的接口来控制camera硬件来实现功能。 驱动流程 打开came…

RK瑞芯微WIFI模组2020最新支持列表,放心使用!

如下所示为RK瑞芯微2020最新支持的WIFIBT模组列表&#xff0c;请参考&#xff01; 标题希望对选型有所帮助&#xff0c;避免踩坑&#xff0c;坑驱动工程师&#xff01; 有事要搞&#xff0c;请私聊&#xff01;

数据类型进阶

----------siwuxie095 1、整数类型 如果去掉注释&#xff0c;报错&#xff1a;Type mismatch: cannot convert from into byte 即 不能把 int 类型转换成 byte 类型 如果选择 Add cast to byte&#xff1a; 即 把 b13 的结果&#xff08;默认为 int 类型&#xff09;强制转换成…

海华模组:WIFI、BT、SoC模组列表

各种模块广泛应用于网络摄像头、智能机器人、儿童故事机、词典笔、智能音箱、智能家电等需要实现无线联网设备的消费类电子产品。 模块化有很大的有点&#xff1a;集成设计、减少调试工作&#xff0c;避开开发盲区、加速将产品推向市场&#xff01; 下面介绍下海华各类通讯模…

JAVA-初步认识-第七章-构造函数和一般函数的区别

一. 构造函数是对象一创建&#xff0c;就被调用了。(调用这个词很特殊&#xff0c;是涉及到实体时&#xff0c;才会有调用的过程) 还有一点想说的是&#xff0c;构造函数的声明应该是固定的&#xff0c;不然没法随着对象的创建一起执行&#xff0c;必须是类名括号的形式。 二. …

深入理解哈希表

转自&#xff1a;https://bestswifter.com/hashtable/ 这篇文章由一个简单的问题引出: 有两个字典&#xff0c;分别存有 100 条数据和 10000 条数据&#xff0c;如果用一个不存在的 key 去查找数据&#xff0c;在哪个字典中速度更快&#xff1f; 有些计算机常识的读者都会立刻回…

正基模组:WIFI/BT/GPS/FM模组列表

各种模块广泛应用于网络摄像头、智能机器人、儿童故事机、词典笔、智能音箱、智能家电等需要实现无线联网设备的消费类电子产品。 模组由于其特性&#xff0c;给终端硬件开发带来巨大的便利性和实用性&#xff0c;具体小结如下&#xff1a; Feature特点:1. 模块均采用邮票孔形…

杨幂掐点祝福唐嫣,打破不和传言,情感营销还能这么玩?

发现今天的蜂蜜泡水特别地甜&#xff0c;舍友说&#xff0c;同样地蜂蜜同样多的水泡出来的水有什么不一样&#xff0c;肯定是你心情变好了。说得好像也有道理&#xff0c;想想最近这么多甜蜜的事&#xff0c;一开始是颖宝结婚&#xff0c;不久唐嫣和罗晋也宣布结婚&#xff0c;…

RTP/RTCP协议介绍

1流媒体协议 当前在Internet上传输音频和视频等信息主要有两种方式&#xff1a;下载和流式传输。 下载情况下&#xff0c;用户需要先下载整个媒体文件到本地&#xff0c;然后才能播放媒体文件。流式传输是指传输之前首先对多媒体进行预处理(降低质量和高效压缩)&#xff0c;然后…

推荐一款软件(作业)

在过去&#xff0c;每当我遇见不认识的英文单词时我的解决方法是:查阅英汉词典&#xff0c;后来在我拥有手机之后&#xff0c;我的解决方法是&#xff1a;上网百度&#xff0c;而现在我的解决方法是&#xff1a;“有道翻译官”。是的&#xff0c;我要介绍的这款软件便是“有道翻…

网易有道最新力作 有道词典笔3 结构拆解

2020年12月1日&#xff0c;有道品牌推出了一款硬件新品&#xff0c;名叫有道词典笔3。 网易有道于2019年8月推出可以“一扫查词”的有道词典笔2代&#xff0c;搭载了OCR&#xff08;光学字符识别&#xff09;技术的产品&#xff0c;大大改变了传统的学习方式&#xff0c;查词效…

有道词典笔3新增功能扫读和点读是怎么集成的?

2020年12月1日&#xff0c;有道品牌推出了一款硬件新品&#xff0c;名叫有道词典笔3。 相对有道于2019年8月推出后来被称为“爆品”的有道词典笔2来说&#xff0c;有道3硬件最大最明显差别是屏幕变的更大了&#xff0c;同时增加了点读功能&#xff08;点读笔点读特定教材的功能…

如何选择一款优秀的儿童读写台灯?

如何选择一款优秀的儿童阅读台灯&#xff1f;除了品牌、外观、材质、价格等因素外&#xff0c;最关键的是技术参数。 先说结论&#xff0c;满足如下几点参数&#xff0c;当数优选&#xff1a; 1-光通量&#xff1a;500lm以上 2-显色指数&#xff1a;≥95 3-色温&#xff1a…

标准C++类std::string的内存共享和Copy-On-Write(写时拷贝)

标准C&#xff0b;&#xff0b;类std::string的内存共享&#xff0c;值得体会&#xff1a; 详见大牛&#xff1a;https://www.douban.com/group/topic/19621165/ 顾名思义&#xff0c;内存共享&#xff0c;就是两个乃至更多的对象&#xff0c;共同使用一块内存&#xff1b; 1.关…

解决 | 此数据库文件跟当前sql server实例不兼容 sql server2008无法连接到(local)...

最近在搞ASP.NET&#xff0c;因实验室VS版本跟PC不一样可能&#xff0c;拷回来一打开就这样子&#xff1a; 眉头一皱的我打开我的古董SQL&#xff0c;自从用了MySQL就没碰它了我的锅。。。果然。。连接的时候。。。不慌&#xff0c;(win 10)打开控制面板\系统和安全\管理工具 -…

IP大时代下,网络枪机技术发展现状

来源&#xff1a;a&s《评测&选型》 作者&#xff1a;海康威视程玮 在视频监控行业内&#xff0c;有很多里程碑式的产品&#xff0c;我们可以从这些产品中了解视频监控的发展趋势。2000年左右&#xff0c;第一台DVR面世奠定了视频监控行业从CCTV走向数字化的基础&#x…

JVM调优总结(3):垃圾回收面临的问题

如何区分垃圾 上面说到的“引用计数”法&#xff0c;通过统计控制生成对象和删除对象时的引用数来判断。垃圾回收程序收集计数为0的对象即可。但是这种方法无法解决循环引用。所以&#xff0c;后来实现的垃圾判断算法中&#xff0c;都是从程序运行的根节点出发&#xff0c;遍历…

运放搭建主动滤波电路

主动低通滤波电路 R1R216K R3R4100K C1C20.01uF 放大倍数AvR4/(R3R4) Freq1KHz 主动高通滤波电路 C12*C20.02uF,C20.01uF R1R2110K 6dBLow-cutFreq100Hz