STM32-DAC_stm32的dac

在使用DAC时,不能直接对上述DORx寄存器写入数据,任何输出到DAC通道x的数据都必须写入到DHRx寄存器中(包含DHR8Rx、DHR12Lx等,根据数据对齐方向和分辨率的情况写入到对应的寄存器中)。

数据被写入到DHRx寄存器后,DAC会根据触发配置进行处理,若使用硬件触发,则DHRx中的数据会在3个APB1时钟周期后传输到DORx,DORx随之输出相应的模拟电压到输出通道;若DAC设置为外部事件触发,可以使用定时器(TIMx_TRGO)、EXTI_9信号或软件触发(SWTRIGx)这几种方式控制数据DAC转换的时机,例如使用定时器触发,配合不同时刻的DHRx数据,可实现DAC输出正弦波的功能。

DAC初始化结构体

typedef struct
{
    uint32_t DAC_Trigger;         // DAC触发方式
    uint32_t DAC_OutputBuffer;    // 是否使能输出缓冲器          
} DAC_ChannelConfTypeDef;
DAC_Trigger

配置DAC的触发模式,当DAC产生相应的触发事件时,才会把DHRx寄存器的值转移到DORx寄存器中进行转换。触发模式有:

定时器触发模式(DAC_TRIGGER_T2/4/6/7_TRGO),使用定时器2/4/6/7控制DHRx寄存器的数据按时间转移到DORx寄存器中进行转换,利用这种方式可以输出特定的波形;

DAC_TRIGGER_EXT_IT9,当发生EXTI_9事件时(如GPIO中断事件),触发中断;

软件触发(DAC_TRIGGER_SOFTWARE),向DAC_SWTRIGR寄存器写入配置即可触发信号进行转换。

DAC_OutputBuffer

使能了DAC的输出缓冲后可以减小输出阻抗,适合直接驱动一些外部负载。

实验环节

DAC配置

DAC_HandleTypeDef hdac;
DMA_HandleTypeDef hdma_dac_ch1;
TIM_HandleTypeDef htim6;

void MX_DAC_Init(void)
{
    DAC_ChannelConfTypeDef sConfig = {0};

    /** DAC Initialization
    */
    hdac.Instance = DAC;
    if (HAL_DAC_Init(&hdac) != HAL_OK)
    {
        Error_Handler();
    }

    /** DAC channel OUT1 config
    */
    sConfig.DAC_Trigger 		= DAC_TRIGGER_T6_TRGO;
    sConfig.DAC_OutputBuffer 	= DAC_OUTPUTBUFFER_ENABLE;
    if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK)
    {
        Error_Handler();
    }
}

void HAL_DAC_MspInit(DAC_HandleTypeDef *dacHandle)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    if (dacHandle->Instance == DAC)
    {
        __HAL_RCC_DAC_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();
		
        /**DAC GPIO Configuration
        PA4     ------> DAC_OUT1
        */
        GPIO_InitStruct.Pin 	= GPIO_PIN_4;
        GPIO_InitStruct.Mode 	= GPIO_MODE_ANALOG;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

        /* DAC DMA Init */
        /* DAC_CH1 Init */
        hdma_dac_ch1.Instance 					= DMA2_Channel3;
        hdma_dac_ch1.Init.Direction 			= DMA_MEMORY_TO_PERIPH;
        hdma_dac_ch1.Init.PeriphInc 			= DMA_PINC_DISABLE;
        hdma_dac_ch1.Init.MemInc 				= DMA_MINC_ENABLE;
        hdma_dac_ch1.Init.PeriphDataAlignment 	= DMA_PDATAALIGN_HALFWORD;
        hdma_dac_ch1.Init.MemDataAlignment 		= DMA_MDATAALIGN_HALFWORD;
        hdma_dac_ch1.Init.Mode 					= DMA_CIRCULAR;
        hdma_dac_ch1.Init.Priority 				= DMA_PRIORITY_HIGH;
        if (HAL_DMA_Init(&hdma_dac_ch1) != HAL_OK)
        {
            Error_Handler();
        }

        __HAL_LINKDMA(dacHandle, DMA_Handle1, hdma_dac_ch1);
    }
}

void HAL_DAC_MspDeInit(DAC_HandleTypeDef *dacHandle)
{
    if (dacHandle->Instance == DAC)
    {
        __HAL_RCC_DAC_CLK_DISABLE();

        /**DAC GPIO Configuration
        PA4     ------> DAC_OUT1
        */
        HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4);

        /* DAC DMA DeInit */
        HAL_DMA_DeInit(dacHandle->DMA_Handle1);
    }
}

void MX_TIM6_Init(void)
{
    TIM_MasterConfigTypeDef sMasterConfig = {0};

    htim6.Instance 					= TIM6;
    htim6.Init.Prescaler 			= 71;
    htim6.Init.CounterMode 			= TIM_COUNTERMODE_UP;
    htim6.Init.Period 				= 999;
    htim6.Init.AutoReloadPreload 	= TIM_AUTORELOAD_PRELOAD_ENABLE;
    if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
    {
        Error_Handler();
    }

    sMasterConfig.MasterOutputTrigger 	= TIM_TRGO_UPDATE;
    sMasterConfig.MasterSlaveMode 		= TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
    {
        Error_Handler();
    }
}

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *tim_baseHandle)
{
    if (tim_baseHandle->Instance == TIM6)
    {
        __HAL_RCC_TIM6_CLK_ENABLE();
    }
}

void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *tim_baseHandle)
{
    if (tim_baseHandle->Instance == TIM6)
    {
        __HAL_RCC_TIM6_CLK_DISABLE();
    }
}
测试环节
/* 波形数据 ---------------------------------------------------------*/
uint16_t Sine12bit[32] =
{
    2048	, 2460	, 2856	, 3218	, 3532	, 3786	, 3969	, 4072	,
    4093	, 4031	, 3887	, 3668	, 3382	, 3042	, 2661	, 2255	,
    1841	, 1435	, 1054	, 714	, 428	, 209	, 65	, 3		,
    24		, 127	, 310	, 564	, 878	, 1240	, 1636	, 2048
};

void test(void)
{
	初始化
	
	/* 启动定时器 */
    HAL_TIM_Base_Start(&htim6);
	
    /* 启动DACx DMA功能 */
    HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t *)Sine12bit, 32, DAC_ALIGN_12B_R);
	
	while(1)
	{}
}
实现现象

示波器捕获到单片机输出正弦波。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值