微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > I2C总线时序模拟(二)-加深理解总线协议

I2C总线时序模拟(二)-加深理解总线协议

时间:11-22 来源:互联网 点击:
[cpp]view plaincopy

print?

  1. /********************************************************************
  2. 此程序是I2C操作平台(主方式的软件平台)的底层的C子程序,如发送数据
  3. 及接收数据,应答位发送,并提供了几个直接面对器件的操作函数,它很方便的
  4. 与用户程序连接并扩展.....
  5. 注意:函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作
  6. 一定的修改....(本例是1us机器周期,即晶振频率要小于12MHZ)
  7. ********************************************************************/
  8. #include/*头文件的包含*/
  9. #include
  10. #defineucharunsignedchar/*宏定义*/
  11. #defineuintunsignedint
  12. #define_Nop()_nop_()/*定义空指令*/
  13. /*常,变量定义区*/
  14. /*端口位定义*/
  15. sbitSDA=P1^3;/*模拟I2C数据传送位*/
  16. sbitSCL=P1^2;/*模拟I2C时钟控制位*/
  17. /*状态标志*/
  18. bitack;/*应答标志位*/
  19. /*******************************************************************
  20. 起动总线函数
  21. 函数原型:voidStart_I2c();
  22. 功能:启动I2C总线,即发送I2C起始条件.
  23. ********************************************************************/
  24. voidStart_I2c()
  25. {
  26. SDA=1;/*发送起始条件的数据信号*/
  27. _Nop();
  28. SCL=1;
  29. _Nop();/*起始条件建立时间大于4.7us,延时*/
  30. _Nop();
  31. _Nop();
  32. _Nop();
  33. _Nop();
  34. SDA=0;/*发送起始信号*/
  35. _Nop();/*起始条件锁定时间大于4μs*/
  36. _Nop();
  37. _Nop();
  38. _Nop();
  39. _Nop();
  40. SCL=0;/*钳住I2C总线,准备发送或接收数据*/
  41. _Nop();
  42. _Nop();
  43. }
  44. /*******************************************************************
  45. 结束总线函数
  46. 函数原型:voidStop_I2c();
  47. 功能:结束I2C总线,即发送I2C结束条件.
  48. ********************************************************************/
  49. voidStop_I2c()
  50. {
  51. SDA=0;/*发送结束条件的数据信号*/
  52. _Nop();/*发送结束条件的时钟信号*/
  53. SCL=1;/*结束条件建立时间大于4μs*/
  54. _Nop();
  55. _Nop();
  56. _Nop();
  57. _Nop();
  58. _Nop();
  59. SDA=1;/*发送I2C总线结束信号*/
  60. _Nop();
  61. _Nop();
  62. _Nop();
  63. _Nop();
  64. }
  65. /*******************************************************************
  66. 字节数据传送函数
  67. 函数原型:voidSendByte(ucharc);
  68. 功能:将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
  69. 此状态位进行操作.(不应答或非应答都使ack=0假)
  70. 发送数据正常,ack=1;ack=0表示被控器无应答或损坏。
  71. ********************************************************************/
  72. voidSendByte(ucharc)
  73. {
  74. ucharBitCnt;
  75. for(BitCnt=0;BitCnt<8;BitCnt++)/*要传送的数据长度为8位*/
  76. {
  77. if((c
  78. ;/*判断发送位*/
  79. elseSDA=0;
  80. _Nop();
  81. SCL=1;/*置时钟线为高,通知被控器开始接收数据位*/
  82. _Nop();
  83. _Nop();/*保证时钟高电平周期大于4μs*/
  84. _Nop();
  85. _Nop();
  86. _Nop();
  87. SCL=0;
  88. }
  89. _Nop();
  90. _Nop();
  91. SDA=1;/*8位发送完后释放数据线,准备接收应答位*/
  92. _Nop();
  93. _Nop();
  94. SCL=1;
  95. _Nop();
  96. _Nop();
  97. _Nop();
  98. if(SDA==1)ack=0;
  99. elseack=1;/*判断是否接收到应答信号*/
  100. SCL=0;
  101. _Nop();
  102. _Nop();
  103. }
  104. /*******************************************************************
  105. 字节数据传送函数
  106. 函数原型:ucharRcvByte();
  107. 功能:用来接收从器件传来的数据,并判断总线错误(不发应答信号),
  108. 发完后请用应答函数。
  109. ********************************************************************/
  110. ucharRcvByte()
  111. {
  112. ucharretc;
  113. ucharBitCnt;
  114. retc=0;
  115. SDA=1;/*置数据线为输入方式*/
  116. for(BitCnt=0;BitCnt<8;BitCnt++)
  117. {
  118. _Nop();
  119. SCL=0;/*置时钟线为低,准备接收数据位*/
  120. _Nop();
  121. _Nop();/*时钟低电平周期大于4.7μs*/
  122. _Nop();
  123. _Nop();
  124. _Nop();
  125. SCL=1;/*置时钟线为高使数据线上数据有效*/
  126. _Nop();
  127. _Nop();
  128. retc=retc<1;
  129. if(SDA==1)retc=retc+1;/*读数据位,接收的数据位放入retc中*/
  130. _Nop();
  131. _Nop();
  132. }
  133. SCL=0;
  134. _Nop();
  135. _Nop();
  136. return(retc);
  137. }
  138. /********************************************************************
  139. 应答子函数
  140. 原型:voidAck_I2c(bita);
  141. 功能:主控器进行应答信号,(可以是应答或非应答信号)
  142. ********************************************************************/
  143. voidAck_I2c(bita)
  144. {
  145. if(a==0)SDA=0;/*在此发出应答或非应答信号*/
  146. elseSDA=1;
  147. _Nop();
  148. _Nop();
  149. _Nop();
  150. SCL=1;
  151. _Nop();
  152. _Nop();/*时钟低电平周期大于4μs*/
  153. _Nop();
  154. _Nop();
  155. _Nop();
  156. SCL=0;/*清时钟线,钳住I2C总线以便继续接收*/
  157. _Nop();
  158. _Nop();
  159. }
  160. /*******************************************************************
  161. 向无子地址器件发送字节数据函数
  162. 函数原型:bitISendByte(ucharsla,ucahrc);
  163. 功能:从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.
  164. 如果返回1表

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top