STM32模数转换器(ADC)

这篇具有很好参考价值的文章主要介绍了STM32模数转换器(ADC)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.ADC的简要 

我们首先说一下ADC的转换过程,然后说一下原理,当然如果嫌啰嗦可以直接跳过。 ADC是英文Analog-to-Digital Converter缩写,翻译过来就是模数转换器,是指将连续变化的模拟信号转换为离散的数字信号的器件。A/D转换的作用是将时间连续、幅值也连续的模拟信号转换为时间离散、值也离散的数字信号,因此,A/D转换一般要经过采样、保持、量化及编码4个过程,如下图所示。在实际电路中,这些过程有的是合并进行的。例如,采样和保持、量化和编码往往都是在转换过程中同时实现的。

stm32的adc模块,# stm32,stm32,单片机,嵌入式硬件

2.ADC框图分析 

 3、ADC的触发转换方式:

1、通用定时器触发ADC转换,这里没有基本定时器,因为基本定时器智能触发DAC转换;
2、外部中断可以产生一个触发脉冲,触发ADC转换;
3、软件触发。

4、数据存储:

ADC 的结果存储在一个左对齐或右对齐的 16 位数据寄存器中。
十二位的ADC放入16位的数据寄存器中需要左右对齐
ADC 具有模拟看门狗特性,允许应用检测输入电压是否超过了用户自定义的阈值上限或下限。
ADC在STM32内部是将电压值转换为数字量,这里锁输入的电压值的范围一般都是固定的,如果用户没有自定义输入电压阈值的上下限,一般输入的电压范围都是0V-3.3V。加入用户自定义输入电压阈值的下限为1.2V,上限为3.0V,这个时候ADC允许输入的电压范围是1.2V-3.0V。

5、ADC输入引脚

目前STM32F4有3个ADC,每个ADC的外部输入源16个,可能有的引脚被三个ADC或者两个ADC共有。
假设PA0,可以是ADC1的通道1,可以是ADC2的通道5,可以是ADC3的通道10。
对于ADC1来说,有8个模拟输入通道可以被3个ADC共用;

stm32的adc模块,# stm32,stm32,单片机,嵌入式硬件

6、ADC时钟

ADC 具有两个时钟方案:
● 用于模拟电路的时钟:ADCCLK,所有 ADC 共用
此时钟来自于经可编程预分频器分频的 APB2 时钟,该预分频器允许 ADC 在 fPCLK2/2、/4、/6 或 /8 下工作。有关 ADCCLK 的最大值,请参见数据手册。

● 用于数字接口的时钟(用于寄存器读/写访问)
此时钟等效于 APB2 时钟。可以通过 RCC APB2 外设时钟使能寄存器 (RCC_APB2ENR) 分别为每个 ADC 使能/禁止数字接口时钟。

对于ADC1来说,有8个模拟输入通道可以被3个ADC共用;
对于ADC2来说,有8个模拟输入通道可以被ADC1和ADC2共用;
对于ADC3来说,有8个模拟输入通道专门用于ADC3;

7、ADC输入通道

1、外部输入通道–16个
有 16 条复用通道。可以将转换分为两组:规则转换和注入转换。每个组包含一个转换序列,该序列可按任意顺序在任意通道上完成。例如,可按以下顺序对序列进行转换:ADC_IN3、ADC_IN8、ADC_IN2、ADC_IN2、ADC_IN0、ADC_IN2、ADC_IN2、ADC_IN15。
● 一个规则转换组最多由 16 个转换构成。必须在 ADC_SQRx 寄存器中选择转换序列的规则通道及其顺序。规则转换组中的转换总数必须写入 ADC_SQR1 寄存器中的 L[3:0] 位。
● 一个注入转换组最多由 4 个转换构成。必须在 ADC_JSQR 寄存器中选择转换序列的注入通道及其顺序。注入转换组中的转换总数必须写入 ADC_JSQR 寄存器中的 L[1:0] 位。
如果在转换期间修改 ADC_SQRx 或 ADC_JSQR 寄存器,将复位当前转换并向 ADC 发送一个新的启动脉冲,以转换新选择的组。
2、内部输入通道–3个温度传感器、VREFINT 和 VBAT 内部通道
● 温度传感器内部连接到通道 ADC1_IN16。
● 内部参考电压 VREFINT 连接到 ADC1_IN17。
● VBAT 通道连接到通道 ADC1_IN18。该通道也可转换为注入通道或规则通道。
注意: 温度传感器、VREFINT 和 VBAT 通道只在主 ADC1 外设上可用

8、数据对齐

stm32的adc模块,# stm32,stm32,单片机,嵌入式硬件

 如果觉得分辨率不需要太高,可以选择左对齐,要不然一般是选择右对齐模式

9、EOC标志位

