STM32驱动AD5676R

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);
}
  • 12
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值