提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
GP8413是一个I2C信号转模拟信号转换器,即DAC,此芯片可以将15Bit数字量0x0000-0x7FFF线性转换成两路独立的0-5V/0-10V模拟电压,输出电压误差为0.2%,线性度可达0.01%。
提示:以下是本篇文章正文内容,下面案例可供参考
一、GP8413特性
GP8413 通过I2C接口,线性转换成0-5V/0-10V的两路模拟电压输出。
一个I2C接口支持8路GP8413并联,通过三位硬件地址A2/A1/A0选择。
VOUT=5V* DATA/0x7FFF或VOUT=10V*DATA/0x7FFF
输入信号范围15Bit,0x0000-0x7FFF
输入I2C信号高电平:2.7V-5.5V
输出电压误差:< 0.2%
输出电压线性度误差:0.01%
输出短路保护,输出脚与地短路时芯片进入保护模式停止输出。
电源电压:9V–36V
功耗:<5mA
启动时间:<2ms
工作温度:-40°C to 85°C
二、管脚定义
其中A0,A1,A2为三位硬件地址,可以实现 8 片 GP8413 芯片的并接使用
典型电路如下所示,V5V为内部LDO,5V输出,必须外接大于1uF电容。VOUT作为板级接口使用时,加12V单向TVS,反接、浪涌保护。
三、代码编写
设置下图中红色配置位,地址设置为 02,则对 VOUT0 进行操作。将 15bit DATA 数据分为 DATA0 Low 和 DATA0 High 写 DATA0 Low为低 Byte, DATA0 High 为高 Byte。例如 0-10V 模式, 输出相对应的电压为:VOUT=DATA0/0x7FFF10V。
设置下图中红色配置位, 地址设置为 04,则对 VOUT1 进行操作。 将 15bit DATA 数据分为 DATA Low 和 DATA High 写入, DATA Low为低 Byte, DATA High 为高 Byte。例如 0-10V 模式, 输出相对应的电压为:VOUT=DATA/0x7FFF10V
1、头文件
代码如下(仅作参考):
//
// Created by LingFei Zhu on 2023/11/2.
//
#ifndef __GP8413_H
#define __GP8413_H
#ifdef __cplusplus
extern "C" {
#endif
#include "main.h"
#include "i2c_core.h"
#define CHANEL_COUNT 2 //DAC通道数目
#define SLAVE_ADDRESS 0X58 //DAC地址
#define RESOLUTION_15_BIT //12bit or 15bit数据,根据芯片来
#define GP8XXX_CONFIG_REG 0x2 //寄存器地址
#define in_min 0 //最小输出电压,一般为0
#define in_max 5 //最大输出电压,与需求相关
#define out_min 0 //i2c输出最小值0
#ifdef RESOLUTION_12_BIT
#define out_max 0x0FFF //15bit输出最大值
#endif
#ifdef RESOLUTION_15_BIT
#define out_max 0x7FFF //15bit输出最大值
#endif
typedef enum{
chanel_0 = 2,
chanel_1 = 4
}DAC_CHANEL_INDEX_T;
typedef enum{
eOutputRange5V = 1,
eOutputRange10V = 2
}eOutPutRange_t;
typedef union{
uint16_t voltage_value;
uint8_t voltage_array[2];
}voltage_mapped;
typedef struct DAC_CHANEL_T
{
DAC_CHANEL_INDEX_T CHANEL; //记录是芯片的通道0 or 通道1
uint8_t addr; //DAC芯片的三位硬件地址
uint16_t cur_voltage; //记录当前输出电压值
}DAC_CHANEL;
uint8_t GP8413_init(i2c_dev *i2c_bus);
void setDACAddrArray(uint8_t index, uint8_t addr, DAC_CHANEL_INDEX_T chanel);
void setDACOutRange(uint8_t index, eOutPutRange_t range);
void setDACOutVoltage(uint8_t index,float voltage);
uint16_t readDACOutVoltage(uint8_t index);
uint8_t I2C_WriteRegister(uint8_t slave_addr, uint8_t reg_addr, uint8_t len, uint8_t *data_ptr);
#ifdef __cplusplus
}
#endif
#endif// __GP8413_H
2、c文件
代码如下(仅作参考):
//
// Created by LingFei Zhu on 2023/11/2.
//
#include "gp8413.h"
#include "i2c_hw.h"
#include "i2c_core.h"
struct DAC_CHANEL_T DAC_ID[CHANEL_COUNT]; //用于存放对应ID的索引和通道信息
i2c_dev *GP8413_dev = NULL; //GP8413的i2c设备结构体指针
/** @brief 初始化
* */
uint8_t GP8413_init(i2c_dev *i2c_bus)
{
if (NULL == i2c_bus)
{
return -1;
}
GP8413_dev = i2c_bus;
return 0;
}
/** @brief 将电压数据映射到15bit数据上
* @param input 输入电压值
* @return 映射后的数据
* */
uint16_t data_map(float input)
{
return (uint16_t)((input - in_min) * (out_max - out_min) / (in_max - in_min) + out_min);
}
/** @brief 初始化索引数组
* @param addr DAC的3bit物理地址
* @param chanel DAC芯片的高低通道
* @param index 总的通道索引值
* */
void setDACAddrArray(uint8_t index, uint8_t addr, DAC_CHANEL_INDEX_T chanel)
{
DAC_ID[index].addr = SLAVE_ADDRESS | addr;
DAC_ID[index].CHANEL = chanel;
DAC_ID[index].cur_voltage = 0;
}
/** @brief 设定最大输出电压5V/10V
* @param index 总的通道索引值
* @param range 输出电压挡位设定
* */
void setDACOutRange(uint8_t index, eOutPutRange_t range)
{
uint8_t data = (range == eOutputRange10V) ? 0x11 : 0x00; //5V模式发送0x00,10V模式发送0x11
uint8_t slave_addr = DAC_ID[index].addr; //从数组中获取地址
uint8_t reg_addr = GP8XXX_CONFIG_REG >> 1;
I2C_WriteRegister(slave_addr, reg_addr, 1, &data);
}
/** @brief 设定输出电压
* @param index 总的通道索引值
* @param voltage 输出电压值
* */
void setDACOutVoltage(uint8_t index,float voltage)
{
uint8_t slave_addr = DAC_ID[index].addr; //从数组中获取地址
uint8_t reg_addr = (DAC_ID[index].CHANEL == chanel_0) ? GP8XXX_CONFIG_REG : GP8XXX_CONFIG_REG <<1;
voltage_mapped t;
t.voltage_value= data_map(voltage);
DAC_ID[index].cur_voltage = t.voltage_value;
I2C_WriteRegister(slave_addr, reg_addr, 2, t.voltage_array);
}
/** @brief 读取当前输出电压
* @param index 总的通道索引值
* @return 当前输出电压值
* */
uint16_t readDACOutVoltage(uint8_t index)
{
return DAC_ID[index].cur_voltage;
}
/** @brief i2c发送函数
* @param slave_addr 器件地址
* @param reg_addr 寄存器地址
* @param len长度
* @param 数据地址
* */
uint8_t I2C_WriteRegister(uint8_t slave_addr, uint8_t reg_addr, uint8_t len, uint8_t *data_ptr)
{
i2c_message DAC_Msg[2];
uint8_t buf[2] = {0};
buf[0] = reg_addr & 0xff;
DAC_Msg[0].size = 1;
DAC_Msg[0].addr = slave_addr;
DAC_Msg[0].flags = I2C_BUS_WR;
DAC_Msg[0].buff = buf;
DAC_Msg[0].retries = 1;
DAC_Msg[1].addr = slave_addr;
DAC_Msg[1].flags = I2C_BUS_WR | I2C_BUS_NO_START;
DAC_Msg[1].buff = (uint8_t*)data_ptr;
DAC_Msg[1].size = len;
i2c_bus_xfer(GP8413_dev, DAC_Msg, 2);
return len;
}
总结
GP8413的驱动还是比较简单的,I2C_WriteRegister为iic的发送函数,读者自行实现即可。