IIC(Inter-Integrated Circuit,I2C)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微处理器及其外围设备。在iic总线上,只需要两条线:串行数据线SDA和串行时钟线SCL,便可完成通信。如图:

IIC启动和停止信号的定义

s3c2440内部有一个IIC总线接口,通过对其寄存器的配置和时序的操作即可完成IIC通信,其编程流程如下:

一,在主设备发送模式下,它的工作流程为:

1,首先配置IIC模式(包括配置GPE15,GPE14为第二功能 时钟线和数据线,iic中断使能,发送时钟频率等)

[html] view plaincopy
  1. rGPECON |= 0xa00000;                //GPE15:IICSDA , GPE14:IICSCL,GPE15,GPE14为第二功能 时钟线和数据线
  2. pISR_IIC = (unsigned)IicInt;//中断注册
  3. rINTMSK &= ~(BIT_IIC);//iic中断使能
  4. rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);//(1<<7)Enable ACK,(0<<6) Prescaler IICCLK=PCLK/16,(1<<5) Enable interrupt,
  5. // (0xf)Transmit clock value Tx clock=IICCLK/(15+1)
  6. // If PCLK 50.7MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz
  7. rIICADD  = 0x10;                    //2440 slave address = [7:1]=0x10;
  8. rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)
  9. rIICLC = (1<<2)|(1);          // Filter enable, 5 clocks SDA output delay       added by lj

2,然后把从设备地址写入接收发送数据移位寄存器IICDS中,再把0xF0写入控制状态寄存器IICSTAT中,这时等待从设备发送应答信号

[html] view plaincopy
  1. rIICSTAT   = 0xf0;              //MasTx,Start
  2. rIICCON    = 0xaf;              //Resumes IIC operation.
  3. while(_iicStatus==0x100);       //Wait until IICSTAT change

3,如果想要继续发送数据,那么在接收到应答信号后,再把待发送的数据写入寄存器IICDS中,清除中断标志后,再次等待应答信号;如果不想再发送数据了,那么把0x90写入寄存器IICSTAT中,清除中断标志并等待停止条件后,即完成了一次主设备的发送。

[html] view plaincopy
  1. rIICSTAT = 0xd0;                    //1101_,11~MasRx,0~stop,1~RxTx enable //Stop MasTx condition
  2. rIICCON  = 0xaf;                    //Resumes IIC operation.
  3. Delay(1);                           //Wait until stop condtion is in effect.
  4. //Write is completed.

二,在主设备接收模式下,它的工作流程为:

1,首先配置IIC模式,然后把从设备地址写入接收发送数据移位寄存器IICDS中,再把0xB0写入控制状态寄存器IICSTAT中

[html] view plaincopy
  1. rIICDS        = slvAddr;            //slvAddr=0xa0
  2. rIICSTAT      = 0xb0;               //1011,10~MasRx,1~Start,1~RxTx enable
  3. rIICCON       = 0xaf;               //Resumes IIC operation.
  4. while(_iicDataCount!=-1);//等待主接收模式停止,在中断函数里进行的

2,这时等待从设备发送应答信号,如果想要接收数据,那么在应答信号后,读取寄存器IICDS,清除中断标志;如果不想接收数据了,那么就向寄存器IICSTAT写入0x90,清除中断标志并等待停止条件后,即完成了一次主设备的接收。

[html] view plaincopy
  1. _iicData[_iicPt++] = rIICDS;
  2. rIICSTAT = 0x90;                 //1001Stop MasRx condition
  3. rIICCON  = 0xaf;                 //Resumes IIC operation.
  4. Delay(1);                        //Wait until stop condtion is in effect

其程序流程图如下:

下面的例程将向AT24C02写入若干字节,并读出来显示在超级终端:

IIC.c

