<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > I2C總線時序模擬(二)-加深理解總線協(xié)議

          I2C總線時序模擬(二)-加深理解總線協(xié)議

          作者: 時間:2016-11-22 來源:網(wǎng)絡(luò) 收藏
          [cpp]view plaincopy
          print?
          1. /********************************************************************
          2. 此程序是I2C操作平臺(主方式的軟件平臺)的底層的C子程序,如發(fā)送數(shù)據(jù)
          3. 及接收數(shù)據(jù),應(yīng)答位發(fā)送,并提供了幾個直接面對器件的操作函數(shù),它很方便的
          4. 與用戶程序連接并擴(kuò)展.....
          5. 注意:函數(shù)是采用軟件延時的方法產(chǎn)生SCL脈沖,固對高晶振頻率要作
          6. 一定的修改....(本例是1us機(jī)器周期,即晶振頻率要小于12MHZ)
          7. ********************************************************************/
          8. #include/*頭文件的包含*/
          9. #include
          10. #defineucharunsignedchar/*宏定義*/
          11. #defineuintunsignedint
          12. #define_Nop()_nop_()/*定義空指令*/
          13. /*常,變量定義區(qū)*/
          14. /*端口位定義*/
          15. sbitSDA=P1^3;/*模擬I2C數(shù)據(jù)傳送位*/
          16. sbitSCL=P1^2;/*模擬I2C時鐘控制位*/
          17. /*狀態(tài)標(biāo)志*/
          18. bitack;/*應(yīng)答標(biāo)志位*/
          19. /*******************************************************************
          20. 起動總線函數(shù)
          21. 函數(shù)原型:voidStart_I2c();
          22. 功能:啟動I2C總線,即發(fā)送I2C起始條件.
          23. ********************************************************************/
          24. voidStart_I2c()
          25. {
          26. SDA=1;/*發(fā)送起始條件的數(shù)據(jù)信號*/
          27. _Nop();
          28. SCL=1;
          29. _Nop();/*起始條件建立時間大于4.7us,延時*/
          30. _Nop();
          31. _Nop();
          32. _Nop();
          33. _Nop();
          34. SDA=0;/*發(fā)送起始信號*/
          35. _Nop();/*起始條件鎖定時間大于4μs*/
          36. _Nop();
          37. _Nop();
          38. _Nop();
          39. _Nop();
          40. SCL=0;/*鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)*/
          41. _Nop();
          42. _Nop();
          43. }
          44. /*******************************************************************
          45. 結(jié)束總線函數(shù)
          46. 函數(shù)原型:voidStop_I2c();
          47. 功能:結(jié)束I2C總線,即發(fā)送I2C結(jié)束條件.
          48. ********************************************************************/
          49. voidStop_I2c()
          50. {
          51. SDA=0;/*發(fā)送結(jié)束條件的數(shù)據(jù)信號*/
          52. _Nop();/*發(fā)送結(jié)束條件的時鐘信號*/
          53. SCL=1;/*結(jié)束條件建立時間大于4μs*/
          54. _Nop();
          55. _Nop();
          56. _Nop();
          57. _Nop();
          58. _Nop();
          59. SDA=1;/*發(fā)送I2C總線結(jié)束信號*/
          60. _Nop();
          61. _Nop();
          62. _Nop();
          63. _Nop();
          64. }
          65. /*******************************************************************
          66. 字節(jié)數(shù)據(jù)傳送函數(shù)
          67. 函數(shù)原型:voidSendByte(ucharc);
          68. 功能:將數(shù)據(jù)c發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待應(yīng)答,并對
          69. 此狀態(tài)位進(jìn)行操作.(不應(yīng)答或非應(yīng)答都使ack=0假)
          70. 發(fā)送數(shù)據(jù)正常,ack=1;ack=0表示被控器無應(yīng)答或損壞。
          71. ********************************************************************/
          72. voidSendByte(ucharc)
          73. {
          74. ucharBitCnt;
          75. for(BitCnt=0;BitCnt<8;BitCnt++)/*要傳送的數(shù)據(jù)長度為8位*/
          76. {
          77. if((c<
          78. ;/*判斷發(fā)送位*/
          79. elseSDA=0;
          80. _Nop();
          81. SCL=1;/*置時鐘線為高,通知被控器開始接收數(shù)據(jù)位*/
          82. _Nop();
          83. _Nop();/*保證時鐘高電平周期大于4μs*/
          84. _Nop();
          85. _Nop();
          86. _Nop();
          87. SCL=0;
          88. }
          89. _Nop();
          90. _Nop();
          91. SDA=1;/*8位發(fā)送完后釋放數(shù)據(jù)線,準(zhǔn)備接收應(yīng)答位*/
          92. _Nop();
          93. _Nop();
          94. SCL=1;
          95. _Nop();
          96. _Nop();
          97. _Nop();
          98. if(SDA==1)ack=0;
          99. elseack=1;/*判斷是否接收到應(yīng)答信號*/
          100. SCL=0;
          101. _Nop();
          102. _Nop();
          103. }
          104. /*******************************************************************
          105. 字節(jié)數(shù)據(jù)傳送函數(shù)
          106. 函數(shù)原型:ucharRcvByte();
          107. 功能:用來接收從器件傳來的數(shù)據(jù),并判斷總線錯誤(不發(fā)應(yīng)答信號),
          108. 發(fā)完后請用應(yīng)答函數(shù)。
          109. ********************************************************************/
          110. ucharRcvByte()
          111. {
          112. ucharretc;
          113. ucharBitCnt;
          114. retc=0;
          115. SDA=1;/*置數(shù)據(jù)線為輸入方式*/
          116. for(BitCnt=0;BitCnt<8;BitCnt++)
          117. {
          118. _Nop();
          119. SCL=0;/*置時鐘線為低,準(zhǔn)備接收數(shù)據(jù)位*/
          120. _Nop();
          121. _Nop();/*時鐘低電平周期大于4.7μs*/
          122. _Nop();
          123. _Nop();
          124. _Nop();
          125. SCL=1;/*置時鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效*/
          126. _Nop();
          127. _Nop();
          128. retc=retc<<1;
          129. if(SDA==1)retc=retc+1;/*讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中*/
          130. _Nop();
          131. _Nop();
          132. }
          133. SCL=0;
          134. _Nop();
          135. _Nop();
          136. return(retc);
          137. }
          138. /********************************************************************
          139. 應(yīng)答子函數(shù)
          140. 原型:voidAck_I2c(bita);
          141. 功能:主控器進(jìn)行應(yīng)答信號,(可以是應(yīng)答或非應(yīng)答信號)
          142. ********************************************************************/
          143. voidAck_I2c(bita)
          144. {
          145. if(a==0)SDA=0;/*在此發(fā)出應(yīng)答或非應(yīng)答信號*/
          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總線以便繼續(xù)接收*/
          157. _Nop();
          158. _Nop();
          159. }
          160. /*******************************************************************
          161. 向無子地址器件發(fā)送字節(jié)數(shù)據(jù)函數(shù)
          162. 函數(shù)原型:bitISendByte(ucharsla,ucahrc);
          163. 功能:從啟動總線到發(fā)送地址,數(shù)據(jù),結(jié)束總線的全過程,從器件地址sla.
          164. 如果返回1表示操作成功,否則操作有誤。
          165. 注意:使用前必須已結(jié)束總線。
          166. ********************************************************************/
          167. bitISendByte(ucharsla,ucharc)
          168. {
          169. Start_I2c();/*啟動總線*/
          170. SendByte(sla);/*發(fā)送器件地址*/
          171. if(ack==0)return(0);
          172. SendByte(c);/*發(fā)送數(shù)據(jù)*/
          173. if(ack==0)return(0);
          174. Stop_I2c();/*結(jié)束總線*/
          175. return(1);
          176. }
          177. /*******************************************************************
          178. 向有子地址器件發(fā)送多字節(jié)數(shù)據(jù)函數(shù)
          179. 函數(shù)原型:bitISendStr(ucharsla,ucharsuba,ucahr*s,ucharno);
          180. 功能:從啟動總線到發(fā)送地址,子地址,數(shù)據(jù),結(jié)束總線的全過程,從器件
          181. 地址sla,子地址suba,發(fā)送內(nèi)容是s指向的內(nèi)容,發(fā)送no個字節(jié)。
          182. 如果返回1表示操作成功,否則操作有誤。
          183. 注意:使用前必須已結(jié)束總線。
          184. ********************************************************************/
          185. bitISendStr(ucharsla,ucharsuba,uchar*s,ucharno)
          186. {
          187. uchari;
          188. Start_I2c();/*啟動總線*/
          189. SendByte(sla);/*發(fā)送器件地址*/
          190. if(ack==0)return(0);
          191. SendByte(suba);/*發(fā)送器件子地址*/
          192. if(ack==0)return(0);
          193. for(i=0;i
          194. {
          195. SendByte(*s);/*發(fā)送數(shù)據(jù)*/
          196. if(ack==0)return(0);
          197. s++;
          198. }
          199. Stop_I2c();/*結(jié)束總線*/
          200. return(1);
          201. }
          202. /*******************************************************************
          203. 向無子地址器件讀字節(jié)數(shù)據(jù)函數(shù)
          204. 函數(shù)原型:bitIRcvByte(ucharsla,ucahr*c);
          205. 功能:從啟動總線到發(fā)送地址,讀數(shù)據(jù),結(jié)束總線的全過程,從器件地
          206. 址sla,返回值在c.
          207. 如果返回1表示操作成功,否則操作有誤。
          208. 注意:使用前必須已結(jié)束總線。
          209. ********************************************************************/
          210. bitIRcvByte(ucharsla,uchar*c)
          211. {
          212. Start_I2c();/*啟動總線*/
          213. SendByte(sla+1);/*發(fā)送器件地址*/
          214. if(ack==0)return(0);
          215. *c=RcvByte();/*讀取數(shù)據(jù)*/
          216. Ack_I2c(1);/*發(fā)送非就答位*/
          217. Stop_I2c();/*結(jié)束總線*/
          218. return(1);
          219. }
          220. /*******************************************************************
          221. 向有子地址器件讀取多字節(jié)數(shù)據(jù)函數(shù)
          222. 函數(shù)原型:bitISendStr(ucharsla,ucharsuba,ucahr*s,ucharno);
          223. 功能:從啟動總線到發(fā)送地址,子地址,讀數(shù)據(jù),結(jié)束總線的全過程,從器件
          224. 地址sla,子地址suba,讀出的內(nèi)容放入s指向的存儲區(qū),讀no個字節(jié)。
          225. 如果返回1表示操作成功,否則操作有誤。
          226. 注意:使用前必須已結(jié)束總線。
          227. ********************************************************************/
          228. bitIRcvStr(ucharsla,ucharsuba,uchar*s,ucharno)
          229. {
          230. uchari;
          231. Start_I2c();/*啟動總線*/
          232. SendByte(sla);/*發(fā)送器件地址*/
          233. if(ack==0)return(0);
          234. SendByte(suba);/*發(fā)送器件子地址*/
          235. if(ack==0)return(0);
          236. Start_I2c();
          237. SendByte(sla+1);
          238. if(ack==0)return(0);
          239. for(i=0;i
          240. {
          241. *s=RcvByte();/*發(fā)送數(shù)據(jù)*/
          242. Ack_I2c(0);/*發(fā)送就答位*/
          243. s++;
          244. }
          245. *s=RcvByte();
          246. Ack_I2c(1);/*發(fā)送非應(yīng)位*/
          247. Stop_I2c();/*結(jié)束總線*/
          248. return(1);
          249. }
          250. /*完畢*/


          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();