0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于STM32F103驱动DAC1220 20位/16位DAC数模转换模块输出可调±10V基准和三角波信号

jf_88434166 来源:jf_88434166 2026-01-10 10:31 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

一、DAC1220模块简介

DAC1220是一款在一定温度范围内,能实现20位或16位线性转换的低功耗串行数模转换器。原理上利用Σ-△技术实现其线性特性,可软件配置为16位输入模式和20位输入模式。20位输入时,建立时间可在15ms内达到0.003%;16位输入时,建立时间最大可在2ms内达到0.012%。输出电压最大为外部参考电压的2倍, 片上自校准电路可动态减少失调和增益误差,最大输出线性误差仅为±0.0015%。DAC1220采用同步串行接口,单一转换系统只需2根信号线控制即可,多转换系统需要片选信号配合。采用单电源供电(+5V,cM0s结构保证其低功耗特性,具有低噪声线性误差小、温漂小等特点。DAC1220可用于工业控制高精度检测、测量系统。
特性

  • 供电电压:5V
  • 通讯协议:SPI串行
  • DAC分辨率位数:20位 / 16位,软件切换
  • 输出通道数:1个
  • 输出电压范围:±10V
  • 输出电压驱动能力:10mA
  • 基准电压:2.5V
  • 电压建立时间:16位:2ms,20位:15ms

应用场景

二、DAC1220模块接口说明

V+输入正
GND输入负
SCLK串行时钟输入
SDIO串行数据输入/输出
CS片选

三、功能框图和时序图分析说明

功能框图

时序图

DAC1220 的 SPI 不是标准 SPI,它是 SDIO 半双工 3 线接口,SDIO 既当 MOSI(输入) 又当 MISO(输出)。

Figure 9:CS 始终拉低时的写入/读取时序(不使用 CS)
寄存器数据:SDIO = 输入模式,每个字节按 bit7→bit0 依次从 SDIO 写入,在 SCLK 上升沿采样。
读寄存器数据:SDIO 在读阶段变成输出,SDIO 输出 OUTM(MSB)、OUT1...OUT0,MCU 在 SCLK 上升沿读取。

Figure 10:使用 CS 的时序
CS 拉低开始通信,SCLK 工作期间保持 CS 低,CS 拉高结束通信,这个版本更像“普通 SPI”,更好实现。

Figure 11:SDIO 从输入到输出切换时序
MCU 必须在切换期间把 SDIO 设置为:写阶段:SDIO = 输出,读阶段:SDIO = 输入,否则会导致总线冲突 → 芯片损坏风险。

四、主要寄存器说明

DAC1220 中有四个寄存器,命令寄存器(CMR)、数据输入寄存器(DIR)、偏移校准寄存器(OCR)、满量程校准寄存器(FCR)。每个读/写命令由 1 字节命令 + N 字节数据 组成。
命令字节格式:R/W (bit7), MB(bits6–5: 表示要读/写 1/2/3 字节), ADR(bits3–0: 起始寄存器地址)。也就是说可以读/写寄存器映射中的连续字节(如写 DIR 的 3 个字节或读 OCR 的 3 字节),下图为命令字格式和起始寄存器地址。


命令寄存器(CMR):用于配置工作模式,分辨率选择,滤波等参数。写入后在最后一个 SCLK 的下降沿生效。


数据输入寄存器(DIR):决定正常模式下的输出电压。在睡眠模式下,写入此寄存器不会影响输出,但其值会被存储。进入正常模式后,DIR中的值立即生效。复位后,DIR的值将为零。

偏移校准寄存器(OCR)和满量程校准寄存器(FCR):
偏移校准寄存器包含一个 24 位二进制补码值。在 DAC 转换之前,该值会加到 DIR 寄存器中的值上。在睡眠模式下,写入此寄存器不会影响输出,但该值会被存储。进入正常模式后,OCR 中的值立即生效。复位后,OCR 的值为零。
满量程校准寄存器存储增益校准常数。在 DAC 转换之前,DIR 寄存器的内容会乘以该值进行调整。在睡眠模式下,写入此寄存器不会影响输出,但该值会被存储。进入正常模式后,FCR 中的值立即生效。

五、STM32F103驱动DAC1220数模转换

准备工作

STM32F103C8T6开发板,DAC1220数模转换模块,OLED屏幕。

接线说明

STM32F103C8T6DAC1220
5VV+
GNDGND
PA0SCLK
PA1SDIO
PA2CS
PB8OLED->SCL
PB9OLED->SDA

代码示例

dac1220.c

#include "DAC1220.h"

u32 TriangleWave_Value[256]={
0 ,8192 , 16384 , 24576 , 32768 , 40960 , 49152 , 57344 , 65536 , 73728 , 81920 , 90112 , 98304 , 106496 , 
	114688 , 122880 , 131072 , 139264 , 147456 , 155648 , 163840 , 172032 , 180224 , 188416 , 196608 , 204800 , 
	212992 , 221184 , 229376 , 237568 , 245760 , 253952 , 262144 , 270336 , 278528 , 286720 , 294912 , 303104 , 
	311296 , 319488 , 327680 , 335872 , 344064 , 352256 , 360448 , 368640 , 376832 , 385024 , 393216 , 401408 , 
	409600 , 417792 , 425984 , 434176 , 442368 , 450560 , 458752 , 466944 , 475136 , 483328 , 491520 , 499712 , 
	507904 , 516096 , 524288 , 532480 , 540672 , 548864 , 557056 , 565248 , 573440 , 581632 , 589824 , 598016 , 
	606208 , 614400 , 622592 , 630784 , 638976 , 647168 , 655360 , 663552 , 671744 , 679936 , 688128 , 696320 , 
	704512 , 712704 , 720896 , 729088 , 737280 , 745472 , 753664 , 761856 , 770048 , 778240 , 786432 , 794624 , 
	802816 , 811008 , 819200 , 827392 , 835584 , 843776 , 851968 , 860160 , 868352 , 876544 , 884736 , 892928 , 
	901120 , 909312 , 917504 , 925696 , 933888 , 942080 , 950272 , 958464 , 966656 , 974848 , 983040 , 991232 , 
	999424 , 1007616 , 1015808 , 1024000 , 1032192 , 1040384 , 1048576 ,1040384 , 1032192 , 1024000 , 1015808 , 1007616 , 
	999424 , 991232 , 983040 , 974848 , 966656 , 958464 , 950272 , 942080 , 933888 , 925696 , 917504 , 909312 , 901120 , 892928 , 
	884736 , 876544 , 868352 , 860160 , 851968 , 843776 , 835584 , 827392 , 819200 , 811008 , 802816 , 794624 , 786432 , 778240 , 
	770048 , 761856 , 753664 , 745472 , 737280 , 729088 , 720896 , 712704 , 704512 , 696320 , 688128 , 679936 , 671744 , 663552 , 
	655360 , 647168 , 638976 , 630784 , 622592 , 614400 , 606208 , 598016 , 589824 , 581632 , 573440 , 565248 , 557056 , 548864 , 
	540672 , 532480 , 524288 , 516096 , 507904 , 499712 , 491520 , 483328 , 475136 , 466944 , 458752 , 450560 , 442368 , 434176 , 
	425984 , 417792 , 409600 , 401408 , 393216 , 385024 , 376832 , 368640 , 360448 , 352256 , 344064 , 335872 , 327680 , 319488 , 
	311296 , 303104 , 294912 , 286720 , 278528 , 270336 , 262144 , 253952 , 245760 , 237568 , 229376 , 221184 , 212992 , 204800 , 
	196608 , 188416 , 180224 , 172032 , 163840 , 155648 , 147456 , 139264 , 131072 , 122880 , 114688 , 106496 , 98304 , 90112 , 
	81920 , 73728 , 65536 , 57344 , 49152 , 40960 , 32768 , 24576 , 16384 , 8192
};

void DAC1220_IO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(	DAC_SCL_CLK|DAC_SDA_CLK|DAC_CS_CLK|RCC_APB2Periph_AFIO, ENABLE );	
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

	GPIO_InitStructure.GPIO_Pin = DAC_SCL_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DAC_SCL_PORT, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = DAC_SDA_PIN;
	GPIO_Init(DAC_SDA_PORT, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = DAC_CS_PIN;
	GPIO_Init(DAC_CS_PORT, &GPIO_InitStructure);
	
	DAC_CS = 0;
}

void SDA_OUT(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = DAC_SDA_PIN;	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DAC_SDA_PORT, &GPIO_InitStructure);
}

