STM32入门笔记08_ADC模数转换器+案例: ADC单通道&ADC多通道

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

AD模数转换器

ADC简介

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

逐次逼近型ADC

adc_nbrofchannel,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

  • IN0~IN7是八个输入通道
  • 通过配置ADDA~ADDC可以选择一个通道作为信号输入
  • 通过比较器, DAC逐渐逼近输入信号, DAC的值最终与输入信号十分接近

ADC框图

adc_nbrofchannel,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

ADC基本结构

adc_nbrofchannel,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

输入通道

通道 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 内部参考电压

转换模式

  • 单次转换, 非扫描模式

adc_nbrofchannel,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

  • 连续转换, 非扫描模式
    adc_nbrofchannel,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言
  • 单次转换, 扫描模式

adc_nbrofchannel,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

  • 连续转换, 扫描模式

adc_nbrofchannel,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

触发控制

adc_nbrofchannel,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

数据对齐

  • 数据右对齐:

adc_nbrofchannel,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

  • 数据左对齐:
    adc_nbrofchannel,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

转换时间

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

  • STM32 ADC的总转换时间为:

    ​ Tconv = 采样时间 + 12.5个ADC周期

  • 例如: 当ADCCLK = 14MHz, 采样时间为1.5个ADC周期

    ​ Tconv = 1.5 + 12.5 = 14个ADC周期 = 1us

校准

  • ADC有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的精准度误差。校准期间, 在每个电容器上都会计算出一个修正码(数字值), 这个码用于消除在随后的转换中每个电容器上产生的误差
  • 建议在每次上电后执行一次校准
  • 启动校准前, ADC必须处于关电状态超过至少两个ADC时钟周期

硬件电路

adc_nbrofchannel,单片机学习笔记,stm32,单片机,嵌入式硬件,c语言

案例1: ADC单通道

配置ADC转换

void AD_Init(void)
{
	// RCC使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);  // 12MHz
	// 配置GPIO口
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	// 选择规则通道
	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
	
	// 配置ADC转换器
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  // 单次转换或者连续转换
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  // 数据对齐模式
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  // ADC模式, 单独还是交叉
	ADC_InitStructure.ADC_NbrOfChannel = 1;  // 扫描的通道数
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;  // 扫描模式或者非扫描模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  // 触发控制
	ADC_Init(ADC1, &ADC_InitStructure);
	
	// 开启ADC功能
	ADC_Cmd(ADC1, ENABLE);
	
	// ADC校准
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);  // 已初始化为零
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET); 
	
}

RCC_ADCCLKConfig

/**
  * @brief  Configures the ADC clock (ADCCLK).
  * @param  RCC_PCLK2: defines the ADC clock divider. This clock is derived from 
  *   the APB2 clock (PCLK2).
  *   This parameter can be one of the following values:
  *     @arg RCC_PCLK2_Div2: ADC clock = PCLK2/2
  *     @arg RCC_PCLK2_Div4: ADC clock = PCLK2/4
  *     @arg RCC_PCLK2_Div6: ADC clock = PCLK2/6
  *     @arg RCC_PCLK2_Div8: ADC clock = PCLK2/8
  * @retval None
  */
void RCC_ADCCLKConfig(uint32_t RCC_PCLK2)

ADC_ContinuousConvMode

*!< Specifies whether the conversion is performed in
                                               Continuous or Single mode.
                                               This parameter can be set to ENABLE or DISABLE. */

ADC_DataAlign

#define ADC_DataAlign_Right                        ((uint32_t)0x00000000)
#define ADC_DataAlign_Left                         ((uint32_t)0x00000800)

ADC_Mode

#define ADC_Mode_Independent                       ((uint32_t)0x00000000)
#define ADC_Mode_RegInjecSimult                    ((uint32_t)0x00010000)
#define ADC_Mode_RegSimult_AlterTrig               ((uint32_t)0x00020000)
#define ADC_Mode_InjecSimult_FastInterl            ((uint32_t)0x00030000)
#define ADC_Mode_InjecSimult_SlowInterl            ((uint32_t)0x00040000)
#define ADC_Mode_InjecSimult                       ((uint32_t)0x00050000)
#define ADC_Mode_RegSimult                         ((uint32_t)0x00060000)
#define ADC_Mode_FastInterl                        ((uint32_t)0x00070000)
#define ADC_Mode_SlowInterl                        ((uint32_t)0x00080000)
#define ADC_Mode_AlterTrig                         ((uint32_t)0x00090000)

