GD32F30x_AD5245数字电位计驱动程序

一、工具

  1、硬件:GD32F30x系列单片机

  2、编译环境:KEIL

  3、AD5245芯片:AD5245BRJ10

二、芯片简介

   AD5245是一款256位调整可实现与机械电位计或可变电阻相同功能的电子器件。采用2.7V至5.5V电源供电,功耗小于8μA,适合电池供电的便携式应用。游标设置可通过I2C兼容型数字接口控制,也可以利用该接口读回游标寄存器的内容。AD0可以将最多两个器件置于同一总线上。命令位将游标位置复位到中间值或关断器件,使之进入零功耗状态。

   A端和B端间RDAC的标称电阻可以为5KΩ、10KΩ、50KΩ和100KΩ。可变电阻的标称电阻(RAB)有256个触点,通过游标端和B端触点访问。RDAC锁存器中的8位数据经过解码,用于选择256种可能的设置之一。

  其它具体介绍请看相关手册,这里不再赘述。

三、芯片I2C通讯协议

  下图包含了设备地址以及读写时序。

 四、硬件电路

五、代码实现

  1、设置电位计值函数

/**
  * @brief 数字电位计值设置
  * @param addr 数字电位计设备地址
  * @param value 数字电位计设置的值
  * @retval none
  * @author Mr.W
  * @date 2020-10-25
  */
void ad5245_value_set(uint8_t addr, uint8_t value)
{
    uint8_t data[2] = {0};
    
    data[0] = 0;
    data[1] = (value&0xFF);
    
    i2c_write(addr, &data[0], 2);
}

   2、I2C初始化

/**
  *****************************************************************************
  * @Name   : I2C1_GPIO_Configuration
  * @Brief  : I2C1引脚初始化
  *****************************************************************************
**/
void I2C1_GPIO_Configuration(void)
{
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_AF);
    
    gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10 | GPIO_PIN_11);   
}

/**
  *****************************************************************************
  * @Name   : I2C1_Configuration
  * @Brief  : I2C1配置
  * @Input  : 
  * @Output : 
  * @Return : 
  *****************************************************************************
**/
void I2C1_Configuration(void)
{
    I2C1_GPIO_Configuration();
    rcu_periph_clock_enable(RCU_I2C1);
    
    i2c_clock_config(I2C1, 250000, I2C_DTCY_2);/*设置I2C频率*/
    i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0);/*设置I2C 地址长度*/

    i2c_enable(I2C1);
    i2c_ack_config(I2C1, I2C_ACK_ENABLE);/*开启应答*/
    
}

  3、I2C写

/**
  * @brief I2C1写函数
  * @param addr设备地址
  * @param pdata 数据指针
  * @param data_length 数据长度
  * @retval none
  * @author Mr.W
  * @date 2020-11-11
  */
void i2c_write(uint8_t addr, uint8_t *pdata, uint32_t data_length)
{
    uint32_t i;
    
    /* wait until I2C bus is idle */
    while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));
    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C1);
    /* wait until SBSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));    
    /* send slave address to I2C bus */
    i2c_master_addressing(I2C1, addr, I2C_TRANSMITTER);
    /* wait until ADDSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
    /* clear ADDSEND bit */
    i2c_flag_clear(I2C1, I2C_FLAG_ADDSEND);
    /* wait until the transmit data buffer is empty */
    while(!i2c_flag_get(I2C1, I2C_FLAG_TBE));
    for(i = 0; i < data_length; i++){
        /* data transmission */
        i2c_data_transmit(I2C1, pdata[i]);
        /* wait until the TBE bit is set */
        while(!i2c_flag_get(I2C1, I2C_FLAG_TBE));
    }
    /* send a stop condition to I2C bus */
    i2c_stop_on_bus(I2C1);
    /* wait until stop condition generate */ 
    while(I2C_CTL0(I2C1)&0x0200);    
}

  4、I2C读

/**
  * @brief I2C1读函数
  * @param addr设备地址
  * @param pdata 数据指针
  * @param data_length 数据长度
  * @retval none
  * @author Mr.W
  * @date 2020-11-11
  */
void i2c_read(uint8_t addr, uint8_t *pdata, uint32_t data_length)
{
    uint32_t i;
    
    /* send a NACK for the next data byte which will be received into the shift register */
    i2c_ackpos_config(I2C1, I2C_ACKPOS_NEXT);
    /* wait until I2C bus is idle */
    while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));
    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C1);
    /* wait until SBSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
    /* send slave address to I2C bus */
    i2c_master_addressing(I2C1, addr, I2C_RECEIVER);
    /* disable ACK before clearing ADDSEND bit */
    i2c_ack_config(I2C1, I2C_ACK_DISABLE);
    /* wait until ADDSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
    /* clear ADDSEND bit */
    i2c_flag_clear(I2C1, I2C_FLAG_ADDSEND);
    /* Wait until the last data byte is received into the shift register */
    while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));
    for(i = 0; i < data_length; i++)
    {
        /* wait until the RBNE bit is set */
        while(!i2c_flag_get(I2C1, I2C_FLAG_RBNE));
        /* read a data from I2C_DATA */
        pdata[i] = i2c_data_receive(I2C1);
    }
    /* send a stop condition */
    i2c_stop_on_bus(I2C1);
    /* wait until stop condition generate */ 
    while(I2C_CTL0(I2C1)&0x0200);
    i2c_ackpos_config(I2C1, I2C_ACKPOS_CURRENT);
    /* enable acknowledge */
    i2c_ack_config(I2C1, I2C_ACK_ENABLE);
}

#endif

原文地址:https://www.cnblogs.com/wenhao-Web/p/14011985.html