STM32基础教程(CubeMX)—— ADC与DAC

ADC与DAC

ADC与DAC的原理

参考电压

   ADC与DAC都是基于参考电压工作的,以百分数的形式进行工作。例如,参考电压为3V时,ADC测定电压为0.5就是1.5V,DAC输出0.5就是输出1.5V。开发板原理图中搜索VREF可以看到参考电压是从哪个管脚引入的。

分辨率

   对于ADC/DAC来说,分辨率表示输出/输入数字量变化一个相邻数据码所需输入/所需输出模拟电压的变化量,反映了ADC/DAC对输入模拟信号最小变化的分辨能力。一般,已知一个转换器的位数,并且知道参考电压,其分辨率就是确定的。即同样位数下,参考电压越大,分辨率越低。

STM32F1的DAC

   STM32F1只有一个DAC,一般是12位的,有两个通道。DAC值的取值范围为0到4095, D A C = V R E F × D O R 4096 DAC输出电压值 =VREF\times\frac{DOR}{4096} ,其中VREF为参考电压,DOR为设置的DAC的值,4096是2的12次方,计算方式为 2 n 2^n n n 是位数。

STM32F1的ADC

   STM32F1的ADC核心一般也就两到三个,而通道有十几个,同一个通道还是所有核心共用的。要注意的是,一个核心同时只能转换一个通道的信号,因此需要排序。另外,ADC通道的最后两个比较特殊,一个是芯片温度传感器,一个是参考电压传感器。

CubeMX的操作

DAC的设置
  1. 在"Pinout & Configuration"界面下,左侧选择下拉菜单选择模拟(Analog),在模拟里面选择DAC。
  2. 在DAC的界面中,勾选你要使用的DAC输出通道。
  3. 勾选输出通道后会在下方出现该通道的设置窗口,在该窗口中打开输出缓冲(output buffer),有输出缓冲的时候才有带负载的能力。第二个选项是触发方式,不选择触发方式的时候,就是没有触发,根据输入实时的进行变化。
  4. DMA:在打开了一个DAC之后,可以选择下方的DMA设置窗口,选择一个通道为其添加一个DMA。DMA是一个寄存器,DAC如果打开了DMA,根据定时器的信号,DMA会自动的将它储存的数组中的数据一个个的传给DAC,这样就实现了用DAC输出变化的模拟量的目的,比如正弦波。不过,如果要输出完美的正弦波,也就是光滑的正弦波,外部还需要设计抗混叠滤波电路。
ADC的设置
  1. 在主界面左边的窗口中选择模拟(Analog),在模拟里面选择ADC。这里有多个ADC,任意选择。
  2. 在ADC的界面中,勾选你要使用的ADC输入通道。注意,两个ADC核心共用输入口,有的还与DAC共用GPIO口。而ADC核心同时只能处理一个通道的数据。
  3. 选择好输入口后,在下方的“Configuration”窗口中,第二个下拉菜单(ADC设置)中,第一个是对齐方式,同DAC对齐方式的意思,一般选右对齐;第二个是扫描转换模式启用选项,一般不管,用了的话会自动启用,启用这个相当于启动了多通道的意思,各通道的顺序在第三个下拉菜单设置;第三个是连续转换模式的启用选项,启用后,在一个通道转换完毕后立刻转换下一个通道,不通过其他方式触发;第四个是非连续转换模式的启用选项,启用后,会将多个通道捆绑,也就是说,一次转换多个,然后等待信号,之后再转换多个。
  4. 第三个下拉菜单是定期转换(regular conversion)的配置菜单,第一个是开启还是关闭的选项;第二个是转换多少个通道的数量设置菜单;第三个选项外部触发转换源,也就是选择转换的触发方式,第一个是软件触发,其他的都是定时器触发,分别是定时器的不同事件;之后的几个Rank,就是对选择的通道进行排序,在里面最后一个选项是转换时间的选择,一般来说,越长,测的越准。
  5. NVIC菜单就是设置中断的,如果启用,则转换完成后触发中断。
  6. 定时器触发采样:这里以定时器触发输出(Trigger Output)事件为例,选用有该事件的定时器,然后在设置定时器分频的那个窗口里面,选择Trigger Output下拉菜单,第二个选项,即触发输出选择选项,选Updata事件为Trigger Output事件的触发事件。这样一来,定时器在定时完成时会产生Updata事件,Updata事件又产生了Trigger Output事件,该事件触发采样。
  7. ADC时钟的设置:ADC的时钟往往比单片机时钟小得多,也就是说,ADC转换的速度比芯片运算速度慢得多,F1系列一般选择12MHz就很大了。ADC时钟的设置,在时钟设置界面,APB2中,如果过大会报警。
  8. DMA:与DAC类似,ADC也可以使用DMA方式进行采集,过程与DAC相反,采集数据放到DMA中。