位 1 EOC:规则通道转换结束 (Regular channel end of conversion)
规则组通道转换结束后,硬件将该位置 1。通过软件或通过读取 ADC_DR 寄存器将该位清零。
0:转换未完成 (EOCS=0) 或转换序列未完成 (EOCS=1)
1:转换已完成 (EOCS=0) 或转换序列已完成 (EOCS=1)
 

10、规则组的四种转换模式

A.单次转化、非扫描: 

stm32的adc模块,# stm32,stm32,单片机,嵌入式硬件

在这种模式下,当ADC转化了一个通道的数据之后,就会给EOC置一,表示转化结束,如果要防放置其他的通道,直接将这个通道连接到序列一的位置即可

B.连续非扫描模式

 在这种情况下就不是像A选项那样子了,而是只需要触发一次,然后直接到寄存器取数据即可

C.单次转换、扫描模式

stm32的adc模块,# stm32,stm32,单片机,嵌入式硬件 在这里要注意为了防止数据被覆盖,那么就需要DMA进行数据转换,防止数据被覆盖

11、代码

#include "stm32f10x.h"                  // Device header

void AD_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);  //设置分频,在这里设置为12HZ,72/6=12
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;   //模拟输入模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); 
	   //在这里表示使用ADC1,然后通道为ADC_Channel_0,通道数目为1,采样时间为 
                                                 ADC_SampleTime_55Cycles5
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;   //设置为单通道
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;   //数据向右对齐,准确率较高
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  //软件触发
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  //非连续转换模式
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;    //非扫描模式
	ADC_InitStructure.ADC_NbrOfChannel = 1;
	ADC_Init(ADC1, &ADC_InitStructure);
	
	ADC_Cmd(ADC1, ENABLE);
	
	ADC_ResetCalibration(ADC1);    //初始化校准寄存器
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);   //等待校准寄存器初始化完成
	ADC_StartCalibration(ADC1);                //ADC开始校准
	while (ADC_GetCalibrationStatus(ADC1) == SET);   //等待校准完成
}

uint16_t AD_GetValue(void)
{
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);   //软件触发ADC
	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);  //EOC成功判断标志位
	return ADC_GetConversionValue(ADC1);   //读取ADC的值
}

注意在设置转换序列的时候,一定要设置好转换序列的数目

在这里好需要注意可以使用判断EOC标志位的形式ADC_GetFlagStatus(),就是使用这个函数

也可以采用判断中断是否进行的函数,例如:

if(ADC_GetITStatus(ADCx, ADC_IT_EOC)==SET)

这个时候通过判断中断是否发生的标志位来判断是否已经发生了转化

但是这个时候要注意要在前面开启中断函数

ADC_ITConfig(ADCx,ADC_IT_EOC,ENABLE);

这个时候在开启了中断函数之后,就能实时观察到是否发生了转换了

要计算STM32中的AD采样率,必须先知道STM32的ADC时钟频率。STM32的ADC时钟频率一般为2-14MHz,所以一般使用以下代码实现12HZ

RCC_ADCCLKConfig(RCC_PCLK2_Div6);

mian.c代码

uint16_t ADValue;
float Voltage;

int main(void)
{
	OLED_Init();
	AD_Init();
	
	OLED_ShowString(1, 1, "ADValue:");
	OLED_ShowString(2, 1, "Volatge:0.00V");
	
	while (1)
	{
		ADValue = AD_GetValue();
		Voltage = (float)ADValue / 4095 * 3.3;
		
		OLED_ShowNum(1, 9, ADValue, 4);
		OLED_ShowNum(2, 9, Voltage, 1);
		OLED_ShowNum(2, 11, (uint16_t)(Voltage * 100) % 100, 2);
		
		Delay_ms(100);
	}
}

ADC的扫描模式配合DMA进行数据转运

AD.C

#include "stm32f10x.h"                  // Device header

uint16_t AD_Value[4];

void AD_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
  
  //配置转化序列,就是上图当中的菜单序列
	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_55Cycles5);
		
	ADC_InitTypeDef ADC_InitStructure;
  //只使用ADC1
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  //不使用外界触发
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  //开启连续转换模式
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  //开启扫描模式
	ADC_InitStructure.ADC_ScanConvMode = ENABLE;
	ADC_InitStructure.ADC_NbrOfChannel = 4;
	ADC_Init(ADC1, &ADC_InitStructure);
	
	DMA_InitTypeDef DMA_InitStructure;
  //将地址指向ADC模数转换后的寄存器地址
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
  //转换16位数据
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  //外设地址不用自增
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  //指向目的地址
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)AD_Value;
  //目的地址接受16位地址
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  
  //存储器地址自增,但是外设地址保持不变
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  
  //传输方向为外设到地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  //缓冲区大小
  
	DMA_InitStructure.DMA_BufferSize = 4;
  //循环传输模式
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  //外设到存储器
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
	DMA_Init(DMA1_Channel1, &DMA_InitStructure);
	
	DMA_Cmd(DMA1_Channel1, ENABLE);
	ADC_DMACmd(ADC1, ENABLE);
	ADC_Cmd(ADC1, ENABLE);
	
  //等待校验位初始化以及校验完成
	ADC_ResetCalibration(ADC1);
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET);
	
  //软件触发
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

