当前位置:首页 > STM32 - DAC学习(固定值 - 三角波)
STM32_DAC学习
1、 学习目的:
使用DAC库函数实现固定值、三角波输出
在完成目的之前我需要对STM32的DAC转换器进行学习和了解,也就说要知道STM32的DAC有哪些特点,能做哪些事。下面我们就先看看DAC的特点。
1、DAC的简介:
STM32的数字/模拟转换模块(DAC)是12位的数字输入,电压输出的数模转换器。虽然是12位的,但是也可以配置成8位的模式(即数字输入可以是12位或者8位)。它可以与DMA控制器配合使用。在12位数字输入模式时,数据的对齐方式可以左对齐或者右对齐,而8位模式在下是固定的右对齐(无需配置)。DAC模块有2个通道,每个通道都是独立的,这也导致了DAC可以单通道独立使用,也可以双通道同时使用。2个通道分别对应的是PA4(1通道)、PA5(2通道)。
2、 DAC主要特征:
●
● ● ● ● ● ● ● ● ●
2个DAC转换器,每个转换器对应1个输出通道 8位或者12位单调输出
12位模式下数据左对齐或者右对齐 同步更新功能 噪声波形生成 三角波形生成
双DAC通道同时或者分别转换 每个通道都有DMA功能 外部触发转换
输入参考电压VREF+
DAC通道模块框图:
3、DAC固定值输出
固定值输出是DAC最简单的使用,在STM32的DAC中我们需要设置的东西并不多。
我可以现在看看DAC_InitTypeDef结构体:
typedef struct {
u32 DAC_Trigger;
//触发选择
//波形发生 //幅值选择
u32 DAC_WaveGeneration; u32 DAC_OutputBuffer; }DAC_InitTypeDef;
u32 DAC_LFSRUnmask_TriangleAmplitude;
//输出缓存控制
在固定值输出时,我们不需要进行触发、幅度设置,只需要使能相应的通道即可。
所以在打开DAC时钟和GPIOA的时钟后,就是进行相应的格式化,固定输出格式化如下:
DAC_InitType.DAC_Trigger = DAC_Trigger_None; //不使用触发功能
DAC_InitType.DAC_WaveGeneration = DAC_WaveGeneration_None; //不使用波形发生功能
DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0; //不屏蔽/幅值选择 DAC_InitType.DAC_OutputBuffer = DAC_OutputBuffer_Disable;//不使用缓存输出 DAC_Init(DAC_Channel_1,&DAC_InitType);
格式化后就是使能DAC相应的通道
DAC_Cmd(DAC_Channel_1,ENABLE); //这里使用通道1
所有的准备工作都好了,要想输出想要的值就必须给DAC转换器输入相应的数据
DAC_SetChannel1Data(DAC_Align_12b_R,1023);//这里输入3.3V/4的12bit数据
4、三角波输出
三角波的输出需要仔细阅读数据手册的内容,不然要想输出三角波是不那么容易的。DAC是通过输入一个数据然后输出相应的电压值,那么三角波就需要周期性的进行数据输入。对于一个波形而言,幅度、直流信号、频率是基本的参数,STM32的三角波产生也是可以对这三个参数进行设置的。 首先幅值的设置比较简单,使用DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude就可以进行设置了
直流信号的设置和固定输出一样,使用设置通道数据函数(DAC_SetChannel1Data)就可以了
频率的设置在三角波产生的时候是最难的,如果没有理解如何设置,可能连三角波都没有。 要想产生三角波就必须使用触发,换句话说触发就是为波形发生准备的,即触发一次DAC内部的计数器值加1然后将值输入DAC输出电压。计数器的作用就是通过加1和幅值进行比较进行递增或者递减产生输入值的,从而产生三角波。从这个中我们也可以体会到三角波的频率是不好计算的。频率和三角波的赋值大小、触发的频率、DAC的转换速度是有关系的,所以只能大概的计算。
首先来使用软件触发产生三角波
DAC_InitType.DAC_Trigger = DAC_Trigger_Software; //使用软件触发功能
DAC_InitType.DAC_WaveGeneration = DAC_WaveGeneration_Triangle; //三角波发生
DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_2047; //三角波幅值
DAC_InitType.DAC_OutputBuffer = DAC_OutputBuffer_Disable;//不使用缓存输出 DAC_Init(DAC_Channel_1,&DAC_InitType);
DAC_Cmd(DAC_Channel_1,ENABLE);//使能通道1
DAC_SetChannel1Data(DAC_Align_12b_R,1023);//设置三角波的直流信号
DAC_WaveGenerationCmd(DAC_Channel_1,DAC_Wave_Triangle,ENABLE);//使能三角波发生
在准备工作完成后,我们还需要以一定频率进行软件触发即:
while(1) {
DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE);//使能软件触发 }
从上面的程序可以看到三角波的频率只能通过幅值进行调节,并且调节的范围小,频率也是不能计算,因为DAC的转换时间不知道大概频率f=1/(((1/36MHz)*3+1/36MHz+tSETTLING)* DAC_TriangleAmplitude_x*2),同时当幅值较小时波形效果较差。当DAC_TriangleAmplitude_63时和小于时波形就不好了,此时测得的f=13KHz左右。测得的最小f=200Hz。 注意:直流信号加上幅值的总电压不得超过VREF+
定时器触发和软件触发原理是一样的,频率计算要难点。
定时器触发代码:
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 1; //计数值 TIM_TimeBaseStructure.TIM_Prescaler = 0; //预分频 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //频率分割
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数方式 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);//T2触发更新
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO;//T2触发
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_Triangle;//三角波发生
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_1023;//幅值0.82V DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;//缓存输出 DAC_Init(DAC_Channel_1, &DAC_InitStructure);
DAC_Cmd(DAC_Channel_1, ENABLE);
DAC_SetDualChannelData(DAC_Align_12b_R,1023,0);//设置三角波直流信号
TIM_Cmd(TIM2, ENABLE);
测得最大频率f=135KHz左右(在DAC_TriangleAmplitude_63时)
最小频率未测出,我测得的频率可以小于10mHz,已经是非常小的了。
共分享92篇相关文档