数模转换器DAC60004初级编程

DAC60004是德州仪器品牌的一款数模转换器,可以将数字量转换为模拟量。

产品的数据手册讲解可以看下面的链接,讲述的比较清楚了

基于FPGA驱动DAC6004_dac ldac解释-CSDN博客

以下是本人使用STM32F407标准固件库开发的程序,亲测有效

本实例中,DAC60004是接到SPI2通讯的,所以,需要编写SPI2的功能代码,如下:

SPI2.c

#include "SPI2.h"

//SPI2	MOSI	PB15	复用推挽输出
//SPI2	MISO	PB14	推挽输出
//SPI2	CLK		PB13	复用推挽输出
//SPI2	CS		PG12	对应的DAC60004的SYNC引脚

//启动SPI2,片选线CS,也就是DAC60004的SYNC引脚,SYNC引脚拉低,开启功能,输入的数字才有效
void SPI2_Start(void)
{
	GPIO_ResetBits(GPIOG,GPIO_Pin_12);
}

//关闭SPI2,也就是拉高片选线CS,即DAC60004的SYNC
void SPI2_Stop(void)
{
	GPIO_SetBits(GPIOG,GPIO_Pin_12);
}

void SPI2_Init(void)
{
	//开启GPIO和SPI2的时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOG,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
	
	//初始化GPIO引脚,PB13,PB15分别对应CLK和MOSI,需要设置为复用推挽输出
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	//复用引脚为SPI2
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2);
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2);
	
	//配置引脚PB14为推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	//配置引脚PG12(对应片选引脚)为上拉输出
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOG,&GPIO_InitStructure);
	
	//配置SPI2,其中CPHA的值必须为1,也就是SPI_CPHA_2Edge
	//DAC60004的最大传输速率为50MHz,而SPI2挂载在APB1总线,对应频率为42MHz
	SPI_InitTypeDef SPI_InitStructure;
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
	SPI_InitStructure.SPI_CRCPolynomial = 7;
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	SPI_Init(SPI2,&SPI_InitStructure);
	
	SPI_Cmd(SPI2,ENABLE);
	SPI2_Stop();		//初始化的时候,就要拉高片选线,对应DAC60004的SYNC
}

//交换一个字节的函数
uint8_t SPI2_SwapByte(uint8_t SPI2_Send)
{
	uint8_t SPI2_Recv = 0;
	//发送一个字节
	while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE) != SET);
	SPI_SendData(SPI2,SPI2_Send);
	
	//接收一个字节
	while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) != SET);
	SPI2_Recv = SPI_I2S_ReceiveData(SPI2);
	
	return SPI2_Recv;
}

SPI2.h

#ifndef __SPI2_H
#define __SPI2_H

#include "stm32f4xx.h"                  // Device header

void SPI2_Start(void);
void SPI2_Stop(void);
void SPI2_Init(void);
uint8_t SPI2_SwapByte(uint8_t SPI2_Send);

#endif

DAC60004.c

#include "DAC6004.h"

/*
	SCLK	PB13	SPI2
	SDIN	PB15	SPI2
	SDO		PB14	SPI2
	SYNC	PG12	SPI2
	
	LDAC	PG15	DAC6004		LOAD
	CLR		PB3		DAC6004
*/

void LOAD_UP(void)
{
	GPIO_SetBits(GPIOG,GPIO_Pin_15);
}

void LOAD_Down(void)
{
	GPIO_ResetBits(GPIOG,GPIO_Pin_15);
}

void CLR_UP(void)
{
	GPIO_SetBits(GPIOB,GPIO_Pin_3);
}

void CLR_Down(void)
{
	GPIO_ResetBits(GPIOB,GPIO_Pin_3);
}

//DAC60004初始化函数
void Init_DAC6004(void)
{
	SPI2_Init();
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOG,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOG,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	LOAD_UP();							//LOAD —— LDAC引脚
	CLR_UP();							//LCR —— CLR引脚
}

//交换指令码
uint32_t Swap_DAC6004(uint32_t sendbuf)
{
	uint32_t Recv = 0;
	SPI2_Start();
	
	Recv = SPI2_SwapByte(sendbuf >> 24);
	Recv <<= 8;
	
	Recv |= SPI2_SwapByte(sendbuf >> 16);
	Recv <<= 8;
	
	Recv |= SPI2_SwapByte(sendbuf >> 8);
	Recv <<= 8;
	
	Recv |= SPI2_SwapByte(sendbuf);
	delay_us(5);
	
	SPI2_Stop();
	
	return Recv;
}

DAC60004.h

#ifndef __DAC6004_H
#define __DAC6004_H

#include "stm32f4xx.h"
#include "SPI2.h"
#include "delay.h"

void LOAD_UP(void);
void LOAD_Down(void);
void CLR_UP(void);
void CLR_Down(void);
void Init_DAC6004(void);
uint32_t Swap_DAC6004(uint32_t sendbuf);

#endif

主函数代码,main.c

#include "stm32f4xx.h"
#include "delay.h"
#include "SPI1.h"
#include "SPI2.h"
#include "DAC6004.h"

int main(void)
{
	Init_DAC6004();						//初始化DAC6004(包括SPI2)
	
	while (1)
	{
		LOAD_UP();
		
		//02:commands  F:所有通道		000:电压有效数位	0:无意义,DAC6004只有12位,读取不到这一位
		//最后一个0:Mode Bits
		Swap_DAC6004(0X02F00000);		//所以后通道的电压变为0
		delay_ms(5);
		LOAD_Down();					//更新输入的电压值,没有这一步,输出端的电压值不变
		delay_s(3);
		
		LOAD_UP();
		Swap_DAC6004(0X02FFFF00);		//所有通道的电压变为V ref(参考电压,REFIN电压)
		delay_ms(5);
		LOAD_Down();
		delay_s(3);
		
		LOAD_UP();
		Swap_DAC6004(0X02F00000);		//所有通道的电压变为0
		delay_ms(5);
		LOAD_Down();
		delay_s(3);
		
		LOAD_UP();
		Swap_DAC6004(0X020FFF00);		//通道a的电压变为V ref,其他通道的电压不变,仍然是0
		delay_ms(5);
		LOAD_Down();
		delay_s(3);
	}
}


/*
	REFIN端接5v时,通道a的输出电压值与数字对应说明:
	0x02000000		0V
	0x02010000		0.31V
	0x02020000		0.62V
	0x02030000		0.92V
	0x02040000		1.23V
	0x02050000		1.54V
	0x02060000		1.85V
	0x02070000		2.16V
	0x02080000		2.47V		FFF/2 = 7FF,即800,所以此处输出的电压值为REFIN的一半
	0x02090000		2.77V
	0x020A0000		3.08V
	0x020B0000		3.39V
	0x020C0000		3.70V
	0x020D0000		4.01V
	0x020E0000		4.32V
	0x020F0000		4.61V
	0x020FFF00		4.93V
	注:0~FFF相当于把5V的电压分成4096份,按照比例输出对应的电压
*/


  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值