AD5724 是一款数模转换器,可保证 12 位单调性,积分非线 性(INL)误差为±1 LSB,总非调整误差(TUE)为 0.1%,建立时 间为 10 μs。该器件还集成了基准电压缓冲和输出放大器,从 而可以进一步节省成本和电路板空间。在以下电源电压范围 内能够保证性能:AVDD 电源电压范围为+4.5 V 至+16.5 V, AVSS 电源电压范围为−4.5 V 至−16.5 V。如果只需要单极性 输出,则可以将 AVSS 与 0 V 相连。各输出通道的输出范围均可独立编程,提供以下选项:0 V至 进一步阅读 +5 V、0 V至+10 V、0 V至+10.8 V、−5 V至+5 V、−10 V至+10 V、−10.8 V至+10.8 V。对于双极性输出,输入编码方式为用 户可选的二进制补码或偏移二进制(取决于BIN\2sCOMP 引 脚的状态)。对于单极性输出,编码方式为标准二进制。
同过向输入寄存器写数据,然后加载到DAC寄存器,然后输出指定电压。
1)设置上电状态为正常模式,设置POWER CONTROL REGISTER 中的DB3-DB1分别设置DACD-DACA的上电模式
2)设置输出范围,设置OUTPUT RANGE SELECT REGISTER中的A2-A0设置DAC的地址,设置DB2-DB0设置具体输出范围
3) 输出电压,设置DAC寄存器中的A2-A0设置DAC地址,设置DB4-DB15设置输出电压。具体见如下
写DAC寄存器时要先拉低SYNC,写完之后拉高SYNC。(注意,否则不会输出)
BBIN\2sCOMP 接地
spi.c代码段
#include "spi.h"
#include "main.h"
#include "stm32f1xx_hal.h"
#include "stm32f1xx_hal_spi.h"
void AD5724R_SPI_Init(void)
{
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* Enable GPIO TX/RX clock */
/*##-2- Configure peripheral GPIO ##########################################*/
/* SPI SCK GPIO pin configuration */
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = SPI_SCK_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(SPI_SCK_GPIO_PORT, &GPIO_InitStruct);
HAL_GPIO_WritePin(SPI_SCK_GPIO_PORT, SPI_SCK_PIN, GPIO_PIN_RESET);
/* SPI MOSI GPIO pin configuration */
GPIO_InitStruct.Pin = SPI_MOSI_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(SPI_MOSI_GPIO_PORT, &GPIO_InitStruct);
HAL_GPIO_WritePin(SPI_MOSI_GPIO_PORT, SPI_MOSI_PIN, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = SPI_CLR_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(SPI_CLR_GPIO_PORT, &GPIO_InitStruct);
HAL_GPIO_WritePin(SPI_CLR_GPIO_PORT, SPI_CLR_PIN, GPIO_PIN_SET);
GPIO_InitStruct.Pin = SDO_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
unsigned char AD5724R_Init(void){
AD5724R_SPI_Init();
LDAC_L;
SYNC_H;
CLR_H;
}
void AD5724R_SetRegister(uint8_t RegisterAddr,uint8_t DACAddr,uint16_t Data)
{
uint8_t wr[3]={0};
assert_param(IS_REG_ADDRESS(RegisterAddr));
assert_param(IS_DAC_ADDRESS(DACAddr));
wr[0] = (RegisterAddr<<3)|(DACAddr);
wr[1] = Data>>8;
wr[2] = Data&0xFF;
SYNC_L;
for(int i = 0;i<3;i++)
simulate_spi_write_byte(wr[i]);
SYNC_H;
}
void AD5724R_SetDACRegisterValue(uint8_t DACAddr,int16_t Data)
{
assert_param(IS_VALID_DATA(Data));
AD5724R_SetRegister(AD5724R_REG_DAC,DACAddr,(uint16_t)(Data<<4));
}
void AD5724R_OutputRangeSelect(uint8_t DACAddr,uint8_t RangeSelect)
{
uint16_t dat;
assert_param(IS_VALID_RANGE(RangeSelect));
dat = 0x07 & RangeSelect ;
AD5724R_SetRegister(AD5724R_REG_RANGE_SELECT,DACAddr,dat);
}
void AD5724R_SetPowerControl(uint8_t PowerStatus)
{
uint16_t dat;
assert_param(IS_VALID_POWER(PowerStatus));
dat = 0x0F & PowerStatus;
AD5724R_SetRegister(AD5724R_REG_POWER_CONTROL,0x000,dat);
}
void simulate_spi_write_byte(u8 data)
{
u8 kk;
SCK_L;
SIMULATE_DELAY_US;
SIMULATE_DELAY_US;
SIMULATE_DELAY_US;
for(kk=0;kk<8;kk++)
{
if((data&0x80)==0x80) MOSI_H;
else MOSI_L;
SIMULATE_DELAY_US;
SCK_H;
SIMULATE_DELAY_US;
SCK_L;
data = data<<1;
}
}
u8 simulate_spi_read_byte(void)
{
u8 kk=0, ret=0;
SCK_L;
SIMULATE_DELAY_US;
SIMULATE_DELAY_US;
SIMULATE_DELAY_US;
for(kk=0;kk<8;kk++)
{
ret = ret<<1;
SIMULATE_DELAY_US;
SCK_H;
SIMULATE_DELAY_US;
if(MISO) ret |= 0x01;
SCK_L;
}
return ret;
}
spi.h代码段
#ifndef __SPI_H
#define __SPI_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
#define SPI_SCK_PIN SCLK_Pin
#define SPI_SCK_GPIO_PORT SCLK_GPIO_Port
#define SPI_MOSI_PIN SDIN_Pin
#define SPI_MOSI_GPIO_PORT SDIN_GPIO_Port
#define SPI_MISO_PIN SDO_Pin
#define SPI_MISO_GPIO_PORT SDO_GPIO_Port
#define SPI_CLR_PIN CLR_Pin
#define SPI_CLR_GPIO_PORT CLR_GPIO_Port
#define MOSI_H HAL_GPIO_WritePin(SPI_MOSI_GPIO_PORT, SPI_MOSI_PIN, GPIO_PIN_SET)
#define MOSI_L HAL_GPIO_WritePin(SPI_MOSI_GPIO_PORT, SPI_MOSI_PIN, GPIO_PIN_RESET)
#define MISO HAL_GPIO_ReadPin(SPI_MISO_GPIO_PORT, SPI_MISO_PIN)
#define SCK_H HAL_GPIO_WritePin(SPI_SCK_GPIO_PORT, SPI_SCK_PIN, GPIO_PIN_SET)
#define SCK_L HAL_GPIO_WritePin(SPI_SCK_GPIO_PORT, SPI_SCK_PIN, GPIO_PIN_RESET)
#define CLR_H HAL_GPIO_WritePin(SPI_CLR_GPIO_PORT, SPI_CLR_PIN, GPIO_PIN_SET)
#define CLR_L HAL_GPIO_WritePin(SPI_CLR_GPIO_PORT, SPI_CLR_PIN, GPIO_PIN_RESET)
#define LDAC_H HAL_GPIO_WritePin(LDAC_GPIO_Port, LDAC_Pin, GPIO_PIN_SET)
#define LDAC_L HAL_GPIO_WritePin(LDAC_GPIO_Port, LDAC_Pin, GPIO_PIN_RESET)
#define SYNC_H HAL_GPIO_WritePin(SYNC_GPIO_Port, SYNC_Pin, GPIO_PIN_SET)
#define SYNC_L HAL_GPIO_WritePin(SYNC_GPIO_Port, SYNC_Pin, GPIO_PIN_RESET)
/* AD5754R Register Map */
#define AD5724R_REG_DAC 0x00 // DAC register
#define AD5724R_REG_RANGE_SELECT 0x01 // Output range select register
#define AD5724R_REG_POWER_CONTROL 0x02 // Power control register
#define AD5724R_REG_CONTROL 0x03 // Control register
/* AD5754R Channel Address */
#define AD5724R_DAC_A 0x00 // Address of channel A
#define AD5724R_DAC_B 0x01 // Address of channel B
#define AD5724R_DAC_C 0x02 // Address of channel C
#define AD5724R_DAC_D 0x03 // Address of channel D
#define AD5724R_DAC_ALL 0x04 // All four DACs
/* AD5754R Range Bits */
#define AD5754R_UNIPOLAR_5_RANGE 0x00 // 0..+5(V)
#define AD5754R_UNIPOLAR_10_RANGE 0x01 // 0..+10(V)
#define AD5754R_UNIPOLAR_10_8_RANGE 0x02 // 0..+10.8(V)
#define AD5754R_BIPOLAR_5_RANGE 0x03 // -5..+5(V)
#define AD5754R_BIPOLAR_10_RANGE 0x04 // -10...+10(V)
#define AD5754R_BIPOLAR_10_8_RANGE 0x05 // -10.8...+10.8(V)
/* Control Functions */
#define AD5754R_NOP_OPERATION 0x00 // No operation instruction used in readback operations.
#define AD5754R_SDO_DISABLE 0x11 // Set by the user to disable the SDO output.
#define AD5754R_CLR_SELECT 0x12 // Selects the clear code: 0V, Midscale or Negative full scale.
#define AD5754R_CLAMP_ENABLE 0x14 // Set by the user to enable the current-limit clamp.
#define AD5754R_TSD_ENABLE 0x18 // Set by the user to enable the thermal shutdown feature.
#define AD5754R_CLEAR 0x40 // Sets the DAC registers to the clear code and updates the outputs.
#define AD5754R_LOAD 0x50 // Updates the DAC registers and, consequently, the DAC outputs.
/*AD5724 Power on status*/
#define AD5724R_DAC_A_POWERON 0x01 //DAC A Power on
#define AD5724R_DAC_B_POWERON 0x02 //DAC A Power on
#define AD5724R_DAC_C_POWERON 0x04 //DAC A Power on
#define AD5724R_DAC_D_POWERON 0x08 //DAC A Power on
#define AD5724R_DAC_ALL_POWERON 0X0F //DAC A Power on
/* */
#define IS_REG_ADDRESS(INSTANCE) ( (INSTANCE == AD5724R_REG_DAC) || \
(INSTANCE == AD5724R_REG_RANGE_SELECT) || \
(INSTANCE == AD5724R_REG_POWER_CONTROL) || \
(INSTANCE == AD5724R_REG_CONTROL) )
#define IS_DAC_ADDRESS(INSTANCE) ( (INSTANCE == AD5724R_DAC_A) || \
(INSTANCE == AD5724R_DAC_B) || \
(INSTANCE == AD5724R_DAC_C) || \
(INSTANCE == AD5724R_DAC_D) || \
(INSTANCE == AD5724R_DAC_ALL) )
#define IS_VALID_DATA(INSTANCE) (INSTANCE)>2048?0:(INSTANCE)<-2047?0:1
#define IS_VALID_RANGE(INSTANCE) ( (INSTANCE == AD5754R_UNIPOLAR_5_RANGE) || \
(INSTANCE == AD5754R_UNIPOLAR_10_RANGE) || \
(INSTANCE == AD5754R_UNIPOLAR_10_8_RANGE) || \
(INSTANCE == AD5754R_BIPOLAR_5_RANGE) || \
(INSTANCE == AD5754R_BIPOLAR_10_RANGE) || \
(INSTANCE == AD5754R_BIPOLAR_10_8_RANGE) )
#define IS_VALID_POWER(INSTANCE) ( (INSTANCE == AD5724R_DAC_A_POWERON) || \
(INSTANCE == AD5724R_DAC_B_POWERON) || \
(INSTANCE == AD5724R_DAC_C_POWERON) || \
(INSTANCE == AD5724R_DAC_D_POWERON) || \
(INSTANCE == AD5724R_DAC_ALL_POWERON) )
#define u8 uint8_t
#define SIMULATE_DELAY_US __nop()
void AD5724R_SetDACRegisterValue(uint8_t DACAddr,int16_t Data);
void AD5724R_OutputRangeSelect(uint8_t DACAddr,uint8_t RangeSelect);
void AD5724R_SetPowerControl(uint8_t PowerStatus);
void AD5724R_SPI_Init(void);
unsigned char AD5724R_Init(void);
/* Reads alert bits form Power Control Register. */
#endif
main.c中使用
AD5724R_Init(); //初始化
AD5724R_SetPowerControl(AD5724R_DAC_ALL_POWERON); //上电后状态
AD5724R_OutputRangeSelect(AD5724R_DAC_A,AD5754R_BIPOLAR_10_RANGE);//DAC_A通道,范围设置
AD5724R_SetDACRegisterValue(AD5724R_DAC_A,1000);//DAC_A,输出