【菜鸟入门】stm32 之 DAC
最后更新于:2022-04-01 14:50:56
DAC可谓是stm32继按键最简单的一个寄存器配置吧,花了半个小时搞定!
DAC主要特征
● 2个DAC转换器:每个转换器对应1个输出通道
● 8位或者12位单调输出
● 12位模式下数据左对齐或者右对齐
● 同步更新功能
● 噪声波形生成
● 三角波形生成
● 双DAC通道同时或者分别转换
● 每个通道都有DMA功能
● 外部触发转换
看了这些东西,貌似很激动的样子,我们下面就开始配置DAC外设了
先直接看看寄存器:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-21_576915b890486.jpg)
位12 DMAEN1:DAC通道1 DMA使能(DAC channel1 DMA enable
该位由软件设置和清除。
0:关闭DAC通道1 DMA模式;
1:使能DAC通道1 DMA模式。
MAMP1[3:0]:DAC通道1屏蔽/幅值选择器(DAC channel1 mask/amplitude selector) 位11:8
由软件设置这些位,用来在噪声生成模式下选择屏蔽位,在三角波生成模式下选择波形的幅
值。
0000:不屏蔽LSFR位0 / 三角波幅值等于1;
0001:不屏蔽LSFR位[1:0] / 三角波幅值等于3;
0010:不屏蔽LSFR位[2:0] / 三角波幅值等于7;
0011:不屏蔽LSFR位[3:0] / 三角波幅值等于15;
0100:不屏蔽LSFR位[4:0] / 三角波幅值等于31;
0101:不屏蔽LSFR位[5:0] / 三角波幅值等于63;
0110:不屏蔽LSFR位[6:0] / 三角波幅值等于127;
0111:不屏蔽LSFR位[7:0] / 三角波幅值等于255;
1000:不屏蔽LSFR位[8:0] / 三角波幅值等于511;
1001:不屏蔽LSFR位[9:0] / 三角波幅值等于1023;
1010:不屏蔽LSFR位[10:0] / 三角波幅值等于2047;
≥1011:不屏蔽LSFR位[11:0] / 三角波幅值等于4095。
位7:6 WAVE1[1:0]:DAC通道1噪声/三角波生成使能(DAC channel1 noise/triangle wave generation
enable)
该2位由软件设置和清除。
00:关闭波形生成;
10:使能噪声波形发生器;
1x:使能三角波发生器。
位5:3 TSEL1[2:0]:DAC通道1触发选择(DAC channel1 trigger selection)
该位用于选择DAC通道1的外部触发事件。
000:TIM6 TRGO事件;
001:对于互联型产品是TIM3 TRGO事件,对于大容量产品是TIM8 TRGO事件;
010:TIM7 TRGO事件;
011:TIM5 TRGO事件;
100:TIM2 TRGO事件;
101:TIM4 TRGO事件;
110:外部中断线9;
111:软件触发。
注意:该位只能在TEN1= 1(DAC通道1触发使能)时设置。
位2 TEN1:DAC通道1触发使能(DAC channel1 trigger enable)
该位由软件设置和清除,用来使能/关闭DAC通道1的触发。
0:关闭DAC通道1触发,写入寄存器DAC_DHRx的数据在1个APB1时钟周期后传入寄存器
DAC_DOR1;
1:使能DAC通道1触发,写入寄存器DAC_DHRx的数据在3个APB1时钟周期后传入寄存器
DAC_DOR1。
注意:如果选择软件触发,写入寄存器DAC_DHRx的数据只需要1个APB1时钟周期就可以传入
寄存器DAC_DOR1。
位1 BOFF1:关闭DAC通道1输出缓存(DAC channel1 output buffer disable)
该位由软件设置和清除,用来使能/关闭DAC通道1的输出缓存。
0:使能DAC通道1输出缓存;
1:关闭DAC通道1输出缓存。
位0 EN1:DAC通道1使能(DAC channel1 enable)
该位由软件设置和清除,用来使能/失能DAC通道1。
0:关闭DAC通道1;
1:使能DAC通道1。
因为DAC1对应的是PA4,所以我们在初始化DAC1的时钟时别忘了 PA4
RCC->APB1ENR |= 1<<29;
RCC->APB2ENR |= 1<<2;
因为我们这里不用DMA,所以就关掉
DAC->CR &= ~(1<<12);//close DMA
如果想输出三级波,那就把6:7位都置1,想输出噪声我们就弄成10b,什么都不想要我们就用00b;这里我想玩玩三角波,我就配置称11;
DAC->CR &= ~(3<<6);//好习惯是先把几位全部清空
DAC->CR |= 3<<6;
因为我们上面设置了三级波模式,这里我们来设置三级波的VPP,可以根据上面的datasheet设置!
DAC->CR &= ~(0xf<<8);
DAC->CR |= 0xf<<8;
DA的触发模式,为了方便起见我们之间选用软件触发,但是
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-21_576915b8a6301.jpg)
所以我们要现设置TEN1=1;然后再设置成软件触发
DAC->CR |= 1<<2;
DAC->CR |= 7<<3;//sw
我们也用不上DAC的缓存,所以二话不说关掉!
DAC->CR |= 1<<1;
下面设置要输出的偏移电源,0当然就是0V了,
DAC->DHR12R1 = 0;
因为我们用到了软件触发,所以我们要时刻关注软件触发寄存器,寄存器就两位:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-21_576915b8c21d3.jpg)
DAC->SWTRIGR |= 1<<0;
然后就打开DA,开始工作!
DAC->CR |= 1<<0;
下面附上我的代码!
~~~
/* dac.c */
#include <stm32f10x.h>
void dac_init()
{
RCC->APB1ENR |= 1<<29;
RCC->APB2ENR |= 1<<2;
DAC->CR &= ~(1<<12); //close DMA
DAC->CR &= ~(0xf<<8);
DAC->CR |= 0xf<<8; //Vp = 512
DAC->CR &= ~(3<<6); //
DAC->CR |= 3<<6;
DAC->CR |= 1<<2;
DAC->CR |= 7<<3; //sw
DAC->CR |= 1<<1;
DAC->DHR12R1 = 0;
DAC->SWTRIGR |= 1<<0;
DAC->CR |= 1<<0;
}
~~~
主函数
~~~
#include <stm32f10x.h>
#include "init.h"
#include "usart.h"
#include "stdio.h"
#include "dac.h"
int main()
{
rs232_init(CPU_72M,9600);
dac_init();
while(1)
{
if(!(DAC->SWTRIGR&(1<<0)))
{
DAC->SWTRIGR |= 1<<0;
}
}
}
~~~
效果:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-21_576915b8d99ba.jpg)
还有什么说的?慢慢瞎搞吧!把瞎搞进行到底!