DAC 可谓是 stm32 继按键最简单的一个寄存器配置吧,花了半个小时搞定!
DAC 主要特征
● 2 个 DAC 转换器:每个转换器对应 1 个输出通道
● 8 位或者 12 位单调输出
● 12 位模式下数据左对齐或者右对齐
● 同步更新功能
● 噪声波形生成
● 三角波形生成
● 双 DAC 通道同时或者分别转换
● 每个通道都有 DMA 功能
● 外部触发转换
看了这些东西,貌似很激动的样子,我们下面就开始配置 DAC 外设了
先直接看看寄存器:
位 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 的触发模式,为了方便起见我们之间选用软件触发,但是
所以我们要现设置 TEN1=1;然后再设置成软件触发
DAC->CR |= 1<<2;
DAC->CR |= 7<<3; //sw
我们也用不上 DAC 的缓存,所以二话不说关掉!
DAC->CR |= 1<<1;
下面设置要输出的偏移电源,0 当然就是 0V 了,
DAC->DHR12R1 = 0;
因为我们用到了软件触发,所以我们要时刻关注软件触发寄存器,寄存器就两位:
DAC->SWTRIGR |= 1<<0;
然后就打开 DA,开始工作!
DAC->CR |= 1<<0;
下面附上我的代码!
/* dac.c */ #include 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 #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; } } }
效果:
还有什么说的?慢慢瞎搞吧!把瞎搞进行到底!