[PIC®/AVR®/dsPIC®产品] I2C的IO的标准模拟时序

[复制链接]
1258|3
 楼主| mintspring 发表于 2023-11-16 09:21 | 显示全部楼层 |阅读模式
i2c.h
  1. #ifndef __FILE_I2CBASIC_H
  2. #define __FILE_I2CBASIC_H

  3. // Send the I2C start command to the target device
  4. void I2CSendStart( void );
  5. // Send the I2C stop command to the target device
  6. void I2CSendStop( void );
  7. // Send a clock pulse and check SDA for an ACK
  8. // Target will send an ACK as a 1
  9. // If SDA is 0 there is no ACK what means NACK
  10. unsigned char I2CCheckACK( void );
  11. // Send a NACK
  12. void I2CSendNACK( void );
  13. // Send a ACK
  14. void I2CSendACK( void );
  15. // Send a byte to the target
  16. void I2CSendByte(unsigned char SendByte);
  17. // Receive a byte from the target
  18. unsigned char I2CGetByte( void );
  19. // ClkSyncByte, do the garbage collection if bus fault
  20. void I2CClkSyncByte(void);

  21. #endif


 楼主| mintspring 发表于 2023-11-16 09:22 | 显示全部楼层
  1. /********************************************************************/
  2. /* Function    : I2C Basic Funktions                           FILE */
  3. /*------------------------------------------------------------------*/
  4. /* Description : This File has the basic functions needed for       */
  5. /*               I2C comunication and is optimized to meet the      */
  6. /*               requirements of 100KHz I2C running on normal       */
  7. /*               8051 Core [url=home.php?mod=space&uid=72445]@[/url] 24MHz                                  */
  8. /*------------------------------------------------------------------*/
  9. /* Author      : Michael Schmitt                                    */
  10. /*------------------------------------------------------------------*/
  11. /* Input       : none                                               */
  12. /*------------------------------------------------------------------*/
  13. /* Returnvalue : none                                               */
  14. /*------------------------------------------------------------------*/
  15. /* History     : 00/03    V1.0 Initial Version                      */
  16. /*                                                                  */
  17. /********************************************************************/
  18. #ifndef __FILE_I2CBASIC_C
  19. #define __FILE_I2CBASIC_C

  20. //#define I2C_DEBUG_MODE

  21. void I2CDelay( void )
  22. {
  23.     NOP;
  24.     NOP;
  25.     NOP;
  26.     NOP;
  27.     NOP;
  28.     NOP;
  29. }

  30. // Send the I2C start command to the target device
  31. // "safety start" for 100kHz devices (24MHz)
  32. void I2CSendStart( void )
  33. {
  34. #ifdef I2C_DEBUG_MODE
  35.     printf("\n\r<Start>");
  36. #endif
  37.     // Start Condition SDA 1->0 while SCL is 1
  38.     I2CDelay();
  39.     I2CSDA = 1;
  40.     I2CDelay();
  41.     I2CSCL = 1;
  42.     I2CDelay();
  43.     I2CSDA = 0;
  44.     I2CDelay();
  45.     I2CSCL = 0;
  46.     I2CDelay();
  47. }


  48. // Send the I2C stop command to the target device
  49. // "safety stop" for 100kHz devices (24MHz)
  50. void I2CSendStop( void )
  51. {
  52. #ifdef I2C_DEBUG_MODE
  53. printf("<Stopp>");
  54. #endif
  55.     // Stop Condition SDA 0->1 while SCL is 1
  56.     I2CDelay();
  57.     I2CSDA = 0;
  58.     I2CDelay();
  59.     I2CSCL = 1;
  60.     I2CDelay();
  61.     I2CSDA = 1;
  62.     I2CDelay();
  63. }


  64. // Send a clock pulse and check SDA for an ACK
  65. // Target will send an ACK as a 1
  66. // If SDA is 0 there is no ACK what means NACK
  67. unsigned char I2CCheckACK( void )
  68. {
  69.     unsigned char return_value;
  70.     I2CSDA = 1;
  71.         NOP;
  72.         NOP;
  73.         NOP;
  74.         NOP;
  75. //    I2CDelay();
  76.     I2CSCL = 1;
  77. //      NOP;
  78. //      NOP;
  79. //      NOP;
  80. //      NOP;
  81. //      NOP;
  82.         NOP;
  83.         NOP;
  84.         NOP;
  85.         NOP;
  86.         NOP;
  87. //    I2CDelay();
  88.     return_value = !I2CSDA;   // invert
  89. #ifdef I2C_DEBUG_MODE
  90.     if( return_value == 1 )
  91.     {
  92.         printf("<?ACK>");
  93.     }
  94.     else
  95.     {
  96.         printf("<?NACK>");
  97.     }
  98. #endif
  99.     I2CSCL = 0;
  100.     return( return_value ); // 1=ACK 0=NACK
  101. }

  102. // Send a NACK
  103. void I2CSendNACK( void )
  104. {
  105. #ifdef I2C_DEBUG_MODE
  106. printf("<!NACK>");
  107. #endif
  108.     // NACK by Master sending a single 1
  109.     I2CSDA = 1;
  110.         NOP;
  111.         NOP;
  112.         NOP;
  113.         NOP;
  114.         NOP;
  115.         NOP;
  116.         NOP;
  117.         NOP;
  118.         NOP;
  119.         NOP;
  120. //    I2CDelay();
  121.     I2CSCL = 1;
  122.         NOP;
  123.         NOP;
  124.         NOP;
  125.         NOP;
  126.         NOP;
  127.         NOP;
  128.         NOP;
  129.         NOP;
  130.         NOP;
  131.         NOP;
  132. //    I2CDelay();
  133.     I2CSCL = 0;
  134.         NOP;
  135.         NOP;
  136.         NOP;
  137.         NOP;
  138.         NOP;
  139.         NOP;
  140.         NOP;
  141.         NOP;
  142.         NOP;
  143.         NOP;
  144. //    I2CDelay();
  145.     I2CSDA = 0;
  146. }

  147. // Send a ACK
  148. void I2CSendACK( void )
  149. {
  150. #ifdef I2C_DEBUG_MODE
  151.     printf("<!ACK>");
  152. #endif
  153.     // ACK by Master sending a single 0
  154.         I2CSDA = 0;
  155.         NOP;
  156.         NOP;
  157.         NOP;
  158.         NOP;
  159.         NOP;
  160.         NOP;
  161.         NOP;
  162.         NOP;
  163.         NOP;
  164.         NOP;
  165. //    I2CDelay();
  166.     I2CSCL = 1;
  167.         NOP;
  168.         NOP;
  169.         NOP;
  170.         NOP;
  171.         NOP;
  172.         NOP;
  173.         NOP;
  174.         NOP;
  175.         NOP;
  176.         NOP;
  177. //    I2CDelay();
  178.     I2CSCL = 0; // Cmd executin lasts 1usec so clk 100KHz
  179. //      NOP;
  180. //      NOP;
  181. //      NOP;
  182. //      NOP;
  183. //      NOP;
  184. //      NOP;
  185. //      NOP;
  186. //      NOP;
  187. //      NOP;
  188. //      NOP;
  189. //    I2CDelay();
  190. //  I2CSDA = 0;
  191. }

  192. // Send a byte to the target
  193. void I2CSendByte(unsigned char SendByte)
  194. {
  195.     register unsigned char i;
  196. #ifdef I2C_DEBUG_MODE
  197. printf("<S:%02X>",(unsigned int)SendByte);
  198. #endif
  199.     for (i=0; i<8; i++)
  200.     {
  201. //      I2CDelay();
  202.         if ( SendByte & 0x80)
  203.         {
  204.             I2CSDA = 1;        // MSB first -> LSB last
  205.         }
  206.         else
  207.         {
  208.             I2CSDA = 0;
  209.         }
  210. //      NOP;
  211. //      NOP;
  212. //      NOP;
  213. //      NOP;
  214.         I2CSCL = 1;
  215.         /* doing the shift during clocking, otherwise the pulse width would be to short */
  216.         NOP;
  217.         NOP;
  218.         NOP;
  219.         NOP;
  220.         NOP;
  221.         NOP;
  222.         NOP;
  223.         SendByte = SendByte << 1;
  224. //      I2CDelay();
  225.         I2CSCL = 0;
  226. //      I2CDelay();
  227.     }
  228. }

  229. // Receive a byte from the target
  230. unsigned char I2CGetByte( void )
  231. {
  232.     register unsigned char i, res;

  233.     I2CSDA = 1; /* release SDA-Line */
  234. //      NOP;
  235. //      NOP;
  236. //      NOP;
  237. //      NOP;
  238. //  I2CDelay();
  239.     res = 0;
  240.     for (i=0;i<8;i++)     // each bit at a time, MSB first
  241.     {
  242.         NOP;
  243.         NOP;
  244.         NOP;
  245.         NOP;
  246.         NOP;
  247.         I2CSCL = 1;
  248.         res = res << 1;
  249. //      I2CDelay();
  250. //      NOP;
  251. //      NOP;
  252. //      NOP;
  253. //      NOP;
  254. //      NOP;
  255.         if (I2CSDA) res++;
  256. //      I2CDelay();
  257. //      NOP;
  258. //      NOP;
  259. //      NOP;
  260. //      NOP;
  261. //      NOP;
  262.         I2CSCL = 0;
  263. //      I2CDelay();
  264.         NOP;
  265.         NOP;
  266.         NOP;
  267.         NOP;
  268.         NOP;
  269.     }
  270. #ifdef I2C_DEBUG_MODE
  271. printf("<G:%02X>",(unsigned int)res);
  272. #endif
  273.     return(res);
  274. }

  275. // ClkSyncByte fclk=100kHz
  276. void I2CClkSyncByte(void)
  277. {
  278.     register unsigned char i;
  279. #ifdef I2C_DEBUG_MODE
  280. printf("<SYNC>");
  281. #endif
  282.     for (i=0; i<8; i++)
  283.     {
  284.         NOP;
  285.         NOP;
  286.         NOP;
  287.         NOP;
  288.         NOP;
  289. //      I2CDelay();
  290.         I2CSCL = 1;
  291.         NOP;
  292.         NOP;
  293.         NOP;
  294.         NOP;
  295.         NOP;
  296.         NOP;
  297.         NOP;
  298.         NOP;
  299.         NOP;
  300.         NOP;
  301. //      I2CDelay();
  302.         I2CSCL = 0;
  303.         NOP;
  304.         NOP;
  305.         NOP;
  306.         NOP;
  307.         NOP;
  308. //      I2CDelay();
  309.     }
  310. }

  311. #endif
 楼主| mintspring 发表于 2023-11-16 09:23 | 显示全部楼层
在这个基础上根据自己情况替换成相应的操作即可。
Jacquetry 发表于 2023-11-20 10:36 来自手机 | 显示全部楼层
模拟方式就是适合移植啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

303

主题

4972

帖子

24

粉丝
快速回复 在线客服 返回列表 返回顶部