DAC8551编程原理以及实现方式

29 篇文章 27 订阅

因项目需要通过0-5V电压控制比例阀,后通过芯片选型,选取DAC8551作为电压输出芯片,输出线性电压控制比例比例阀。资料来源于:德州仪器TI—DAC8551数据手册

DAC8551介绍

DAC8551 是一款小型、低功耗、电压输出、16 位数模转换器 (DAC)。 它是单调的,提供良好的线性度。 DAC8551 使用一个通用的 3 线串行接口,该接口以高达 30 MHz 的时钟速率运行,并与标准 SPI、QSPI、Microwire和数字信号处理器 (DSP) 接口兼容。
DAC8551 需要外部参考电压来设置其输出范围。 DAC8551 包含一个上电复位电路,可确保 DAC 输出在 0 V 上电并保持在该位置,直到对器件进行有效写入。 DAC8551 包含可通过串行接口访问的断电功能,可将器件在 5 V 时的电流消耗降低至 200 nA。

知其然知其所以然—编程原理

网上有许多源代码,但是并未介绍如何实现DAC8551的电压输出控制,这里通过解读DAC8551数据手册,来具体介绍如果控制其电压输出。
在这里插入图片描述
引脚定义介绍:
DIN 7 串行数据输入。 数据在串行时钟输入的每个下降沿被同步到 24 位输入移位寄存器。

GND 8 GND 器件上所有电路的接地参考点

SCLK 6 串行时钟输入。 数据可以以高达 30MHz 施密特触发器逻辑输入的速率传输。

SYNC 5 电平触发控制输入(低电平有效)。 这是输入数据的帧同步信号。
当 SYNC 变为低电平时,它启用输入移位寄存器,并且数据在随后时钟的下降沿传输。 DAC 在第 24 个时钟之后更新(除非 SYNC 在此边沿之前变为高电平,在这种情况下,SYNC 的上升沿充当中断并且写入序列被 DAC8551 忽略)。 施密特触发器逻辑输入。

VDD 1 PWR 电源输入,2.7 V 至 5.5 V VFB 3 I 输出放大器的反馈连接。 对于电压输出操作,外部连接到 VOUT。

VOUT 4 来自 DAC 的模拟输出电压。

VREF 2 参考电压输入。

DAC8551 支持四种独立的操作模式。 这些模式可通过设置控制寄存器中的两个位(PD1PD0)进行编程。 表 1 显示了位的状态如何对应于器件的操作模式。
在这里插入图片描述
当这两个位都设置为“0”时,该器件正常工作,其典型电流消耗为 200 μA(5 V 时)。
因只需要输出电压即可,所以这里不关注其他模式信息,具体内容参见数据手册。

编程

1、串行接口

DAC8551 有一个3 线串行接口(SYNC、SCLK 和DIN),它与SPI、QSPI 和Microwire 接口标准以及大多数DSP 兼容。
写序列从将 SYNC 线拉低开始。 来自 DIN 线的数据在 SCLK 的每个下降沿同步到 24 位移位寄存器。 串行时钟频率可高达 30 MHz,使 DAC8551 与高速 DSP 兼容。 在串行时钟的第 24 个下降沿,最后一个数据位被输入并执行编程功能(即,DAC 寄存器内容的变化和/或操作模式的变化)。
此时,SYNC 线可能会保持低电平或高电平。 在任何一种情况下,都必须在下一个写序列之前将其拉高至少 33 ns,以便 SYNC 的下降沿可以启动下一个写序列。 必须在下一个写序列之前再次拉高。

2、输入移位寄存器

输入移位寄存器为 24 位宽,如图所示。前六位是未使用的位。 接下来的两位(PD1 和 PD0)是控制位,用于控制器件处于哪种操作模式(正常模式或三种断电模式中的任何一种)。 各种模式的更完整描述位于掉电模式中。
接下来的 16 位是数据位。 这些位在 SCLK 的第 24 个下降沿传输到 DAC 寄存器。
在这里插入图片描述

3 SYNC 中断

在正常的写入序列中,SYNC 线在 SCLK 的至少 24 个下降沿保持低电平,DAC 在第 24 个下降沿更新。 但是,如果 SYNC 在第 24 个下降沿之前变为高电平,则它将作为写入序列的中断。 移位寄存器被复位,写序列被视为无效。 如图 50 所示,既不会更新 DAC 寄存器内容,也不会更改操作模式。
在这里插入图片描述DAC8551 的输入编码是直接二进制,因此理想输出电压由下式给出: DIN = 加载到 DAC 寄存器的二进制代码的十进制等效值; 它的范围可以从 0 到 65535
在这里插入图片描述

编程代码实现——以为F103为例—DAC8552

DAC8552程序.h文件

#ifndef __DAC8552_H_
#define __DAC8552_H_

extern uint16_t Zero_Voltage_OutPut;
extern uint16_t LOAD_Channel;

#define SUB 85
//------------------------------------------------------------------------------
//IO口宏定义:
//------------------------------------------------------------------------------
#define SYNC_1 GPIO_SetBits(GPIOE, GPIO_Pin_2)
#define SYNC_0 GPIO_ResetBits(GPIOE, GPIO_Pin_2)
#define DIN_1  GPIO_SetBits(GPIOE, GPIO_Pin_3)
#define DIN_0  GPIO_ResetBits(GPIOE, GPIO_Pin_3)
#define SCLK_1 GPIO_SetBits(GPIOE, GPIO_Pin_4)
#define SCLK_0 GPIO_ResetBits(GPIOE, GPIO_Pin_4)