void SDA_IN(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = DAC_SDA_PIN; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_Init(DAC_SDA_PORT, &GPIO_InitStructure);
}

void DAC1220_Write_Byte(uint8_t out_data)
{
	uint8_t index;
	SDA_OUT();
	DAC_SCLK=0;
	DAC_SDIO=0;
	for(index=0;index< 8;index++)
	{
		delay_us(5);
		DAC_SCLK=1;
		if((out_data&0x80)==0x80)
		{
			DAC_SDIO=1;
		}
		else
		{
			DAC_SDIO=0;
		}
		out_data=out_data< < 1;		//数据移位
		delay_us(5);
		DAC_SCLK=0;		//锁存数据
	}
}
uint8_t DAC1220_Read_Byte(void)
{
	uint8_t data=0,index=0;
	SDA_IN();
	DAC_SCLK=0;
	for(index=0;index< 8;index++)
	{
		delay_us(5);
		DAC_SCLK=1;
		data< <=1;
		if(R_DAC_SDIO)
			data++;
		delay_us(5);
		DAC_SCLK=0;		//锁存数据
	}
	delay_us(5);
	return data;
}


/*复位DA*/
void DAC1220_Reset(void)
{
	DAC_SCLK = 0;
	delay_us(10);
	
//****//
//SCLK复位模式
//DAC1220没有专用的复位引脚。
//相反,它包含一个等待特殊模式出现在SCLK上的电路,并在检测到特殊模式时触发内部硬件复位线。
//此模式称为SCLK重置模式。
//这种模式与SCLK上通常出现的时钟模式有很大的不同,在正常工作时不太可能被意外检测到。CS低有效
//详见DAC1220.PDF:页11:Table 5. Reset Timing Characteristics
	DAC_SCLK = 1;
	delay_us(600*TXIN);
	DAC_SCLK = 0;
	delay_us(20*TXIN);
	DAC_SCLK = 1;
	delay_us(1100*TXIN);
	DAC_SCLK = 0;
	delay_us(20*TXIN);
	DAC_SCLK = 1;
	delay_us(2100*TXIN);
	DAC_SCLK = 0;
//****//
	delay_us(10);
}

