36.DAC工作原理与配置

DAC工作原理与配置

参考资料
STM32FX开发板
《STM32FX开发指南-HAL库版本》-第X章 DAC实验
STM32FXxx官方资料:
《STM32FX中文参考手册》-第N章 数字模拟转换DAC

笔记基于正点原子官方视频
视频连接https://www.bilibili.com/video/BV1Wx411d7wT?p=71&spm_id_from=333.1007.top_right_bar_window_history.content.click
如有侵权,联系删除

一、 DAC工作原理

1.DAC简介

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

2.STM32的DAC模块主要特点

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

3.DAC模块方图

在这里插入图片描述

VDDA和VSSA为DAC模块模拟部分的供电。
Vref+则是DAC模块的参考电压。
DAC_OUTx就是DAC的输出通道了(对应PA4或者PA5引脚)。
在这里插入图片描述

4.DAC转换原理

在这里插入图片描述

5.DAC数据格式

在这里插入图片描述

6.DAC触发选择

在这里插入图片描述

7.DAC其他

在这里插入图片描述

二、DAC相关寄存器

1.DAC相关寄存器

里面内容参见《STM32FX中文参考手册》
在这里插入图片描述

2.DAC通道1相关寄存器
  • DAC控制寄存器 DAC_CR

  • DAC软件触发寄存器DAC_SWTRIGR

  • DAC通道1的12位右对齐数据保持寄存器DAC_DHR12R1

  • DAC通道1的12位左对齐数据保持寄存器DAC_DHR12L1

  • DAC通道1的8位右对齐数据保持寄存器DAC_DHR8R1

  • DAC通道1数据输出寄存器DAC_DOR1

3.DAC控制寄存器DAC_CR

在这里插入图片描述

4.DAC通道1的12位右对齐数据保持寄存器DAC_DHR12R1

在这里插入图片描述

5.DAC通道1的12位左对齐数据保持寄存器DAC_DHR12L1

在这里插入图片描述

6.DAC通道1的8位右对齐数据保持寄存器DAC_DHR8R1

在这里插入图片描述

7.DAC通道1数据输出寄存器DAC_DOR1

在这里插入图片描述

三、DAC硬件连接

在这里插入图片描述

四、DAC-HAL库函数配置

1.DAC相关HAL库函数
  • HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef* hdac);

  • void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac);

  • HAL_StatusTypeDef HAL_DAC_Start();

  • HAL_StatusTypeDef HAL_DAC_Stop();

  • HAL_StatusTypeDef HAL_DAC_ConfigChannel();

  • HAL_StatusTypeDef HAL_DAC_SetValue();

  • void HAL_DAC_IRQHandler(DAC_HandleTypeDef* hdac);

  • void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef* hdac);

  • void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef* hdac);

  • void HAL_DAC_ErrorCallbackCh1(DAC_HandleTypeDef *hdac);

  • void HAL_DAC_DMAUnderrunCallbackCh1(DAC_HandleTypeDef *hdac);

2.DAC配置步骤:

① 开启DAC和IO口时钟,设置输入引脚为模拟输入:
__HAL_RCC_DAC_CLK_ENABLE(); //使能DAC时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟

② 初始化DAC和通道参数 :
HAL_DAC_Init();
HAL_DAC_ConfigChannel();

③ 使能DAC转换通道:
HAL_DAC_Start();

④ 设置DAC输出值:
HAL_DAC_SetValue();

五、DAC配置实例

实现功能
通过按键控制一个数字变量,按键WK_UP每按一下数字自加200,按键 KEY1每按一下数字自减200
数值通过ADC输出,然后用DAC采集到输出的数字量并转化成模拟量电压(4096->3.3v)

1.引入DAC支持文件

在这里插入图片描述

2.开启DAC和IO口时钟,设置输入引脚为模拟输入:
__HAL_RCC_DAC_CLK_ENABLE(); //使能DAC时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟

在这里插入图片描述

//DAC底层驱动,时钟配置,引脚 配置
//此函数会被HAL_DAC_Init()调用
//hdac:DAC句柄
void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac)
{      
    GPIO_InitTypeDef GPIO_Initure;			//定义GPIO结构体
    __HAL_RCC_DAC_CLK_ENABLE();             //使能DAC时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();			//开启GPIOA时钟
	
    GPIO_Initure.Pin=GPIO_PIN_4;            //PA4
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟模式
    GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
}
3.初始化DAC和通道参数
HAL_DAC_Init();
HAL_DAC_ConfigChannel();

在这里插入图片描述

