STM32
登录
直播中
刘洋
10年用户
1178经验值
擅长:可编程逻辑 嵌入式技术
私信
关注
[问答]
STM32 ADC的转换模式有哪几种
开启该帖子的消息推送
STM32
adc
寄存器
ADC是什么?逐次比较型 A/D是由哪些部分组成的?
STM32
ADC的主要特性有哪些?
STM32 ADC的转换模式有哪几种?
回帖
(1)
姬中岩
2021-11-1 10:38:31
4.11.1.1 ADC 概念
ADC 就是模拟量输入转换成数字量。
我们先简单介绍一下逐次比较型 A/D,逐次比较型 A/D 包括 n 位逐次比较型 A/D 转换器如图 1 所示。 它由控制逻辑威廉希尔官方网站 、 时序产生器、 移位寄存器、
D/A 转换器及电压比较器组成。
图 1 的威廉希尔官方网站 ,它由启动脉冲启动后,在第一个时钟脉冲作用下,控制威廉希尔官方网站 使时序产生器的最高位置 1, 其他位置 0, 其输出经数据寄存器将 1000……0,送入 D/A 转换器。输入电压首先与 D/A 器输出电压(VREF/2)相比较,如v1≥VREF/2,比较器输出为 1,若 vI《 VREF/2,则为 0。比较结果存于数据寄存器的 Dn-1 位。然后在第二个 CP 作用下,移位寄存器的次高位置 1,其他低位置 0。 如最高位已存 1, 则此时 vO=(3/4)VREF。 于是 v1 再与(3/4)VREF
相比较,如 v1≥(3/4)VREF,则次高位 Dn-2 存 1,否则 Dn-2=0;如最高位为0, 则 vO=VREF/4, 与 vO 比较, 如 v1≥VREF/4, 则 Dn-2 位存 1, 否则存 0……。
以此类推,逐次比较得到输出数字量。为了进一步理解逐次比较 A/D 转换器的工作原理及转换过程。下面用实例加以说明。
设图 1 威廉希尔官方网站 为 8 位 A/D 转换器,输入模拟量 vA=6.84V,D/A 转换器基准电压 VREF=10V。 根据逐次比较 D/A 转换器的工作原理,可画出在转换过程中 CP、启动脉冲、D7~D0 及 D/A 转换器输出电压 vO 的波形,如图 11.10.2
所示。由图.2 可见,当启动脉冲低电平到来后转换开始,在第一个 CP 作用下,数据寄存器将 D7~D0=10000000 送入 D/A 转换器,其输出电压 v0=5V,vA与 v0 比较,vA》v0 存 1;第二个 CP 到来时,寄存器输出 D7~D0=11000000,v0 为 7.5V,vA 再与 7.5V 比较,因 vA《7.5V,所以 D6 存 0;输入第三个 CP时,D7~D0=10100000,v0=6.25V;vA 再与 v0 比较,……如此重复比较下去,经 8 个时钟周期,转换结束。由图中 v0 的波形可见,在逐次比较过程中,与输出数字量对应的模拟电压 v0 逐渐逼近 vA 值,最后得到 A/D 转换器转换结果 D7~D0 为 10101111。该数字量所对应的模拟电压为 6.8359375V,与实际输入的模拟电压 6.84V 的相对误差仅为 0.06%。
4.11.1.3 STM32 ADC 模拟量输入功能
1、STM32 单片机自带 ADC 转换,STM32 ADC 是 12 位逐次逼近型模拟数字转换器。它有多达 18 个通道,可测量 16 个外部和 2 个内部信号源。各通道的A/D 转换可以单次、连续、扫描或者间断模式执行。ADC 的结果可以左对齐或者右对齐方式存储在 16 位数据寄存器中。模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。ADC 的输入时钟不得超过14MHz,它是由 PCLK2 经分频产生。
2、STM32 ADC 主要特性
12 位分辨率
转换结束、注入转换结束和发生模拟看门狗事件时产生中断
单次和连续转换模式
从通道 0 到通道 n 的自动扫描模式
间断模式执行
自校准
带内嵌数据一致性的数据对齐
采样间隔可以按通道分别编成
规律转换和注入转换均有外部触发选项
双重模式(带 2 个或者以上 ADC 的器件)
3、ADC 转换时间
STM32F103xx 增强型:时钟为 56MHz 时,转换时间为 1μs(时钟 72MHz时为 1.17μs);
STM32F101xx 基本型:时钟为 28MHz 时,转换时间为 1μs(时钟 36MHz时为 1.55μs);
STM32F102xxUSB 型:时钟为 48MHz 时,转换时间为 1.2μs;
STM32F105xx 和 STM32F107xx 型:时钟为 56MHz 时,转换时间为 1μs(时钟 72MHz 时为 1.17μs);
ADC 供电要求:2.4V~3.6V
ADC 输入范围:VREF-《=VIN《=VREF+;
规则通道转换期间有 DMA 请求产生;
4、ADC 引脚说明
ADC 模拟量输入说明
名称 信号类型 注释
Vref+ 输入,模拟参考正极 ADC 使用的高端/正极参考电压,2.4V《VREF《VDOA
Vdao 输入,模拟电源
Vref- 输入,模拟参考负极
Vssa 输入,模拟电源地 等效于 VSS 的模拟电源地
ADCx_IN[15:0] 模拟输入信号 16 个模拟输入通道
ADC 模拟量输入通道列表
ADC1 ADC2 ADC3
通道 0 PA0 PA0 PA0
通道 1 PA1 PA1 PA1
通道 2 PA2 PA2 PA2
通道 3 PA3 PA3 PA3
通道 4 PA4 PA4
通道 5 PA5 PA5
通道 6 PA6 PA6
通道 7 PA7 PA7
通道 8 PB0 PB0
通道 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 内部参考电压
4.11.1.4 STM 32 ADC 通道选择说明
有 16 个多路通道,可以把转换组织成两组:规则组和注入组。在任意多个通道上以任意顺序进行的一系列转换构成成组转换。
规则组由多达 16 个转换组成。规则通道和它们的转换顺序在 ADC_SQRx寄存器中选择。规则组中转换的总数应写入 ADC_SQR1 寄存器的 L[3:0]位中。
注入组由 4 个转换组成。注入通道和它们的转换顺序在 ADC_JSQR 寄存器中选择,注入组里的转换总数应写入 ADC_JSQR 寄存器的 L[1:0]位中。
如果 ADC_SQRx 或 ADC_JSQR 寄存器在转换期间被更改,当前的转换被清0,一个新的启动脉冲将发送到 ADC 以转换新选择的组。
温度传感器和通道 ADC1_IN16 相连接,内部参照电压 VREFINT 和 ADC1_IN17相连接。可以按照注入或者规则通道对这两个内部通道进行转换。
注意:温度传感器和 VREFINT 只能出现在主 ADC1 中。
4.11.1.5 STM 32 ADC 转换模式
1、单次转换模式
单次转换模式下,ADC 只执行一次转换。该模式即可通过设置 ADC_CR2 寄存器的 ADON 位(仅仅适用于规则通道)启动,也可以通过外部触发启动(适用于规则通道或注入通道),这时 CONT 位为 0。
一旦选择通道的转换完成:
如果一个规则通道被转换:
——转换数据被储存在 16 位 ADC_DR 寄存器中
——EOC(转换结束)标志被设置
——如果设置了 EOCIE,则产生中断。
如果一个注入通道被转换:
——转换数据被储存在 16 位 ADC_DRJ1 寄存器中
——JEOC(转换结束)标志被设置
——如果设置了 EOCIE,则产生中断,然后 ADC 停止。
2、连续转换模式
连续转换模式下,当前面的 ADC 转换一结束就马上启动另一次转换。此模式可以通过外部触发启动或者设置 ADC_CR2 寄存器上的 ADON 位启动,这时 CONT 位为 1。
每次转换完成后:
如果一个规则通道被转换:
——转换数据被储存在 16 位 ADC_DR 寄存器中
——EOC(转换结束)标志被设置
——如果设置了 EOCIE,则产生中断。
如果一个注入通道被转换:
——转换数据被储存在 16 位 ADC_DRJ1 寄存器中
——JEOC(转换结束)标志被设置
——如果设置了 JEOCIE 位,则产生中断。
3、扫描模式
扫描模式可通过设置 ADC_CR1 寄存器的 SCAN 位来选择。一旦这个位被设置,ADC 扫描所有被 ADC_SQRX 寄存器()或者 ADC_JSQR()选中的所有通道。在每个组的每个通道上执行单次转换。在每个转换结束时,同一组的下一个通道被自动转换。如果设置了 CONT 位,转换不会再选择组的最后一个通道上停止,而是再次从选择组的第一个通道继续转换。
如果设置了 DMA 位,在没次 ECO 后,DMA 控制器把规则组通道的转换数据传输到 SRAM 中。而注入通道转换的数据总是存储在 ADC_JDRx 寄存器中。
4.11.1.6 STM 32 ADC 时钟配置
Void RCC_ADCCLKConfing(uint32_t RCC_PCLK2) 分频函数。
输入参数范围:
#define RCC_PCLK2_Div2 ((uint32_t)0x00000000)
#define RCC_PCLK2_Div4 ((uint32_t)0x00004000)
#define RCC_PCLK2_Div6 ((uint32_t)0x00008000)
#define RCC_PCLK2_Div8 ((uint32_t)0x0000C000)
STM32 的 ADC 最大的转换速率时 1MHz,也就是转换时间为 1us(在ADCCLK=14M,采样周期为 1.5 个 ADC 时钟下得到),不要让 ADC 的时钟超过14M,否则将导致结果准确率下降。
4.11.1.7 ADC 的采样时间
可编程的通道采样时间
ADC 使用若干个 ADC_CLK 周期对输入电压采样, 采样周期数目可以通过ADC_SMPR1 和 ADC_SMPR2 寄存器中的 SMP[2:0]位更改。 每个通道可以分别用不同的时间采样。
总转换时间如下计算:TCONV=采样时间+12.5 个周期
例如:当 ADCCLK=14MHz,采样时间为 1.5 周期
TCON=1.5+12.5=14 周期=1us
常常使用的周期:
1.5 周期、7.5 周期、13.5 周期、28.5 周期、41.5 周期、55.5 周期、
71.5 周期、239.5 周期。
4.11.1.8 ADC 的数据对齐
ADC_CR2 寄存器中的 ALIGN 位选择转换后数据存储的对齐方式。数据可以左对齐或右对齐,如图 29 和图 30 所示。
注入组通道转换的数据值已经减去了在 ADC_JOFRx 寄存器中定义的偏移量,因此结果可以是一个负值。SEXT 位是扩展的符号值。
对于规则组通道,不需要减去偏移值,因此只有 12 个位有效
4.11.2 ADC 的数据校准
ADC 有一个内置自校准模式,校准可以大幅减少因内部电容器组的变化而早晨的准精度误差。在校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换中每个电容器上产生的误差。
通过设置 ADC_CR2 寄存器的 CAL 位启动校准。一旦校准结束,CAL 位被硬件复位,可以开始正常转换。建议在上电时执行一次 ADC 校准。校准阶段结束后,校准码存储在 ADC_DR 中。
注意:
1、建议在每次上电后执行一次校准。
2、启动校准前,ADC 必须处于关电状态(ADON=‘0’)超过至少两个
ADC 时钟周期。
4.11.4 硬件设计
STM32 库函数文件
GPIO 引脚时钟使能
本节实验用到了 PA 和 PC 端口,所以要把 PA 和 PC 端口的时钟打开;串口 1 时钟打开;因为要与外部芯片通讯,所以要打开功能复用时钟;ADC 模拟量时钟打开;设置分频,6 分频,主频是 72M,分频后是 12M,符合要求,
要求是不大于 14M。
GPIO 管脚电平控制函数
在主程序中采用 while(1)循环语句,采用查询的方式等待 ADC 模拟量转换完毕,初始化完成以后要在主程序中采集模拟量,加入滤波、取平均值等措施然后转换送出打印。下面是 while(1)语句中详细的内容。
while(1){ad=0;for(i=0;i《50;i++){
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
ad=ad+ADC_GetConversionValue(ADC1);
}
ad=ad/50;
printf(“ad =%frn”,3.3/4095*ad);//实际电压值
stm32f10x_it.c 文件里的内容是
在中断处理 stm32f10x_it.c 文件里中串口 1 子函数非空,进入中断处理函数后,先打开串口 1,和外部设备联络好,让后通过 CAN 通讯子函数把数据发送到总线上。
#include “stm32f10x_it.h”
#include “stm32f10x_exti.h”
#include “stm32f10x_rcc.h”
#include “misc.h”
#include “pbdata.h”
void NMI_Handler(void){
}
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET){
USART_SendData(USART1,USART_ReceiveData(USART1));
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}
}
main.c 文件里的内容是
大家都知道 prinif 重定向是把需要显示的数据打印到显示器上。在这个试验中 ADC 模拟量输入程序,是把从外部得到的模拟量转换成数字信号,通过 prinif 重定向打印到串口精灵上
void RCC_Configuration(void){
SystemInit();//72m
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//12M 最大 14M
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;//
LEDGPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//
TXGPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//
RXGPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;//
RXGPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//模拟量输入
GPIO_Init(GPIOC,&GPIO_InitStructure);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void USART_Configuration(void){
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate=9600;USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_Parity=USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;USART_Init(USART1,&USART_InitStructure);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
USART_Cmd(USART1,ENABLE);USART_ClearFlag(USART1,USART_FLAG_TC);
}
void ADC_Configuration(void){
ADC_InitTypeDef ADC_InitStructure;//结构体
ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//模式
ADC_InitStructure.ADC_ScanConvMode=DISABLE;//单通道
ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//单次循环ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//软件启动方式ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//右对齐方式
ADC_InitStructure.ADC_NbrOfChannel=1;//通道数目,我们用 1 个通道
ADC_Init(ADC1,&ADC_InitStructure);//把结构体变量参数传递
ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_239Cycles5);//规则组
ADC_Cmd(ADC1,ENABLE);//ADC 校准
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));//等待 ADC 是否复位完成
ADC_StartCalibration(ADC1);//ADC 开始校准
while(ADC_GetCalibrationStatus(ADC1));//ADC 开始校准
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//等待 ADC 校准是否完成后,启动ADC
}
串口通信工程需要如下配置
4.11.1.1 ADC 概念
ADC 就是模拟量输入转换成数字量。
我们先简单介绍一下逐次比较型 A/D,逐次比较型 A/D 包括 n 位逐次比较型 A/D 转换器如图 1 所示。 它由控制逻辑威廉希尔官方网站 、 时序产生器、 移位寄存器、
D/A 转换器及电压比较器组成。
图 1 的威廉希尔官方网站 ,它由启动脉冲启动后,在第一个时钟脉冲作用下,控制威廉希尔官方网站 使时序产生器的最高位置 1, 其他位置 0, 其输出经数据寄存器将 1000……0,送入 D/A 转换器。输入电压首先与 D/A 器输出电压(VREF/2)相比较,如v1≥VREF/2,比较器输出为 1,若 vI《 VREF/2,则为 0。比较结果存于数据寄存器的 Dn-1 位。然后在第二个 CP 作用下,移位寄存器的次高位置 1,其他低位置 0。 如最高位已存 1, 则此时 vO=(3/4)VREF。 于是 v1 再与(3/4)VREF
相比较,如 v1≥(3/4)VREF,则次高位 Dn-2 存 1,否则 Dn-2=0;如最高位为0, 则 vO=VREF/4, 与 vO 比较, 如 v1≥VREF/4, 则 Dn-2 位存 1, 否则存 0……。
以此类推,逐次比较得到输出数字量。为了进一步理解逐次比较 A/D 转换器的工作原理及转换过程。下面用实例加以说明。
设图 1 威廉希尔官方网站 为 8 位 A/D 转换器,输入模拟量 vA=6.84V,D/A 转换器基准电压 VREF=10V。 根据逐次比较 D/A 转换器的工作原理,可画出在转换过程中 CP、启动脉冲、D7~D0 及 D/A 转换器输出电压 vO 的波形,如图 11.10.2
所示。由图.2 可见,当启动脉冲低电平到来后转换开始,在第一个 CP 作用下,数据寄存器将 D7~D0=10000000 送入 D/A 转换器,其输出电压 v0=5V,vA与 v0 比较,vA》v0 存 1;第二个 CP 到来时,寄存器输出 D7~D0=11000000,v0 为 7.5V,vA 再与 7.5V 比较,因 vA《7.5V,所以 D6 存 0;输入第三个 CP时,D7~D0=10100000,v0=6.25V;vA 再与 v0 比较,……如此重复比较下去,经 8 个时钟周期,转换结束。由图中 v0 的波形可见,在逐次比较过程中,与输出数字量对应的模拟电压 v0 逐渐逼近 vA 值,最后得到 A/D 转换器转换结果 D7~D0 为 10101111。该数字量所对应的模拟电压为 6.8359375V,与实际输入的模拟电压 6.84V 的相对误差仅为 0.06%。
4.11.1.3 STM32 ADC 模拟量输入功能
1、STM32 单片机自带 ADC 转换,STM32 ADC 是 12 位逐次逼近型模拟数字转换器。它有多达 18 个通道,可测量 16 个外部和 2 个内部信号源。各通道的A/D 转换可以单次、连续、扫描或者间断模式执行。ADC 的结果可以左对齐或者右对齐方式存储在 16 位数据寄存器中。模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。ADC 的输入时钟不得超过14MHz,它是由 PCLK2 经分频产生。
2、STM32 ADC 主要特性
12 位分辨率
转换结束、注入转换结束和发生模拟看门狗事件时产生中断
单次和连续转换模式
从通道 0 到通道 n 的自动扫描模式
间断模式执行
自校准
带内嵌数据一致性的数据对齐
采样间隔可以按通道分别编成
规律转换和注入转换均有外部触发选项
双重模式(带 2 个或者以上 ADC 的器件)
3、ADC 转换时间
STM32F103xx 增强型:时钟为 56MHz 时,转换时间为 1μs(时钟 72MHz时为 1.17μs);
STM32F101xx 基本型:时钟为 28MHz 时,转换时间为 1μs(时钟 36MHz时为 1.55μs);
STM32F102xxUSB 型:时钟为 48MHz 时,转换时间为 1.2μs;
STM32F105xx 和 STM32F107xx 型:时钟为 56MHz 时,转换时间为 1μs(时钟 72MHz 时为 1.17μs);
ADC 供电要求:2.4V~3.6V
ADC 输入范围:VREF-《=VIN《=VREF+;
规则通道转换期间有 DMA 请求产生;
4、ADC 引脚说明
ADC 模拟量输入说明
名称 信号类型 注释
Vref+ 输入,模拟参考正极 ADC 使用的高端/正极参考电压,2.4V《VREF《VDOA
Vdao 输入,模拟电源
Vref- 输入,模拟参考负极
Vssa 输入,模拟电源地 等效于 VSS 的模拟电源地
ADCx_IN[15:0] 模拟输入信号 16 个模拟输入通道
ADC 模拟量输入通道列表
ADC1 ADC2 ADC3
通道 0 PA0 PA0 PA0
通道 1 PA1 PA1 PA1
通道 2 PA2 PA2 PA2
通道 3 PA3 PA3 PA3
通道 4 PA4 PA4
通道 5 PA5 PA5
通道 6 PA6 PA6
通道 7 PA7 PA7
通道 8 PB0 PB0
通道 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 内部参考电压
4.11.1.4 STM 32 ADC 通道选择说明
有 16 个多路通道,可以把转换组织成两组:规则组和注入组。在任意多个通道上以任意顺序进行的一系列转换构成成组转换。
规则组由多达 16 个转换组成。规则通道和它们的转换顺序在 ADC_SQRx寄存器中选择。规则组中转换的总数应写入 ADC_SQR1 寄存器的 L[3:0]位中。
注入组由 4 个转换组成。注入通道和它们的转换顺序在 ADC_JSQR 寄存器中选择,注入组里的转换总数应写入 ADC_JSQR 寄存器的 L[1:0]位中。
如果 ADC_SQRx 或 ADC_JSQR 寄存器在转换期间被更改,当前的转换被清0,一个新的启动脉冲将发送到 ADC 以转换新选择的组。
温度传感器和通道 ADC1_IN16 相连接,内部参照电压 VREFINT 和 ADC1_IN17相连接。可以按照注入或者规则通道对这两个内部通道进行转换。
注意:温度传感器和 VREFINT 只能出现在主 ADC1 中。
4.11.1.5 STM 32 ADC 转换模式
1、单次转换模式
单次转换模式下,ADC 只执行一次转换。该模式即可通过设置 ADC_CR2 寄存器的 ADON 位(仅仅适用于规则通道)启动,也可以通过外部触发启动(适用于规则通道或注入通道),这时 CONT 位为 0。
一旦选择通道的转换完成:
如果一个规则通道被转换:
——转换数据被储存在 16 位 ADC_DR 寄存器中
——EOC(转换结束)标志被设置
——如果设置了 EOCIE,则产生中断。
如果一个注入通道被转换:
——转换数据被储存在 16 位 ADC_DRJ1 寄存器中
——JEOC(转换结束)标志被设置
——如果设置了 EOCIE,则产生中断,然后 ADC 停止。
2、连续转换模式
连续转换模式下,当前面的 ADC 转换一结束就马上启动另一次转换。此模式可以通过外部触发启动或者设置 ADC_CR2 寄存器上的 ADON 位启动,这时 CONT 位为 1。
每次转换完成后:
如果一个规则通道被转换:
——转换数据被储存在 16 位 ADC_DR 寄存器中
——EOC(转换结束)标志被设置
——如果设置了 EOCIE,则产生中断。
如果一个注入通道被转换:
——转换数据被储存在 16 位 ADC_DRJ1 寄存器中
——JEOC(转换结束)标志被设置
——如果设置了 JEOCIE 位,则产生中断。
3、扫描模式
扫描模式可通过设置 ADC_CR1 寄存器的 SCAN 位来选择。一旦这个位被设置,ADC 扫描所有被 ADC_SQRX 寄存器()或者 ADC_JSQR()选中的所有通道。在每个组的每个通道上执行单次转换。在每个转换结束时,同一组的下一个通道被自动转换。如果设置了 CONT 位,转换不会再选择组的最后一个通道上停止,而是再次从选择组的第一个通道继续转换。
如果设置了 DMA 位,在没次 ECO 后,DMA 控制器把规则组通道的转换数据传输到 SRAM 中。而注入通道转换的数据总是存储在 ADC_JDRx 寄存器中。
4.11.1.6 STM 32 ADC 时钟配置
Void RCC_ADCCLKConfing(uint32_t RCC_PCLK2) 分频函数。
输入参数范围:
#define RCC_PCLK2_Div2 ((uint32_t)0x00000000)
#define RCC_PCLK2_Div4 ((uint32_t)0x00004000)
#define RCC_PCLK2_Div6 ((uint32_t)0x00008000)
#define RCC_PCLK2_Div8 ((uint32_t)0x0000C000)
STM32 的 ADC 最大的转换速率时 1MHz,也就是转换时间为 1us(在ADCCLK=14M,采样周期为 1.5 个 ADC 时钟下得到),不要让 ADC 的时钟超过14M,否则将导致结果准确率下降。
4.11.1.7 ADC 的采样时间
可编程的通道采样时间
ADC 使用若干个 ADC_CLK 周期对输入电压采样, 采样周期数目可以通过ADC_SMPR1 和 ADC_SMPR2 寄存器中的 SMP[2:0]位更改。 每个通道可以分别用不同的时间采样。
总转换时间如下计算:TCONV=采样时间+12.5 个周期
例如:当 ADCCLK=14MHz,采样时间为 1.5 周期
TCON=1.5+12.5=14 周期=1us
常常使用的周期:
1.5 周期、7.5 周期、13.5 周期、28.5 周期、41.5 周期、55.5 周期、
71.5 周期、239.5 周期。
4.11.1.8 ADC 的数据对齐
ADC_CR2 寄存器中的 ALIGN 位选择转换后数据存储的对齐方式。数据可以左对齐或右对齐,如图 29 和图 30 所示。
注入组通道转换的数据值已经减去了在 ADC_JOFRx 寄存器中定义的偏移量,因此结果可以是一个负值。SEXT 位是扩展的符号值。
对于规则组通道,不需要减去偏移值,因此只有 12 个位有效
4.11.2 ADC 的数据校准
ADC 有一个内置自校准模式,校准可以大幅减少因内部电容器组的变化而早晨的准精度误差。在校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换中每个电容器上产生的误差。
通过设置 ADC_CR2 寄存器的 CAL 位启动校准。一旦校准结束,CAL 位被硬件复位,可以开始正常转换。建议在上电时执行一次 ADC 校准。校准阶段结束后,校准码存储在 ADC_DR 中。
注意:
1、建议在每次上电后执行一次校准。
2、启动校准前,ADC 必须处于关电状态(ADON=‘0’)超过至少两个
ADC 时钟周期。
4.11.4 硬件设计
STM32 库函数文件
GPIO 引脚时钟使能
本节实验用到了 PA 和 PC 端口,所以要把 PA 和 PC 端口的时钟打开;串口 1 时钟打开;因为要与外部芯片通讯,所以要打开功能复用时钟;ADC 模拟量时钟打开;设置分频,6 分频,主频是 72M,分频后是 12M,符合要求,
要求是不大于 14M。
GPIO 管脚电平控制函数
在主程序中采用 while(1)循环语句,采用查询的方式等待 ADC 模拟量转换完毕,初始化完成以后要在主程序中采集模拟量,加入滤波、取平均值等措施然后转换送出打印。下面是 while(1)语句中详细的内容。
while(1){ad=0;for(i=0;i《50;i++){
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
ad=ad+ADC_GetConversionValue(ADC1);
}
ad=ad/50;
printf(“ad =%frn”,3.3/4095*ad);//实际电压值
stm32f10x_it.c 文件里的内容是
在中断处理 stm32f10x_it.c 文件里中串口 1 子函数非空,进入中断处理函数后,先打开串口 1,和外部设备联络好,让后通过 CAN 通讯子函数把数据发送到总线上。
#include “stm32f10x_it.h”
#include “stm32f10x_exti.h”
#include “stm32f10x_rcc.h”
#include “misc.h”
#include “pbdata.h”
void NMI_Handler(void){
}
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET){
USART_SendData(USART1,USART_ReceiveData(USART1));
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}
}
main.c 文件里的内容是
大家都知道 prinif 重定向是把需要显示的数据打印到显示器上。在这个试验中 ADC 模拟量输入程序,是把从外部得到的模拟量转换成数字信号,通过 prinif 重定向打印到串口精灵上
void RCC_Configuration(void){
SystemInit();//72m
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//12M 最大 14M
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;//
LEDGPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//
TXGPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//
RXGPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;//
RXGPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//模拟量输入
GPIO_Init(GPIOC,&GPIO_InitStructure);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void USART_Configuration(void){
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate=9600;USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_Parity=USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;USART_Init(USART1,&USART_InitStructure);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
USART_Cmd(USART1,ENABLE);USART_ClearFlag(USART1,USART_FLAG_TC);
}
void ADC_Configuration(void){
ADC_InitTypeDef ADC_InitStructure;//结构体
ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//模式
ADC_InitStructure.ADC_ScanConvMode=DISABLE;//单通道
ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//单次循环ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//软件启动方式ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//右对齐方式
ADC_InitStructure.ADC_NbrOfChannel=1;//通道数目,我们用 1 个通道
ADC_Init(ADC1,&ADC_InitStructure);//把结构体变量参数传递
ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_239Cycles5);//规则组
ADC_Cmd(ADC1,ENABLE);//ADC 校准
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));//等待 ADC 是否复位完成
ADC_StartCalibration(ADC1);//ADC 开始校准
while(ADC_GetCalibrationStatus(ADC1));//ADC 开始校准
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//等待 ADC 校准是否完成后,启动ADC
}
串口通信工程需要如下配置
举报
更多回帖
rotate(-90deg);
回复
相关问答
STM32
adc
寄存器
ADC
的
转换
模式
有
哪几种
?
2021-12-02
8786
ADC
需要的引脚
有
哪些?
转换
模式
有
哪几种
?
2021-11-18
2918
STM32F103-ADC
有
哪几种
转化
模式
2021-10-27
1716
STM32
的
ADC
模数
转换
器
有
哪几种
工作
模式
及应用呢
2021-11-15
4993
STM32
支持
哪几种
低功耗
模式
2021-09-22
1596
STM32
的
ADC
通道
有
哪几种
不同的工作
模式
2021-09-27
3331
STM32
的
ADC
有
哪些重要特点呢
2021-10-28
5279
STM32
有
哪几种
输入输出
模式
?
2021-11-04
963
请问STM8的
ADC
有
哪几种
工作
模式
?
2020-11-16
1758
Stm32
有
哪几种
休眠
模式
2021-09-24
1689
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
英国威廉希尔公司网站
william hill官网 版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分