void DAC1220_Init(void)
{
	uint8_t command;			//缓存命令字节
	DAC1220_IO_Init();
	DAC1220_Reset();
	DAC1220_Self_Calibration();//自校准
	command=0x04;
	DAC1220_Write_Byte(command);
	delay_us(10);
	DAC1220_Write_Byte(0x00);
	delay_us(10);
	command=0x05;
	DAC1220_Write_Byte(command);
	delay_us(10);
	DAC1220_Write_Byte(0xA0);	//配置成正常20位模式,(直接二进制)Straight binary
	delay_us(10);
	
}

void DAC1220_WDAT(uint32_t dat)
{
	uint8_t command;

	if(dat > 1048575)
		dat = 1048575;
	dat = dat< < 4;
	
	delay_us(10);
	command=0x00;		//DIR高字节
	DAC1220_Write_Byte(command);
	delay_us(10);
	command=(dat >>16)&0X00FF;			//写DIR高位数据
	DAC1220_Write_Byte(command);
	delay_us(10);

	command=0x01;		//写中位数据
	DAC1220_Write_Byte(command);
	delay_us(10);
	command=(dat >>8)&0X00FF;
	DAC1220_Write_Byte(command);
	delay_us(10);

	command=0x02;		//写低位数据
	DAC1220_Write_Byte(command);
	delay_us(10);
	command=(dat >>0)&0X00FF;
	DAC1220_Write_Byte(command);
	delay_us(10);

}

