STM32F103(十八)ADC总结(5W字)
Posted 自信且爱笑‘
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32F103(十八)ADC总结(5W字)相关的知识,希望对你有一定的参考价值。
学习板:STM32F103ZET6
ADC
- 一、ADC简介
- 二、ADC相关寄存器
- 1、 ADC状态寄存器(ADC_SR)
- 2、 ADC控制寄存器 1(ADC_CR1)(极其重要)
- 3、 ADC控制寄存器2(ADC_CR2)
- 4、ADC采样时间寄存器 1(ADC_SMPR1)和 ADC采样时间寄存器 2(ADC_SMPR2)
- 5、 ADC注入通道数据偏移寄存器x (ADC_JOFRx)(x=1..4)
- 6、ADC看门狗高阀值寄存器(ADC_HTR)和ADC看门狗低阀值寄存器(ADC_LRT)
- 7、ADC规则序列寄存器 1~3(ADC_SQR1 ~3)(重点说明一个东西)
- 8、ADC注入序列寄存器(ADC_JSQR)
- 9、ADC 注入数据寄存器x (ADC_JDRx) (x= 1..4)
- 10、ADC规则数据寄存器(ADC_DR)
- 三、ADC相关库函数
- 1、ADC时钟设置函数RCC_ADCCLKConfig()
- 2、ADC初始化函数ADC_Init()(+扫描模式和连续转换区别)
- 3、ADC使能函数ADC_Cmd()
- 4、ADC的DMA使能函数ADC_DMACmd()
- 5、ADC中断使能函数ADC_ITConfig()
- 6、ADC初始化取消函数ADC_DeInit()
- 7、ADC结构体初始化函数ADC_StructInit()
- 8、ADC复位校准函数ADC_ResetCalibration()
- 9、获取复位校准状态函数FlagStatus ADC_GetResetCalibrationStatus()
- 10、ADC校准函数ADC_StartCalibration()
- 11、获取ADC校准状态函数FlagStatus ADC_GetCalibrationStatus()
- 12、启用或禁用ADC软件转换函数ADC_SoftwareStartConvCmd()
- 13、ADC软件开启转换状态获取函数FlagStatus ADC_GetSoftwareStartConvStatus()
- 14、ADC间断模式下通道数设置函数ADC_DiscModeChannelCountConfig()
- 15、ADC间断模式使能函数ADC_DiscModeCmd()
- 16、ADC规则通道设置函数ADC_RegularChannelConfig()
- 17、外部触发转换设置函数ADC_ExternalTrigConvCmd()
- 18、获取ADC转换值函数uint16_t ADC_GetConversionValue()
- 19、返回DR寄存器值函数uint32_t ADC_GetDualModeConversionValue(void);
- 20、自动的注入通道转换设置函数ADC_AutoInjectedConvCmd()
- 21、注入通道上的间断模式设置函数ADC_InjectedDiscModeCmd()
- 22、启动注入通道组转换的外部事件设置函数ADC_ExternalTrigInjectedConvConfig()
- 23、外部事件触发注入通道转换的使能函数ADC_ExternalTrigInjectedConvCmd()
- 24、软件触发注入通道使能函数ADC_SoftwareStartInjectedConvCmd()
- 25、获取ADC注入通道状态函数FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus()
- 26、ADC注入通道设置函数ADC_InjectedChannelConfig()
- 27、注入通道序列长度设置函数ADC_InjectedSequencerLengthConfig()
- 28、设置注入通道偏移量函数ADC_SetInjectedOffset()
- 29、获取注入通道转换值函数uint16_t ADC_GetInjectedConversionValue()
- 30、模拟看门狗设置函数ADC_AnalogWatchdogCmd()
- 31、模拟看门狗阈值设置函数ADC_AnalogWatchdogThresholdsConfig()
- 32、通道的模拟看门狗设置函数ADC_AnalogWatchdogSingleChannelConfig()
- 33、启用或禁用温度传感器和Vrefint通道函数ADC_TempSensorVrefintCmd()
- 34、获取ADC转换状态函数FlagStatus ADC_GetFlagStatus()
- 35、清除标志位函数ADC_ClearFlag()
- 36、获取中断状态函数ADC_GetITStatus()
- 37、清除中断标志位函数ADC_ClearITPendingBit()
- 38、最后说明
- 四、ADC编程顺序
- 五、例1(单通道转换一次)
- 六、举例(多规则通道,扫描模式转换)
- 七、例3(单通道连续模式)
- 八、结束语
一、ADC简介
1、详述
ADC(Analog Digital Converter),顾名思义为模拟to数字转换,将模拟信号转化为一定比例的电压值。对于32的GPIO来讲,通常只有高电平和低电平之分,即当识别到高电平时并不能知道是3.3V还是3.2V。使用ADC后就可以很好的检查出电平具体是多少伏特了。所以不要把ADC单纯的理解为模拟->数字的转换,而要理解为未知(伏值)信号—>已知(伏值)信号的转换。
可以这样理解,当一个信号输入的MCU时,哪怕它是模拟信号,由于MCU的识别占用一定时间,所以看似是识别模拟信号,其实信号已经算是抽样信号了。
学过《信号与系统》的朋友应该知道模拟信号、抽样信号、数字信号的区别。现再区别一下:
模拟信号:时间连续、幅值连续的信号。比如声音信号、温度信号
抽样信号:时间离散、幅值连续的信号。比如每隔一个时间取一个声音信号值。
数字信号:时间离散、幅值离散的信号。比如每隔一个时间取一个声音信号值,然后将所有取值量化到一个幅值区间。
通过《信号与系统》我们知道,模拟信号到数字信号必须经过抽样和量化。
再回到ADC内容,如果将模拟信号输入到单片机的GPIO,由于单片机的识别有一定时间,如每识别一次信号需要1us,则此时单片机其实已经将模拟信号自动转换为时间间隔为1us的抽样信号。但是仅仅是抽样信号,单片机只知道它是每隔1us的信号是高电平还是低电平,并不知道它具体幅值多少。那么通过ADC,可以较为准确的将幅值量化(经过量化就变成数字信号了)。量化的幅值范围与设置的参考电压有关,将幅值量化到参考电压范围内。
2、STM32的ADC数量和通道数
STM32拥有1~3个ADC,具体几个与芯片型号有关系。都是采用12位逐次逼近型模数转换器,有18个通道,其中16个通道测量外部输入,2个为内部信号源检测(注意不是外设),从芯片图中也能看到,下图已高亮:
归结为下图:
3、STM32的ADC时钟
上图红色箭头显示,ADC的最大时钟为14MHZ。图中绿色标注和蓝色标注是底层中的设置的各类时钟。系统时钟为72MHZ,AHB预分频系数为1,则ADC预分频系数必须大于等于6,所以我习惯把预分频系数设置为6,此时ADC的时钟频率为12MHZ。
4、STM32的ADC转换速率
ADC转换时间=采样时间+12.5个时钟周期
这个采样时间可以设置,最小为1.5个时钟周期
所以最大转换速率=1.5+12.5=14(个时钟周期),ADC最大时钟频率为14MHZ,则14个时钟周期为1us,即最快时(采样周期最小、时钟最大)为1us
5、STM32的ADC规则通道和注入通道
ADC的规则通道和注入通道很好理解。正常情况下只需使用规则通道,规则通道最多16个通道转换,根据实际需求选择转换通道数量。如有8路信号,则可以把每一路信号接ADC的不同引脚,并都可设置为规则通道,此时有8个规则通道。
注入通道就可以把它看做是中断。当执行某一功能的ADC转换A时,突然想执行另一个ADC转换B,这样需要中断此时的ADC转换A去执行ADC转换B,此时可用将转换A设置为规则通道,转换B设置为注入通道。注入通道最多有四个。这个控制触发注入通道的信号可用是内部信号、外部中断、定时器输入捕获通道的信号。
6、ADC框图(比较重要)
上图中:
绿色框框是注入通道的触发,主要是外部中断、定时器输入捕获通道、定时器内部信号。
红色框框是ADC的0~15的16个外部通道、内部温度传感器和VREFINT两个内部通道。
蓝色框框是参考电压、供电电压。ADC量化后输出负参考电压~正参考电压直接的值;一般参考电压为0 ~3.3V;VDDA和VSSA给ADC的模数转换器供电
如下图所示:
正参考电压=VDDA=3.3V
负参考电压=VSSA=0
供电正=VDDA=3.3V
供电负==VSSA=0
黄色框框是设置中断、看门狗。当规则通道转换结束后ADC状态寄存器ADC_SR位1(EOC)硬件置1,当注入通道转换结束后ADC状态寄存器ADC_SR位2(JEOC)硬件置1。如果使能了ADC中断,则会进入中断服务函数。
深蓝色框框是ADC模拟看门狗,ADC输入的模拟电压值幅值要在一定范围内,这个范围在下面俩个寄存器中设定。当输入电压低于低阈值或高于高阈值时ADC模拟看门狗被激活。注意这个看门狗可以作用于1个或多个通道,且只需将对应通道的ADC转换重新复位,程序不用完全复位。
二、ADC相关寄存器
1、 ADC状态寄存器(ADC_SR)
位0:模拟看门狗标志位
当输入的模拟信号低于低阈值或高于高阈值时(ADC_LTR和ADC_HTR寄存器定义),该位硬件置1,发生看门狗事件。
位1:转换结束标志位
当只进行规则通道转换时,各通道转换结束后该位置1;当一次ADC转换期间包含了注入通道转换,则当规则和注入通道转换都结束后该位才置1 。(相当于中断返回后继续执行完本通道转换才置1)
注意该位可以软件清零或者读ADC_DR寄存器清零,正因为需要软件清零或者读DR寄存器清零,所以才不用担心多个规则通道连续模式时数据来不及读取。
位2:注入通道转换结束标志位
当注入通道转换结束(可能一次“中断”有多个注入通道转换,需要全部结束)后该位硬件置1。
位3:注入通道开始标志位
当发生“中断”进行注入通道转换时,该位硬件置1 。
位4:规则通道开始标志位
当规则通道开始转换时,该位硬件。
当然在程序中可以通过识别该寄存器的对应位来得到状态,如判断注入通道转换是否结束,代码:
if(ADC1->SR&0x04)
{
}
2、 ADC控制寄存器 1(ADC_CR1)(极其重要)
位4:0:模拟看门狗通道选择
需要注意的是ADC1的16个外部通道和2个内部通道都用到了。而ADC2、ADC3的通道只用到一部分。
位5:允许产生EOC中断位
当规则通道全部转换完成后,SR寄存器的位1位硬件置1,如果CR1寄存器位5置1允许中断,则会发生中断。
位6:允许产生模拟看门狗中断位
如果输入模拟信号的电源低于低阈值或高于高阈值,会发生错误,如果允许了看门狗,则会重新执行通道转换。如果该寄存器位6置1,允许产生看门狗中断,则会发生中断。
位7:允许产生注入通道转换结束中断位
当注入通道转换结束后,寄存器SR的位2硬件置1表示结束。当CR1寄存器位7置1允许中断时,会产生中断。
位8:扫描模式设置位
该位设置连续扫描模式,当该位值1时,会扫描所有被ADC_SQRX寄存器(对规则通道)或ADC_JSQR(对注入通道)选中的通道。且每个通道只转换1次,一个通道转换结束后,会自动转换下一个通道,当所有选中的通道都被转换一次后,再重新开始转换所有通道。
如果设置了规则通道和注入通道中断,当所有通道都被转换后才能发生中断。
如果设置了DMA位,在每次EOC后,DMA控制器把规则组通道的转换数据传输到SRAM中。而注入通道转换的数据总是存储在ADC_JDRx寄存器中。
位9:扫描模式中单一通道使用模拟看门狗
当位8置1设置了扫描模式,每个选中的通道都会进行一次转换。对于单个通道,如果输入模拟信号低于设置的低阈值或高于设置的高阈值会触发看门狗,并重新执行对应通道的转换。
位10:自动的注入通道组转换
之前也总结过,注入通道转换时要触发,有外部中断触发、定时器输入捕获通道信号触发、定时器内部信号源触发。如果位10置1设置自动注入通道转换,则不再需要触发,当所有规则通道执行完毕后,自动执行注入通道转换。
位11:规则通道上的间断模式
位12:注入通道上的间断模式
位15:13:间断模式通道计数
这个间断模式细讲一下:
首先间断模式的通道个数:本寄存器的位15:13设置1~8个,即选择一次外部触转换几个通道。
其次间断模式的哪几个通道:转换的所有通道时SQRx(1~3)选择的通道。SQRx设置了一个转换序列的通道次序。
如设置有10个通道:1、9、8、2、4、11、3、5、7、6;正常情况下一个转换序列就是按照这个顺序来的。现在把它设置为间断模式,且CR1寄存器位15:13=011,即每次外部触发后转换三个通道。则有:
第一次外部触发:转换1、9、8
第二次外部触发:转换2、4、11
第三次外部触发:转换3、5、7
第四次外部触发:转换6
第四次转换完成后,SR寄存器的位1硬件置1表示规则通道转换完成。
以上说的是规则通道,注入通道也一样,不过注入通道的序列长度、通道顺序都在JSQR寄存器中设置。
如:JSQR寄存器位21:20=11,表示4个注入通道,然后位19:15、14:10、9:5、4:0分别设置注入通道顺序。注入通道:15、10、13、12
每次外部触发后,只能执行一次注入通道转换:
第一次外部触发:转换通道15
第二次外部触发:转换通道10
第三次外部触发:转换通道13
第四次外部触发:转换通道12
第四次触发并转换完毕后会SR寄存器相关位置1表示转换结束,如果设置了注入通道中断,还会发生中断。
第五次外部触发:转换通道15…
注意:自动注入和间断模式不能同时使用
位19:16:双模式选择
这个了解即可,反正我从来没用到过。可以查看中文参考手册了解了解。
位23、位22:规则通道、注入通道开启模拟看门狗
当对应位置1后,如果输入信号超出定义的阈值,会发生看门狗事件,重新转换对应通道。
3、 ADC控制寄存器2(ADC_CR2)
位0:开/关A/D转换器
需要注意的是要单独对该寄存器设置,最好不要用下面的方法:
ADC1—>CR2|=0x...1//(非1数)
即开启AD转换时最好单独成行:
ADC1->CR2|=1;
位1:连续转换设置位
如果设置该位设置了1,则前面的ADC转换(整个序列)刚结束就开启另一次转换。不过每个规则通道转换结束后都能产生结束标志(SR寄存器)、都可产生中断(如果使能了中断)。注入通道也一样。
位2:A/D校准
ADC内置一个自校准模式,可大幅减小因内部电容器组的变化而造成的准精度误差,校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换中每个电容器上产生的误差。
当校准结束后,该位会被硬件置1
注意校准时机,一般在ADC上电之前校准,校准完成后,只是隔2个ADC时钟周期再启动ADC。
位3:复位校准
由软件设置,硬件清零,一般情况下可以不用。
位8:直接存储器访问模式
设置DMA
位11:设置数据对齐
通道转换数据会存储在DR寄存器,DR寄存器为32位寄存器,除了双模式下用到高16位,其他情况下通道转换数据都存储在低16位中,上图所示的对齐,一般采用右对齐,即该位置0
位14:11:选择启动注入通道组转换的外部事件
之前也总结到,启动注入通道时,需要外部中断触发、定时器捕获通道信号触发、定时器内部信号源触发,这3位就是来设置触发方式的。
位15:选择启动注入通道组转换的外部事件
该位使能外部触发注入通道,与位14:11一起配合设置。
位19:17:选择启动规则通道组转换的外部事件
在扫描模式下,各规则通道时按照设定序列连续、循环转换的。如果不采用扫码模式,可以使用外部触发的方式,当有外部信号触发时再启动ADC转换。
位20:规则通道的外部触发转换模式
使能规则通道的外部触发转换模式,与位19:17配合设置。
位21:开始转换注入通道
当该位置1后停止规则通道转换(那怕规则通道序列没有执行完毕),开始转入注入通道转换。
位22:开始转换规则通道
该位置1后开始规则通道序列转换。
位22:温度传感器和VREFINT使能
温度传感器和VREFINT使能是ADC1特有的通道16、和17两个内部信号转换,用来使能这两个通道功能。下一博客会总结这两块的内容。
4、ADC采样时间寄存器 1(ADC_SMPR1)和 ADC采样时间寄存器 2(ADC_SMPR2)
ADC_SMPR1寄存器来设置通道10~17的采样时间,每3位设置一个通道。
ADC_SMPR2寄存器来设置通道0~9的采样时间,每3位设置一个通道。
当然可以不设置,这样采样时间就默认为1.5个周期,此时也是通道转换最快的情况。
5、 ADC注入通道数据偏移寄存器x (ADC_JOFRx)(x=1…4)
这四个寄存器分别对应四个注入通道(注入通道最多四个)
该寄存器中存储的偏移量只用于注入通道的数据对齐,而对规则通道无效。
目的是将注入通道的转换的数据值减去该寄存器存储的偏移量,让这个值可以为负数,并储存在ADC_JDRx寄存器中。
6、ADC看门狗高阀值寄存器(ADC_HTR)和ADC看门狗低阀值寄存器(ADC_LRT)
这两个寄存器来设置模拟看门狗的上下限的,设置了上下限后,ADC的模拟输入幅值就有了一个范围限定,如果模拟输入超过这个上、下限范围,会触发模拟看门狗,重新转换对应通道,程序不会跳转到下一通道的采集。
7、ADC规则序列寄存器 1~3(ADC_SQR1 ~3)(重点说明一个东西)
这三个寄存器用来设置某次AD转换中所有规则通道的转换次序,如果多路信号输入,由于选用的引脚不同,即可能不是只用到前几个通道,通道占用是打乱的,那么怎么才能有序的识别出来呢?
比如:
第一路信号使用ADC通道1
第二路信号使用ADC通道5
第三路信号使用ADC通道2
第四路信号使用ADC通道10
第五路信号使用ADC通道14
第六路信号使用ADC通道3
第七路信号使用ADC通道4
…
则可以将ADC_SQR3的:
位4:0(序列中第一个要转换的通道序号)值1,表示第一个转换通道是通道1,所以位4:0=00001
位9:5(序列中第二个要转换的通道序号)值5,表示第二个转换通道是通道5,所以位9:5=0x00101
位14:10(序列中第三个要转换的通道序号)值2,表示第三个转换通道是通道2,所以位14:10=0x00010
位19:15(序列中第四个要转换的通道序号)值10,表示第四个转换通道是通道10,所以位19:15=0x01010
位24:20(序列中第五个要转换的通道序号)值14,表示第五个转换通道是通道14,所以位24:20=0x01110
位29:25(序列中第六个要转换的通道序号)值3,表示第六个转换通道是通道3,所以位29:25=0x00011
ADC_SQR2寄存器:
位4:0(序列中第七个要转换的通道序号)值4,表示第七个转换通道是通道4,所以位4:0=0x00100
8、ADC注入序列寄存器(ADC_JSQR)
该寄存器与SQRx(1~3)类似,用来设置注入通道序列顺序的。
接上面例子,将第8、9、10三路信号作为注入通道信号。
第八路信号使用ADC通道6、则JSQR寄存器位4:0=6,表示注入序列执行的第一个通道为通道6,位4:0=0x00110
第九路信号使用ADC通道7、则JSQR寄存器位9:5=7,表示注入序列执行的第二个通道为通道7,位9:5=0x00111
第十路信号使用ADC通道8、则JSQR寄存器位14:10=8,表示注入序列执行的第三个通道为通道8,位14:10=0x01000
9、ADC 注入数据寄存器x (ADC_JDRx) (x= 1…4)
该寄存器用来储存每次注入序列的每个通道转换完成后的值。需要及时读取,否则会被注入序列的下一次转换结果覆盖。
10、ADC规则数据寄存器(ADC_DR)
用来储存规则序列的各通道转换结果也需要及时读取,否则会覆盖。
三、ADC相关库函数
ADC的函数主要集中在stm32f10x_adc.h中
使用前需要将.c文件添加进来:
1、ADC时钟设置函数RCC_ADCCLKConfig()
该函数在stm32f10x_rcc.h中
参数:
表示几分频后作为ADC时钟。上图红色箭头所示,ADC最大时钟频率是14MHZ,默认状态下系统时钟是72MHZ,故至少需要6分频,所以一般情况下设置参数为RCC_PCLK2_Div6
即可。
2、ADC初始化函数ADC_Init()(+扫描模式和连续转换区别)
(1)参数1
表示哪个ADC
(2)参数2
参数2是一个结构体,看一下结构体的各成员变量:
①ADC_Mode
选择ADC的模式
上述的模式:
之后项目中用到可能会回来总结一下双ADC模式,也可能不总结了。本博已经总结太多了。
正常情况先选则独立模式: ADC_Mode_Independent
②ADC_ScanConvMode
选择是否开启扫描模式,对于多个规则通道来讲,可以开启扫描模式,每个通道都循环转换;或者想一直显示,可以开启扫描模式。核心意图就是是否让ADC不停的去转换。对于单次转换,可以不设置扫描模式。
③ADC_ContinuousConvMode
设置是否开启连续转换。对于单次转换,可以不设置。
这里区分一下连续转换和扫描模式的区别:
只要记住扫描模式要执行完全部通道的;连续模式是你执行完毕后还要不要自动重新执行。
举个例子:
假如有5个规则通道的序列,且规则序列的顺序被设置好了,转换顺序为A、B、C、D、E
不在扫描模式下:
单次转换模式下:
启动ADC——>执行A——>等待下次启动——>启动ADC——>执行A——>等待下次启动
连续转换模式下:
启动ADC——>执行A——>执行A——>执行A…
扫描模式下:
单次转换模式下:
启动ADC——>执行A——>执行B——>执行C——>执行D——>执行E——>等待ADC启动——>启动ADC——>执行A——>执行B——>执行C——>执行D——>执行E——>等待ADC启动…
连续转换模式下:
启动ADC——>执行A——>执行B——>执行C——>执行D——>执行E——>执行A——>执行B——>执行C——>执行D——>执行E——>执行A…
扫描模式下,如果设置了DMA位,在每次EOC后,DMA控制器把规则组通道的转换数据传输到SRAM中。而注入通道转换的数据总是存储在ADC_JDRx寄存器中。
所以扫描模式要配合DMA使用的。
④ADC_ExternalTrigConv
这个参数用来设置启动规则转换组转换的外部事件
根据需要设置,如果设置了定时器捕获通道信号触发,则输入捕获那一块也得设置。所以一般可以用ADC_ExternalTrigConv_None
,采用软件触发。
当然可以灵活运用,使用外部中断,当有外部中断时设置ADC转换也可以实现相应的功能。
⑤ADC_DataAlign
设置ADC数据存储是左对齐还是右对齐
一般采用右对齐ADC_DataAlign_Right
,即低位对齐
⑥ADC_NbrOfChannel
设置规则序列长度,即设置使用ADC几个通道。
3、ADC使能函数ADC_Cmd()
参数1:
选择哪个ADC
参数2:
DISABLE或ENABLE
4、ADC的DMA使能函数ADC_DMACmd()
参数1:
选择哪个ADC
参数2:
DISABLE或ENABLE
这个函数使能了DMA,但是DMA还需要另外设置,这个之后博客会有专门一篇博客来总结。
5、ADC中断使能函数ADC_ITConfig()
参数1:
选择哪个ADC
参数2:
分别是规则通道转换中断、模拟看门狗中断、注入通道转换中断
参数3:
DISABLE或ENABLE
6、ADC初始化取消函数ADC_DeInit()
从函数体上也可以看到,将ADC的寄存器设置为缺省值。
7、ADC结构体初始化函数ADC_StructInit()
通过函数体可以看到,设置ADC初始化函数的那个结构体参数为:
独立模式、非扫描模式、非连续模式、定时器1通道1捕获信号触发、右对齐、一个ADC通道。
8、ADC复位校准函数ADC_ResetCalibration()
参数:
选择哪个ADC
是对CR2寄存器位3的操作。
9、获取复位校准状态函数FlagStatus ADC_GetResetCalibrationStatus()
参数:
选择哪个ADC
看一下函数体:
当处于复位校准状态时,CR2寄存器位3为1,此时执行:
ADCx->CR2 & CR2_RSTCAL_Set
后值为1
当复位校准完成后,位3硬件置0,执行:
ADCx->CR2 & CR2_RSTCAL_Set
后值为0。
故该函数返回SET表示正处于校准状态,返回RESET表示复位校准已经完成。
10、ADC校准函数ADC_StartCalibration()
该函数是对CR2寄存器位2的操作
将该位置1,进行ADC校准。
可以在启动ADC之前使用该函数校准ADC
11、获取ADC校准状态函数FlagStatus ADC_GetCalibrationStatus()
当处于校准状态时,CR2寄存器位2为1,此时执行:
ADCx->CR2 & CR2_CAL_Set
后值为1
当复位校准完成后,位2硬件置0,执行:
ADCx->CR2 & CR2_CAL_Set
后值为0。
故该函数返回SET表示正处于校准状态,返回RESET表示校准已经完成。
12、启用或禁用ADC软件转换函数ADC_SoftwareStartConvCmd()
参数1:
选择哪个ADC
参数2:
DISABLE或ENABLE
当参数为ENABLE时:
执行:
ADCx->CR2 |= CR2_EXTTRIG_SWSTART_Set;
此时CR2寄存器的位22和位20都为1,即使用外部时间触发转换,并同时开启转换通道(虽然打开,但只有当外部信号到了触发完成后才开始转换)。
故当参数为ENABLE是选择外部触发来开启转换
当参数为DISABLE时:
执行:
ADCx->CR2 &= CR2_EXTTRIG_SWSTART_Reset;
此时CR2寄存器的位22和位20都为0,即不使用外部时间触发转换,并关闭转换通道
故当参数为DISABLE是选择软件触发来开启转换
13、ADC软件开启转换状态获取函数FlagStatus ADC_GetSoftwareStartConvStatus()
该函数是对CR2寄存器位22的操作
当转换通道开启时,该位为1,执行
ADCx->CR2 & CR2_SWSTART_Set
后的值为1,返回SET。
当转换通道未开启时,该位为0,执行
ADCx->CR2 & CR2_SWSTART_Set
后的值为0,返回RESET。
故返回SET时表示转换通道开启,返回RESET时表示转换通道未开启。
14、ADC间断模式下通道数设置函数ADC_DiscModeChannelCountConfig()
参数1:
选择哪个ADC
参数2:
为1~8之间的数。
该函数是对CR1寄存器位15:13的操作
间断模式之前总结过,不在赘述
理解一下以下代码:
tmpreg1 = ADCx->CR1;
/* Clear the old discontinuous mode channel count */
tmpreg1 &= CR1_DISCNUM_Reset;
/* Set the discontinuous mode channel count */
tmpreg2 = Number - 1;
tmpreg1 |= tmpreg2 << 13;
/* Store the new register value */
ADCx->CR1 = tmpreg1;
第一行是把CR1目前的状态赋值给tmpreg1 。
第二行是tmpreg1 =tmpreg1 &0xffff1fff
,即对CR1寄存器位15:13清零
第三行对第二个参数Number -1,因为输入1的时候表示间断模式下一次转换的通道数是1,此时位15:13=0,故位15:13的值与Number 相差1.
第四行对tmpreg2 先左移13位后Number - 1的值与位15:13对齐了,然后或运算,覆盖位15:13
第五行直接赋值,对CR1寄存器的位15:13重新赋值。
15、ADC间断模式使能函数ADC_DiscModeCmd()
参数1:
选择哪个ADC
参数2:
ENABLE或DISABLE
该函数是对CR1寄存器位11操作,当参数2为ENABLE时表示设置为间断模式,当参数2为DISABLE时设置为不使用间断模式。
16、ADC规则通道设置函数ADC_RegularChannelConfig()
参数1:
选择哪个ADC
参数2:
表示哪个规则通道:
参数3:
规则序列中参数2所在的第几位。
参数3范围是1~16,对应SQR1 ~3寄存器,之前非常详细的说过。
参数4:
参数4是选择采用时间。
17、外部触发转换设置函数ADC_ExternalTrigConvCmd()
参数1:
选择哪个ADC
参数2:
ENABLE或DISABLE
该函数是对CR2寄存器的位20操作,当参数2为ENABLE时表示使用外部触发ADC转换,当参数为DISABLE时表示不使用外部触发ADC转换。
这个函数与本目:12、启用或禁用ADC软件转换函数ADC_SoftwareStartConvCmd()
功能类似,总结的时候一直觉得哪个函数不太好,所以以后可以用这个函数。
18、获取ADC转换值函数uint16_t ADC_GetConversionValue()
参数:
选择哪个ADC
该函数是对DR寄存器的操作,通道转换结束后会把转换值存储在DR寄存器中,通过该函数获取转换值
19、返回DR寄存器值函数uint32_t ADC_GetDualModeConversionValue(void);
20、自动的注入通道转换设置函数ADC_AutoIn
以上是关于STM32F103(十八)ADC总结(5W字)的主要内容,如果未能解决你的问题,请参考以下文章