打印
[AT32F403/403A]

AT32F403A基于V2库 io模拟iic读写AT24C04

[复制链接]
163|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
TimeRiddle|  楼主 | 2025-5-29 14:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本文使用的是AT32F403A的PB14和PB15来模拟IIC的时序,设置IO为复用开漏输出模式。

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

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


初始化代码
/** 
  * [url=home.php?mod=space&uid=247401]@brief[/url]  i2c gpio initialization.
  * @param  none.
  * @retval none.
  */
void i2c_config(void)
{
  gpio_init_type gpio_initstructure;
  
  /* i2c gpio clock enable */
  crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);
  crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);
  
  I2C_SDA_HIGH();
  
  I2C_SCL_HIGH();
  
  /* gpio configuration */  
  gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_OPEN_DRAIN;  
  gpio_initstructure.gpio_pull           = GPIO_PULL_UP;  
  gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;  
  gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;

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

  /* configure i2c pins: sda */     
  gpio_initstructure.gpio_pins = I2Cx_SDA_PIN;
  gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_initstructure);
}
驱动代码:
/** 
  * @brief  used to set the i2c clock frequency.
  * @param  none.
  * @retval none.
  */
void i2c_delay(void)
{
  delay_us(5);
}

/**
  * @brief  used to generate start conditions.
  * @param  none.
  * @retval none.
  */
void i2c_start(void)
{
  i2c_delay();
  
  I2C_SDA_HIGH();
  I2C_SCL_HIGH();
  i2c_delay();
  
  I2C_SDA_LOW();
  i2c_delay();
  
  I2C_SCL_LOW();
}

/**
  * @brief  used to generate stop conditions.
  * @param  none.
  * @retval none.
  */
void i2c_stop(void)
{
  I2C_SCL_LOW();
  I2C_SDA_LOW();  
  i2c_delay();
  
  I2C_SCL_HIGH();
  i2c_delay();
  
  I2C_SDA_HIGH();
  i2c_delay();
}

/**
  * @brief  used to generate ack conditions.
  * @param  none.
  * @retval none.
  */
void i2c_ack(void)
{
  I2C_SCL_LOW();
  I2C_SDA_LOW();
  i2c_delay();
  
  I2C_SCL_HIGH();
  i2c_delay();
  
  I2C_SCL_LOW();
}

/**
  * @brief  used to generate nack conditions.
  * @param  none.
  * @retval none.
  */
void i2c_no_ack(void)
{
  I2C_SCL_LOW();
  I2C_SDA_HIGH();
  i2c_delay();
  
  I2C_SCL_HIGH();
  i2c_delay();
  
  I2C_SCL_LOW();
}

/**
  * @brief  used to wait ack conditions.
  * @param  none.
  * @retval ack receive status.
  *         - 1: no ack received.
  *         - 0: ack received.
  */
uint8_t i2c_wait_ack(uint8_t timeout)
{
  I2C_SCL_LOW();
  I2C_SDA_HIGH();  
  
  i2c_delay();
  
  while(timeout)
  {
    if (I2C_SDA_READ() == 0)
    {
      I2C_SCL_HIGH();
      
      i2c_delay();
      
      I2C_SCL_LOW();
      
      return 0;
    }
   
    i2c_delay();
   
    timeout--;
  }  

  I2C_SCL_HIGH();
  i2c_delay();      

  I2C_SCL_LOW();
  
  i2c_delay();  
  
  return 1;
}

/**
  * @brief  send a byte.
  * @param  data: byte to be transmitted.
  * @retval none.
  */
void i2c_send_byte(uint8_t data)
{
  uint8_t i = 8;
  
  while (i--)
  {
    I2C_SCL_LOW();
   
    if (data & 0x80)
    {
      I2C_SDA_HIGH();   
    }
    else
    {
      I2C_SDA_LOW();   
    }   
   
    i2c_delay();

    data <<= 1;
   
    I2C_SCL_HIGH();
    i2c_delay();
  }
  
  I2C_SCL_LOW();
  I2C_SDA_HIGH();   
}

/**
  * @brief  receive a byte.
  * @param  data: byte to be received.
  * @retval none.
  */
uint8_t i2c_receive_byte(void)
{
  uint8_t i = 8;
  uint8_t byte = 0;

  I2C_SDA_HIGH();
  
  while (i--)
  {
    byte <<= 1;
   
    I2C_SCL_LOW();
    i2c_delay();
   
    I2C_SCL_HIGH();
    i2c_delay();
   
    if (I2C_SDA_READ())
    {
      byte |= 0x01;
    }
  }
  
  I2C_SCL_LOW();
  
  return byte;
}


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

19

帖子

0

粉丝