STM32-DAC数模转换

DAC数模转换:将数字信号转换成模拟信号

特性:2个DAC转换器每个都拥有一个转换通道

8位或12位单调输出(8位右对齐;12位左对齐右对齐)

双ADC通道同时或者分别转换

外部触发中断

  1. 电压源
  2. 控制部分(外部触发3个APB1;不使用1个APB1)
  3. 外部触发
  4. 输出:DAC1-PA4;DAC2-PA5

软件设计流程:

  • 使能端口以及DAC时钟;设置引脚为模拟输入
cs 复制代码
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC时钟
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//模拟量输入
  • 初始化DAC,设置DAC工作模式(触发选择;DAC波形发生;屏蔽\幅值选择器;DAC输出)
cs 复制代码
typedef struct
{
  uint32_t DAC_Trigger;                      /*!< 指定所选DAC通道的外部触发源
                                               此参数可以是 @ref DAC_trigger_selection 中的一个值 */

  uint32_t DAC_WaveGeneration;               /*!< 指定是否生成DAC通道的噪声波或三角波,或不生成任何波形
                                               此参数可以是 @ref DAC_wave_generation 中的一个值 */

  uint32_t DAC_LFSRUnmask_TriangleAmplitude; /*!< 指定噪声波生成的LFSR掩码或DAC通道的三角波最大生成幅度
                                               此参数可以是 @ref DAC_lfsrunmask_triangleamplitude 中的一个值 */

  uint32_t DAC_OutputBuffer;                 /*!< 指定是否启用或禁用DAC通道的输出缓冲器
                                               此参数可以是 @ref DAC_output_buffer 中的一个值 */
}DAC_InitTypeDef;
  • 使能DAC输出通道
cs 复制代码
	DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC通道1
  • 设置DAC输出值
cs 复制代码
/**
  * @brief  设置DAC通道1的转换数据
  * @param  DAC_Align: 指定数据对齐方式
  *         该参数可以是 @ref DAC_data_align 中的一个值,例如:
  *           - DAC_Align_8b_R: 8位右对齐
  *           - DAC_Align_12b_L: 12位左对齐
  *           - DAC_Align_12b_R: 12位右对齐
  * @param  Data: 要转换的数字值
  *         - 对于8位右对齐,有效范围为0~255(0x00~0xFF)
  *         - 对于12位右对齐,有效范围为0~4095(0x000~0xFFF)
  *         - 对于12位左对齐,有效范围同样为0~4095,但数据需左移4位
  * @retval 无
  * @note   写入的数据将在下次触发事件(如软件触发或定时器触发)时转换为模拟电压
  *         转换后的电压值 = (Data / 满量程值) × VREF+
  *         例如,对于12位DAC且VREF+=3.3V,Data=2048对应电压1.65V
  */
void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data)

代码如下:

cs 复制代码
#include "dac.h"

/*******************************************************************************
* 函 数 名         : DAC1_Init
* 函数功能		   : DAC1初始化函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void DAC1_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	DAC_InitTypeDef DAC_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC时钟
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;//DAC_1
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//模拟量输入
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	DAC_InitStructure.DAC_Trigger=DAC_Trigger_None;	//不使用触发功能 TEN1=0
	DAC_InitStructure.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
	DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
	DAC_InitStructure.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;	//DAC1输出缓存关闭 BOFF1=1
	DAC_Init(DAC_Channel_1,&DAC_InitStructure);	 //初始化DAC通道1
	
	DAC_SetChannel1Data(DAC_Align_12b_R, 0);  //12位右对齐数据格式设置DAC值

	DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC通道1

}

主函数代码:(按键按下,DAC写入转换值)

cs 复制代码
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "usart.h"
#include "key.h"
#include "dac.h"


/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	u8 i=0;
	u8 key;
	int dac_value=0;
	u16 dacval;
	float dac_vol;
	
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组
	LED_Init();
	USART1_Init(115200);
	KEY_Init();
	DAC1_Init();
	
	while(1)
	{
		key=KEY_Scan(0);//单次按下
		if(key==KEY_UP_PRESS)
		{
			dac_value+=400;
			if(dac_value>=4000)
			{
				dac_value=4095;
			}
			DAC_SetChannel1Data(DAC_Align_12b_R,dac_value);//写入4095
		}
		else if(key==KEY1_PRESS)
		{
			dac_value-=400;	
			if(dac_value<=0)
			{
				dac_value=0;
			}
			DAC_SetChannel1Data(DAC_Align_12b_R,dac_value);			
		}
		
		i++;
		if(i%20==0)
		{
			LED1=!LED1;
		}
		
		if(i%50==0)
		{
			dacval=DAC_GetDataOutputValue(DAC_Channel_1);
			dac_vol=(float)dacval*(3.3/4096);
			printf("输出DAC电压值为:%.2fV\r\n",dac_vol);
		}
		delay_ms(10);	
	}
}
相关推荐
youcans_5 分钟前
【嵌入式软件AI编程】03. STM32 VS Code 开发环境与工具链
stm32·单片机·ai编程·嵌入式软件·claude code
国科安芯15 分钟前
抗辐射MCU在低轨卫星电源管理单元中的电压监测与保护策略研究
大数据·单片机·嵌入式硬件·电源管理·低轨卫星·抗辐射·星间链路
分享资料1 小时前
去耦电容和旁路电容的区别
嵌入式硬件·硬件工程
深圳市恒锐丰科技杨生1 小时前
LTK118 2‑7V 单通道 H 桥直流有刷电机驱动芯片|集成 MOS 低压消费类驱动方案
嵌入式硬件·硬件工程
星河单片机1 小时前
STM32读取电阻式土壤湿度模块+OLED显示完整教程
stm32·单片机·嵌入式硬件·土壤湿度
不悔哥1 小时前
开源 LVGL:把手机级界面塞进 MCU
单片机·智能手机·开源
影寂ldy2 小时前
C# UdpClient 单播 三种通信版本
stm32·单片机·c#
szxinmai主板定制专家2 小时前
基于 RK3576 的智能割草机器人解决方案,从样机到量产
人工智能·嵌入式硬件·计算机视觉·fpga开发·机器人·rk3588+fpga·割草机器人
单片机仿真设计2 小时前
【proteus仿真】基于单片机的水肥一体化智能监控系统(仿真图+程序)
stm32·单片机·嵌入式硬件·proteus
单片机仿真设计3 小时前
【proteus仿真】基于 STM32 单片机破碎机监测保护系统(仿真图+程序)
stm32·单片机·proteus