STM32实现DAC输出的相关设置

STM32 DAC简介

        大容量的STM32F103具有内部DAC,战舰STM32选择的是STM32F103ZET6属于大容量产品,所以是带有DAC模块的。

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

STM32的DAC模块主要特点有:

① 2个DAC转换器:每个转换器对应1个输出通道

② 8位或者12位单调输出

③ 12位模式下数据左对齐或者右对齐

④ 同步更新功能

⑤ 噪声波形生成

⑥ 三角波形生成

⑦ 双DAC通道同时或者分别转换

⑧ 每个通道都有DMA功能

单个DAC通道的框图如图24.1.1所示:



图24.1.1 DAC通道模块框图

图中VDDA和VSSA为DAC模块模拟部分的供电,而Vref+则是DAC模块的参考电压。DAC_OUTx就是DAC的输出通道了(对应PA4或者PA5引脚)。

从图24.1.1可以看出,DAC输出是受DORx寄存器直接控制的,但是我们不能直接往DORx寄存器写入数据,而是通过DHRx间接的传给DORx寄存器,实现对DAC输出的控制。前面我们提到,STM32的DAC支持8/12位模式,8位模式的时候是固定的右对齐的,而12位模式又可以设置左对齐/右对齐。单DAC通道x,总共有3种情况:

 

 

DAC模块的通道1来输出模拟电压,其详细设置步骤如下:

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

STM32F103ZET6的DAC通道1是接在PA4上的,所以,我们先要使能PORTA的时钟,然后设置PA4为模拟输入(虽然是输入,但是STM32内部会连接在DAC模拟输出上)。

2)使能DAC1时钟。

同其他外设一样,要想使用,必须先开启相应的时钟。STM32的DAC模块时钟是由APB1提供的,所以我们先要在APB1ENR寄存器里面设置DAC模块的时钟使能。

3)设置DAC的工作模式。

该部分设置全部通过DAC_CR设置实现,包括:DAC通道1使能、DAC通道1输出缓存关闭、不使用触发、不使用波形发生器等设置。  

4)设置DAC的输出值。

通过前面3个步骤的设置,DAC就可以开始工作了,我们使用12位右对齐数据格式,所以我们通过设置DHR12R1,就可以在DAC输出引脚(PA4)得到不同的电压值了。

最后,再提醒一下大家,本例程,我们使用的是3.3V的参考电压,即Vref+连接VDDA。

 


实现DAC输出0-5V电压,需要使用STM32内部的DAC模块,以下是实现步骤: 1. 配置GPIO口为模拟输出模式。 2. 配置DAC模块的时钟和参考电压值。 3. 配置DAC输出数据缓存区。 4. 启动DAC转换并设置输出电压值。 具体实现步骤如下: 1. 配置GPIO口为模拟输出模式。 使用CubeMX或手动配置寄存器,将需要输出的引脚配置为模拟输出模式,例如PA4引脚。 2. 配置DAC模块的时钟和参考电压值。 DAC模块的时钟和参考电压值需要根据实际情况进行配置,例如使用STM32F429的DAC模块,可以设置时钟为APB1时钟的1/4,参考电压值为3.3V。 3. 配置DAC输出数据缓存区。 DAC模块的输出数据缓存区可以使用DMA或者中断方式进行配置。如果使用DMA方式,需要先配置DMA通道和缓存区地址,然后启动DMA传输。如果使用中断方式,需要先开启DAC中断,然后在DAC中断处理函数中更新DAC输出值。 4. 启动DAC转换并设置输出电压值。 启动DAC转换可以使用软件触发或者硬件触发方式。使用软件触发方式,需要在DAC转换开始前调用DAC软件触发函数。使用硬件触发方式,需要配置外部触发源,并将DAC触发方式设置为外部触发。 设置DAC输出电压值可以使用DAC输出数据缓存区或者直接设置DAC数据寄存器的方式。例如,设置输出电压为2.5V,可以将DAC数据寄存器设置为0x7FF。 完整的代码示例如下(使用STM32CubeIDE): ``` #include "stm32f4xx.h" DAC_HandleTypeDef hdac; void DAC_Config(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin : PA4 */ GPIO_InitStruct.Pin = GPIO_PIN_4; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* DAC1 clock enable */ __HAL_RCC_DAC_CLK_ENABLE(); /* DAC1 DMA Init */ /* DAC1_CH1 Init */ hdma_dac1.Instance = DMA1_Stream5; hdma_dac1.Init.Channel = DMA_CHANNEL_7; hdma_dac1.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_dac1.Init.PeriphInc = DMA_PINC_DISABLE; hdma_dac1.Init.MemInc = DMA_MINC_ENABLE; hdma_dac1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_dac1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_dac1.Init.Mode = DMA_CIRCULAR; hdma_dac1.Init.Priority = DMA_PRIORITY_LOW; hdma_dac1.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_dac1) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(&hdac, DMA_Handle1, hdma_dac1); /* DAC1 interrupt Init */ HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 0, 0); HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn); /* DAC1 init */ hdac.Instance = DAC; HAL_DAC_Init(&hdac); HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t *)DAC_Buffer, DAC_Buffer_Size, DAC_ALIGN_12B_R); } void TIM6_DAC_IRQHandler(void) { HAL_DAC_IRQHandler(&hdac); } int main(void) { HAL_Init(); DAC_Config(); while (1) { HAL_Delay(1000); /* Set DAC output voltage to 2.5V */ DAC_Buffer[0] = 0x7FF; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值