前几天不小心把板子掉地上了,液晶屏摔坏了,暂时先停一下液晶屏的学习,等新的板子来了再继续学习。
ADC指的是Analog to Digital Converter(模数转换器),即将连续变化的模拟信号转换为数字信号,常见的模拟信号有例如:压力、温度、声音等,我们可以将诸如上面说的集中通过模数转换器将其转换为更容易存储的数字信息。
在ADC中输入电压模拟量,并不是什么电压范围都可以直接输入的,我们知道MCU的电源电压一般都为0-3.3V,而429中ADC的输入范围为VREF- ≤ VIN ≤ VREF+。设计时,是将VSSA和VREF-接地,把VREF+和VDDA接3.3V,因此ADC的输入电压范围就是03.3V。我们在常见的模拟量一般为05V、010V或者-10V+10V,针对于这些电压比较高的,可以在外部增加转换电路,将电压转换为0~3.3V即可。
在F429上面,一共有三个独立的ADC 1/2/3,其分辨率有6/8/10/12位可选,每个ADC具有19个通道,其中外部通道共有16个。这就相当于可以采集3*16=48路模拟量信号(通道数不代表可以同时使用的通道数,具体看下表)。
ADC IO分配
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 | PF3 |
通道10 | PC0 | PC0 | PC0 |
通道11 | PC1 | PC1 | PC1 |
通道12 | PC2 | PC2 | PC2 |
通道13 | PC3 | PC3 | PC3 |
通道14 | PC4 | PC4 | PF4 |
通道15 | PC5 | PC5 | PF5 |
通道16 | 连接内部VSS | 连接内部VSS | 连接内部VSS |
通道17 | 连接内部Vrefint | 连接内部VSS | 连接内部VSS |
通道18 | 连接内部温度传感器/内部VBAT | 连接内部VSS | 连接内部VSS |
这里我们可以看到在三组通道中,前两组ADC1、ADC2的引脚0-15一致,ADC3与ADC1/2的第4-10、14-15共8个通道引脚不同,因此假如我们在使用过程中,假如ADC1/2的引脚全部用完,也可以使用ADC3通道中这8个引脚,因此实际429的ADC通道可以同时使用引脚数一共为16+8=24组
除了以上说的引脚外,ADC1/2/3的1618位内部通道,ADC2/3的1618引脚全部连接到内部VSS,ADC1的通道16连接到VSS,通道17连接到内部参考电压VREFINT,通道18连接的为芯片内部温度传感器或者备用电源VBAT。
外部使用的16个通道,在转换时区分为规则通道和注入通道,其中规则通道最多为16路,注入通道最多为4路,其区别如下:
规则通道:从字面上理解,就是规规矩矩的做模数转换的通道。
注入通道:可以强制插入到规则通道中,并且注入通道一定是在存在规则通道时才会存在。
这里举个不恰当的例子来说明一下规则通道和注入通道的区别,假如有一个房子,房子外面一共有16个监控摄像头,房子内有4个监控摄像头,监控系统正常情况下是显示外面16个摄像头的内容,这些内容是由监控系统挨个去扫描数据从而显示的,当我们需要看室内的情况时,可以通过监控系统的切换,暂时不接收室外视频数据流,从而只显示室内摄像头的数据流,看完后再自动切换回室外摄像头数据流。这里室外摄像头就相当于规则通道,室内摄像头则为注入通道。
根据上面通道的分类,转换顺序可分为规则序列和注入序列,分别由不同的寄存器进行控制。
规则序列:
控制规则序列的寄存器有3个,分别为SQR3、SQR2、SQR1,每个SQR寄存器有5位,取值范围为1-16,对应通道ADCx_IN[0-15]。其中SQR3控制规则序列中前6个通道(这里说的前6个通道,不是物理意义上的0-5通道,而是顺序)。比如我们想在第一次采集第ADCx_IN15通道的数据,那么在SQ1[4:0]中写入16即可。SQR2控制转换序列中第712个通道,SQR1则控制第1316个通道,可能我们一次接入的转换通道不够16位,那么具体需要转换多少位,则由SQR1的L[3:0]来控制。规则序列寄存器配置如下表:
注入序列:
注入序列寄存器只有一个JSQR,最多支持4个通道,具体多少有JSQR的JL[2:0]决定,如果JL的值小于4的时候,JSQR跟SQR决定转换顺序的设置不一样,第一次转换的位JCQRx[4:0],其中x=4-JL,跟SQR的顺序相反。如果JL = 0时,表示只有1个转换,那么转换顺序就从JSQR4开始,如果JL = 4,转换顺序就跟SQR一致。注入序列寄存器配置如下表:
ADC转换起始和结束可以有ADC的控制寄存器2:ADC_CR2的ADON位来控制,写入1时启动转换,写入0时停止转换。同时也可以通过外部事件触发转换,可以设置为内部定时器触发或者外部IO触发,具体选择哪种触发源由ADC控制寄存器2:ADC_CR2的EXTSEL[3:0]和JEXTSEL[3:0]位控制,其中EXTSEL[3:0]用于选择规则通道的触发源,JEXTSEL[3:0]选择注入通道的触发源。触发源选定后,是否需要激活有ADC的控制器2:ADC_CR2的EXTTRIG和JEXTTRIG这两位激活。
若设置为外部触发,可以通过设置ADC寄存器2:ADC_CR2的EXTEN[1:0]和JEXTEN[1:0]来控制触发极性,可以设置为:禁止触发检测、上升沿检测、下降沿检测以及上升沿下降沿军检测。
ADC时钟:
作为一个外设,ADC同样也需要开启时钟,ADC的输入时钟ADC_CLK有PCLK2经过分频产生,最大值为36MHz,分频因子由ADC通用控股之寄存器ADC_CCR的ADCPRE[1:0]设置,可设置的分频系数有2、4、6和8分频,由于PCLK2一般我们设置的为90MHz,所以这里我们可以将分频系数设置为4分频(90MHz/4 = 22.5MHz),或者设置为6分频(90MHz/6 = 15MHz)。这里注意,VDD我们接的时3.3V,时钟周期看VDDA = 2.4 to 3.6V。
采样时间:
ADC对输入的电压进行周期性采集,采样的周期数通过采样时间寄存器ADC_SMPR1和ADC_SMPR2中的SMP[2:0]位进行设置,ADC_SMPR1用于控制通道09,ADC_SMPR2用于控制1017。每个通道可以设置不同的时间进行采样。采样周期可设置的最小值为3个周期,周期即为1/ADC_CLK。
ADC的转换时间跟ADC的输入时钟和采样周期相关,公式为:
T c o n v = 采样时间 + 12 个周期 Tconv = 采样时间 + 12个周期 Tconv=采样时间+12个周期
当PCLK2 = 90MHz时,经过ADC预分频器分频得到的最大时钟为22.5MHz,采样周期设置为最快采样周期,即3个周期,那么Tconv = 3 + 12 = 15个周期 = 15 * (1/22.5) = 0.6667us。
前面对于ADC的转换序列分为规则数列和注入序列,为了设置这两组序列,分别存在规则数据寄存器ADC_DR和注入数据寄存器ADC_JDRx,ADC将模拟量转为数字量时,根据其转换组别不同,数据存入的寄存器也不同,其中规则组的数据存放在ADC_DR寄存器,而注入组的数据则是存放在JDRx中。如果使用的时双重或者三重模式,那么规则组的数据则是存放在规矩寄存器ADC_CDR中。
规则数据寄存器ADC_DR
规则组数据寄存器ADC_DR只有一个,是一个32位的寄存器,其中只有低16位有效,并且只是用于独立模式存放转换完成的数据,因为ADC的精度最大为12位,而ADC_DR是16位有效,因此ADC存放数据时,需要选择左对齐或者右对齐,具体选择哪种方式,由ADC_CR2的11位ALIGN设置,比如:设置ADC精度位12位,如果设置数据位左对齐,那么转换完成的数据存放在ADC_DR寄存器的[4:15]位中,如果设置为右对齐,则存放在ADC_AR寄存器的[0:11]位中。
这里需要注意的是,前面学习到前面规则序列时,知道规则序列一共有16个,但是因为规则数据寄存器只有1个,如果多通道转换时,所有转换的数据都会全部存储到ADC_DR寄存器中,存储的先后顺序也会随着转换完成通道的先后顺序依次进行**覆盖**,如果没有及时取走转换成的数据,可能就会被下一个通道转换完成的数据给覆盖掉,这里就需要使用ADC状态寄存器的ADC_SR来获取ADC转换的进度状态,从而保证转换数据能正常获取。
当然除了这种办法外,还可以启用DMA模式,将转换完成的数据传输到内存中,这样就不会存在数据的覆盖了,具体如何实现,等后面我们在学习。
注入数据寄存器ADC_JDRx
注入组与规则组不同,注入组共有4个数据寄存器,刚好对应4个通道,因此不存在与规则组一样有数据覆盖的问题。ADC_JDRx同样时32位寄存器,低16位有效,高16位保存,数据同样也分左对齐和右对齐,具体以哪种方式存放,由ADC_CR2的11位ALIGN设置。
通用规则数据寄存器ADC_CDR
规则数据寄存器ADC_DR只是用与独立模式,即上面说的ADC1/2/3只启用任意一组,而通用规则数据寄存器ADC_CDR则适用于双重和三重模式(双重模式为启用任意两组ADC通道,三重则为3个通道都启用),此处需要注意的是,双重或三重模式下尽可能配合DMA数据传输使用。
ADC在完成数据转换后,可以产生中断,其中中断分为4种,分别为:
前面两个中断比较好理解,就是表示ADC正常转换结束后触发的中断,可以通过相应的中断标志位和中断使能写出配套的中断服务程序。
模拟看门狗中断
在前面我们了解到,ADC的输入范围为VREF- ≤ VIN ≤ VREF+,其中VREF- ~ VREF+为ADC转换采集的模拟量阈值区间,假如采集的模拟量电压低于VREF-或者高于VREF+,这种情况该怎么办呢?为了因对输入模拟电压超出阈值区间,这里需要开启模拟看门狗中断,低阈值由ADC_LTR设置,高阈值由ADC_HTR设置,比如设置高阈值为2.5V,当模拟输入电压高于2.5V时,就会产生模拟看门狗中断,同理低阈值也一样。
溢出中断
如果发生DMA传输数据丢失,会置位ADC状态寄存器ADC_SR的OVR位,如果同时使能溢出中断,则在转换结束后会产生一个溢出中断。
DMA请求
ADC转换结束后,除了产生终端外,还可以产生DMA请求,将转换好的数据直接存储到内存中,对于独立模式的多通道AD转换使用DMA传输非常有必要,对于双重模式或者三重模式使用DMA可以说时必不可少的。可以避免丢失在下一次写入之前还未被读出的ADC_DR寄存器中的数据。
模拟电压经过ADC转换后,是个相对精度的数字值,什么意思呢?在F429开发板中,ADC的输入电压范围设置位0~3.3V,假如此时我们设置采集精度为12位,那么当输入模拟电压达到3.3V时,12位寄存器就会被填满,此时我们如果通过串口以16进制打印出来,会发现并不是我们要的3.3V,而是FFF,那么才能将最终输出的数据转换为我们需要的数值呢?这里就用到了电压转换。
V o l t = V ∗ V o u t / 2 n Volt=V * Vout / 2 ^ n Volt=V∗Vout/2n
其中,V为3.3V,Vout极为ADC_DR中的数值,n则表示我们选择的精度,上面的例子中,n = 12,因此假如此时输入模拟电压为3.3V时,那么输出应为3.3 * FFF / 2^12,即3.3 * 4096 /4096,即输出数据为3.3。
OK,关于ADC的基本知识就学习到这里,后面继续学习关于ADC的相关结构体并且进行实战。