【菜鸟入门】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) 还有什么说的?慢慢瞎搞吧!把瞎搞进行到底!
';