void DAC1220_Self_Calibration(void) //自校准
{
	DAC1220_Write_Byte(0x04);//写命令 寄存器高字节
	delay_us(10);
	DAC1220_Write_Byte(0x00);//校准期间输出将断开
	delay_us(10);
	DAC1220_Write_Byte(0x05);//写命令 寄存器低字节
	delay_us(10);
	DAC1220_Write_Byte(0xA1);	//配置成20位模式,(直接二进制)Straight binary  校准模式
	delay_ms(600); //等待校准
	
	DAC1220_Write_Byte(0x85);//读命令 寄存器低字节
	delay_us(10);
	while((DAC1220_Read_Byte()&0x03)!=0) //检测校准是否完成
	{
		delay_ms(500);
	}
	
}
void DAC1220VolWrite(float v)
{
	uint32_t dacData;
	dacData=mapfloat(v,-10.0,10.0,0,1048575);
	DAC1220_WDAT(dacData);
}


/*
************************************************************
*	函数名称:	mapfloat
*
*	函数功能:	将一个区间内的值,映射到另一个区间
*
*	入口参数:	x输入值、
*						in_min输入最小值,
*						in_max输入最大值,
*						out_min输出最小值,
*						out_max输出最大值。
*	返回参数:	映射后的值
*	说明:	
************************************************************/
uint32_t mapfloat(float x, float in_min, float in_max, uint32_t out_min, uint32_t out_max)
{
	uint32_t out;
	out=(x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;

 return out;
  
}

main.c

#include "stm32_config.h"
#include "stdio.h"
#include "DAC1220.h"
#include "timer.h"
#include "oled.h"
#include "key.h"

uint8_t Num;
int32_t Vol = 1000;
uint16_t dacValue = 0;

int main(void)
{

	MY_NVIC_PriorityGroup_Config(NVIC_PriorityGroup_2);	//设置中断分组
	delay_init(72);	//初始化延时函数
	OLED_Init();
	Key_Init();
	Timer_Init();
	
	DAC1220_Init();
	delay_ms(100);
	
	OLED_ShowString(1,5,"DAC1220");
	
	while(1)
	{
		//电压输出
		Vol += Key_GetNum();
		OLED_ShowSignedNum(2,1,Vol,5);
		
		DAC1220VolWrite((float)Vol/1000);

		
		//三角波输出
//		DAC1220_WDAT(TriangleWave_Value[dacValue]);
//		dacValue++;
//		if(dacValue >= 256) dacValue = 0;
	}
}

void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		Num++;
		if(Num > 20)
		{
			Key_Loop();
			Num = 0;
		}
		
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

效果展示


六、注意事项与常见问题

注意事项:

  1. 模块供电电源不超过5.5V。
  2. 由于模块是高精度器件,为了避免不必要的干扰,建议 使用线性电源供电。
  3. 输出信号线建议使用SMA对应接口。接口不匹配容易导致接触不良,劣质的线材可能导致信号衰减或者噪声过大。
  4. 如需简单测试模块功能,建议搭配本店控制板使用,正确接线后给控制板供电即可实现模拟电压输出。

常见问题:

Q: 模块输出电压是多少?输出电压的驱动能力是多少?
A: 目前模块的电路能输出±10V,驱动能力10mA以内。

Q: 用电压表测试电压正常,接上负载后电压降低是什么情况?
A: 由于模块只有10mA的驱动能力,当负载功率大时,输出电压就会被拉低。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • dac
    dac
    +关注

    关注

    44

    文章

    2860

    浏览量

    197869
  • 数模转换器
    +关注

    关注

    14

    文章

    1603

    浏览量

    86217
  • STM32F103
    +关注

    关注

    34

    文章

    501

    浏览量

    68462
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    DAC1220受干扰损坏怎么解决?

    使用DAC1220作为基准源,在我公司一台高压脉冲电源上工作,50kV电压通过闸流管放电产生4us的电压和电流脉冲,因此地线存在较大干扰。整个DAC输出电平上都会叠加一个高频振荡,在
    发表于 01-14 07:18

    为什么STM32F103 DA设置输出三角输出没反应?

    STM32F103 DA设置输出三角输出没反应不知道哪里设置错了。
    发表于 08-09 00:10

    基于AT32F403的DAC基础配置(STM32F103类似)

    基于AT32F403的DAC基础配置(STM32F103类似):AT32的DAC有两个独立通道,每个通道可以分别产生稳定电平,三角
    发表于 12-14 19:40

    如何用STM32F103DAC输出一个周期2khz的正弦

    什么是DAC数模转换器?DAC数模转换器是由哪些部分组成的?如何用STM32F103DAC
    发表于 11-15 06:27

    如何使用STM32F103DAC输出周期为2khz的正弦

    STM32F103DAC模块功能有哪些?如何使用STM32F103DAC输出周期为2khz的
    发表于 11-15 07:47

    DAC数模转换器的主要特点有哪些

    DAC:数模转换器,即将数字量(数字123)转化为模拟量(电压值1v2v3v)。STM32DAC模块
    发表于 01-11 07:01

    16电压输出数模转换DAC7644

    16电压输出数模转换DAC7644
    发表于 04-30 17:28 39次下载

    DAC1020和DAC1220数模转换器为电路提供优良的温度和跟踪特性的概述

    DAC1020和DAC1220分别是10和12二进制乘法数模转换器。沉积薄膜R2R电阻梯形划
    发表于 05-16 16:29 11次下载
    <b class='flag-5'>DAC</b>1020和<b class='flag-5'>DAC1220</b><b class='flag-5'>数模转换</b>器为电路提供优良的温度和跟踪特性的概述

    STM32_ DAC输出三角波形

    STM32_DAC输出三角波形
    的头像 发表于 04-08 10:56 9863次阅读
    <b class='flag-5'>STM32</b>_ <b class='flag-5'>DAC</b><b class='flag-5'>输出</b><b class='flag-5'>三角</b>波形

    基于STM32f103使用的DAC正弦

    基于STM32f103使用的DAC正弦
    发表于 08-02 10:05 118次下载

    DAC数模转换模块)-STM32F103

    注意本文章内容只适用于大容量的STM32F101xx和STM32F103xx产品。DAC 简介(数模转换)数字/模拟
    发表于 11-16 15:36 49次下载
    <b class='flag-5'>DAC</b>(<b class='flag-5'>数模</b><b class='flag-5'>转换</b><b class='flag-5'>模块</b>)-<b class='flag-5'>STM32F103</b>

    基于STM32F103DAC8411驱动程序

    基于STM32F103DAC8411驱动程序,亲测可用,欢迎大家一起交流
    发表于 08-28 11:21 26次下载

    DAC1220一款20位数模(D/A)转换器数据表

    电子发烧友网站提供《DAC1220一款20位数模(D/A)转换器数据表.pdf》资料免费下载
    发表于 07-26 09:11 2次下载
    <b class='flag-5'>DAC1220</b>一款<b class='flag-5'>20</b><b class='flag-5'>位数模</b>(D/A)<b class='flag-5'>转换</b>器数据表

    DAC80516 十六通道 16 电压输出数模转换器(DAC)产品文档总结

    16DAC80516是一款低功耗、16通道、缓冲电压输出数模转换器(
    的头像 发表于 10-23 15:58 1231次阅读
    <b class='flag-5'>DAC</b>80516 十六通道 <b class='flag-5'>16</b> <b class='flag-5'>位</b>电压<b class='flag-5'>输出</b><b class='flag-5'>数模转换</b>器(<b class='flag-5'>DAC</b>)产品文档总结

    深入解析DAC122020低功耗数模转换器的卓越性能与应用

      在电子工程师的设计世界里,数模转换器(DAC)是连接数字世界和模拟世界的重要桥梁。今天,我们要深入探讨一款性能卓越的20低功耗数模转换
    的头像 发表于 12-09 14:34 1111次阅读
    深入解析<b class='flag-5'>DAC1220</b>:<b class='flag-5'>20</b><b class='flag-5'>位</b>低功耗<b class='flag-5'>数模转换</b>器的卓越性能与应用