main.c文章来源地址https://www.toymoban.com/news/detail-603759.html

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"

int main(void)
{
	OLED_Init();
	AD_Init();
	
	OLED_ShowString(1, 1, "AD0:");
	OLED_ShowString(2, 1, "AD1:");
	OLED_ShowString(3, 1, "AD2:");
	OLED_ShowString(4, 1, "AD3:");
	
	while (1)
	{
		OLED_ShowNum(1, 5, AD_Value[0], 4);
		OLED_ShowNum(2, 5, AD_Value[1], 4);
		OLED_ShowNum(3, 5, AD_Value[2], 4);
		OLED_ShowNum(4, 5, AD_Value[3], 4);
		
		Delay_ms(100);
	}
}

到了这里,关于STM32模数转换器(ADC)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • stm32学习笔记-7ADC模数转换器

    注:笔记主要参考B站 江科大自化协 教学视频“STM32入门教程-2023持续更新中”。 注:工程及代码文件放在了本人的Github仓库。 ADC(Analog-Digital Converter)模拟-数字转换器 可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立 模拟电路到数字电路的桥梁 。当然

    2024年02月13日
    浏览(19)
  • STM32F4_模数转换器(ADC)详解

    目录 1. ADC是什么 2. ADC主要特性 3. ADC框图 3.1 ADC开关控制 3.2 ADC时钟 3.3 通道选择 3.4 单次转换模式和连续转换模式 3.5 时序图 3.6 模拟看门狗 4 温度传感器 5. ADC中断 6. ADC初始化结构体 6.1 ADC相关实验配置 7. 相关寄存器 7.1 ADC控制寄存器:ADC_CR1和ADC_CR2 7.2 ADC通用控制寄存器:A

    2024年02月15日
    浏览(17)
  • STM-32:ADC模数转换器—ADC单通道转换/ADC多通道转换

    ADC(Analog-Digital Converter),意即模拟-数字转换器,简称模数转换器。ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁。与ADC相对应,从数字电路到模拟电路的桥梁即DAC(Digital-Analog Convertor),数模转换器。 DAC不是唯一可以

    2024年02月09日
    浏览(27)
  • STM32f103入门(10)ADC模数转换器

    ADC简介 ADC(Analog-Digital Converter)模拟-数字转换器 ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁 12位逐次逼近型ADC,1us转换时间 输入电压范围:0~ 3.3V,转换结果范围:0~ 4095 18个输入通道,可测量16个外部和2个内部信号源

    2024年02月10日
    浏览(15)
  • STM32入门笔记08_ADC模数转换器+案例: ADC单通道&ADC多通道

    ADC(Analog-Digtal Converter) 模拟-数字转换器 ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量, 建立模拟电路到数字电路的桥梁 12位逐次逼近型ADC, 1us转换时间 输入电压范围: 0~3.3V, 转换结果范围: 0~4095 18个输入通道, 可测量16个外部和2个内部信号源 规则组和注入组

    2024年02月04日
    浏览(23)
  • STM32笔记(1)———ADC模数转换器原理及单、双通道转换

    ADC(Analog-Digital Converter),意即模拟-数字转换器,简称模数转换器。 ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁。 DAC:数字到模拟的桥梁(PWM控制灯的亮度和电机旋转的速度,DAC的使用只要是在信号发生器、音频解码

    2024年02月04日
    浏览(18)
  • 超详细!!STM32-ADC模数转换器-驱动内部温度传感器

      在STM32微控制器系列中,ADC(Analog-to-Digital Converter)是一个重要的外设模块,它允许微控制器将模拟信号转换成数字信号以进行处理。模拟信号–数字信号。    MCU只能处理数字量(10011001),如果需要MCU区分模拟输入信号时,MCU直接做不了,需要将模拟信号通过模数转换

    2024年02月19日
    浏览(16)
  • 基于51单片机 + MQ-3酒精传感器 + ADC0832模数转换器 + LCD1602液晶显示器的酒精检测系统

    废话不多说,直接上东西。本文是基于51单片机的酒精检测系统设计,用的元器件有:51单片机、MQ-3酒精传感器、ADC0832模数转换器、 LCD1602液晶显示器、喇叭等元器件。 1、MQ-3 酒精检测传感器,用于检测酒精浓度。当然采集到的数据是模拟的还需要通过ADC0832模数转换器将其转

    2024年02月12日
    浏览(25)
  • STM32-ADC模数转换

    ADC的概念 Analog-to-Digital Converter的缩写。指模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件。 ADC的作用 采集传感器的数据,测量输入电压,检查电池电量剩余,监测温湿度等。 典型的模拟数字转换器将模拟信号转换为表示一定

    2024年01月20日
    浏览(17)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包