DAC_HandleTypeDef DAC1_Handler;//DAC句柄

//初始化DAC
void DAC1_Init(void)
{
    DAC_ChannelConfTypeDef DACCH1_Config;
    
    DAC1_Handler.Instance=DAC;
    HAL_DAC_Init(&DAC1_Handler);                						 //初始化DAC
    
    DACCH1_Config.DAC_Trigger=DAC_TRIGGER_NONE;             			//不使用触发功能
    DACCH1_Config.DAC_OutputBuffer=DAC_OUTPUTBUFFER_DISABLE;			//DAC1输出缓冲关闭
    HAL_DAC_ConfigChannel(&DAC1_Handler,&DACCH1_Config,DAC_CHANNEL_1);	//DAC通道1配置
    
    HAL_DAC_Start(&DAC1_Handler,DAC_CHANNEL_1);  						//开启DAC通道1
}
4.设置DAC输出值:
HAL_DAC_SetValue();

在这里插入图片描述

//设置通道1输出电压
//当数值为1000时,DAC输出1V
//vol:0~3300,代表0~3.3V
void DAC1_Set_Vol(u16 vol)
{
	double temp=vol;
	temp/=1000;		//temp=temp/1000;
	temp=temp*4096/3.3;
    HAL_DAC_SetValue(&DAC1_Handler,DAC_CHANNEL_1,DAC_ALIGN_12B_R,temp);//12位右对齐数据格式设置DAC值
}

到这里dac.c函数编写完毕,dac.c代码如下:

#include "dac.h"

DAC_HandleTypeDef DAC1_Handler;//DAC句柄

//初始化DAC
void DAC1_Init(void)
{
    DAC_ChannelConfTypeDef DACCH1_Config;
    
    DAC1_Handler.Instance=DAC;
    HAL_DAC_Init(&DAC1_Handler);                						 //初始化DAC
    
    DACCH1_Config.DAC_Trigger=DAC_TRIGGER_NONE;             			//不使用触发功能
    DACCH1_Config.DAC_OutputBuffer=DAC_OUTPUTBUFFER_DISABLE;			//DAC1输出缓冲关闭
    HAL_DAC_ConfigChannel(&DAC1_Handler,&DACCH1_Config,DAC_CHANNEL_1);	//DAC通道1配置
    
    HAL_DAC_Start(&DAC1_Handler,DAC_CHANNEL_1);  						//开启DAC通道1
}

//DAC底层驱动,时钟配置,引脚 配置
//此函数会被HAL_DAC_Init()调用
//hdac:DAC句柄
void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac)
{      
    GPIO_InitTypeDef GPIO_Initure;			//定义GPIO结构体
    __HAL_RCC_DAC_CLK_ENABLE();             //使能DAC时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();			//开启GPIOA时钟
	
    GPIO_Initure.Pin=GPIO_PIN_4;            //PA4
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟模式
    GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
}

//设置通道1输出电压
//当数值为1000时,DAC输出1V
//vol:0~3300,代表0~3.3V
void DAC1_Set_Vol(u16 vol)
{
	double temp=vol;
	temp/=1000;		//temp=temp/1000;
	temp=temp*4096/3.3;
    HAL_DAC_SetValue(&DAC1_Handler,DAC_CHANNEL_1,DAC_ALIGN_12B_R,temp);//12位右对齐数据格式设置DAC值
}

同时,dac.h代码如下:

#ifndef __DAC_H
#define __DAC_H
#include "sys.h"

extern DAC_HandleTypeDef DAC1_Handler;//DAC句柄

void DAC1_Init(void);
void DAC1_Set_Vol(u16 vol);		//当数值为1000时,DAC输出1V
#endif
5.main.c函数编写
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "lcd.h"
#include "sdram.h"
#include "usmart.h"
#include "adc.h"
#include "dac.h"
 
