說明:以下圖片有些來自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
程序經過測試,沒有問題,主函數很簡單,這裏就不在敘述了。完。