双通道,16位,DAC8562驱动实验(基于STM32F103C8T6)
一、DAC8563的主要参数
DAC8562是Ti公司的一款高精度DAC
DAC8563具有 2.5V、4ppm/°C 基准的 16 位、双通道、低功耗、超低短时脉冲波形干扰、缓冲电压输出 DAC。
采用SPI接口进行通信,具有内部参考电压、软件可编程增益和输出保护等功能。
供电电压:2.7~5.5V
分辨率:16bit,双通道
通讯接口:3线SPI串行通讯,速率最高至50MHz,支持3.3V和5V单片机(有MOSI/CLK/CS,无MISO)
内部自带2.5V参考电压。使用内部参考电压时,DAC通道输出电压根据增益设置的不同可输出0~2.5V(增益为1)或0~5V(增益为2,默认)
二.DAC8563的芯片封装:
引脚说明:
- VoutA、VoutB:模拟输出电压通道A、B
- LDAC: 将寄存器设置值同步输出,在同步模式下该引脚接地,下降沿有效
- CLR:异步清除输入,在写输出寄存器时若产生下降沿,则写操作中止。下降沿触发后,DAC8563输出电压中间值。注意清0时,要延时操作。
- SYNC 片选:电平触发(低电平)而非边沿触发,为低时才会采样数据至DAC寄存器。发送数据时要延时
- SCLK: 串行时钟输入,数据传输速率最大至50MHz,因此SPI的时钟最大只能设置为50MHz
- Din: 串行数据输入,在时钟的下降沿被采样
- AVDD: 供电电源输入(2.7~5.5V)
- VREFIN/VREFOUT:双向参考电压引脚,当使用内部参考时,该引脚向外输出内部参考电压2.5V。
三、DAC856X输出电压计算公式
DAC856X的计算公式如下:
DIN:配置DAC856X数据输出寄存器的数值,范围0 到2^16 – 1,即0到65535。
2n:对于DAC856X来说,n是16。
VREF:如果使用内部参考电压,那么此数值是2.5V,如果使用外部参考电压,由VREFIN引脚的输入决定。
Gain:增益设置。禁止内部电压基准后,默认增益是1。如果使能内部电压基准后,默认增益是2。具体增益是1还是2,可以通过DAC856X的寄存器设置。
四.实验平台
- stm32f103c8t6
2.芯片
连接关系
#define LDAC PBout(3)
#define CLR PBout(4)
#define SYNC PBout(5)
#define SCLK PBout(6)
#define DIN PBout(7)
#ifndef __DAC8562_H
#define __DAC8562_H
#include <sys.h>
////-----------------LCD端口定义----------------
#define LDAC PBout(3)
#define CLR PBout(4)
#define SYNC PBout(5)
#define SCLK PBout(6)
#define DIN PBout(7)
/*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 //供电电压VDD=为3.3V,输出电压最大为3.3V,3.3/5*65535=43253.1
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);
void DAC856x_Set_out_Voltage(uint8_t DAC_Channel,uint16_t volt);//mv
#endif
#include "DAC8562.h"
#include "delay.h"
void DAC856x_GPIO_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void DAC856x_Init(void)
{
//将CLR,SYNC拉高
SYNC=1;
LDAC=1;
// GPIO_SetBits(GPIOB,GPIO_Pin_2);
// GPIO_SetBits(GPIOB,GPIO_Pin_0);
//将CLK时钟拉低,CLR拉低
// GPIO_ResetBits(GPIOB,GPIO_Pin_3);
// GPIO_ResetBits(GPIOB,GPIO_Pin_1);
SCLK=0;
CLR=0;
//初始化配置
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)); //选用内部参考电压
}
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);
}
}
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;
}
void DAC856x_Set_out_Voltage(uint8_t DAC_Channel,uint16_t volt)//mv
{
uint16_t DAC_Data;
//最大输出5V,此时VDD供电需要大于5V
DAC_Data = (uint16_t)(volt*13.1072f);//D=(35536*VOUT)/2.5/2
DAC856x_SetVoltage(DAC_Channel, DAC_Data);
}
//******************************************************************************/
#include "delay.h"
#include "sys.h"
#include "led.h"
#include "DAC8562.h"
int main(void)
{
DAC856x_GPIO_Init();
DAC856x_Init();
DAC856x_SetVoltage(WrtirToInputReg_Command_DAC_AB ,0) ;
while(1)
{
DAC856x_Set_out_Voltage(WrtirToInputReg_Command_DAC_A ,1500) ;//1500mv
DAC856x_Set_out_Voltage(WrtirToInputReg_Command_DAC_B ,2600) ;//2600mv
}
}