前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >(28)STM32——DAC数模转换笔记

(28)STM32——DAC数模转换笔记

作者头像
小点点
发布2022-12-12 14:55:41
7000
发布2022-12-12 14:55:41
举报
文章被收录于专栏:小点点

目录

学习目标

成果展示 

介绍

特点

框图

数据格式

触发选择

寄存器

硬件 

配置

代码 

总结 


学习目标

        本节学习的是有关DAC的知识点,主要进行的是数字信号到模拟信号的转换,内容其实和我们之前学51的时候是类似的,在此就不做过多介绍,如果对AD/ DA有不太了解的同学还是建议先去看一下51的AD/DA转换。

成果展示 

https://live.csdn.net/v/embed/233690

DAC

介绍

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

特点

  • 2 个 DAC 转换器:每个转换器对应 1 个输出通道
  • 8 位或者 12 位单调输出
  • 12 位模式下数据左对齐或者右对齐
  • 同步更新功能
  • 噪声波形生成
  • 三角波形生成
  • 双 DAC 通道同时或者分别转换
  • 每个通道都有 DMA 功能

框图

        图中 VDDA 和 VSSA 为 DAC 模块模拟部分的供电,而 Vref+则是 DAC 模块的参考电 压。DAC_OUTx 就是 DAC 的输出通道了(对应 PA4 或者 PA5 引脚)。 值得我们注意的是,如果我们想要写入东西到DOR中去,则必须通过DHR寄存器来写入,所以这样会有一个延迟,时间大概是3个时钟周期。

数据格式

  • 8位数据右对齐:用户将数据写入DAC_DHR8Rx[7:0]位(实际存入DHRx[11:4]位)。  
  • 12 位数据左对齐:用户将数据写入 DAC_DHR12Lx[15:4]位(实际存入 DHRx[11:0] 位)。
  • 12 位数据右对齐:用户将数据写入 DAC_DHR12Rx[11:0]位(实际存入 DHRx[11:0] 位)。

 触发选择

        这个是选择触发源,我们本实验使用的是软件触发。 

寄存器

        和之前一样,手册都有,我就不再赘述了。

硬件 

        我们需要注意的是,DAC模块是连接到PA4引脚上的,所以我们到时候需要使能相应的GPIO,还有,本实验同时使用ADC,DAC 模块,所以还需要使用跳线帽连接ADC和DAC模块,让DAC的模拟输出作为ADC的模拟输入。

配置

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

代码语言:javascript
复制
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能 GPIOA 时钟
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化

2、使能 DAC1 时钟。

代码语言:javascript
复制
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能 DAC 时钟

3、初始化 DAC,设置 DAC 的工作模式。

代码语言:javascript
复制
 void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct);

4、使能 DAC 转换通道。

代码语言:javascript
复制
 DAC_Cmd(DAC_Channel_1, ENABLE); //使能 DAC 通道 1

5、设置 DAC 的输出值。

代码语言:javascript
复制
  DAC_SetChannel1Data(DAC_Align_12b_R, 0); //12 位右对齐数据格式设置 DAC 值
 

代码 

代码语言:javascript
复制
#include "dac.h"
 

//DAC通道1输出初始化
void Dac1_Init(void)
{  
	GPIO_InitTypeDef  GPIO_InitStructure;
	DAC_InitTypeDef  DAC_InitType;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC时钟
	   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化

	DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
	DAC_InitType.DAC_OutputBuffer = DAC_OutputBuffer_Disable; //DAC1输出缓存关闭 
	DAC_InitType.DAC_Trigger = DAC_Trigger_None;//不使用触发功能
	DAC_InitType.DAC_WaveGeneration = DAC_WaveGeneration_None;//不使用波形发生
	DAC_Init(DAC_Channel_1,&DAC_InitType);	 //初始化DAC通道1

	DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC通道1
  
	DAC_SetChannel1Data(DAC_Align_12b_R, 0);  //12位右对齐数据格式设置DAC值
}

代码语言:javascript
复制
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "adc.h"
#include "dac.h"
#include "key.h"

int main(void)
{ 
	u16 adcx;
	float temp;
 	u8 t=0;	 
	u16 dacval=0;
	u8 key;	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);      //初始化延时函数
	uart_init(115200);		//初始化串口波特率为115200	
	LED_Init();					//初始化LED 
	Adc_Init(); 				//adc初始化
	KEY_Init(); 				//按键初始化
	Dac1_Init();		 		//DAC通道1初始化		     	 	
  DAC_SetChannel1Data(DAC_Align_12b_R,dacval);//初始值为0	
	while(1)
	{
		t++;
		key=KEY_Scan(1);			  
		if(key==WKUP_PRES)
		{		 
			if(dacval<4000)dacval+=200;
			DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//设置DAC值
		}else if(key==KEY1_PRES)	
		{
			if(dacval>200)dacval-=200;
			else dacval=0;
			DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//设置DAC值
		}	 
		if(t==100||key==KEY1_PRES||key==WKUP_PRES) 	//WKUP/KEY1按下了,或者定时时间到了
		{	  
 			adcx=DAC_GetDataOutputValue(DAC_Channel_1);//读取前面设置DAC的值
			printf ("DAC VAL:%d",adcx);	  //显示DAC寄存器值    
			printf ("\r\n\r\n");			
			temp=(float)adcx*(3.3/4096);			         //得到DAC电压值
			adcx=temp;
 			printf("DAC VOL:%fV",temp);	      	   //显示电压值
			printf ("\r\n\r\n");
 			adcx=Get_Adc_Average(ADC_Channel_5,10);		//得到ADC转换值	  
			temp=(float)adcx*(3.3/4096);			        //得到ADC电压值
			adcx=temp;
 			printf("ADC VOL:%fV",temp);     	  //显示电压值
			printf ("\r\n\r\n");
			LED0=!LED0;	   
			t=0;
		}	    
		delay_ms(10);	 
	}	
}

总结 

        本节DAC的基础知识就先介绍到这,后期还会对代码进行修改以及调试,继续探索一下AD/DA的功能,好了,谢谢大家的观看。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 学习目标
  • 成果展示 
  • 介绍
    • 特点
      • 框图
        • 数据格式
          • 寄存器
            • 硬件 
              • 配置
              • 代码 
              • 总结 
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档