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);	
	}
}
相关推荐
majingming12314 分钟前
esp8266-01S实现PPM波形
单片机·嵌入式硬件
TESmart碲视2 小时前
USB一线连多屏?Display Link技术深度解析
stm32·单片机·嵌入式硬件·物联网·计算机外设·电脑·智能硬件
森焱森2 小时前
60 美元玩转 Li-Fi —— 开源 OpenVLC 平台入门(附 BeagleBone Black 驱动简单解析)
c语言·单片机·算法·架构·开源
__基本操作__2 小时前
stm32计时的两个方法
stm32·单片机·嵌入式硬件
BW.SU3 小时前
单片机显示Unicode字符介绍
单片机·嵌入式硬件·界面设计·字库·单片机驱动彩屏·ra8889·ra8876
MARIN_shen4 小时前
Marin说PCB之Allegro高亮BOM器件技巧详解
单片机·嵌入式硬件·硬件工程·pcb工艺
权、狐妖5 小时前
STM32G473串口通信-USART/UART配置和清除串口寄存器状态的注意事项
stm32·单片机·嵌入式硬件
YTao_G5 小时前
STM32模块:023 WDG看门狗
stm32·单片机·嵌入式硬件