AD5676R是低功耗、8通道、16位缓冲电压输出数模转换器(DAC)。
它包括一个2.5 V、2 ppm/°C内部基准电压源(默认使能)和一个增益选择引脚,提供2.5 V(增益= 1)或5 V(增益= 2)的满量程输出。
功能框图
引脚
SYNC低电平有效控制输入。这是输入数据的帧同步信号。当同步开始时低,数据在接下来 24 个时钟的下降沿传输
SCLK串行时钟输入。数据在串行时钟输入的下降沿被记录到输入移位寄存器中。数据传输速率高达 50 MHz。
SDI串行数据输入。该器件有一个 24 位输入移位寄存器。数据被记录到寄存器上串行时钟输入的下降沿。
GAIN跨度设置销。当该引脚连接至 GND 时,所有八个 DAC 输出的跨度为 0 V 至 VREF。如果该引脚是与 VLOGIC 相连,所有八个 DAC 均输出范围为 0 V 至 2 × VREF。
RSTSEL上电复位引脚。将此引脚连接至 GND,将所有八个 DAC 通电至零电平。将此引脚连接至 VLOGIC将所有八个 DAC 通电至中档
LDAC加载 DAC。 LDAC 以异步和同步两种模式运行。将该引脚脉冲拉低允许任何或全部的DAC寄存器被更新,如果输入寄存器有新数据,这允许同时地更新所有 DAC 输出。该引脚也可以永久拉低
SDO串行数据输出。该引脚可用于将多个设备以菊花链方式连接在一起,也可用于回过头再读。串行数据在SCLK上升沿传输,下降沿有效
RESET异步复位输入。 RESET 输入对下降沿敏感。当RESET为低电平时,所有LDAC脉冲都是被忽略。当 RESET 被激活时,输入寄存器和 DAC 寄存器将更新为零刻度或中刻度,取决于 RSTSEL 引脚的状态。
时序
框架
AD5676R 实现分段串 DAC具有内部输出缓冲器的架构
写寄存器
AD5676R的输入移位寄存器为24位宽。数据首先装入MSB (DB23),前四位是命令位,C3到C0,其次是4位DAC地址位,A3到A0,最后是16位数据字。这些数据位被传输到SCLK的24个下降沿上的输入寄存器,并在SYNC的上升沿上更新。
命令
常用到的是0011,写入并更新寄存器
寄存器地址
DAC更新
AD5676R DAC具有双缓冲接口,由两组寄存器组成:输入寄存器和DAC寄存器。用户可以写入输入寄存器的任意组合。对DAC寄存器的更新由LDAC引脚控制。
当使用命令0001将数据时钟输入寄存器时,LDAC保持低电平。寻址输入寄存器和DAC寄存器都在同步的上升沿上更新,输出开始改变。
写命令和LDAC引脚真值表
下电模式
AD5676R包含两种独立的下电模式。命令0100被指定为下电功能。通过在输入移位寄存器中设置16位,位DB15到位DB0,这些断电模式是软件可编程的。每个DAC通道都有两个比特。下表显示了这两位的状态如何对应于设备的操作模式。
注:使用DAC之前要设置AD5676R的通道为Normal模式。
代码
.h文件
#ifndef AD5676R_H
#define AD5676R_H
#include <stdio.h>
#include "main.h"
/**********************************************************************************************************
*控制位
**********************************************************************************************************/
#define AD5676_CTRL_NOP 0
#define AD5676_CTRL_WRITE 1
#define AD5676_CTRL_UPDATE 2
#define AD5676_CTRL_WRITEUPDATE 3
#define AD5676_CTRL_PWR 4
#define AD5676_CTRL_LDAC_MASK 5
#define AD5676_CTRL_SWRESET 6
#define AD5676_CTRL_IREF_REG 7
#define AD5676_CTRL_DCEN 8
#define AD5676_CTRL_RB_REG 9
/**********************************************************************************************************
*关电操作模式掩码
**********************************************************************************************************/
#define AD5676_PWRM_NORMAL 0
#define AD5676_PWRM_1K 1
#define AD5676_PWRM_100K 2
#define AD5676_PWRM_THREESTATE 3
#define AD5676_PWRM_MASK 3
/* Enable/disable defines */
#define AD5676_INTREF_EN 1
#define AD5676_INTREF_DIS 0
#define AD5676_DC_EN 1
#define AD5676_DC_DIS 0
#define AD5676_RB_EN 1
#define AD5676_RB_DIS 0
#define PKT_LENGTH 3 // SPI packet length in byte
#define ADDR_MASK 0xFF // Mask for Address bits
#define CMD_OFFSET 4 // Offset for Command
#define AD5676_CMD_MASK 0xFF
#define AD5676_MSB_MASK 0xFF00 // Most significant byte of the data word
#define AD5676_MSB_OFFSET 8
#define AD5676_LSB_MASK 0x00FF // Least significant byte of the data word
#define AD5676_LSB_OFFSET 0
/******************************************************************************/
/*************************** Types Declarations *******************************/
/******************************************************************************/
typedef enum
{
AD5676_CH_0 = 0,
AD5676_CH_1,
AD5676_CH_2,
AD5676_CH_3,
AD5676_CH_4,
AD5676_CH_5,
AD5676_CH_6,
AD5676_CH_7,
} ad5676_dac_channels;
/**********************************************************************************************************
结构体:ad5676r控制引脚
**********************************************************************************************************/
typedef struct
{
mcu_pin_t LDAC; //加载 DAC
mcu_pin_t SYNC; //片选 拉低开始传数据
mcu_pin_t RST; //复位 拉低复位
} mcu_ad5676_pin_t;
/**********************************************************************************************************
结构体:ad5676r
**********************************************************************************************************/
typedef struct
{
mcu_ad5676_pin_t pins;
uint32_t power_down_mask;
uint32_t ldac_mask;
} mcu_ad5676_t;
/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
mcu_ad5676_t *mcu_ad5676r_get_addr(void);
void ad5676_init(void);
void ad5676_set_shift_reg(uint8_t command,uint8_t address,uint16_t data);
void ad5676_write_register(ad5676_dac_channels channel,uint16_t data);
void ad5676_update_register(ad5676_dac_channels channel);
void ad5676_write_update_register( ad5676_dac_channels channel,uint16_t data);
void ad5676_power_mode( ad5676_dac_channels channel,uint8_t mode);
void ad5676_ldac_mask( ad5676_dac_channels channel,uint8_t enable);
void ad5676_software_reset(void);
void ad5676_internal_reference(uint8_t value);
#endif //AD5676R_H
.c文件
mcu_ad5676_t mcu_ad5676 = {0};
/**********************************************************************************************************
* 函 数 名: mcu_ad5676r_get_addr
* 功能说明: 获取ad5676地址
* 形 参: 无
* 返 回 值: ad5676地址
**********************************************************************************************************/
mcu_ad5676_t *mcu_ad5676r_get_addr(void)
{
return &mcu_ad5676;
}
/**********************************************************************************************************
* 函 数 名: mcu_ads127L11_get_addr
* 功能说明: ad5676初始化配置
* 形 参: 无
* 返 回 值: 无
**********************************************************************************************************/
void ad5676_init(void)
{
mcu_ad5676_t *dev = mcu_ad5676r_get_addr();
dev->power_down_mask = 0;
dev->ldac_mask = 0;
HAL_GPIO_WritePin(MCU_ADS124S08_RST_GPIO_Port, MCU_ADS124S08_RST_Pin, GPIO_PIN_RESET);
//LDAC低电平
HAL_GPIO_WritePin(MCU_AD5676_LDAC_GPIO_Port, MCU_AD5676_LDAC_Pin, GPIO_PIN_RESET);
//拉高SYNC
HAL_GPIO_WritePin(MCU_AD5676_SYNC_GPIO_Port, MCU_AD5676_SYNC_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(MCU_ADS124S08_RST_GPIO_Port, MCU_ADS124S08_RST_Pin, GPIO_PIN_SET);
HAL_Delay(50);
//CH7
ad5676_power_mode(AD5676_CH_7,AD5676_PWRM_NORMAL);
ad5676_write_update_register(AD5676_CH_7,65500);//3.3V
//CH6
ad5676_power_mode(AD5676_CH_6,AD5676_PWRM_NORMAL);
ad5676_write_update_register(AD5676_CH_6,40000);//3.05V
//CH5
ad5676_power_mode(AD5676_CH_5,AD5676_PWRM_NORMAL);
ad5676_write_update_register(AD5676_CH_5,30000);//2.288V
//CH4
ad5676_power_mode(AD5676_CH_4,AD5676_PWRM_NORMAL);
ad5676_write_update_register(AD5676_CH_4,20000);//1.525V
//CH3
ad5676_power_mode(AD5676_CH_3,AD5676_PWRM_NORMAL);
ad5676_write_update_register(AD5676_CH_3,15000);//1.144V
//CH2
ad5676_power_mode(AD5676_CH_2,AD5676_PWRM_NORMAL);
ad5676_write_update_register(AD5676_CH_2,10000);//0.762V
//CH1
ad5676_power_mode(AD5676_CH_1,AD5676_PWRM_NORMAL);
ad5676_write_update_register(AD5676_CH_1,5000);//0.381V
//CH0
ad5676_power_mode(AD5676_CH_0,AD5676_PWRM_NORMAL);
ad5676_write_update_register(AD5676_CH_0,0);//0.0V
}
/***********************************************************************************************************
* 函 数 名: ad5676_set_shift_reg
* 功能说明: 设置输入寄存器
* 形 参: command - 命令控制位 4位
* address - 地址位 4位
* data - 要写入到输入寄存器的数据 16位
* 返 回 值: value read from register
***********************************************************************************************************/
void ad5676_set_shift_reg(uint8_t command,uint8_t address,uint16_t data)
{
uint8_t TX_data_buff [ PKT_LENGTH ] = {0, 0, 0};
TX_data_buff[0] = ((command & AD5676_CMD_MASK) << CMD_OFFSET) | (address & ADDR_MASK);//命令位+地址位
TX_data_buff[1] = (data & AD5676_MSB_MASK) >> AD5676_MSB_OFFSET;//取16位中的高8位,然后右移到低8位,这样就从16位变成的8位
TX_data_buff[2] = (data & AD5676_LSB_MASK);//&是取其中某位,|是加上某位
//拉低SYNC
HAL_GPIO_WritePin(MCU_AD5676_SYNC_GPIO_Port, MCU_AD5676_SYNC_Pin, GPIO_PIN_RESET);
//传输到24位输入寄存器
HAL_SPI_Transmit(&hspi4, TX_data_buff,PKT_LENGTH, 1000000);
//拉高SYNC
HAL_GPIO_WritePin(MCU_AD5676_SYNC_GPIO_Port, MCU_AD5676_SYNC_Pin, GPIO_PIN_SET);
}
/**********************************************************************************************************
* 函 数 名: ad5676_write_register
* 功能说明: 设置输入寄存器
* 形 参:channel要写入的通道 AD5676_CH_0 ~ AD5676_CH_7
* data 要写入的值
* 返 回 值: 无
**********************************************************************************************************/
void ad5676_write_register(ad5676_dac_channels channel,uint16_t data)
{
uint16_t data_rec = data;
ad5676_set_shift_reg( AD5676_CTRL_WRITE, channel, data_rec);
}
/**********************************************************************************************************
* 函 数 名: ad5676_update_register
* 功能说明: 更新寄存器n
* 形 参:channel要写入的通道 AD5676_CH_0 ~ AD5676_CH_7
* 返 回 值: 无
**********************************************************************************************************/
void ad5676_update_register(ad5676_dac_channels channel)
{
//D7-D0确定n?
//ad5676_set_shift_reg(AD5676_CTRL_UPDATE, address, 0);
ad5676_set_shift_reg(AD5676_CTRL_UPDATE, 0, channel);
}
/**********************************************************************************************************
* 函 数 名: ad5676_write_update_register
* 功能说明: 写入并且更新通道(独立于LDAC)
* 形 参:channel要写入的通道 AD5676_CH_0 ~ AD5676_CH_7
* data 要写入的值
* 返 回 值: 无
**********************************************************************************************************/
void ad5676_write_update_register( ad5676_dac_channels channel,uint16_t data)
{
uint16_t data_rec = data;
ad5676_set_shift_reg(AD5676_CTRL_WRITEUPDATE, channel,data_rec);
}
/**********************************************************************************************************
* 函 数 名: ad5676_power_mode
* 功能说明: 设置通道电源模式
* 形 参:channel:要写入的通道 AD5676_CH_0 ~ AD5676_CH_7
* mode: 电源模式
* 'AD5676_PWRM_NORMAL' - Normal Mode
* 'AD5676_PWRM_1K' - Power-down mode 1kOhm to GND
* 'AD5676_PWRM_100K' - Power-down mode 100kOhm to GND
* 'AD5676_PWRM_THREESTATE' - Three-State
* 返 回 值: 无
**********************************************************************************************************/
void ad5676_power_mode( ad5676_dac_channels channel,uint8_t mode)
{
mcu_ad5676_t *dev = mcu_ad5676r_get_addr();
if (channel > AD5676_CH_7)
channel -= AD5676_CH_7 + 1;
dev->power_down_mask &= ~(0x3 << (channel *2));//保留某位
dev->power_down_mask |= (mode << (channel *2));//加上某位
ad5676_set_shift_reg(AD5676_CTRL_PWR, channel,dev->power_down_mask);
}
/**********************************************************************************************************
* 函 数 名: ad5676_ldac_mask
* 功能说明: 设置硬件LADC掩码寄存器 如果哪个通道忽略 LDAC 上的转换
* 形 参:channel:要写入的通道 AD5676_CH_0 ~ AD5676_CH_7
* enable: 使能 1/0
* 返 回 值: 无
**********************************************************************************************************/
void ad5676_ldac_mask( ad5676_dac_channels channel,uint8_t enable)
{
mcu_ad5676_t *dev = mcu_ad5676r_get_addr();
dev->ldac_mask &= ~(0x1 << channel);
dev->ldac_mask |= (enable << channel);
ad5676_set_shift_reg( AD5676_CTRL_LDAC_MASK, 0, dev->ldac_mask);
}
/**********************************************************************************************************
* 函 数 名: ad5676_software_reset
* 功能说明: 软件复位
* 形 参:无
* 返 回 值: 无
**********************************************************************************************************/
void ad5676_software_reset(void)
{
ad5676_set_shift_reg(AD5676_CTRL_SWRESET, 0, 0x1234);
}
/**********************************************************************************************************
* 函 数 名: ad5676_internal_reference
* 功能说明: 设置内部参考寄存器值
* 形 参:value 内部参考寄存器值
* 返 回 值: 无
**********************************************************************************************************/
void ad5676_internal_reference(uint8_t value)
{
ad5676_set_shift_reg(AD5676_CTRL_IREF_REG, 0, value);
}