寒假学习之stm32(14)----DAC(数模转换)

PS:上一讲我们讲到了ADC(模数转换),这一讲中,我们介绍一下DAC(数模转换),简而言之,数模转换所完成的工作和模数转换正好相反——数字量转化成模拟量

ADC的时候,我们的stm32是引脚是负责接收一个模拟量,并且把它转化成数字量,而DAC的时候,我们的引脚是负责处理内部的数字指令,将其转化成模拟量进行输出,此时的引脚作为一个输出使用~

这是德州仪器的一篇英文DAC的知识简介:
http://e2e.ti.com/blogs_/b/analogwire/archive/2013/02/25/dac-essentials-a-new-blog-series

wiki的介绍:
https://zh.wikipedia.org/wiki/%E6%95%B8%E4%BD%8D%E9%A1%9E%E6%AF%94%E8%BD%89%E6%8F%9B%E5%99%A8

模拟量和数字量之间的关系:
寒假学习之stm32(14)----DAC(数模转换)_第1张图片


OK,接下来开始介绍关于stm32内部的DAC特性

stm32内部的DAC

说实话,和stm32对ADC的支持相比较,DAC的支持显得可能会稍稍薄弱(误差大概高了0.03V),不过,这并不影响我们使用它。

特点
· 和ADC不同,在stm32中,ADC的结果存储在一个16位的寄存器中,但是,DAC可以配置为8位或12位模式,也可以与DMA控制器配合使用,当配置为12位模式时,也需要考虑左对齐或者右对齐。
· DAC模块有2个输出通道(PA4,PA5),每个通道都有单独的转换器。
· 在双DAC模式下,2个通道可以独立地进行转换,也可以同时进行转换并同步地更新2个通道的输出

DAC的主要模块:

1.  2个DAC转换器:每个转换器对应1个输出通道
2. 八位或十二位的单调输出
3. 噪声波形生成
4. 三角波生成
5. 双DAC同时转换,亦可分别转换
6. 每个通道都有DMA功能

DAC的框图

寒假学习之stm32(14)----DAC(数模转换)_第2张图片
PS:我么可以看到,DAC可以被通用定时器触发,也可以被外部中断9触发,但是,我们考虑到初学,先不用管这些组合的问题,先简单了解下DAC的库函数配置~

DAC输出电压的范围理论上是在0~Vref,但是,实际上stm32f103的芯片会比理论值大了0.03V。

VDAC=Vref*(DOR/4095),4095是十二位寄存器的最大值-_-.

DAC的库函数配置(以DAC1为例):

因为在使能DACx之后,相应的GPIO引脚会自动与DAC的模拟输出引脚相连,设置为输入,为例避开干扰RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );      //使能PORTA通道时钟 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;                // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //模拟输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_4)  ;//PA.4 输出高

2. 使能DAC1时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );      //使能DAC通道时钟 

3. 初始化DAC并且设置工作模式

DAC_InitType.DAC_Trigger=DAC_Trigger_None;  //不使用触发功能 TEN1=0
DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;    //DAC1输出缓存关闭 BOFF1=1
DAC_Init(DAC_Channel_1,&DAC_InitType);   //初始化DAC通道1

4. 使能DAC的转换通道

DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC1
  1. 设置DAC的输出值

    DAC_SetChannel1Data(DAC_Align_12b_R,temp);//12位右对齐数据格式设置DAC值
    配置过程一览

void Dac1_Init(void)
{

    GPIO_InitTypeDef GPIO_InitStructure;
    DAC_InitTypeDef DAC_InitType;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );    //使能PORTA通道时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );      //使能DAC通道时钟 

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;                // 端口配置
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //模拟输入
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA,GPIO_Pin_4)  ;//PA.4 输出高

    DAC_InitType.DAC_Trigger=DAC_Trigger_None;  //不使用触发功能 TEN1=0
    DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
    DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
    DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;    //DAC1输出缓存关闭 BOFF1=1
    DAC_Init(DAC_Channel_1,&DAC_InitType);   //初始化DAC通道1

    DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC1

    DAC_SetChannel1Data(DAC_Align_12b_R, 0);  //12位右对齐数据格式设置DAC值

}

//设置通道1输出电压
//vol:0~3300,代表0~3.3V
void Dac1_Set_Vol(u16 vol)
{
    float temp=vol;
    temp/=1000;
    temp=temp*4096/3.3;
    DAC_SetChannel1Data(DAC_Align_12b_R,temp);//12位右对齐数据格式设置DAC值
}

你可能感兴趣的:(stm32)