问答

汇集网友智慧,解决技术难题

21ic问答首页 -

IO IO模拟 ic iic 模拟

2025-08-23
本文使用的是AT32F403A的PB14和PB15来模拟IIC的时序,设置IO为复用开漏输出模式。

         由于AT24C02的三个地址硬件上都是拉到地,所以地址为0xA0。

         驱动软件部分就是通过对IO的拉高拉低,以及读取值等操作,实现iic的时序,包括开始时序,停止时序,ack、no ack、等待ack,发送时序,接收时序等,想要了解的可去看源码,同时此驱动代码是从雅特力官网获取的然后修改io部分。


初始化代码
  1. /**
  2.   * [url=home.php?mod=space&uid=247401]@brief[/url]  i2c gpio initialization.
  3.   * @param  none.
  4.   * @retval none.
  5.   */
  6. void i2c_config(void)
  7. {
  8.   gpio_init_type gpio_initstructure;
  9.   
  10.   /* i2c gpio clock enable */
  11.   crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);
  12.   crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);
  13.   
  14.   I2C_SDA_HIGH();
  15.   
  16.   I2C_SCL_HIGH();
  17.   
  18.   /* gpio configuration */  
  19.   gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_OPEN_DRAIN;  
  20.   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;  
  21.   gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;  
  22.   gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;

  23.   /* configure i2c pins: scl */   
  24.   gpio_initstructure.gpio_pins = I2Cx_SCL_PIN;
  25.   gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_initstructure);

  26.   /* configure i2c pins: sda */     
  27.   gpio_initstructure.gpio_pins = I2Cx_SDA_PIN;
  28.   gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_initstructure);
  29. }
驱动代码:
  1. /**
  2.   * @brief  used to set the i2c clock frequency.
  3.   * @param  none.
  4.   * @retval none.
  5.   */
  6. void i2c_delay(void)
  7. {
  8.   delay_us(5);
  9. }

  10. /**
  11.   * @brief  used to generate start conditions.
  12.   * @param  none.
  13.   * @retval none.
  14.   */
  15. void i2c_start(void)
  16. {
  17.   i2c_delay();
  18.   
  19.   I2C_SDA_HIGH();
  20.   I2C_SCL_HIGH();
  21.   i2c_delay();
  22.   
  23.   I2C_SDA_LOW();
  24.   i2c_delay();
  25.   
  26.   I2C_SCL_LOW();
  27. }

  28. /**
  29.   * @brief  used to generate stop conditions.
  30.   * @param  none.
  31.   * @retval none.
  32.   */
  33. void i2c_stop(void)
  34. {
  35.   I2C_SCL_LOW();
  36.   I2C_SDA_LOW();  
  37.   i2c_delay();
  38.   
  39.   I2C_SCL_HIGH();
  40.   i2c_delay();
  41.   
  42.   I2C_SDA_HIGH();
  43.   i2c_delay();
  44. }

  45. /**
  46.   * @brief  used to generate ack conditions.
  47.   * @param  none.
  48.   * @retval none.
  49.   */
  50. void i2c_ack(void)
  51. {
  52.   I2C_SCL_LOW();
  53.   I2C_SDA_LOW();
  54.   i2c_delay();
  55.   
  56.   I2C_SCL_HIGH();
  57.   i2c_delay();
  58.   
  59.   I2C_SCL_LOW();
  60. }

  61. /**
  62.   * @brief  used to generate nack conditions.
  63.   * @param  none.
  64.   * @retval none.
  65.   */
  66. void i2c_no_ack(void)
  67. {
  68.   I2C_SCL_LOW();
  69.   I2C_SDA_HIGH();
  70.   i2c_delay();
  71.   
  72.   I2C_SCL_HIGH();
  73.   i2c_delay();
  74.   
  75.   I2C_SCL_LOW();
  76. }

  77. /**
  78.   * @brief  used to wait ack conditions.
  79.   * @param  none.
  80.   * @retval ack receive status.
  81.   *         - 1: no ack received.
  82.   *         - 0: ack received.
  83.   */
  84. uint8_t i2c_wait_ack(uint8_t timeout)
  85. {
  86.   I2C_SCL_LOW();
  87.   I2C_SDA_HIGH();  
  88.   
  89.   i2c_delay();
  90.   
  91.   while(timeout)
  92.   {
  93.     if (I2C_SDA_READ() == 0)
  94.     {
  95.       I2C_SCL_HIGH();
  96.       
  97.       i2c_delay();
  98.       
  99.       I2C_SCL_LOW();
  100.       
  101.       return 0;
  102.     }
  103.    
  104.     i2c_delay();
  105.    
  106.     timeout--;
  107.   }  

  108.   I2C_SCL_HIGH();
  109.   i2c_delay();      

  110.   I2C_SCL_LOW();
  111.   
  112.   i2c_delay();  
  113.   
  114.   return 1;
  115. }

  116. /**
  117.   * @brief  send a byte.
  118.   * @param  data: byte to be transmitted.
  119.   * @retval none.
  120.   */
  121. void i2c_send_byte(uint8_t data)
  122. {
  123.   uint8_t i = 8;
  124.   
  125.   while (i--)
  126.   {
  127.     I2C_SCL_LOW();
  128.    
  129.     if (data & 0x80)
  130.     {
  131.       I2C_SDA_HIGH();   
  132.     }
  133.     else
  134.     {
  135.       I2C_SDA_LOW();   
  136.     }   
  137.    
  138.     i2c_delay();

  139.     data <<= 1;
  140.    
  141.     I2C_SCL_HIGH();
  142.     i2c_delay();
  143.   }
  144.   
  145.   I2C_SCL_LOW();
  146.   I2C_SDA_HIGH();   
  147. }

  148. /**
  149.   * @brief  receive a byte.
  150.   * @param  data: byte to be received.
  151.   * @retval none.
  152.   */
  153. uint8_t i2c_receive_byte(void)
  154. {
  155.   uint8_t i = 8;
  156.   uint8_t byte = 0;

  157.   I2C_SDA_HIGH();
  158.   
  159.   while (i--)
  160.   {
  161.     byte <<= 1;
  162.    
  163.     I2C_SCL_LOW();
  164.     i2c_delay();
  165.    
  166.     I2C_SCL_HIGH();
  167.     i2c_delay();
  168.    
  169.     if (I2C_SDA_READ())
  170.     {
  171.       byte |= 0x01;
  172.     }
  173.   }
  174.   
  175.   I2C_SCL_LOW();
  176.   
  177.   return byte;
  178. }


回答 +关注
人浏览 人回答问题 分享 举报
个回答

您需要登录后才可以回复 登录 | 注册