因项目需要通过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 支持四种独立的操作模式。 这些模式可通过设置控制寄存器中的两个位(PD1
和 PD0
)进行编程。 表 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不出电压信息。