[html] view plaincopy
  1. //===================================================================
  2. //       SMDK2440 IIC configuration
  3. //  GPE15=IICSDA, GPE14=IICSCL
  4. //  "Interrupt mode" for IIC block中断模式下的IIC操作
  5. //===================================================================
  6. //******************[ Test_Iic ]**************************************
  7. void Test_Iic(void)
  8. {
  9. unsigned int i,j,save_E,save_PE;
  10. static U8 data[256];
  11. Uart_Printf("\nIIC Test(Interrupt) using AT24C02\n");
  12. save_E   = rGPECON;//保护现场
  13. save_PE  = rGPEUP;
  14. rGPEUP  |= 0xc000;                  //Pull-up disable ,1_disable,0_enable
  15. rGPECON |= 0xa00000;                //GPE15:IICSDA , GPE14:IICSCL,GPE15,GPE14为第二功能 时钟线和数据线
  16. pISR_IIC = (unsigned)IicInt;//中断注册
  17. rINTMSK &= ~(BIT_IIC);//iic中断使能
  18. rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);//(1<<7)Enable ACK,(0<<6) Prescaler IICCLK=PCLK/16,(1<<5) Enable interrupt,
  19. // (0xf)Transmit clock value Tx clock=IICCLK/(15+1)
  20. // If PCLK 50.7MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz
  21. rIICADD  = 0x10;                    //2440 slave address = [7:1]=0x10;
  22. rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)
  23. rIICLC = (1<<2)|(1);                  // Filter enable, 5 clocks SDA output delay       added by lj
  24. Uart_Printf("Write test data into AT24C02\n");
  25. for(i=0;i<256;i++)
  26. Wr24C080(0xa0,(U8)i,i);//写入0~255主设备地址0~255?从设备地址0xa0?
  27. for(i=0;i<256;i++)//data[]清零
  28. data[i] = 0;
  29. Uart_Printf("Read test data from AT24C02\n");
  30. for(i=0;i<256;i++)
  31. Rd24C080(0xa0,(U8)i,&(data[i])); //从同一个地址读入256个字节
  32. //Line changed 0 ~ f
  33. for(i=0;i<16;i++)
  34. {
  35. for(j=0;j<16;j++)
  36. Uart_Printf("%2x ",data[i*16+j]);
  37. Uart_Printf("\n");//每16字节换一行
  38. }
  39. rINTMSK |= BIT_IIC; //iic操作结束,禁止iic中断
  40. rGPEUP  = save_PE;  //恢复现场
  41. rGPECON = save_E;
  42. }
  43. //*************************[ Wr24C080 ]****************************
  44. void Wr24C080(U32 slvAddr,U32 addr,U8 data)
  45. {
  46. _iicMode      = WRDATA;//写数据模式
  47. _iicPt        = 0;
  48. _iicData[0]   = (U8)addr;
  49. _iicData[1]   = data;
  50. _iicDataCount = 2;//中断里写两个数据(地址)
  51. rIICDS   = slvAddr;                 //slvAddr=0xa0
  52. rIICSTAT = 0xf0;                    //11MasTx,1Start,1enable rx/tx(使能中断)首先发送从设备地址,在中断函数里发送数据
  53. //Clearing the pending bit isn't needed because the pending bit has been cleared.
  54. while(_iicDataCount!=-1);//等待主发送模式停止,在中断函数里进行的
  55. _iicMode = POLLACK;//MasTx condition  has Stoped,等待ACK应答模式,有应答表示从设备已经收到
  56. while(1)
  57. {
  58. rIICDS     = slvAddr;           //slvAddr=0xa0
  59. _iicStatus = 0x100;             //IICSTAT clear?
  60. rIICSTAT   = 0xf0;              //MasTx,Start
  61. rIICCON    = 0xaf;              //Resumes IIC operation.
  62. while(_iicStatus==0x100);       //Wait until IICSTAT change
  63. if(!(_iicStatus&0x1))
  64. break;                      //When ACK is received
  65. }
  66. rIICSTAT = 0xd0;                    //1101_,11~MasRx,0~stop,1~RxTx enable //Stop MasTx condition
  67. rIICCON  = 0xaf;                    //Resumes IIC operation.
  68. Delay(1);                           //Wait until stop condtion is in effect.
  69. //Write is completed.
  70. }
  71. //**********************[ Rd24C080 ] ***********************************
  72. void Rd24C080(U32 slvAddr,U32 addr,U8 *data)
  73. {
  74. _iicMode      = SETRDADDR;//写地址模式
  75. _iicPt        = 0;
  76. _iicData[0]   = (U8)addr;
  77. _iicDataCount = 1;//写一个数据(地址)
  78. rIICDS   = slvAddr;                 //slvAddr=0xa0首先写入从设备地址
  79. rIICSTAT = 0xf0;                    //MasTx,Start发送从设备地址
  80. //Clearing the pending bit isn't needed because the pending bit has been cleared.
  81. while(_iicDataCount!=-1);//等待主发送模式停止,在中断函数里进行的
  82. _iicMode      = RDDATA;//读数据模式
  83. _iicPt        = 0;
  84. _iicDataCount = 1;//读一个数据(地址)
  85. rIICDS        = slvAddr;            //slvAddr=0xa0
  86. rIICSTAT      = 0xb0;               //1011,10~MasRx,1~Start,1~RxTx enable
  87. rIICCON       = 0xaf;               //Resumes IIC operation.
  88. while(_iicDataCount!=-1);//等待主接收模式停止,在中断函数里进行的
  89. *data = _iicData[1];//iic发送过来的数据将被放入_iicData[1]中,然后被传递到data[]数组中
  90. }
  91. //-------------------------------------------------------------------------
  92. void __irq IicInt(void)         //iic中断函数
  93. {
  94. U32 iicSt,i;
  95. rSRCPND = BIT_IIC;          //Clear pending bit
  96. rINTPND = BIT_IIC;          //Clear pending bit
  97. iicSt   = rIICSTAT;         //读取状态寄存器的值
  98. if(iicSt & 0x8){}           //When bus arbitration is failed.
  99. if(iicSt & 0x4){}           //When a slave address is matched with IICADD
  100. if(iicSt & 0x2){}           //When a slave address is 0000000b
  101. if(iicSt & 0x1){}           //When ACK isn't received用户自己添加?
  102. switch(_iicMode)            //根据不同的模式作出相应的动作
  103. {
  104. case POLLACK:
  105. _iicStatus = iicSt;//等待
  106. break;
  107. case RDDATA:
  108. if((_iicDataCount--)==0)
  109. {
  110. _iicData[_iicPt++] = rIICDS;
  111. rIICSTAT = 0x90;                 //1001Stop MasRx condition
  112. rIICCON  = 0xaf;                 //Resumes IIC operation.
  113. Delay(1);                        //Wait until stop condtion is in effect.
  114. //Too long time...
  115. //The pending bit will not be set after issuing stop condition.
  116. break;                           //在停止状态下,中断挂起位将不会被置位
  117. }
  118. _iicData[_iicPt++] = rIICDS;         //将rIICDS中的数据,即接收到的数据存入_iicData[1];The last data has to be read with no ack.
  119. if((_iicDataCount)==0)
  120. rIICCON = 0x2f;                  //Resumes IIC operation with NOACK.
  121. else
  122. rIICCON = 0xaf;                  //Resumes IIC operation with ACK
  123. break;
  124. case WRDATA:
  125. if((_iicDataCount--)==0)            //_iicDataCount=2,当第三次进入中断时进入此{},停止主发送模式
  126. {
  127. rIICSTAT = 0xd0;                //1101Stop MasTx condition
  128. rIICCON  = 0xaf;                //Resumes IIC operation.
  129. Delay(1);                       //Wait until stop condtion is in effect.
  130. //The pending bit will not be set after issuing stop condition.
  131. //在停止状态下,中断挂起位将不会被置位
  132. break;
  133. }
  134. rIICDS = _iicData[_iicPt++];        //_iicData[0] has dummy.可以发送两个数据,第一个发送的是_iicData[0]=addr即主设备地址,
  135. //第二个发送的是_iicData[1]=data即要发送的数据,
  136. for(i=0;i<10;i++);                  //for setup time until rising edge of IICSCL等待时钟上升沿
  137. rIICCON = 0xaf;                     //resumes IIC operation.
  138. break;
  139. case SETRDADDR:
  140. //          Uart_Printf("[ S%d ]",_iicDataCount);
  141. if((_iicDataCount--)==0)
  142. break;                          //IIC operation is stopped because of IICCON[4]
  143. rIICDS = _iicData[_iicPt++];        //只发送一个数据_iicData[0]=addr,即主设备地址
  144. for(i=0;i<10;i++);                  //For setup time until rising edge of IICSCL等待时钟上升沿
  145. rIICCON = 0xaf;                     //Resumes IIC operation.重复iic操作
  146. break;
  147. default:
  148. break;
  149. }
  150. }

