说明:以下图片有些来自Ti的DAC8562的芯片手册,仅供参考;STM32的库是使用的正点原子的库函数。
这里我们介绍一下DAC8562的配置与使用,DAC8562是Ti公司的一款高精度DA,其位数为16位,输出量程可以根据参考电压选择,其特性简介如下:
Relative Accuracy:
DAC756x (12-Bit): 0.3 LSB INL
DAC816x (14-Bit): 1 LSB INL
DAC856x (16-Bit): 4 LSB INL
Glitch Impulse: 0.1 nV-s
Bidirectional Reference: Input or 2.5-V Output
Output Disabled by Default
±5-mV Initial Accuracy (Max)
4-ppm°C Temperature Drift (Typ)
10-ppm/°C Temperature Drift (Max)
20-mA Sink and Source Capability
Power-On Reset to Zero Scale or Mid-Scale
Low-Power: 4 mW (Typ, 5-V AVDD, Including Internal Reference Current)
Wide Power-Supply Range: 2.7 V to 5.5 V
50-MHz SPI With Schmitt-Triggered Inputs
LDAC and CLR Functions
Output Buffer With Rail-to-Rail Operation
Packages: WSON-10 (3 mm × 3 mm), VSSOP-10
Temperature Range: –40°C to 125°C
我们将其翻译成中文,如下:
相对精度:
DAC756X(12位):0.3 LSB输入
DAC816X(14位):1 LSB输入
DAC856X(16位):4 LSB输入
故障脉冲:0.1 nv-s
双向参考:输入或2.5-V输出
默认情况下禁用输出
±5-mV初始精度(最大值)
4-ppm°C温度漂移(典型)
10 ppm/°C温度漂移(最大)
20 mA水槽和电源容量
上电重置为零刻度或中刻度
低功率:4 mW(典型,5-V AVDD,包括内部参考电流)
宽电源范围:2.7 V至5.5 V
带施密特触发输入的50兆赫SPI
ldac和clr函数
带轨对轨操作的输出缓冲器
封装:WSON-10(3 mm×3 mm),VSSOP-10
温度范围:–40°C至125°C
在配置该DAC8562之前,我们需要知道其引脚图,以及相应的引脚定义:
图一 芯片引脚图
图二 引脚定义图
从图中我们可以知道:
AVDD:供电引脚,电压范围从2.7V到5.5V;
CLR:异步复位引脚,下降沿触发,这里DAC8562的寄存器会复位成0;
DIN:数据输入引脚:
GND:接地;
LDAC:数据装载引脚;
SCLK:时钟输入;
SYNC:同步帧;
VOUT_A:电压输出通道A;
VOUT_B:电压输出通道B;
VREF:参考电压输入/输出;
同时我们还需要知道芯片内部的原理框图,如下:
图三 芯片内部原理图
我们需要知道其电路原理图,下面给大家两个电路图,一个是Ti给的评估板参考电路图,一个是自己画的电路图:
图四 官方电路图
图五 自己的电路图
DAC8562的配置流程,其实非常简单,其流程图如下:
图六 DAC8562配置流程图
我们需要将数据和指令写入相应的寄存器,就需要知道相应的写入时序,这里DAC8562的写入时序如下:
图七 时序图
当SYNC为低时,写入的数据才有效,同时,数据在时钟下降沿会被写入寄存器,最后LDAC的的下降沿将其装入相应的寄存器中。
其数据的格式如下:
图八 数据格式图
那么我们相应的程序就如下:
void DAC856x_Write_Data(u8 command,u16 data)
{
int i;
SYNC = 1;
delay_us(1);
SYNC = 0;
for(i=7;i>=0;i--) //写入指令与地址
{
SCLK = 1;
delay_us(10);
DIN = (command>>i)%2;
delay_us(10);
SCLK = 0;
delay_us(10);
}
for(i=15;i>=0;i--) //写入相应的数据
{
SCLK = 1;
delay_us(10);
DIN = (data>>i)%2;
delay_us(10);
SCLK = 0;
delay_us(10);
}
}
前面8位为我们需要写入的指令与地址,后面为需要写入的数据。其指令表可以参考芯片手册的第38页,非常详细,链接:http://202.114.207.36/cache/3/03/www.ti.com/8296d63ca25b9f6e1ab766ab35f3c5db/dac8562.pdf
接下来我们就需要进行相应的配置了,其配置程序如下:
void DAC856x_Init(void)
{
//将CLR,SYNC拉高
GPIO_SetBits(GPIOC,GPIO_Pin_2);
GPIO_SetBits(GPIOC,GPIO_Pin_0);
//将时钟拉低,CLR拉高
GPIO_ResetBits(GPIOC,GPIO_Pin_3);
GPIO_ResetBits(GPIOC,GPIO_Pin_1);
//初始化配置
DAC856x_Write_Data((WrtirToInputReg_Command_Reset_All_Regs>>16),(WrtirToInputReg_Command_Reset_All_Regs&0xFFFF)); //复位
DAC856x_Write_Data((WrtirToInputReg_Command_POWERUP_DAC_A_B>>16),(WrtirToInputReg_Command_POWERUP_DAC_A_B&0xFFFF)); //启动
DAC856x_Write_Data((WrtirToInputReg_Command_ENABLE_INTERNAL>>16),(WrtirToInputReg_Command_ENABLE_INTERNAL&0xFFFF)); //选用内部参考电压
}
接下来我们需要设置DAC的输出电压,这里由于我们选用的是内部参考,其增益默认为两倍,其输电压计算的原理框图如下:
图九 输出电压计算框图
这里我们的输出电压函数如下:
void DAC856x_SetVoltage(u8 DAC_Channel,u16 Dac_Data)
{
if(DAC_Channel == WrtirToInputReg_Command_DAC_A)
{
if(Dac_Data <= Max_Dac_Data)
DAC856x_Write_Data(WrtirToInputReg_Command_DAC_A,Dac_Data);
else
DAC856x_Write_Data(WrtirToInputReg_Command_DAC_A,Max_Dac_Data);
}
if(DAC_Channel == WrtirToInputReg_Command_DAC_B)
{
if(Dac_Data <= Max_Dac_Data)
DAC856x_Write_Data(WrtirToInputReg_Command_DAC_B,Dac_Data);
else
DAC856x_Write_Data(WrtirToInputReg_Command_DAC_B,Max_Dac_Data);
}
if(DAC_Channel == WrtirToInputReg_Command_DAC_AB)
{
if(Dac_Data <= Max_Dac_Data)
DAC856x_Write_Data(WrtirToInputReg_Command_DAC_AB,Dac_Data);
else
DAC856x_Write_Data(WrtirToInputReg_Command_DAC_AB,Max_Dac_Data);
}
LDAC = 0;
delay_us(100);
LDAC = 1;
}
最后我们需要初始化相应的IO口,其程序如下:
void DAC856x_GPIO_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE); //使能GPIOC时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
我们相应的头文件定义如下:
#ifndef __DAC8563_H
#define __DAC8563_H
#include <sys.h>
#define LDAC PCout(0)
#define CLR PCout(1)
#define SYNC PCout(2)
#define SCLK PCout(3)
#define DIN PCout(4)
/*Voltage Set*/
#define WrtirToInputReg_Command_DAC_A 0x18
#define WrtirToInputReg_Command_DAC_B 0x19
#define WrtirToInputReg_Command_DAC_AB 0x1F
/*Command Set*/
#define WrtirToInputReg_Command_DAC_AB_Gain_2 0x020000 //Normal Default
#define WrtirToInputReg_Command_DAC_B_Gain_2_A_Gain_1 0x020001
#define WrtirToInputReg_Command_DAC_B_Gain_1_A_Gain_2 0x020002
#define WrtirToInputReg_Command_DAC_B_Gain_1_A_Gain_1 0x020003 //Power_Down Default
#define WrtirToInputReg_Command_Reset_All_Regs 0x280001
#define WrtirToInputReg_Command_POWERUP_DAC_A_B 0x200003
#define WrtirToInputReg_Command_ENABLE_INTERNAL 0x380001
#define Max_Dac_Data 43254 //输出电压为3.3V
void DAC856x_GPIO_Init(void);
void DAC856x_Write_Data(u8 command,u16 data);
void DAC856x_Init(void);
void DAC856x_SetVoltage(u8 DAC_Channel,u16 Dac_Data);
#endif
程序经过测试,没有问题,主函数很简单,这里就不在叙述了。完。