赞
踩
ADC的概念:
Analog-to-Digital Converter的缩写。指模/数转换器或者模拟/数字转换器。是指将连续变化的模拟信号转换为离散的数字信号的期间。
ADC的作用:
采集传感器数据,测量输入电压,检查电池电量剩余,监测温湿度等。
典型的模拟数字转换器将模拟信号转换为表示一定比例电压值的数字信号,具体的方法如下图所示。
我们都知道,模拟信号是连续信号,数字信号是离散信号,模数转换的基本做法就是将连续的模拟信号抓换成离散的数字信号。一般而言,我们在开发过程中都是将传感器的模拟信号,通过stm32的ADC,将模拟的信号转换成用一定数值表示的数字信号。
我们在采集模拟信号的过程中,由于每个采集点之间的时间的不同,所以导致用数字信号拟合到的模拟信号也是不同的,当采集点越密,拟合的模拟信号也就越准确,这也就有了下面分辨率的概念。
ADC的性能指标:
stm32f103的ADC特性:
以上就是ADC的功能框图,stm32的ADC转换功能就是通过以上框图完成的。这个框图大概分为7的部分,第一部分是电压输入范围,第二部分是输入通道,第三部分是转换顺序,第四部分是转换时钟来源,第五部分是相关数据寄存器,第六部分是相关标志位和相应中断使能位,第七部分是触发源选择,下面我们来一个部分一个部分讲解。
每个ADC有16的外部通道,另外还有两个内部ADC源挂载到ADC1上
上面的图片是3个ADC不同的通道对应的不同的引脚,ADC1除了这16路ADC通道以外,还有两个ADC通道,一路为内部温度传感器,另一路为内部参照电压,这些电路构成了整个ADC的通道结构。
第三部分主要是用来配置转换顺序的
我们可以很清楚的看到,第三个部分分为注入通道组合规则通道组
ADC时钟:
ADC的时钟来源是由PCLK2经过分频产生的,stm32f103系列的时钟最大可以配置为14MHZ,但是PCLK2的时钟是72MHZ,所以我们一般要进行6分频来进行对ADC时钟的配置。
ADC的总转换时间:
ADC使用若干个ADC_CLK周期对输入电压进行采样,采样周期数目可以通过ADC_SMPR1和ADC_SMPR2寄存器中的SMP[2:0]位进行更改。每个通道可以分别用不同的时间采样。
总转换时间如下计算:
Tconv = 采样时间+12.5个周期
例如当ADCCLK=14MHZ的时候,采样时间为1.5周期
Tconv = 1.5+12.5 = 14周期 = 1us
由于我们最主要使用的是规则通道组,因此我们这个地方就只介绍规则数据寄存器
规则数据寄存器ADC_DR:
ADC_DR只有一个,是一个32位的寄存器,只有低16位有效并且只是用于独立模式存放转换完成的数据。因为stm32f103的ADC的精度是12位,ADC_DR是16位有效,这样就会产生数据存放过程中左对齐或者右对齐的情况存在。我们在使用ADC转换的时候,一般都是使用右对齐,因为这样可以让12位的数据存放在DR的低12位中,方便我们读取。如果要是设置为左对齐,这样取出数据后还要进行一定的转换,不利于我们对数据的处理。
由于规则通道组只有一个数据寄存器,因此,对于多个规则通道的转换,使用DMA非常有帮助。这样可以避免丢失在下一次写入之前还未被读出的ADC_DR寄存器中的数据。在使能DMA模式的情况下,每次完成规则通道组中的一个通道转换后,都会生成一个DMA请求。
第六个部分主要就是进行相关标志位的读写操作并且对相关标志位进行使能。
但是我们平常主要是使用软件触发源来进行ADC的触发转换。
单次转化非扫描模式是最简单的一种模式,我们每次都只会转换一条通道,并且当这条通道转换完成后也不会去扫描是否有下一条通道开启了转换,当转换完成后就直接将标志位EOC进行置位,通知我们转换完成。
连续转换非扫描模式也比较简单,这个模式也是只能进行一条通道的转换,当开启转换后,会一直持续转换这一条通道的值,每次转换结束会将EOC置位,并且接着进行下一次的转换。当我们需要读取转换结果的时候,就直接从DR寄存器里面读取就好了。
单次转换扫描模式也是开启转换后需要只进行一次转换,但是这次转换并不只是转换一个通道,而是配置扫描模式的所有通道进行转换,如上图,转换开启后,先进行通道2的转换,然后依次为通道5、通道4…最后到通道6转换结束,EOC置位,当无转换开始信号的时候,不自动开启下一轮的转换。
当然,我们还需要配置通道数目,当我们配置为7个通道数目的时候,可以将上面的通道全部转换,但是只配置6个通道数目的时候,就只能转换到通道3,这也就是配置通道数目的作用。
但是当我们设置扫描模式的时候,需要及时将数据读走,否则每个通道的转换都会将输入存入DR寄存器,这样如果不及时读走数据,那么数据就会被覆盖。
连续转换扫描模式就是在扫描模式的基础上加上连续转换,当所配置的所有通道依次转换完成后,转换不会停止,而是继续新一轮的转换。
总的来说,扫描模式就是依次扫描配置的通道进行转换,连续模式就是指ADC转换完成后不停止,继续下一次的转换,这两种模式的组合就构成了上述的4种模式。
实验要求:利用ADC1采集模拟量并转换成数字量。
USART1的配置和其他配置和原来相同。
HAL_ADC_Start( &hadc1); //开启ADC
if(HAL_ADC_PollForConversion(&hadc1, 100)==HAL_OK ) //如果转换结果完成
{
printf("the adc value is %d\r\n",HAL_ADC_GetValue(&hadc1));//读取打印结果并用串口打印出来结果
}
HAL_Delay(1000); //延时1s,防止采样过快
我用的是光敏传感器来进行采样的,采样结果如下:
当无遮挡的时候,采样结果大概在900左右;当遮挡住以后,采样结果大概在2500左右。
用中断方式来进行ADC的转换我们需要进行两个部分的代码的书写
首先是main.c中的ADC中断开启函数,然后就是ADC中断的回调函数。
下面就是两段代码
main.c中的代码
HAL_ADC_Start_IT(&hadc1); //开启ADC转换中断
HAL_Delay(1000);//延时1s
adc.c中的ADC的回调函数
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) //进入ADC中断
{
if(hadc->Instance==ADC1) //判断是否为ADC1的中断
{
printf("the ADC value is %d\r\n",HAL_ADC_GetValue(&hadc1));//打印相关内容
}
}
转换结果如下:
当我用手将传感器全部捂住以后,显示结果在3500左右,当有一定缝隙的时候,结果在2500左右,当完全暴露的时候,结果在900左右。
多通道采集的过程中,因为规则转换组只有一个数据寄存器,因此我们需要每转换完一次,都要及时运走数据,否则就会被覆盖。
我尝试了两种方法来进行数据及时搬运。
一种是通过读取DR寄存器,当DR寄存器不等于0的时候,就立马读走数据。
另一种方法是我设置两个通道的转换时间相同,可以触发半次转换完成中断和转换完成中断,这两个分别来读取数据。
但是这两种方法都无法将两个通道的数据及时读出来,因此,我们还是在下一章学习了DMA以后,再进行多通道数据的采集吧。
如果有人不使用DMA将两个数据的通道都读出来了,欢迎评论和我交流。
ADC的相关寄存器包括以下几个:
状态寄存器主要是用低5位,其余位置保留,这里主要是用来表示ADC的相关状态,包括规则通道转换开始标志位,注入通道转换开始标志位,注入通道转换完成标志位、通道转换完成标志位、模拟看门狗标志位等。
控制寄存器主要是用来控制相关配置的,但是有很多的位不太重要,我们下面找几个比较重要的位来说一下。
位5-位8是比较重要的位,位5是允许产生EOC中断,位6是允许模拟看门狗中断,位7是允许产生注入通道转换结束中断,位8是设置扫描模式(扫描模式下,设置了EOCIE或者JEOCIE位,只有最后一个通道转换完毕后才能产生EOC或者JEOC中断。)
这个寄存器我们也主要介绍比较重要的位。
位0控制ADC转换的启动
位1控制连续转换或者单次转换
位8控制是否启动DMA
位11控制对齐方式
这两个寄存器分别配置17个通道的采样周期,寄存器2配置前9个通道的采样周期,寄存器1配置剩下的采样周期。
ADC的看门狗寄存器可以用于配置阈值上限和阈值下限
超过阈值上限或者低于阈值下限就会产生相应的事件。
ADC的数据寄存器包括注入数据寄存器和规则数据寄存器
其中,注入数据寄存器有四个,可以分别保存注入4个注入通道组的转换数据;规则数据寄存器只有一个,用于保存规则通道组中的转换数据。
以上就是关于相关ADC的知识,欢迎大家批评指正!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。