【STM32】ADC模拟数字转换(规则组单通道)

news2024/9/21 11:01:15

本篇博客重点在于标准库函数的理解与使用,搭建一个框架便于快速开发 

目录

 ADC简介

ADC时钟配置

引脚模拟输入模式

规则组通道选择

ADC初始化 

工作模式

数据对齐

 触发转换方式

连续与单次转换模式

扫描模式

组内的通道个数

ADC初始化框架

ADC上电

ADC校验

 获取转换数据

 ADC规则组单通道框架

 AD.h

 AD.c


 ADC简介

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

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

ADC时钟配置

就是配置上图的RCC时钟部分,为ADC提供时钟(CLOCKk)信号

已知ADC都在APB2总线(如图)

再由RCC时钟树,需要使能APB2外设的ADC时钟。ADCCLK最大为14MHz,可选6分频或8分频,分别提供最大12MHz和9MHz的时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//ADC1外设时钟使能
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz

引脚模拟输入模式

 内部通道

温度传感器和通道ADC1_IN16相连接

内部参照电压VREFINT和ADC1_IN17相连接

注意: 温度传感器和VREFINT只能出现在主ADC1中

外部通道

选择模拟输入模式,外部的模拟信号直接作为ADCx的INy(y=0~15)

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

GPIO初始化

STM32F103C8T6的PA0默认复用为ADC1_IN0

GPIO的其它参数的理解可以阅读下方博客,这里不再赘述。

【STM32】GPIO和AFIO标准库使用框架-CSDN博客

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  //ADC1的通道0
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

规则组通道选择

在任意多个通道上以任意顺序进行的一系列转换构成成组转换。

先学习规则组通道转换,1个组里可以有0~16个通道的任意排列组合

例如,可以如下顺序完成转换

构成转换的规则组

转换的序号通道号(ADCxINy)
1通道3
2通道8

3

通道2
4通道 2
5通道0
6通道2
7通道2
8通道15

 每一个规则组里的通道可以单独配置组里的序号,所以单独配置几个序号就调用几个通道配置函数

参数解释

ADCxx 可以是 选择哪一个ADC 外设
ADC_Channel被设置的 ADC 通道
Rank规则组采样顺序
ADC_SampleTime指定 ADC 通道的采样时间值

ADC转换需要时间,在这里可以设置每个序号对应的通道以不同的时间采样

//配置放在规则组序列1里的通道ADC1_IN0及采样时间55.5个ADC采样周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);

ADC初始化 

工作模式

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

数据对齐

转换结果为12位,转换完成后存放在16位数据寄存器中,需要选择数据左对齐还是右对齐

只有一个数据寄存器,转换后的结果会被覆盖,要及时取走

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐

 触发转换方式

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

连续与单次转换模式

连续转换模式

 连续模式使能条件下, 连续模式开启,只需要触发一次,就可不停的转换,这时,不需要查看转换完成标志位,直接读取数据寄存器即可得到数据。

单次转换模式

执行一次转换后ADC停止,需要重新发出触发信号,再次启动转换。

ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//单次转换模式

来自参考手册:

 ● 规则组由多达16个转换组成。规则通道和它们的转换顺序在ADC_SQRx寄存器中选择。规 则组中转换的总数应写入ADC_SQR1寄存器的L[3:0]位中。

● 注入组由多达4个转换组成。注入通道和它们的转换顺序在ADC_JSQR寄存器中选择。注入 组里的转换总数目应写入ADC_JSQR寄存器的L[1:0]位中。

如果ADC_SQRx或ADC_JSQR寄存器在转换期间被更改,当前的转换被清除,一个新的启动脉冲将发送到ADC以转换新选择的组。

规则组序列一有1个通道,并且配置为连续转换模式时,不建议更改序列1位置的通道号。不建议这时通过更改序列1的通道号来实现多个ADCx通道转换

扫描模式

非扫描模式只转换组内的序列一位置的通道,扫描模式会从序列一的通道依次转换到指定的序列号的通道,组内最后一个转换完成置EOC标志位

ADC_InitStructure.ADC_ScanConvMode = DISABLE;

组内的通道个数

非扫描模式时,通道数为1,仅在扫描模式下,才需要指定大于1的数

ADC_InitStructure.ADC_NbrOfChannel = 1;

ADC初始化框架

	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框图 

ADC上电

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

ADC校验

ADC有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的准精度误差。在 校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换 中每个电容器上产生的误差。 通过设置ADC_CR2寄存器的CAL位启动校准。一旦校准结束,CAL位被硬件复位,可以开始正 常转换。建议在上电时执行一次ADC校准。校准阶段结束后,校准码储存在ADC_DR中。

注意:

