STM32学习(ADC模数转换器)

1.ADC简介

ADC(Analog-Digital Converter)模拟-数字转换器
ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁
12位逐次逼近型ADC,1us转换时间
输入电压范围:0~3.3V,转换结果范围:0~4095
18个输入通道,可测量16个外部(GPIO口,在引脚直接接模拟信号就行)和2个内部信号源(内部温度传感器和内部参考电压,温度传感器可以测量CPU的温度,比如你电脑可以显示CPU的温度,就可以用ADC读取这个温度传感器来测量,内部参考电压是1.2V左右的基准电压,这个基准电压不随外部电压变化而变化的,所以如果你芯片的供电不是标准的3.3V,那测量外部引脚的电压可能就不对,这是就可以读取这个基准电压进行校准,这样就可以得到正确的电压值)
规则组和注入组两个转换单元
模拟看门狗自动监测输入电压范围

STM32F103C8T6 ADC资源:ADC1、ADC2,10个外部输入通道

2.ADC基本结构

        左边是输入通道,16个GPIO口,外加两个内部通道,然后进入AD转换器,AD转换器里有两个组,一个是规则组,一个是注入组,规则组最多可以选中16个通道,注入组最多可以选择4个通道,然后转换的结果可以存放在AD数据寄存器里,其中规则组只有1个数据寄存器,注入组4个,然后下面有触发控制源,提供了开始转换这个START信号,触发控制可以选择软件触发和硬件触发,硬件触发主要来自定时器,当然页可以选择外部中断的引脚,右边这里是来自于RCC的ADC时钟CLOCK,ADC逐次比较的过程就是由这个时钟推动的,然后上面,可以布置一个模拟看门狗用于检测转换结果的范围,如果超出设定的阈值。就通过中断输出控制,向NVIC申请中断,另外,规则组和注入组转换完成后会有个EOC信号,它会置一个标志位,当然也会通向NVIC,最后右下角这里还有个开关控制,在库函数中,就是ADC_Cmd函数,用于给ADC上电的。

3.ADC知识点

3.1 输入通道

通道

ADC1

ADC2

ADC3

通道0

PA0

PA0

PA0

通道1

PA1

PA1

PA1

通道2

PA2

PA2

PA2

通道3

PA3

PA3

PA3

通道4

PA4

PA4

PF6

通道5

PA5

PA5

PF7

通道6

PA6

PA6

PF8

通道7

PA7

PA7

PF9

通道8

PB0

PB0

PF10

通道9

PB1

PB1

通道10

PC0

PC0

PC0

通道11

PC1

PC1

PC1

通道12

PC2

PC2

PC2

通道13

PC3

PC3

PC3

通道14

PC4

PC4

通道15

PC5

PC5

通道16

温度传感器

通道17

内部参考电压

3.2 转换模式

1.单次转换,非扫描模式

        在非扫描模式下,只有序列1的通道有效,这时,菜单同时选中一组的方式就退化为简单地选中一个的方式,在这里可以在序列1的位置,指定我们向选择的通道,然后我们就可以触发转换,ADC就会对这个通道2金星模数转换,过一小段时间后,转换完成,转换结果放在数据寄存器里,同时给EOC标志位置1,转换过程结束,我们判断这个EOC标志位,如果转换完了,那我们就可以在数据寄存器读取结果了。如果我们想在启动一次转换就需要在触发一次。

2.连续转换,非扫描模式

        它与单次转换不同的时在一次转换结束后不会停止,而是立刻开始下一轮的转换,然后一直持续下去,这样就只需要开始触发一次,之后就可以一直转换了,这个模式的好处就是,开始转换之后不需要等待一段时间的,因为它一直都在转换,所以你就不需要手动开始转换,也不用判断是否结束,想要读AD值的时候,直接从数据寄存器取就是。

3.单次转换,扫描模式

        这是单词转换,所以转换一次后就会停下来,下次转换就得再触发才能开始,然后时扫描模式,会用到这个菜单列表,可以选择每个序列位的通道,通道可以任意指定页可以重复,然后初始化结构体里还会有个参数,就是通道数目,每次触发后,就会一次对指定通道进行AD转换,转换结果都会放到数据寄存器里,这里为了防止数据被覆盖,就需要用DMA及时将数据挪走,通道都转换完成后,残生EOC信号,转换结束。然后触发下一次,进行新一轮的转换。

4.连续转换,扫描模式

3.3 触发控制

        触发信号的选择,可以通过配置右边的寄存器来完成,使用库函数,直接给个参数就行。

3.4 数据对齐

    ADC是12位的,它的转换结果就是12位的数据,但数据寄存器是16位的,所以就存在一个数据对齐的问题。

数据右对齐

       12位的数据向右靠,高位多出来的几位就补0,一般使用右对齐,这样读取16位寄存器,直接就是转换结果

        12位的数据向左靠,低位多出来的几位就补0,选择左对齐直接读的话,得到的数据会比实际值大,因为数据左对齐就是把数据左移4次,二进制特点数据左移一次,就等效于把这个数据乘2,这里左移4次就成16了。左对齐的用途,如果你不想要这么高的分辨率,觉得0~4095这个数太大,就需要简单的判断,不需要这么高的分辨率,选择左对齐,然后把数据高八位取出来,舍去后4位,这个12位的ADC退化为8位的ADC。

3.5 转换时间

AD转换的步骤:采样,保持,量化,编码

STM32 ADC的总转换时间为:
    TCONV = 采样时间 + 12.5个ADC周期

例如:当ADCCLK=14MHz,采样时间为1.5个ADC周期
    TCONV = 1.5 + 12.5 = 14个ADC周期 = 1μs

4.ADC配置

1.开启RCC时钟,包括ADC和GPIO的时钟,ADCCLK的分频器也需要配置

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);    
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

RCC_ADCCLKConfig(RCC_PCLK2_Div6);

2.配置GPIO,把需要用的GPIO配置成模拟输入的模式

3.配置多路开关,把通道接入到右边的规则列表里

ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);

4.配置ADC转换器(如果向配置看门狗,有几个函数来配置阈值和检测通道的;如果向开启中那就再中断输出控制里用ITConfig函数开启对应的中断输出,然后再NVIC配置优先级即可)

ADC_InitTypeDef ADC_InitStructure;  //定义结构体变量
ADC_InitStructure.ADC_Mode //模式
ADC_InitStructure.ADC_DataAlign /数据对齐
ADC_InitStructure.ADC_ExternalTrigConv  //外部触发
ADC_InitStructure.ADC_ContinuousConvMode //连续转换
ADC_InitStructure.ADC_ScanConvMode  //扫描模式
ADC_InitStructure.ADC_NbrOfChannel //通道数,仅在扫描模式下,才需要指定大于1的数,在非扫描模式下,只能是1
ADC_Init(ADC1, &ADC_InitStructure);    

5.开关控制(开器ADC之后,根据手册的建议,我们还可以对ADC校准,这样可以减小误差)

ADC_Cmd(ADC1, ENABLE);//使能ADC1,ADC开始运行

ADC_ResetCalibration(ADC1); //固定流程,内部有电路会自动执行校准
while (ADC_GetResetCalibrationStatus(ADC1) == SET);
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1) == SET);

  • 19
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值