分享

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

 weikong66 2013-03-28
【青风带你学stm32f051系列教程】第14课 DAC的运用
2013年02月25日 ? 教程 ? 评论数 3 ? 被围观 494+

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个波形,一个为正弦波,一个为梯形波。并且赋值为一个数组:

1
2
3
4
5
6
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};

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

1
2
</pre>
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&Sine12bit;
1
2
3
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&Escalator8bit;
<pre>

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void EXTI4_15_IRQHandler(void)
{
 if(EXTI_GetITStatus(EXTI_Line7) != RESET)
 {
 /* 改变波形 */
 WaveChange = !WaveChange;
  
/* 改变选择的波形 */
 SelectedWavesForm = !SelectedWavesForm;
  
/*清除按键中断*/
  
 EXTI_ClearITPendingBit(EXTI_Line7);
 }
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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);
}

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

1
2
3
4
5
6
7
typedef struct
{
 uint32_t DAC_Trigger; /*!<指定选定的DAC通道的外部触发*/
  
uint32_t DAC_OutputBuffer; /*!< 指定的DAC通道的输出缓冲是否被启用或禁用。*/
}DAC_InitTypeDef;

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

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* 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);

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/* 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);

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多