1 建议在每次上电后执行一次校准。

2 启动校准前,ADC必须处于关电状态(ADON=’0’)超过至少两个ADC时钟周期

直接调用即可 

	ADC_ResetCalibration(ADC1);
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
    while (ADC_GetCalibrationStatus(ADC1) == SET);

 获取转换数据

uint16_t AD_GetValue(uint8_t ADC_Channel)
{
	ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5);//在每次转换前,根据函数形参灵活更改规则组的通道1
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);//软件触发AD转换一次
	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);//等待EOC标志位,即等待AD转换结束
	return ADC_GetConversionValue(ADC1);//读数据寄存器,得到AD转换的结果
}

​​​​​​​​​​​​​​ ADC规则组单通道框架

 AD.h

#ifndef __AD_H
#define __AD_H

void AD_Init(void);
uint16_t AD_GetValue(uint8_t ADC_Channel);

#endif

 AD.c

#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); //选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz
	
	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);

	/*
      不在此处配置规则组序列,而是在每次AD转换前配置,这样可以灵活更改AD转换的通道
      如果要设置序列1为固定的通道在这里调用一次就可,AD_GetValue()中的通道配置应删除	
    */

    //ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);

	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//模式,选择独立模式,即单独使用ADC1
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不用硬件触发,软件触发
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//连续转换,失能,每转换一次规则组序列后停止
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;扫描模式,失能,只转换规则组的序列1这一个位置
	ADC_InitStructure.ADC_NbrOfChannel = 1; //通道数,为1,仅在扫描模式下,才需要指定大于1的数,在非扫描模式下,只能是1
	ADC_Init(ADC1, &ADC_InitStructure);
	
	ADC_Cmd(ADC1, ENABLE);//使能ADC1,ADC开始运行
	
	ADC_ResetCalibration(ADC1);
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET);
}


/**
  * 函    数:获取AD转换的值
  * 参    数:ADC_Channel 指定AD转换的通道,范围:ADC_Channel_x,其中x可以是0/1/2
  * 返 回 值:AD转换的值,范围:0~4095
  */
uint16_t AD_GetValue(uint8_t ADC_Channel)
{
	ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5);//在每次转换前,根据函数形参灵活更改规则组的通道1
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);//软件触发AD转换一次
	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);//等待EOC标志位,即等待AD转换结束
	return ADC_GetConversionValue(ADC1);//读数据寄存器,得到AD转换的结果
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2038136.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高质量翻译对高质量内容和用户体验的影响

在当今全球化的数字环境中,高质量翻译在塑造高质量内容和用户体验方面的重要性怎么强调都不为过。随着公司和开发人员在不同地区和文化中扩大影响力,有效地翻译成为确保内容与不同受众产生共鸣的关键因素。高质量的翻译不仅保留了原始内容的完整性&#…

【网络层】上

目录 一. 网络层功能概述二. SDN的基本功能2.1 数据平面2.2 控制平面(传统方法/每路由器法)2.3 控制平面(SDN方法) 三. 路由算法与路由协议四. IP数据报4.1 IP数据报格式4.2 IP数据报分片4.3 IP地址 (IPV4)…

2024年华为认证H12-811题库(超级好用的刷题软件)

某个ACL规则如下:则下列哪些IP地址可以被permit规则匹配: rule 5 permit ip source 10.0.2.0 0.0.254.255 A、10.0.4.5 B、10.0.5.6 C、10.0.6.7 D、10.0.2.1 试题答案:A;C;D 试题解析: 10.0.2.000001010.00000000.00000010.0000000…

php 匿名类

https://andi.cn/page/621667.html

TMGM原油返佣是多少

在全球金融市场中,原油交易一直是投资者的重要选择之一。其中,交易平台的选择更是关系到投资者盈利的关键因素。TMGM,作为一家全球领先的在线交易提供商,以其公正、透明的交易环境和优质的服务赢得了广大投资者的信赖。那么&#…

【python小脚本】摄像头rtsp流转hls m3u8 格式web端播放

写在前面 工作需要,简单整理实际上这种方式延迟太高了,后来前端直接接的海康的的插件博文内容为 摄像头 rtsp 实时流转 hls m3u8 的一个 Python 脚本理解不足小伙伴帮忙指正 😃,生活加油 99%的焦虑都来自于虚度时间和没有好好做事&#xff0c…

【TiDB】07-tiup工具安装及使用

目录 1、在线安装 1.2、脚本代码如下 2、离线安装 2.1、下载安装包 2.2、安装脚本 3、卸载 4、常用命令 TiDB 提供了丰富的工具,可以帮助你进行部署运维、数据管理(例如,数据迁移、备份恢复、数据校验)、在 TiKV 上运行 S…