Keil5的操作

直接控制DAC
  1. 需要在程序中启动DAC,启动的方式类似定时器的启动,函数为HAL_DAC_Start(&hdac,DAC_CHANNEL_1);
  2. 控制DAC输出的值,使用的函数是HAL_DAC_SetValue(DAC地址,DAC通道,DAC对齐方式,DAC的值),其中DAC对齐方式,是指你给的数字在DAC的寄存器中是左对齐还是右对齐,一般是右对齐,符合数据的计数方式。
  3. 注意事项: 如果使用DAC控制LED灯的亮度,要考虑到LED灯的开启电压或开启电流,一般加了限流电阻的LED,其开启电压高于0.7V,一般在2V左右。因此,要综合考虑设置DOR的值。另外,DAC输出口有可能不是你要控制的那个外设的输入口,同PWM输出一样,有时候需要连线。
利用DMA控制DAC
  1. 需要在程序中启动DAC,启动的方式类似定时器的启动,函数为HAL_DAC_Start(&hdac,DAC_CHANNEL_1);
  2. DMA:在函数中使用“DAC_Start_DMA”关键词找到对应的启动函数启动,启动后就会开始传送。
直接控制ADC
  1. 可选:启用ADC自校准HAL_ADCEx_Calibration_Start(ADC核心的地址),之后需要等待一段时间等待自校准结束再进行下一步编程操作,一般等待延时100即可。
  2. 启用带中断的ADC:HAL_ADC_Start_IT(ADC核心的地址),这里不需要指定ADC的通道,因为通道在CubeMX里面已经进行过排序,会按照那个顺序来。另外,这个函数相当于初始化,只是打开ADC功能,并不会立刻开始转换,它会等待转换指令。这个转换指令就是之前在CubeMX里ADC排序那里设定的信号。另外,如果使用定时器触发,记得打开定时器。
  3. 编写ADC的中断服务函数:与其他中断一致,中断服务函数的位置也是在用户应用文件夹中的“芯片型号_it.c”文件中,关键词为ADC,函数全名为"HAL_ADC_IRDHAndler"。这个中断服务函数处理所有adc的中断,同样的,中断服务函数中已经做了一些必要的处理,我们需要编辑的同样是中断服务函数中调用的回调函数。
  4. 读取转换结果: 传入回调函数的参数是一个地址,假设传入的是adc1的地址,那么就说明adc1转换完毕。如果要读取ADC转换的结果,就使用函数HAL_ADC_GetValue(adc的地址),这里可以直接写传入函数的参数。注意,这里传入的参数就是一个数字,它不代表具体的电压值,需要通过公式计算出具体的电压值,公式为: A D C = V R E F × x 4096 ADC输入电压值=VREF\times\frac{x}{4096} ,其中VREF为参考电压,x为读取的ADC的值,4095是12位所能表示的最大的数值,计算方式为 2 n 2^n n n 是位数。
  5. DMA:在函数中使用“ADC_Start_DMA”关键词找到对应的启动函数启动,启动后就会开始传送。

猜你喜欢

转载自blog.csdn.net/weixin_43718316/article/details/107988846