首页 > 代码库 > cortex_m3_stm32嵌入式学习笔记(十八):DAC实验(数模转换)

cortex_m3_stm32嵌入式学习笔记(十八):DAC实验(数模转换)

STM32 的 DAC 模块(数字/模拟转换模块)是 12 位数字输入,电压输出型的 DAC。 DAC可以配置为 8 位或 12 位模式,也可以与 DMA 控制器配合使用。 DAC 工作在 12 位模式时,数据可以设置成左对齐或右对齐。 DAC 模块有 2 个输出通道,每个通道都有单独的转换器。在双 DAC 模式下, 2 个通道可以独立地进行转换,也可以同时进行转换并同步地更新 2 个通道的输出。

本节实验,我们将利用按键(或 USMART) 控制 STM32 内部 DAC1来输出电压,通过 ADC1的通道1 采集 DAC的输出电压,在 LCD 模块上面显示 ADC 获取到的电压值以及 DAC 的设定输出电压值等信息。

STM32 的 DAC 模块主要特点有:
① 2 个 DAC 转换器:每个转换器对应 1 个输出通道
② 8 位或者 12 位单调输出
③ 12 位模式下数据左对齐或者右对齐
④ 同步更新功能
⑤ 噪声波形生成
⑥ 三角波形生成
⑦ 双 DAC 通道同时或者分别转换
⑧ 每个通道都有 DMA 功能


当 DAC 的参考电压为 Vref+的时候(对 STM32F103RC 来说就是 3.3V), DAC 的输出电压是线性的从 0~Vref+, 12 位模式下 DAC 输出电压与 Vref+以及 DORx 的计算公式如下:
                  DACx 输出电压=Vref*( DORx/4095)

我的ADC和DAC的理解是:

ADC可以采集电压把电压转换为数字,DAC可以把数字转换为电压的形式并输出


配置步骤:

1)开启PA 口时钟,设置PA4 为模拟输入。

STM32F103RCT6 的 DAC 通道 1 在 PA4 上,所以,我们先要使能 PORTA 的时钟,然后设置 PA4 为模拟输入。 DAC 本身是输出,但是为什么端口要设置为模拟输入模式呢?因为一但使能 DACx 通道之后,相应的 GPIO 引脚( PA4 或者 PA5)会自动与 DAC 的模拟输出相连,设置为输入,是为了避免额外的干扰。
2)使能DAC1 时钟。
3) 初始化DAC,设置DAC 的工作模式。
4) 使能DAC 转换通道
5) 设置DAC 的输出值

dac.c
#include "dac.h"
void Dac1_Init(void)
{
	GPIO_InitTypeDef GPIO_ist;
	DAC_InitTypeDef DAC_ist;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );//使能 PA 时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE ); //使能 DAC 时钟
	GPIO_ist.GPIO_Pin=GPIO_Pin_4;
	GPIO_ist.GPIO_Mode=GPIO_Mode_AIN;//模拟输入
	GPIO_ist.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_ist);
	GPIO_SetBits(GPIOA,GPIO_Pin_4);//PA.4 输出高
	
	DAC_ist.DAC_Trigger=DAC_Trigger_None; //不使用触发功能
	DAC_ist.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
	DAC_ist.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;
	DAC_ist.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;//关DAC1输出缓存
	DAC_Init(DAC_Channel_1,&DAC_ist);  //初始化 DAC 通道 1
	
	DAC_Cmd(DAC_Channel_1,ENABLE);//使能 DAC1
	DAC_SetChannel1Data(DAC_Align_12b_R,0);//12位右对齐,设置DAC初始值
}

//设置通道 1 输出电压
//vol:0~3300,代表 0~3.3V
void Dac1_Set_Vol(u16 vol)
{
	float temp=vol;
	temp/=1000;
	temp=temp*4096/3.3;
	DAC_SetChannel1Data(DAC_Align_12b_R,temp);//12位右对齐设置DAC值
}
u16 Dac1_Get_Vol(void)
{
	return DAC_GetDataOutputValue(DAC_Channel_1);
}


dac.h
#ifndef _DAC_H
#define _DAC_H
#include "sys.h"
void Dac1_Init(void);
u16 Dac1_Get_Vol(void);
void Dac1_Set_Vol(u16 vol);
#endif

主函数。。通过按键来调节DAC输出电压的强度,WKUP增强,KEY0减弱(也可以通过USMART组件设置)
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "adc.h"
#include "dac.h"
#include "key.h"
void init()
{
	delay_init();	    	 //延时函数初始化	  
	uart_init(9600);	 	//串口初始化为9600
	LED_Init();		  		//初始化与LED连接的硬件接口
 	LCD_Init();
	KEY_Init();
	Adc_Init();
	Dac1_Init();
	
	POINT_COLOR=RED;//设置字体为红色
	LCD_ShowString(60,40,200,24,24,"DAC Test ^-^");
	LCD_ShowString(60,70,200,16,16,"Bigggg difficulty");
	LCD_ShowString(60,90,200,16,16,"2015/1/25");
	LCD_ShowString(60,110,200,16,16,"By--Mr yh");
	LCD_ShowString(60,130,200,16,16,"WK_UP:+ KEY0:-");
	//显示提示信息
	POINT_COLOR=BLUE;//设置字体为蓝色
	LCD_ShowString(60,150,200,16,16,"DAC VAL:");
	LCD_ShowString(60,170,200,16,16,"DAC VOL:0.000V"); 
	LCD_ShowString(60,190,200,16,16,"ADC VOL:0.000V");
	Dac1_Set_Vol(330);
}
int main(void)
{
	
	u16  adcnum=0;
	u16 dacnum=0;
	float tem;
	u8 key,t=0;
	init();
	while(1)
	{
		t++;
		key=KEY_Scan(0);
		if(key==WK_UP_PRES)
		{
			if(dacnum<4000)dacnum+=200;
			DAC_SetChannel1Data(DAC_Align_12b_R,dacnum);
		}
		else if(key==KEY0_PRES)
		{
			if(dacnum>200)dacnum-=200;
			else dacnum=0;
			DAC_SetChannel1Data(DAC_Align_12b_R,dacnum);
		}
		
		if(t==10||key==WK_UP_PRES||key==KEY0_PRES)
		{
			adcnum=Dac1_Get_Vol();dacnum=adcnum;
			LCD_ShowxNum(124,150,adcnum,4,16,0);//显示DAC寄存器值
			tem=(float)adcnum*(3.3/4096); //得到DAC电压值
			adcnum=tem;
			LCD_ShowxNum(124,170,tem,1,16,0);//显示电压值整数部分
			tem-=adcnum;tem*=1000;
			LCD_ShowxNum(140,170,tem,3,16,0X80);//显示电压值的小数部分
			adcnum=Get_Adc_Average(ADC_Channel_1,10);
			tem=(float)adcnum*(3.3/4096);
			adcnum=tem;
			LCD_ShowxNum(124,190,tem,1,16,0);
			tem-=adcnum;tem*=1000;
			LCD_ShowxNum(140,190,tem,3,16,0X80);
			t=0;
			LED0=!LED0;
		}
		delay_ms(10);
	}
}



最后在通过杜邦线将PA1和PA4连起来就好了。。至于为什么要连这两个口 看图

                                            技术分享

ADC1 和DAC1 分别挂在了 PA1和PA4上,所以我们想要通过ADC1采集DAC1输出的电压,就要将这两点连起来


cortex_m3_stm32嵌入式学习笔记(十八):DAC实验(数模转换)