//------------------------------------------------------------------------------
//写寄存器宏定义:
//参考(低、中、高);通道(A、B);输出阻抗(低、高)
//------------------------------------------------------------------------------
#define No_Impedance       0x00
#define Low_Impedance      0x01  //低四位可以是0000、    0001、  0010、    0011
#define Middle_Impedance   0x02  //分别代表    普通模式  1K阻抗 100K阻抗  高阻抗
#define High_Impedance     0x03  //阻抗为输出阻抗

#define Channel_A 0x00
#define Channel_B 0x04

#define Load_No 0x00
#define Load_A  0x10
#define Load_B  0x20
#define Load_AB 0x30

//------------------------------------------------------------------------------
//函数定义:
//------------------------------------------------------------------------------
void DAC8552_DA_convert(uint16_t datasheet, uint16_t channel);
void DAC8552_SEND_1(void);
void DAC8552_SEND_0(void);
void DAC8552_delay1ms (uint16_t n);
void DAC8552_Out_Put_Voltage(void);
void DAC8552_GPIO_Configuration(void);
void DAC8552_RCC_Configuration(void);

#endif

DAC8552程序.c文件

#include "stm32f10x.h"
#include "DAC8552.h"

uint16_t Zero_Voltage_OutPut = No_Impedance;
uint16_t LOAD_Channel = Load_AB;
uint16_t Channel_A_OutPut=32767, Channel_B_OutPut=16384;//max=65535

void DAC8552_GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_SetBits(GPIOE, GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4);
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOE, &GPIO_InitStructure);
}

void DAC8552_RCC_Configuration(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
}

//------------------------------------------------------------------------------
//函数名称:输出DAC
//函数功能:输出设定的电压
//参数传递:无
//------------------------------------------------------------------------------
void DAC8552_Out_Put_Voltage(void)
{
    DAC8552_DA_convert(Channel_A_OutPut, Channel_A);
    DAC8552_DA_convert(Channel_B_OutPut, Channel_B);
}

//------------------------------------------------------------------------------
//函数名称:延时
//函数功能:延时
//参数传递:无
//------------------------------------------------------------------------------
void DAC8552_delay1ms (uint16_t n)   
{
  while(n--);
}

//------------------------------------------------------------------------------
//函数名称:写数据
//函数功能:送0的子程序
//参数传递:无
//------------------------------------------------------------------------------
void DAC8552_SEND_0(void)
{
	DIN_0;
	//DAC8552_delay1ms(20);
	SCLK_1;
	//DAC8552_delay1ms(20);
	SCLK_0;
	//DAC8552_delay1ms(20);
}

//------------------------------------------------------------------------------
//函数名称:写数据
//函数功能:送1的子程序
//参数传递:无
//------------------------------------------------------------------------------
void DAC8552_SEND_1(void)
{
	DIN_1;
	//DAC8552_delay1ms(20);
	SCLK_1;
	//DAC8552_delay1ms(20);
	SCLK_0;
	//DAC8552_delay1ms(20);
}

//------------------------------------------------------------------------------
//函数名称:写入DA输出寄存器的数据
//函数功能:D/A转换的子程序
//参数传递:unsigned int datasheet  输出的电压
//------------------------------------------------------------------------------
void DAC8552_DA_convert(uint16_t datasheet, uint16_t channel)
{
     uint16_t i;
     uint16_t a,b,m;
	
     m=((Zero_Voltage_OutPut|channel)|LOAD_Channel);  //在此处设置参考电压、输出通道以及输出阻抗大小
     b=datasheet&0x00ff;
     a=datasheet>>8; //取高8位
     SYNC_1;
     SYNC_0;
     
     for(i=0;i<8;i++)
     {
      if((m&0x80)==0)
        {DAC8552_SEND_0();}
      else
        {DAC8552_SEND_1();}
      m<<=1;
     }
     
     for(i=0;i<8;i++)
     {
      if((a&0x80)==0)
       {DAC8552_SEND_0();}
      else
       {DAC8552_SEND_1();}
      a<<=1;
     }
     
     for(i=0;i<8;i++)
     {
      if((b&0x80)==0)
       {DAC8552_SEND_0();}
      else
       {DAC8552_SEND_1();}
      b<<=1;
     }
     //DAC8552_delay1ms(100);
     SYNC_1;
}

测试例程

#include "stm32f10x.h"
#include "DAC8552.h"

int main(void)
{
	SystemInit();

	//DAC8552初始化代码开始
	DAC8552_RCC_Configuration();
	DAC8552_GPIO_Configuration();
	
	while (1)
	{
		DAC8552_Out_Put_Voltage();
	}
}

####

IO模拟SPI波形

void DAC_8551(unsigned int date)
{
	unsigned char i,flag;
	unsigned int flag_data;
	unsigned char temp=0x00;//写模式
	SYNC_0;
	delay_us(1);
	for(i=0;i<8;i++)
	{
		SCLK_1;
		flag=temp&0x80;
		if(flag==0x80)//写数据
			DIN_1;
			else
			DIN_0;
			temp=temp<<1;
			delay_us(1);
			SCLK_0;
			delay_us(1);
	}
 DAC16位数据转换///
 	for(i=0;i<16;i++)
	{
		SCLK_1;
		flag_data=date&0x8000;
		if(flag_data==0x8000)
			DIN_1;
			else
			DIN_0;
			date=date<<1;
			delay_us(1);
			SCLK_0;
			delay_us(1);
	}
	
	 SYNC_1;
	 //delay_us(50);

	 //DIN_1;
}

示波器波形图片

DAC_8551(16000);

黄色DIN,蓝色CLK
请添加图片描述黄色DIN,蓝色SYNC
请添加图片描述
波形正确,但是硬件IO不出电压信息。

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值