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. 转:Swing中的线程探究
  2. linux centos yum 报错 [Errno 256] No more mirrors to try 解决方法
  3. 读书笔记 Effective C++: 02 构造析构赋值运算
  4. android 通知灯 测试,Android灯光系统通知灯【转】
  5. 国际电信联盟:3GPP系标准成为唯一被认可的5G标准
  6. 底部按钮吸附_知乎的药丸按钮(二)我的 iOS 实现
  7. node link 踩坑记录
  8. [转]OpenGL基础技术讲座--发展历史
  9. Android-【报错】java.lang.ClassCastException: .MainActivity cannot be cast to java.lang.Runnable
  10. 求助:使用foreach函数获取到后台数据时未在表格上渲染的问题
  11. USB2.0 EMC标准设计
  12. 全球软件无线电市场(SDR)标明到2020年的显著增量美元机会
  13. python分号报错_go、java已经python中分号的使用
  14. 如何使用群发工具?邮件群发软件免费有哪些?
  15. 软件研发落地实践,要从设计就开始
  16. Truffle框架的初使用
  17. js 百度地图标记定位(一)
  18. Android 4游戏编程入门经典
  19. 输入【ionic start myApp tabs】命令创建项目时失败
  20. Time For Kids 很不错的英语学习周刊

热门文章

  1. golang 使用negroni,实现server
  2. 备份android分区,备份分区
  3. python爬虫 爬取小姐姐图片
  4. 中国为什么非要买美国国债
  5. C#之Base64编码解码
  6. AFNetworkReachabilityManager检测网络状态
  7. 创业好,还是上班好?你觉得呢
  8. 《深入理解计算机系统(原书第三版)》pdf
  9. 多肉淘宝养成记(含治疗玻璃心)
  10. 多核cpu是并发还是并行_多核CPU及其带来的并发更改