新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > S3C2440 IIC总线接口

S3C2440 IIC总线接口

作者:时间:2016-11-21来源:网络收藏
s3c2440内部有一个IIC总线接口,因此为我们连接带有IIC通信模块的外围设备提供了便利。它具有四种操作模式:主设备发送模式、主设备接收模式、从设备发送模式和从设备接收模式。
在这里只把s3c2440当做IIC总线的主设备来使用,因此只介绍前两种操作模式。在主设备发送模式下,它的工作流程为:首先配置IIC模式,然后把从设备地址写入接收发送数据移位寄存器IICDS中,再把0xF0写入控制状态寄存器IICSTAT中,这时等待从设备发送应答信号,如果想要继续发送数据,那么在接收到应答信号后,再把待发送的数据写入寄存器IICDS中,清除中断标志后,再次等待应答信号;如果不想再发送数据了,那么把0x90写入寄存器IICSTAT中,清除中断标志并等待停止条件后,即完成了一次主设备的发送。在主设备接收模式下,它的工作流程为:首先配置IIC模式,然后把从设备地址写入接收发送数据移位寄存器IICDS中,再把0xB0写入控制状态寄存器IICSTAT中,这时等待从设备发送应答信号,如果想要接收数据,那么在应答信号后,读取寄存器IICDS,清除中断标志;如果不想接收数据了,那么就向寄存器IICSTAT写入0x90,清除中断标志并等待停止条件后,即完成了一次主设备的接收。在完成上述两个模式时,主要用到了控制寄存器IICCON、控制状态寄存器IICSTAT和发送接收数据移位寄存器IICDS。由于我们只把s3c2440当做主设备来用,并且系统的IIC总线上只有这么一个主设备,因此用来设置从设备地址的地址寄存器IICADD,和用于仲裁总线的多主设备线路控制寄存器IICLC都无需配置。寄存器IICCON的第6位和低4位用于设置IIC的时钟频率,因为IIC的时钟线SCL都是由主设备提供的。s3c2440的IIC时钟源为PCLK,当系统的PCLK为50MHz,而从设备最高需要100kHz时,可以将IICCON的第6位置1,IICCON的低4位全为0即可。寄存器IICCON的第7位用于设置是否发出应答信号,第5位用于是否使能发送和接收中断,第4位用于中断的标志,当接收或发送数据后一定要对该位进行清零,以清除中断标志。寄存器IICSTAT的高2位用于设置是哪种操作模式,当向第5位写0或写1时,则表示结束IIC或开始IIC通讯,第4位用于是否使能接收/发送数据。
上面的一段是摘取网上某人的,写的很好。
AT24C02A(时序图详细见数据手册)
写操作有两种模式:字节写和页写。
在字节写模式下,主器件发送起始命令和从器件地址信息(R/W位置零)给从器件。在从器件产生应答信号后,主器件发送AT24C02的字节地址,主器件在收到从器件的另一个应答信号后,再发送数据到被寻址的存储单元。AT24C02再次应答并在主器件产生停止信号后开始内部数据的擦写,在内部擦写过程中,AT24C02不再应答主器件的任何请求。
页写操作的启动字节,地址字节和第一个数据字节都跟字节写的方式一样,不同在于传送了一字节数据后并不产生停止信号。主器件被允许发送8个字节,每发送一个字节数据后AT24C02产生一个应答位并将字节地址低位加1,高位保持不变。如果在发送停止信号之前主器件发送超过8个字节,地址计数器将自动翻转,先前写入的数据将被覆盖。只要接收到主器件发送的停止信号,AT24C02启动内部写周期,将数据在一个写周期内写到数据区
读操作有三种模式:立即地址读、选择性读和连续读。
立即地址读
AT24C02包含一个地址计数器,内容为最后操作字节的地址加1。因此,如果上次读或写的操作地址为N,则立即读的地址从地址N+1开始。AT24C02接收到器件地址信号和R/W位置1后,它首先发送一个应答信号,然后发送一个8位字节数据。主器件不需发送一个应答信号,但要产生一个停止信号,这时AT24C02停止传输。
选择性读
选择性读操作允许主器件对寄存器的任意字节进行读操作。为进行这种操作,首先应该设定字节地址。主器件向AT24C02发送起始信号和从器件地址,从器件响应之后发送主器件想读取的字节数据的地址。AT24C02应答之后,主器件重新发送起始信号和从器件地址,此时R/W位才置1。AT24C02响应并发送应答信号,然后输出所要求的一个8位字节数据,主器件不发送应答信号但产生一个停止信号,此时AT24C02停止传输。
连续读
连续读操作的启动跟选择性读操作一样,除了在AT24C02发送完一个8位字节数据后,主器件产生一个应答信号而不是停止信号,这个应答信号告知AT24C02要求更多的数据。对应每个应答信号,AT24C02将发送下一个地址的8位数据字节。为提供连续读操作,AT24C02内部地址计数器在每次读操作完成之后递增。这样整个寄存器区域在可在一个读操作内全部读出。
贴出一个三星官方IIC测试程序,使用的是中断查询发式
  1. #include
  2. #include"2440addr.h"
  3. #include"2440lib.h"
  4. #include"def.h"
  5. #defineWRDATA(1)
  6. #definePOLLACK(2)
  7. #defineRDDATA(3)
  8. #defineSETRDADDR(4)
  9. #defineIICBUFSIZE0x20
  10. staticU8iicData[IICBUFSIZE];
  11. staticvolatileintiicDataCount;
  12. staticvolatileintiicStatus;
  13. staticvolatileintiicMode;
  14. staticintiicPt;
  15. voidWr24C02(U32slvAddr,U32addr,U8data);
  16. voidRd24C02(U32slvAddr,U32addr,U8*data);
  17. voidIicPoll(void);
  18. voidRun_IicPoll(void);
  19. voidMain(void)
  20. {
  21. unsignedinti,j;
  22. staticU8data[256];//用于存储AT24C02读出的数据
  23. SelectFclk(2);//设置系统时钟400M
  24. ChangeClockDivider(2,1);//设置分频1:4:8
  25. CalcBusClk();//计算总线频率
  26. rGPHCON&=~((3<<4)|(3<<6));
  27. rGPHCON|=(2<<4)|(2<<6);//GPH2--TXD[0];GPH3--RXD[0]
  28. rGPHUP=0x00;//使能上拉功能
  29. Uart_Init(0,115200);
  30. Uart_Select(0);
  31. Uart_Printf("[IICTest(Polling)usingAT24C020]n");
  32. rGPEUP|=0xc000;//关上拉
  33. rGPECON&=~0xf0000000;
  34. rGPECON|=0xa0000000;//GPE15:IICSDA,GPE14:IICSCL
  35. //使能应答,IIC总线时钟IICCLK=PCLK/16,使能中断,发送时钟IICCLK/16
  36. rIICCON=(1<<7)|(0<<6)|(1<<5)|(0xf);
  37. rIICADD=0x10;//2440从机地址=[7:1]
  38. rIICSTAT=0x10;//IIC总线数据输出使能(Rx/Tx)
  39. Uart_Printf("WritetestdataintoAT24C02n");
  40. for(i=0;i<256;i++)
  41. Wr24C02(0xa0,(U8)i,i);//写入数据到AT24C02
  42. for(i=0;i<256;i++)//数组数据清零
  43. data[i]=0;
  44. Uart_Printf("ReadtestdatafromAT24C02n");
  45. for(i=0;i<256;i++)
  46. Rd24C02(0xa0,(U8)i,&(data[i]));//读取AT24C02的数据放入data数组中
  47. for(i=0;i<16;i++)
  48. {
  49. for(j=0;j<16;j++)
  50. Uart_Printf("%2x",data[i*16+j]);//打印从AT24C02读出的数据
  51. Uart_Printf("n");
  52. }
  53. }
  54. voidWr24C02(U32slvAddr,U32addr,U8data)//slvAddr为从地址
  55. {//addr为字节地址,data为写入的数据
  56. iicMode=WRDATA;//写数据模式
  57. iicPt=0;
  58. iicData[0]=(U8)addr;
  59. iicData[1]=data;
  60. iicDataCount=2;//根据AT24C02字节写的发式,要写从地址和字节地址
  61. rIICDS=slvAddr;//把0xa0地址写入到数据移位寄存器IICDS
  62. //MasterTxmode,Start(Write),IIC-busdataoutputenable
  63. //Busarbitrationsucessful,AddressasslavestatusflagCleared,
  64. //Addresszerostatusflagcleared,Lastreceivedbitis0
  65. rIICSTAT=0xf0;//
  66. //Clearingthependingbitisntneededbecausethependingbithasbeencleared.
  67. while(iicDataCount!=-1)
  68. Run_IicPoll();
  69. iicMode=POLLACK;
  70. while(1)
  71. {
  72. rIICDS=slvAddr;
  73. iicStatus=0x100;//Tocheckif_iicStatusischanged
  74. rIICSTAT=0xf0;//MasterTx,Start,OutputEnable,Sucessful,Cleared,Cleared,0
  75. rIICCON=0xaf;//ResumesIICoperation.
  76. while(iicStatus==0x100)
  77. Run_IicPoll();
  78. if(!(iicStatus&0x1))
  79. break;//WhenACKisreceived
  80. }
  81. rIICSTAT=0xd0;//MasterTxcondition,Stop(Write),OutputEnable
  82. rIICCON=0xaf;//ResumesIICoperation.
  83. Delay(1);//Waituntilstopcondtionisineffect.
  84. //Writeiscompleted.
  85. }
  86. //************************[_Rd24C02]********************************
  87. voidRd24C02(U32slvAddr,U32addr,U8*data)
  88. {
  89. iicMode=SETRDADDR;//设置要从从机读取数据的从地址
  90. iicPt=0;
  91. iicData[0]=(U8)addr;
  92. iicDataCount=1;//写从地址
  93. rIICDS=slvAddr;
  94. rIICSTAT=0xf0;//MasTx,Start
  95. //Clearingthependingbitisntneededbecausethependingbithasbeencleared.
  96. while(iicDataCount!=-1)
  97. Run_IicPoll();
  98. iicMode=RDDATA;//读数据模式
  99. iicPt=0;
  100. iicDataCount=1;//
  101. rIICDS=slvAddr;
  102. rIICSTAT=0xb0;//MasterRx,Start
  103. rIICCON=0xaf;//ResumesIICoperation.
  104. while(iicDataCount!=-1)
  105. Run_IicPoll();
  106. *data=iicData[1];
  107. }
  108. voidRun_IicPoll(void)
  109. {
  110. if(rIICCON&0x10)//Tx/Rx中断使能
  111. IicPoll();
  112. }
  113. voidIicPoll(void)
  114. {
  115. U32iicSt,i;
  116. iicSt=rIICSTAT;//ICC状态寄存器
  117. if(iicSt&0x8){}//总线仲裁失败
  118. if(iicSt&0x4){}//从地址与ICCADD地址匹配
  119. if(iicSt&0x2){}//从地址为00000000b
  120. if(iicSt&0x1){}//未收到ACK
  121. switch(iicMode)
  122. {
  123. casePOLLACK:
  124. iicStatus=iicSt;
  125. break;
  126. caseRDDATA://从从机中读取数据
  127. if((iicDataCount--)==0)
  128. {
  129. iicData[iicPt++]=rIICDS;
  130. rIICSTAT=0x90;//StopMasRxcondition
  131. rIICCON=0xaf;//ResumesIICoperation.
  132. Delay(1);//Waituntilstopcondtionisineffect.
  133. //Toolongtime...
  134. //Thependingbitwillnotbesetafterissuingstopcondition.
  135. break;
  136. }
  137. iicData[iicPt++]=rIICDS;
  138. //Thelastdatahastobereadwithnoack.
  139. if((iicDataCount)==0)
  140. rIICCON=0x2f;//ResumesIICoperationwithNOACK.
  141. else
  142. rIICCON=0xaf;//ResumesIICoperationwithACK
  143. break;
  144. caseWRDATA://写数据到从机
  145. if((iicDataCount--)==0)
  146. {
  147. rIICSTAT=0xd0;//stopMasTxcondition
  148. rIICCON=0xaf;//resumesIICoperation.
  149. Delay(1);//waituntilstopcondtionisineffect.
  150. //Thependingbitwillnotbesetafterissuingstopcondition.
  151. break;
  152. }
  153. rIICDS=iicData[iicPt++];//iicData[0]hasdummy.
  154. for(i=0;i<10;i++);//forsetuptimeuntilrisingedgeofIICSCL
  155. rIICCON=0xaf;//resumesIICoperation.
  156. break;
  157. caseSETRDADDR://设置要从从机机读取数据的从机地址
  158. if((iicDataCount--)==0)
  159. {
  160. break;//IICoperationisstoppedbecauseofIICCON[4]
  161. }
  162. rIICDS=iicData[iicPt++];
  163. for(i=0;i<10;i++);//forsetuptimeuntilrisingedgeofIICSCL
  164. rIICCON=0xaf;//resumesIICoperation.
  165. break;
  166. default:
  167. break;
  168. }
  169. }





关键词: S3C2440IIC总线接

评论


技术专区

关闭