ADC_NbrOfChannel

 /*!< Specifies the number of ADC channels that will be converted
                                               using the sequencer for regular channel group.
                                               This parameter must range from 1 to 16. */

ADC_ScanConvMode

/*!< Specifies whether the conversion is performed in
                                               Scan (multichannels) or Single (one channel) mode.
                                               This parameter can be set to ENABLE or DISABLE */

ADC_ExternalTrigConv

#define ADC_ExternalTrigConv_T1_CC1                ((uint32_t)0x00000000) /*!< For ADC1 and ADC2 */
#define ADC_ExternalTrigConv_T1_CC2                ((uint32_t)0x00020000) /*!< For ADC1 and ADC2 */
#define ADC_ExternalTrigConv_T2_CC2                ((uint32_t)0x00060000) /*!< For ADC1 and ADC2 */
#define ADC_ExternalTrigConv_T3_TRGO               ((uint32_t)0x00080000) /*!< For ADC1 and ADC2 */
#define ADC_ExternalTrigConv_T4_CC4                ((uint32_t)0x000A0000) /*!< For ADC1 and ADC2 */
#define ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO    ((uint32_t)0x000C0000) /*!< For ADC1 and ADC2 */

#define ADC_ExternalTrigConv_T1_CC3                ((uint32_t)0x00040000) /*!< For ADC1, ADC2 and ADC3 */
#define ADC_ExternalTrigConv_None                  ((uint32_t)0x000E0000) /*!< For ADC1, ADC2 and ADC3 */

#define ADC_ExternalTrigConv_T3_CC1                ((uint32_t)0x00000000) /*!< For ADC3 only */
#define ADC_ExternalTrigConv_T2_CC3                ((uint32_t)0x00020000) /*!< For ADC3 only */
#define ADC_ExternalTrigConv_T8_CC1                ((uint32_t)0x00060000) /*!< For ADC3 only */
#define ADC_ExternalTrigConv_T8_TRGO               ((uint32_t)0x00080000) /*!< For ADC3 only */
#define ADC_ExternalTrigConv_T5_CC1                ((uint32_t)0x000A0000) /*!< For ADC3 only */
#define ADC_ExternalTrigConv_T5_CC3                ((uint32_t)0x000C0000) /*!< For ADC3 only */

整体代码:

ADC.c
#include "stm32f10x.h"

/*
初始化ADC
*/
void AD_Init(void)
{
	// RCC使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);  // 12MHz
	// 配置GPIO口
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	// 选择规则通道
	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
	
	// 配置ADC转换器
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  // 单次转换或者连续转换
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  // 数据对齐模式
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  // ADC模式, 单独还是交叉
	ADC_InitStructure.ADC_NbrOfChannel = 1;  // 扫描的通道数
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;  // 扫描模式或者非扫描模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  // 触发控制
	ADC_Init(ADC1, &ADC_InitStructure);
	
	// 开启ADC功能
	ADC_Cmd(ADC1, ENABLE);
	
	// ADC校准
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);  // 已初始化为零
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET); 
	
}

/*
获取ADC模块转换的值
*/
uint16_t AD_GetValue(void)
{
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);  // 软件触发
	while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);  // 等待转换完毕
	return ADC_GetConversionValue(ADC1);
}
main.c
#include "stm32f10x.h" 
#include "delay.h"
#include "OLED.h"
#include "ADC.h"
// ADC单通道
// 2023年3月25日19:12:09
uint16_t ADValue;
float volatge;

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

案例2: ADC多通道

整体代码

ADC.c
#include "stm32f10x.h"

/*
初始化ADC
*/
void AD_Init(void)
{
	// RCC使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);  // 12MHz
	// 配置GPIO口
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 配置ADC转换器
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  // 单次转换或者连续转换
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  // 数据对齐模式
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  // ADC模式, 单独还是交叉
	ADC_InitStructure.ADC_NbrOfChannel = 1;  // 扫描的通道数
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;  // 扫描模式或者非扫描模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  // 触发控制
	ADC_Init(ADC1, &ADC_InitStructure);
	
	// 开启ADC功能
	ADC_Cmd(ADC1, ENABLE);
	
	// ADC校准
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);  // 已初始化为零
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET); 
	
}

