因项目需要通过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
#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)
#define No_Impedance 0x00
#define Low_Impedance 0x01
#define Middle_Impedance 0x02
#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;
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);
}
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--);
}
void DAC8552_SEND_0(void)
{
DIN_0;
SCLK_1;
SCLK_0;
}
void DAC8552_SEND_1(void)
{
DIN_1;
SCLK_1;
SCLK_0;
}
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;
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;
}
SYNC_1;
}
测试例程
#include "stm32f10x.h"
#include "DAC8552.h"
int main(void)
{
SystemInit();
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);
}
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;
}
示波器波形图片
DAC_8551(16000);
黄色DIN,蓝色CLK 黄色DIN,蓝色SYNC 波形正确,但是硬件IO不出电压信息。
|