int main(void)
{
    u16 adcx;
	float temp;
 	u8 t=0;	 
	u16 dacval=0;
	u8 key;	
    HAL_Init();                     //初始化HAL库   
    Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz
    delay_init(180);                //初始化延时函数
    uart_init(115200);              //初始化USART
    usmart_dev.init(90); 		    //初始化USMART	
    LED_Init();                     //初始化LED 
    KEY_Init();                     //初始化按键
    SDRAM_Init();                   //初始化SDRAM
    LCD_Init();                     //初始化LCD
    MY_ADC_Init();                  //初始化ADC1
    DAC1_Init();                    //初始化DAC1
    
	POINT_COLOR=RED; 
	LCD_ShowString(30,50,200,16,16,"Apollo STM32F429");	
	LCD_ShowString(30,70,200,16,16,"DAC TEST");	
	LCD_ShowString(30,90,200,16,16,"Apollo Control By Wire");
	LCD_ShowString(30,110,200,16,16,"2022/4/2");	 
	LCD_ShowString(30,130,200,16,16,"WK_UP:+  KEY1:-");	 
	POINT_COLOR=BLUE;//设置字体为蓝色      	 
	LCD_ShowString(30,150,200,16,16,"DAC VAL:");	      
	LCD_ShowString(30,170,200,16,16,"DAC VOL:0.000V");	      
	LCD_ShowString(30,190,200,16,16,"ADC VOL:0.000V"); 	
    
    HAL_DAC_SetValue(&DAC1_Handler,DAC_CHANNEL_1,DAC_ALIGN_12B_R,0);//初始值为0 	
    while(1)
	{
		t++;
		key=KEY_Scan(0);			  
		if(key==WKUP_PRES)
		{		 
			if(dacval<4000)dacval+=200;
            HAL_DAC_SetValue(&DAC1_Handler,DAC_CHANNEL_1,DAC_ALIGN_12B_R,dacval);//设置DAC值
		}else if(key==2)	
		{
			if(dacval>200)dacval-=200;
			else dacval=0;
            HAL_DAC_SetValue(&DAC1_Handler,DAC_CHANNEL_1,DAC_ALIGN_12B_R,dacval);//设置DAC值
		}	 
		if(t==10||key==KEY1_PRES||key==WKUP_PRES) 	    //WKUP/KEY1按下了,或者定时时间到了
		{	  
            adcx=HAL_DAC_GetValue(&DAC1_Handler,DAC_CHANNEL_1);	//读取前面设置DAC的值
			LCD_ShowxNum(94,150,adcx,4,16,0);     	    //显示DAC寄存器值
			temp=(float)adcx*(3.3/4096);			    //得到DAC电压值
			adcx=temp;
 			LCD_ShowxNum(94,170,temp,1,16,0);     	    //显示电压值整数部分
 			temp-=adcx;
			temp*=1000;
			LCD_ShowxNum(110,170,temp,3,16,0X80); 	    //显示电压值的小数部分
 			adcx=Get_Adc_Average(ADC_CHANNEL_5,10);     //得到ADC转换值	  
			temp=(float)adcx*(3.3/4096);			    //得到ADC电压值
			adcx=temp;
 			LCD_ShowxNum(94,190,temp,1,16,0);     	    //显示电压值整数部分
 			temp-=adcx;
			temp*=1000;
			LCD_ShowxNum(110,190,temp,3,16,0X80); 	    //显示电压值的小数部分
			LED0=!LED0;	   
			t=0;
		}	    
		delay_ms(10);	
	}
}
  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F103RCT6是一款基于ARM Cortex-M3内核的微控制器,它具有丰富的外设和强大的计算能力,广泛应用于嵌入式系统开发。下面是对其工作原理的简要介绍: 1. 内核架构:STM32F103RCT6采用了ARM Cortex-M3内核,该内核具有高性能、低功耗和高代码密度等特点。它支持32位指令集和硬件浮点运算,能够实现高效的数据处理和控制。 2. 外设功能:STM32F103RCT6集成了多种外设模块,包括通用输入输出口(GPIO)、定时器、串行通信接口(UART/SPI/I2C)、模数转换器(ADC)、数字模拟转换器(DAC)等。这些外设模块可以通过寄存器配置和编程实现各种功能的扩展和控制。 3. 存储器系统:STM32F103RCT6具有Flash存储器和SRAM存储器。Flash存储器用于存储程序代码和常量数据,可通过Bootloader进行更新。SRAM存储器用于存储变量和临时数据,提供了快速的读写访问。 4. 时钟系统:STM32F103RCT6的时钟系统包括主时钟(HCLK)、系统时钟(SYSCLK)和外设时钟(PCLK)等。通过配置时钟源和分频器,可以灵活地控制各个时钟信号的频率和精度,以满足不同应用的需求。 5. 中断和异常处理:STM32F103RCT6支持多级中断和异常处理机制,可以响应外部事件和内部异常。通过配置中断向量表和中断优先级,可以实现对不同事件的及时响应和处理。 6. 开发工具:针对STM32F103RCT6的开发,可以使用ST公司提供的开发工具套件,如STM32CubeMX、Keil MDK等。这些工具提供了丰富的开发资源和示例代码,方便开发者进行软硬件的配置和调试。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值