S3c2440 IIC相关推荐

  1. s3c2440 IIC AT24C08 (II)非中断模式

    承接上一篇:    http://blog.csdn.net/qq361294382/article/details/51589964 本次实验使用非中断方式实现S3C2440 对于AT24C08 实 ...

  2. S3C2440之IIC

    http://blog.csdn.net/okliujieko/article/details/7039937 S3C2440之IICS3C2440之IIC IIC(Inter-Integrated ...

  3. S3C2440之IIC裸机驱动

    花了两天的时间终于把这个搞定了,其实I2C的原理还是比较简单的,只是几个细节性的东西还是需要特别的注意,主要是需要注意一下几点: 1.rIICCON &= ~0x10; 清中断必须要在rIIC ...

  4. S3C2440 SDRAM内存驱动 .

    SDRAM(Synchronous Dynamic Random Access Memory,同步动态随机存储器)也就是通常所说的内存.内存的工作原理.控制时序.及相关控制器的配置方法一直是嵌入式系统 ...

  5. S3C2440时钟系统详解

    在讲述系统时钟之前,因为这些设备都是挂靠在系统时钟上的,所以必须先说系统时钟,S3C2440的时钟系统如下 外部时钟源分两种,晶振或者外部频率,由om3-2选择,时钟电路根据两种选择也有两种 我们来分 ...

  6. linux 扫描i2c端口,s3c2440用I2C接口访问EEPROM

    在前面阅读理解了I2C的官方协议文档后,就拿s3c2440和EEPROM来验证一下. 本来是想用s3c2440的SDA和SCL管脚复用为GPIO来模拟的,但在没有示波器的情况下搞了一周,怎么都出不来, ...

  7. Exynos4412 IIC总线驱动开发(一)—— IIC 基础概念及驱动架构分析

    关于Exynos4412 IIC 裸机开发请看 :Exynos4412 裸机开发 -- IIC总线 ,下面回顾下 IIC 基础概念 一.IIC 基础概念 IIC(Inter-Integrated Ci ...

  8. I2C总线学习—查缺补漏—S3C2440的I2C控制器

    I2C总线学习-查缺补漏-S3C2440的I2C控制器                  学习了IIC总线协议的理论部分,觉得应该学习具体操作2440的IIC控制器,毕竟最终都是为了学习S3C2440 ...

  9. Linux底层IIC 总线的理解、调用函数以及常见面试问题

    对 IIC 总线的理解.调用函数以及常见面试问题 一.IIC 总线概述: IIC 即Inter-Integrated Circuit(集成电路总线) I2C总线是PHLIPS公司推出的一种串行总线, ...

最新文章

  1. Condition_number
  2. Spring Boot AOP记录用户操作日志
  3. mysql5.6 pt-query-digest,分析pt-query-digest输出信息
  4. 几何分布和超几何分布
  5. SQL语句:SQLwhile(0=0)与while @@fetch_status=0.
  6. 音视频技术开发周刊 56期
  7. count(id)count(1)count(*)count(字段)
  8. GBDT和随机森林的区别
  9. 截至频率_截至2013年核心Java帖子
  10. 咦,拆分个字符串都这么讲究?
  11. inux下切换到root权限有以下几种方式
  12. .NET Interop.SHDocVw和MSHTML引用如何操作
  13. SQL 数据库 学习 012 数据库关系图
  14. wds和extap作为cpe区别
  15. FAST-LIO论文阅读
  16. es linux下使用api进行es故障操作处理
  17. 我经历过的失败产品和项目(四):没有落单的多媒体彩铃媒体服务器
  18. c语言写照明系统的代码,无线LED照明系统设计(ZigBee)的设计与实现(C语言)
  19. STC15w4k32s4单片机 串口通信
  20. Ajax,Axios,Fetch的学习,对比和使用

热门文章

  1. H264 Annex B 与 AVCC的区别
  2. 思科交换机备份文件到服务器,CISCO交换机备份和恢复配置文件的方法
  3. 基于51单片机的数字气压计
  4. P1567_统计天数
  5. 解决Ubuntu14.04不能打正确拼音--无法选择第二个拼音
  6. 小马哥----高仿苹果6s 主板型号S106s 更换内核 刷机拆机主板图与开机识别图
  7. 快速减肥的30种方法
  8. python总结与习题(一)
  9. 最长递增子序列 O(NlogN)算法
  10. Html5 Egret游戏开发 成语大挑战(一)开篇