新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > I2C總線時序模擬(二)-加深理解總線協議

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

        作者: 時間:2016-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表示操作成功,否則操作有誤。
        165. 注意:使用前必須已結束總線。
        166. ********************************************************************/
        167. bitISendByte(ucharsla,ucharc)
        168. {
        169. Start_I2c();/*啟動總線*/
        170. SendByte(sla);/*發送器件地址*/
        171. if(ack==0)return(0);
        172. SendByte(c);/*發送數據*/
        173. if(ack==0)return(0);
        174. Stop_I2c();/*結束總線*/
        175. return(1);
        176. }
        177. /*******************************************************************
        178. 向有子地址器件發送多字節數據函數
        179. 函數原型:bitISendStr(ucharsla,ucharsuba,ucahr*s,ucharno);
        180. 功能:從啟動總線到發送地址,子地址,數據,結束總線的全過程,從器件
        181. 地址sla,子地址suba,發送內容是s指向的內容,發送no個字節。
        182. 如果返回1表示操作成功,否則操作有誤。
        183. 注意:使用前必須已結束總線。
        184. ********************************************************************/
        185. bitISendStr(ucharsla,ucharsuba,uchar*s,ucharno)
        186. {
        187. uchari;
        188. Start_I2c();/*啟動總線*/
        189. SendByte(sla);/*發送器件地址*/
        190. if(ack==0)return(0);
        191. SendByte(suba);/*發送器件子地址*/
        192. if(ack==0)return(0);
        193. for(i=0;i
        194. {
        195. SendByte(*s);/*發送數據*/
        196. if(ack==0)return(0);
        197. s++;
        198. }
        199. Stop_I2c();/*結束總線*/
        200. return(1);
        201. }
        202. /*******************************************************************
        203. 向無子地址器件讀字節數據函數
        204. 函數原型:bitIRcvByte(ucharsla,ucahr*c);
        205. 功能:從啟動總線到發送地址,讀數據,結束總線的全過程,從器件地
        206. 址sla,返回值在c.
        207. 如果返回1表示操作成功,否則操作有誤。
        208. 注意:使用前必須已結束總線。
        209. ********************************************************************/
        210. bitIRcvByte(ucharsla,uchar*c)
        211. {
        212. Start_I2c();/*啟動總線*/
        213. SendByte(sla+1);/*發送器件地址*/
        214. if(ack==0)return(0);
        215. *c=RcvByte();/*讀取數據*/
        216. Ack_I2c(1);/*發送非就答位*/
        217. Stop_I2c();/*結束總線*/
        218. return(1);
        219. }
        220. /*******************************************************************
        221. 向有子地址器件讀取多字節數據函數
        222. 函數原型:bitISendStr(ucharsla,ucharsuba,ucahr*s,ucharno);
        223. 功能:從啟動總線到發送地址,子地址,讀數據,結束總線的全過程,從器件
        224. 地址sla,子地址suba,讀出的內容放入s指向的存儲區,讀no個字節。
        225. 如果返回1表示操作成功,否則操作有誤。
        226. 注意:使用前必須已結束總線。
        227. ********************************************************************/
        228. bitIRcvStr(ucharsla,ucharsuba,uchar*s,ucharno)
        229. {
        230. uchari;
        231. Start_I2c();/*啟動總線*/
        232. SendByte(sla);/*發送器件地址*/
        233. if(ack==0)return(0);
        234. SendByte(suba);/*發送器件子地址*/
        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();/*發送數據*/
        242. Ack_I2c(0);/*發送就答位*/
        243. s++;
        244. }
        245. *s=RcvByte();
        246. Ack_I2c(1);/*發送非應位*/
        247. Stop_I2c();/*結束總線*/
        248. return(1);
        249. }
        250. /*完畢*/


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 长海县| 桐柏县| 临夏县| 澎湖县| 年辖:市辖区| 乐东| 繁峙县| 汪清县| 汤阴县| 富民县| 万州区| 古蔺县| 祁阳县| 巩留县| 华池县| 商洛市| 金川县| 上杭县| 襄城县| 长治县| 青龙| 壤塘县| 南通市| 陇南市| 吉水县| 喀喇| 鹤壁市| 鲁甸县| 南昌市| 白玉县| 牙克石市| 防城港市| 调兵山市| 临沂市| 皋兰县| 右玉县| 漳州市| 抚州市| 光山县| 惠安县| 晋江市|