意大利Panel触摸屏维修显示屏EBP419 EMBEDDED

意大利Panel触摸屏维修显示屏维修EBP400系列EMBEDDED PC EBP419 panel维修产品主要包括:操作面板,触摸屏,终端机,触摸面板等。应用于包装、食品饮料、纺织与各种工业自动化领域。 panel触摸屏无论是机械工程、装置或单个应用,HMI几乎都可以简化操作,并且通过HMI,还…

大数据技术——DolphinScheduler的集群部署

目录 第1章 DolphinScheduler简介 1.1 DolphinScheduler概述 1.2 DolphinScheduler核心架构 第2章 DolphinScheduler部署说明 2.1 软硬件环境要求 2.1.1 操作系统版本要求 2.1.2 服务器硬件要求 2.2 部署模式 2.2.1 单机模式 2.2.2 伪集群模式 2.2.3 集群模式 第3章…

语音转文字例会纪要有什么好?一分钟掌握5款语音转文字软件

你是否曾在紧张的会议现场,因笔记跟不上发言者语速而焦虑不已?亦或是在采访结束后,面对一堆录音文件感到头大,不知如何迅速整理成可用的文本? 别急,科技的进步总能给我们惊喜。今天,我要为你带…

Golang多版本环境安装并存

1. 准备 请先安装最新版本的Go,详见 https://go.dev/doc/install go version2. 配置镜像加速 go env -w GO111MODULEon go env -w GOPROXYhttps://goproxy.cn,direct3. 安装Go指定版本 Golang官方提供dl工具来实现多版本的Go环境管理,详见项目&#…

带你速通C语言——常量(3)

常 量 在C语言中,常量是一种在程序执行过程中其值不会改变的量。声明常量的方法有两种主要方式:使用const关键字和预处理指令#define。 1.使用 const关键字 当你使用const关键字声明常量时,你需要在声明时立即初始化它,并且在其生…

【强化学习的数学原理】课程:从零开始到透彻理解-30分钟了解强化学习名词脉络

完全零基础的学习强化学习,希望能入门 此图为强化学习的一个脉络图,主要分为两个板块 基础的工具 基本的概念贝尔曼公式贝尔曼最优公式算法和方法 值迭代和策略迭代蒙特卡洛的方法时序差分的方法Value Function ApproximationPolicy Gradient 方法Actor…

糟糕界面集锦-控件篇07

对制作一个图形界面程序的步骤还有疑问吗?在Unisyns Automate Pro 中这个问题特别明显:开发人员显然忘记了TAB 键的作用是在控件之间遍历这个常识。作者使用了开发工具自动生成的控件次序(Tab Order)。程序的界面如下图,需要说明的是&#xf…

二、达梦数据库(DM8)- Django集成

达梦数据库(DM8)- Django集成 一、集成介绍二、下载驱动包三、Windows1.安装dmPython2.测试dmPython3.安装django-dmPython5.配置数据库信息6.测试 四、Linux1.x86_642.aarch_642.1 安装gcc编译工具2.2 安装dmPython 五、注意事项1.django-授权SYS.SYSOB…

<数据集>怠岗图片数据集<目标检测>

图片数量:2479张 类别数:3 序号类别名称图片数1工作状态9182使用手机2883打瞌睡1273 图片示例: 工作状态: 使用手机: 打瞌睡:

如何减少 Docker 镜像大小:6 种优化方法

如果您想减少docker镜像的大小,您需要使用构建docker镜像的标准最佳实践。 本博客讨论了您可以快速实施的各种优化技术,以制作最小、最精简的 docker 镜像。我们还将介绍一些用于 Docker 镜像优化的最佳工具。 Docker 作为一种容器引擎,可以…

SpringBoot快速入门(手动创建)

目录 案例:需求 步骤 1 创建Maven项目 2 导入SpringBoot起步依赖 3 定义Controller 4 编写引导类 案例:需求 搭建简单的SpringBoot工程,创建hello的类定义h1的方法,返回Hello SpringBoot! 步骤 1 创建Maven项目 大家&…

【Java】文件IO

文章目录 一、什么是文件二、硬盘1. 机械硬盘2. 固态硬盘 三、文件路径四、文件类型 文件 硬盘 系统管理文件,引入一个额专门的模块,“文件系统”,每个文件都有一个“路径”描述文件所在位置 一、什么是文件 此处谈到的文件,本…

SQL Zoo 8+.NSS Tutorial

以下数据来自SQL Zoo 1.at Edinburgh Napier University,studying (8) Computer Science,Show the the percentage who STRONGLY AGREE.(在爱丁堡纳皮尔大学,学习“计算机科学”,显示STRONGLY AGREE的百分比&#xff0…