[DemoCode下载] 用IO模拟I2C

[复制链接]
 楼主| 598330983 发表于 2025-2-22 11:03 | 显示全部楼层 |阅读模式
  1. /**************************************************************************//**
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V1.00
  4. * [url=home.php?mod=space&uid=247401]@brief[/url]    Use GPIO to simuliate I2C waveform
  5. *
  6. * @note
  7. * Copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
  8. ******************************************************************************/
  9. #include <stdio.h>
  10. #include "NUC230_240.h"
  11. #include "NuEdu-Basic01.h"


  12. /*----------------------------------------------------------------------------*/
  13. /* Define                                                                     */
  14. /*----------------------------------------------------------------------------*/
  15. #define I2C_ADDRESS_W   0xa0
  16. #define I2C_ADDRESS_R   0xa1
  17. #define I2C_DELAY_TIME  10
  18. #define ACK             0
  19. #define NO_ACK          1
  20. #define I2C_CLK         PA11
  21. #define I2C_DAT         PA10


  22. /*----------------------------------------------------------------------------*/
  23. /* Global variable                                                            */
  24. /*----------------------------------------------------------------------------*/


  25. /*----------------------------------------------------------------------------*/
  26. /* Functions                                                                  */
  27. /*----------------------------------------------------------------------------*/


  28. void I2C_Init(void)
  29. {
  30.     /* Configure PA10 as open-drain mode */
  31.     GPIO_SetMode(PA, BIT10, GPIO_PMD_OPEN_DRAIN);

  32.     /* Configure PA11 as open-drain mode */
  33.     GPIO_SetMode(PA, BIT11, GPIO_PMD_OPEN_DRAIN);

  34.     /* Control PA11 output status */
  35.     I2C_CLK = 1;

  36.     /* Control PA10 output status */
  37.     I2C_DAT = 1;
  38. }


  39. void I2C_Start(void)
  40. {
  41.     /*  I2C START Condition */
  42.     I2C_DAT = 1;
  43.     I2C_CLK = 1;

  44.     /*  I2C delay 10us */
  45.     CLK_SysTickDelay(I2C_DELAY_TIME);
  46.     I2C_DAT = 0;
  47.     I2C_CLK = 0;
  48.     CLK_SysTickDelay(I2C_DELAY_TIME);
  49. }


  50. void I2C_Stop(void)
  51. {
  52.     /*  I2C STOP Condition */
  53.     I2C_DAT = 0;
  54.     I2C_CLK = 1;
  55.     I2C_DAT = 1;
  56. }


  57. uint8_t I2C_Write(uint8_t u8Data)
  58. {
  59.     uint8_t u8Count;

  60.     /* Write to slave */
  61.     for (u8Count = 0; u8Count < 8; u8Count++)
  62.     {
  63.         /* Send data bit */
  64.         if ((u8Data & 0x80) == 0x80)
  65.             I2C_DAT = 1;
  66.         else
  67.             I2C_DAT = 0;

  68.         /* Shift one bit */
  69.         u8Data <<= 1;

  70.         I2C_CLK = 1;

  71.         /*  I2C delay 10us */
  72.         CLK_SysTickDelay(I2C_DELAY_TIME);
  73.         I2C_CLK = 0;
  74.         CLK_SysTickDelay(I2C_DELAY_TIME);
  75.     }

  76.     I2C_DAT = 1;
  77.     I2C_CLK = 1;

  78.     /*  I2C delay 5us */
  79.     CLK_SysTickDelay(I2C_DELAY_TIME / 2);

  80.     /* Read ACK bit from slave */
  81.     u8Data = I2C_DAT;

  82.     CLK_SysTickDelay(I2C_DELAY_TIME / 2);
  83.     I2C_CLK = 0;
  84.     CLK_SysTickDelay(I2C_DELAY_TIME);
  85.     return u8Data;
  86. }


  87. uint8_t I2C_Read(uint8_t u8Ack)
  88. {
  89.     uint8_t u8Data, u8Count;

  90.     u8Data = 0x00;

  91.     /* Read from slave */
  92.     for (u8Count = 0; u8Count < 8; u8Count++)
  93.     {
  94.         /* Shift one bit */
  95.         u8Data <<= 1;

  96.         /* Read data bit */
  97.         u8Data |= I2C_DAT;

  98.         I2C_CLK = 1;
  99.         CLK_SysTickDelay(I2C_DELAY_TIME);
  100.         I2C_CLK = 0;
  101.         CLK_SysTickDelay(I2C_DELAY_TIME);
  102.     }

  103.     /* Send ACK bit to slave */
  104.     I2C_DAT = u8Ack;

  105.     I2C_CLK = 1;

  106.     /*  I2C delay 10us */
  107.     CLK_SysTickDelay(I2C_DELAY_TIME);
  108.     I2C_CLK = 0;
  109.     CLK_SysTickDelay(I2C_DELAY_TIME);

  110.     return u8Data;
  111. }


  112. void I2C_GPIO_Write_Byte(uint16_t u16Addr, uint8_t u8Data)
  113. {
  114.     uint8_t u8AddrH, u8AddrL;

  115.     u8AddrH = u16Addr >> 8;
  116.     u8AddrL = (uint8_t)u16Addr;

  117.     /* Send Start bit to I2C EEPROM */
  118.     I2C_Start();

  119.     /* Send control byte to I2C EEPROM */
  120.     printf("ack=0x%x,\n\r", I2C_Write(I2C_ADDRESS_W));

  121.     /* Send I2C EEPROM's High Byte Address */
  122.     printf("ack=0x%x,\n\r", I2C_Write(u8AddrH));

  123.     /* Send I2C EEPROM's Low Byte Address */
  124.     printf("ack=0x%x,\n\r", I2C_Write(u8AddrL));

  125.     /* Send data byte to I2C EEPROM */
  126.     printf("ack=0x%x,\n\r", I2C_Write(u8Data));

  127.     /* Send Stop bit to I2C EEPROM */
  128.     I2C_Stop();
  129. }

  130. void I2C_GPIO_Read_Byte(uint16_t u16Addr, uint8_t *pu8Data)
  131. {
  132.     uint8_t u8AddrH, u8AddrL;

  133.     u8AddrH = u16Addr >> 8;
  134.     u8AddrL = (uint8_t)u16Addr;

  135.     /* Send Start bit to I2C EEPROM */
  136.     I2C_Start();

  137.     /* Send control byte to I2C EEPROM */
  138.     printf("ack=0x%x,\n\r", I2C_Write(I2C_ADDRESS_W));

  139.     /* Send I2C EEPROM's High Byte Address */
  140.     printf("ack=0x%x,\n\r", I2C_Write(u8AddrH));

  141.     /* Send I2C EEPROM's Low Byte Address */
  142.     printf("ack=0x%x,\n\r", I2C_Write(u8AddrL));

  143.     /* Send Start bit to I2C EEPROM */
  144.     I2C_Start();

  145.     /* Send control byte to I2C EEPROM */
  146.     printf("ack=0x%x,\n\r", I2C_Write(I2C_ADDRESS_R));

  147.     /* Read data byte from EEPROM */
  148.     *pu8Data = I2C_Read(NO_ACK);

  149.     /* Send Stop bit to I2C EEPROM */
  150.     I2C_Stop();
  151. }
  152. /*----------------------------------------------------------------------------*/
  153. /*  MAIN function                                                             */
  154. /*----------------------------------------------------------------------------*/
  155. int main(void)
  156. {
  157.     uint8_t u8Data;

  158.     /* Init System */
  159.     SYS_Init();

  160.     /* Initial UART0 to 115200-8n1 for print message */
  161.     UART0_Init();

  162.     /* Init software I2C */
  163.     I2C_Init();

  164.     /* Write 0x55 into address 0x0000 */
  165.     I2C_GPIO_Write_Byte(0x0000, 0x55);

  166.     /* Delay 10ms */
  167.     CLK_SysTickDelay(10000);

  168.     /* Read 0x55 from address 0x0000 */
  169.     I2C_GPIO_Read_Byte(0x0000, &u8Data);
  170.     printf("data=0x%x,\n\r", u8Data);

  171.     while (1);
  172. }

  173. /*** (C) COPYRIGHT 2019 Nuvoton Technology Corp. ***/



 楼主| 598330983 发表于 2025-2-22 11:04 | 显示全部楼层
IO模拟I2C,要注意使用IO的开漏模式,这样,只有拉低和高阻态,高阻态的时候可以通过上拉电阻给总线拉高。这样就完美的模拟了I2C的物理特性。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

266

主题

5573

帖子

22

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