×
嵌入式 > 技术百科 > 详情

【青风带你学stm32f051系列教程】第14课 DAC的运用

发布时间:2020-06-17 发布时间:
|

DAC的主要作用就是将数字信号变为模拟信号输出,数字/ 模拟转换模块(DAC) 是12位数字输入,电压输出的数字/ 模拟转换器。DAC可以配置为8 位或12位模式,也可以与DMA控制器配合使用。DAC工作在12位模式时,数据可以设置成左对齐或右对齐。DAC可以通过引脚输入参考电压VDD以获得更精确的转换结果。

数字输入经过DAC被线性地转换为模拟电压输出,其范围为0到VDD。 任一DAC通道引脚上的输出电压满足下面的关系:

DAC输出 = VREFx (DOR / 4095)

下面我们就从软硬件2个方面对如何配置时钟DAC模块进行详细的分析:

硬件准备:

硬件方面采用PA4作为DAC输出管脚,内部存储单元输出数字量。

软件准备:

打开keil编译环境,设置系统工程树:

我们需要编写DAC的配置子函数DAC.C,按键中断我们可以直接调用在第二节编写的按键中断驱动。实验第一步就是给2个数字波形,我们设置2个波形,一个为正弦波,一个为梯形波。并且赋值为一个数组:

[c]

const uint16_t Sine12bit[32] = {
2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4095, 4056,
3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263, 909,
599, 344, 155, 38, 0, 38, 155, 344, 599, 909, 1263, 1647};
const uint8_t Escalator8bit[6] = {0x0, 0x33, 0x66, 0x99, 0xCC, 0xFF};

[/c]

实验中为了快速对数据进行调用,并且减少多CPU的负担,我们采用DMA进行数据的传输,把我们的赋值数组直接放入DMA_MemoryBaseAddr内,因此可以输入如下:

[c]
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&Sine12bit;

[/c]

[c]

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&Escalator8bit;


[/c]

当然两种不同的波形我们需要进行选择,选择DAC对哪一个进行转换,选择我们可以通过采用按键中断进行选择,按下后改变一次波形选择,那么按键中断的子函数可以编写为如下:
[c]

void EXTI4_15_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line7) != RESET)
{
/* 改变波形 */
WaveChange = !WaveChange;

/* 改变选择的波形 */
SelectedWavesForm = !SelectedWavesForm;

/*清除按键中断*/

EXTI_ClearITPendingBit(EXTI_Line7);
}
}

[/c]

DAC我们必须对其所采用的硬件进行配置,首先我们使能DAC和DMA的时钟,然后配置DAC输出管脚,上面说过,我们采用PA4作为输出管脚,采用其模拟数字功能,因此需要对IO管脚进行配置,具体代码如下:

[c]

void DAC_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

/* DMA1 时钟使能 */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

/* DAC 外设时钟使能*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);

/* GPIOA 时钟使能 */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

/*配置 PA.04 为模拟输出 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}

[/c]

回到主函数,在主函数里,我们需要设置DAC的通道触发方式,这个参数在stm32f0xx_dac.h文件中通过结构体进行了描述:

[c]

typedef struct
{
uint32_t DAC_Trigger; /*!<指定选定的DAC通道的外部触发*/

uint32_t DAC_OutputBuffer; /*!< 指定的DAC通道的输出缓冲是否被启用或禁用。*/
}DAC_InitTypeDef;

[/c]

对上面两个产生进行配置,我们采用TIM2做为触发源:

[c]

/* DAC 通道1配置 */
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO;
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;

[/c]

DAC的触发源在STM32F051参考手册中有详细的说明,我们可以首先看看DAC的功能结构图,如下图所示,可以看出其可以通过多个触发源进行触发转换:

详细的触发源列表可以归纳如下:

有效设置了TIM2定时器作为触发源,下面我们就需要来配置TIM定时器,配置TIM2定时器在之前通用定时器的运用中详细讲解过,大家可以回忆,这样里面我们按照要求如下配置:

[c]

/* TIM2 外设时钟使能*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

/* 定时器基础配置 */
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 0xFF;
TIM_TimeBaseStructure.TIM_Prescaler = 0x0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

/* TIM2触发输出模式选择 */
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);

/* TIM2使能 */
TIM_Cmd(TIM2, ENABLE);

[/c]

配置完定时器后,我们需要把DMA连通DAC输入端,首先初始化DMA,使能通道,代码如下所示:

[c]

/* DMA 通道3配置 */
DMA_DeInit(DMA1_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12R1_ADDRESS;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&Sine12bit;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 32;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);

/* 使能DMA1通道3 */
DMA_Cmd(DMA1_Channel3, ENABLE);

/* DAC 通道1初始化 */
DAC_Init(DAC_Channel_1, &DAC_InitStructure);

/* 使能DAC 通道1: 当 DAC 通道1被使能 , PA.04 自动与DAC转换器相连. */
DAC_Cmd(DAC_Channel_1, ENABLE);

/* 使能DAC通道1的DMA */
DAC_DMACmd(DAC_Channel_1, ENABLE);

[/c]

实验下载现象:

按下用户KEY1,选择输出的不同波形。


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
NTMD6N03R2G的技术参数