/*
获取ADC模块转换的值
*/
uint16_t AD_GetValue(uint8_t ADC_Channel)
{
	ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5);
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);  // 软件触发
	while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);  // 等待转换完毕
	return ADC_GetConversionValue(ADC1);
}
main.c
#include "stm32f10x.h" 
#include "delay.h"
#include "OLED.h"
#include "ADC.h"
// ADC多通道
// 2023年3月25日20:42:57
uint16_t AD0, AD1, AD2, AD3;
float volatge;

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)
	{
		AD0 = AD_GetValue(ADC_Channel_0);
		AD1 = AD_GetValue(ADC_Channel_1);
		AD2 = AD_GetValue(ADC_Channel_2);
		AD3 = AD_GetValue(ADC_Channel_3);
		
		OLED_ShowNum(1, 5, AD0, 4);
		OLED_ShowNum(2, 5, AD1, 4);
		OLED_ShowNum(3, 5, AD2, 4);
		OLED_ShowNum(4, 5, AD3, 4);
		
		Delay_ms(100);
	}
}

参考资料

【STM32入门教程-2023持续更新中】 https://www.bilibili.com/video/BV1th411z7sn/?p=22&share_source=copy_web&vd_source=ee06a25b3dfb2900ab707b01fdff6667文章来源地址https://www.toymoban.com/news/detail-766225.html

到了这里,关于STM32入门笔记08_ADC模数转换器+案例: ADC单通道&ADC多通道的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • STM32模数转换器(ADC)

    1.ADC的简要  我们首先说一下ADC的转换过程,然后说一下原理,当然如果嫌啰嗦可以直接跳过。  ADC是英文Analog-to-Digital Converter缩写,翻译过来就是模数转换器,是指将连续变化的模拟信号转换为离散的数字信号的器件。A/D转换的作用是将时间连续、幅值也连续的模拟信号转

    2024年02月16日
    浏览(51)
  • 【STM32学习】模数转换器——ADC

    [STM32固件库(标准外设库)入门学习 第七章 ADC数模转换(一) 刘凯:STM32F103(一):ADC 通过上述的两个链接以及stm32的参考手册,应该可以把ADC理解的差不多了,接下来说一下自己对某些内容的理解。 STM32 ADC转换速度与精度 对于AD转换所需要的时间,我们经常看到:Tconv = S

    2024年02月05日
    浏览(45)
  • STM32之模数转换器ADC

    目录 1、ADC介绍 1.什么是ADC? ADC的全称是Analog-to-Digital Converter,指模拟/数字转换器  2.ADC的性能指标 3.ADC特性 12位分辨率 4.ADC通道 5.ADC转换顺序  6.ADC触发方式  7.ADC转化时间  8.ADC转化模式  9.模拟看门狗 实验:使用ADC读取烟雾传感器的值  CubeMX配置   ​编辑 代码实现  效

    2024年02月04日
    浏览(71)
  • STM32之模数转换器(ADC)

    一、模数转换器介绍 1、模数转换器简介 为什么使用模拟转换器?? 因为MCU只能识别01010101的数字信号,而外部物理信号均为模拟信号,如声音、光、电等,所以为了让计算机能够处理外部物理的信息,必须要通过模拟转换器将模拟量转换成数字量。 模数转换器:将模拟信号

    2024年02月20日
    浏览(42)
  • 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日
    浏览(35)
  • STM-32:ADC模数转换器—ADC单通道转换/ADC多通道转换

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

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

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

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

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

    2024年02月12日
    浏览(61)
  • 快速了解A/D(模数转换器)

    以下是一个简要的概述: A/D转换器是一种电子设备 ,用于将模拟信号转换为数字信号。它将连续变化的模拟信号离散化为一系列数字值,以便于数字系统的处理和分析。 A/D转换器的原理图 通常包括模拟输入电路、采样保持电路、编码器、数字输出接口等。 了解A/D转换器的

    2024年02月06日
    浏览(40)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包