四、GD32 MCU 常见外设介绍 (6) ADC 模块介绍

6.1.ADC 基础知识

12 位逐次逼近式模数转换器模块(ADC),可以采样来自于外部输入通道、内部输入通道的模拟信号,采样转换后,转换结果可以按照最低有效位对齐或最高有效位对齐的方式保存在相应的数据寄存器中。

6.2.GD32 ADC 外设原理

GD32 ADC 主要特性

◼ 高性能:

– ADC采样分辨率: 12位、 10位、 8位、或者6位分辨率;

– 前置校准功能;

– 可编程采样时间;

– 数据存储模式:最高有效位对齐和最低有效位对齐;

– 支持规则数据转换的DMA请求。

◼ 模拟输入通道:

– 16个外部模拟输入通道;

– 1个内部温度传感器输入通道(VSENSE);

– 1个内部参考电压输入通道(VREFINT)。

◼ 转换开始的发起:

– 软件触发;

– 硬件触发。

◼ 转换模式:

– 转换单个通道,或者扫描一序列的通道;

– 单次运行模式,每次触发转换一次选择的输入通道;

– 连续运行模式,连续转换所选择的输入通道;

– 间断运行模式;

– 同步模式(适用于具有两个或多个ADC的设备)。

◼ 转换结果阈值监测器功能: 模拟看门狗。

◼ 中断的产生:

– 常规序列转换结束;

– 模拟看门狗事件。

◼ 过采样:

– 16位的数据寄存器;

– 可调整的过采样率,从2x到256x;

– 高达8位的可编程数据移位。

◼ ADC供电要求:

– 2.4V到3.6V,一般供电电压为3.3V。

◼ ADC输入范围: VREF- ≤VIN ≤VREF+。

– VREF- : ADC 负参考电压, VREF- = VSSA

– VREF+ : ADC 正参考电压, 2.6 V ≤ VREF+ ≤ VDDA

ADC 结构框图介绍

6.3.硬件连接说明

ADC的检测需要将输入阻抗和采样周期保持一定的关系,下表列出了以GD32E103为例子 

6.4.软件配置说明

查询法

查询法采用的是转换单个通道,或者扫描一序列的通道,通过不断切换通道的方式去读取对应通道的ADC数值。我们介绍使用库函数来设置 ADC0 的通道来进行 AD 转换的步骤,下面讲解其详细设置步骤:

开启 GPIO口时钟和 ADC0 时钟,设置GPIO口为模拟输入。

rcu_periph_clock_enable(RCU_GPIOA);/* enable GPIOB clock */rcu_periph_clock_enable(RCU_GPIOB);/* enable ADC0 clock */
rcu_periph_clock_enable(RCU_ADC0);
/* config ADC clock */
rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV4);
/* enable alternate function clock */
rcu_periph_clock_enable(RCU_AF); //使能 GPIO 口复用

这里需要说明一下, ADC 的通道与引脚的对应关系在数据手册可以查到

(1)配置 ADC 输入时钟分频,模式为独立模式,转换长度以及触发方式等

/* reset ADC */
adc_deinit(ADC0);
/* ADC mode config */
adc_mode_config(ADC_MODE_FREE); //独立模式
/* ADC continous function enable */
adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE)
/* ADC data alignment config */
adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT); //ADC 数据右对齐
adc_special_function_config(ADC0,ADC_CONTINUOUS_MODE,DISABLE);
/* ADC channel length config */
adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);//设置 ADC 转换的通道数量
/* ADC trigger config */
adc_external_trigger_source_config(ADC0,ADC_REGULAR_CHANNEL,ADC0_1_EXTTRIG_REGULAR_NONE);
//通过软件触发 ADC 转换
adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);

(2)开启 AD 转换器

在设置完了以上信息后,我们就开启 AD 转换器了

/* enable ADC interface */
adc_enable(ADC0);
delay_1ms(1);//延迟 等待稳定
/* ADC calibration and reset calibration */
adc_calibration_enable(ADC0);//使能 ADC 校准

(3)读取 ADC 值 在上面的步骤完成后, ADC 就算准备好了。所谓的查询法就是不断地进行通道切换

unsigned short adc0_transfer(unsigned char adc_channel)
{
uint16_t ADC_temp;/* ADC regular channel config */adc_regular_channel_config(ADC0, 0, adc_channel, ADC_SAMPLETIME_55POINT5);
adc_software_trigger_enable(ADC0,ADC_REGULAR_CHANNEL);while(!adc_flag_get(ADC0, ADC_FLAG_EOC));//等待转换完成/* clear the end of conversion flag */adc_flag_clear(ADC0, ADC_FLAG_EOC);ADC_temp=adc_regular_data_read(ADC0);return ADC_temp;
}

这里还需要说明一下ADC的参考电压,是以Vref作为参考电压。

常规通道转换 DMA 搬运

通过ADC转换,在ADC 转换完成后 触发DMA 进行数据搬运。

DMA 请求,可以通过设置 ADC_CTL1 寄存器的 DMA 位来使能,它用于规则组多个通道的转换结果。 ADC 在规则组一个通道转换结束后产生一个 DMA 请求, DMA 接受到请求后可以将转换的数据从 ADC_RDATA 寄存器传输到用户指定的目的地址。

在和查询法一节的差别,主要在于ADC 的配置方面和DMA的配置

(1)ADC 的配置

/* ADC channel length config */adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 4);//常规通道长度配置/* ADC regular channel config */adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_4, ADC_SAMPLETIME_55POINT5);adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_5, ADC_SAMPLETIME_55POINT5);adc_regular_channel_config(ADC0, 2, ADC_CHANNEL_6, ADC_SAMPLETIME_55POINT5);adc_regular_channel_config(ADC0, 3, ADC_CHANNEL_7, ADC_SAMPLETIME_55POINT5);/* ADC trigger config */
adc_external_trigger_source_config(ADC0,ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_NONE);adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
/* ADC DMA function enable */adc_dma_mode_enable(ADC0);//使能 DMA 模式/* enable ADC interface */adc_enable(ADC0);delay_1ms(1);/* ADC calibration and reset calibration */
adc_calibration_enable(ADC0);

 (2)DMA的配置

 /* ADC_DMA_channel configuration */
dma_parameter_struct dma_data_parameter;/* ADC DMA_channel configuration */dma_deinit(DMA0, DMA_CH0);/* initialize DMA single data mode */dma_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(ADC0)); //外设地址dma_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;dma_data_parameter.memory_addr = (uint32_t)(&adc_value); //搬运目标地址dma_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT; dma_data_parameter.direction = DMA_PERIPHERAL_TO_MEMORY;dma_data_parameter.number = 4;dma_data_parameter.priority = DMA_PRIORITY_HIGH;dma_init(DMA0, DMA_CH0, &dma_data_parameter);/* enable DMA circulation mode */dma_circulation_enable(DMA0, DMA_CH0);/* enable DMA channel */
dma_channel_enable(DMA0, DMA_CH0);

(3)触发ADC 转换

adc_software_trigger_enable(ADC0,ADC_REGULAR_CHANNEL);

 注入通道-中断

在和查询法一节的差别,主要在于ADC 的配置方面和注入通道会产生中断

(1)ADC 的配置

 /* reset ADC */adc_deinit(ADC0);/* ADC mode config */adc_mode_config(ADC_MODE_FREE);/* ADC continous function enable */adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);/* ADC data alignment config */adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);/* ADC channel length config *//注入通道配置adc_channel_length_config(ADC0, ADC_INSERTED_CHANNEL, 4);//注入通道长度配置/* ADC inserted channel config */adc_inserted_channel_config(ADC0, 0, ADC_CHANNEL_0, ADC_SAMPLETIME_55POINT5);adc_inserted_channel_config(ADC0, 1, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);adc_inserted_channel_config(ADC0, 2, ADC_CHANNEL_2, ADC_SAMPLETIME_55POINT5);adc_inserted_channel_config(ADC0, 3, ADC_CHANNEL_3, ADC_SAMPLETIME_55POINT5);/* ADC trigger config */ //通过 EXTI 15 进行触发adc_external_trigger_source_config(ADC0,ADC_INSERTED_CHANNEL,ADC0_1_EXTTRIG_INSERTED_EXTI_15); /* ADC external trigger enable */adc_external_trigger_config(ADC0, ADC_INSERTED_CHANNEL, ENABLE);
/* clear the ADC flag */adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOC);adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOIC);/* enable ADC interrupt */
adc_interrupt_enable(ADC0, ADC_INT_EOIC);//使能注入通道的中断
/* enable ADC */
adc_enable(ADC0);
delay_1ms(1);
/* ADC calibration and reset calibration */
adc_calibration_enable(ADC0);

(2)ADC 注入通道转换完成服务函数

void ADC0_1_IRQHandler(void)
{/* clear the ADC flag */adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOIC);//清除注入通道转换完成标志位/* read ADC inserted group data register */inserted_data[0] = adc_inserted_data_read(ADC0, ADC_INSERTED_CHANNEL_0);inserted_data[1] = adc_inserted_data_read(ADC0, ADC_INSERTED_CHANNEL_1);inserted_data[2] = adc_inserted_data_read(ADC0, ADC_INSERTED_CHANNEL_2);inserted_data[3] = adc_inserted_data_read(ADC0, ADC_INSERTED_CHANNEL_3);
}

6.5.ADC 使用注意事项

  1. ADC通道的采集引脚未配置为模拟输入,GD32要求通道IO口必须配置为模拟输入;

  2. ADC时钟过高,ADC采样时钟高于ADC最高采样时钟获取到的数据不具有参考意义,需要手动分频到合适的ADC 要求的频率;

  3. ADC采样值偏小或不稳定,应该适当的降低ADC时钟,加大采样周期的值;

  4. ADC的查询法在获取ADC数值的时候,不允许重入,即不允许在同一时间调用ADC的数据读取函数;

  5. ADC在使能之后需要进行短暂的延时,时间周期约为2毫秒左右,以保证ADC能正常启动。

本章内容每日持续更新,如有兴趣,请关注收藏

更多GD32 MCU相关咨询:https://www.gd32bbs.com/ 

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

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

相关文章

elasticsearch-7.3.1安装注意事项

elasticsearch-7.3.1安装注意事项 一、背景二、步骤1、查看原ES版本2、新环境服务器2.1、是否有elasticsearch2.2、安装elasticsearch2.3、配置参数2.4、启动elasticsearch2.5、设置密码 三、报错-问题总结1、jdk不适用2、bootstrap checks failed3、Address already in use4、…

vue3前端开发-小兔鲜项目-图片切换效果和动态class

vue3前端开发-小兔鲜项目-图片切换效果和动态class!这次实现的效果是&#xff0c;图片预览效果&#xff0c;根据小图片&#xff0c;来实时改变大图&#xff08;预览&#xff09;的效果。同时让动态的特征class也跟着显示出来。 <script setup> import {ref} from vue // …

Linux 各目录

Linux 是一个非常严谨的操作系统&#xff0c;每个目录都有自己的作用&#xff0c;这些作用是固定的&#xff0c;没有特殊情况&#xff0c;应严格执行&#xff1b; Linux 中所有东西以文件形式存储和管理&#xff0c;命令也不例外&#xff1b; 以下四个 bin 是二进制文件&…

freesql简单使用操作mysql数据库

参考&#xff1a;freesql中文官网指南 | FreeSql 官方文档 这两天准备做一个测试程序&#xff0c;往一个系统的数据表插入一批模拟设备数据&#xff0c;然后还要模拟设备终端发送数据包&#xff0c;看看系统的承压能力。 因为系统使用的第三方框架中用到了freesql&#xff0c…

数据库的事务隔离级别有哪些?

并行事务会引发什么问题&#xff1f; 同时处理多个事务的时候&#xff0c;就可能出现脏读&#xff08;dirty read&#xff09;、不可重复读&#xff08;non-repeatable read&#xff09;、幻读&#xff08;phantom read&#xff09;的问题。脏读: 如果一个事务「读到」了另一个…

NSSCTF-2021年SWPU联合新生赛

[SWPUCTF 2021 新生赛]finalrce 这道题目考察tee命令和转义符\ 这题主要是&#xff0c;遇到一种新的符号&#xff0c;"\"—转义符。我理解的作用就是在一些控制字符被过滤的时候&#xff0c;可以用转义符&#xff0c;让控制符失去原本的含义&#xff0c;变为字面量…

react中配置路径别名@

1.说明 在react项目中想要使用代替“src/”需要在项目根目录下配置两个文件&#xff0c;craco.config.js和sconfig.json&#xff1b; craco.config.js配置文件是用于项目解读为“src/” jsconfig.json配置文件是用于vsCode在编辑过程是输入后可以将src下的文件目录进行自动联…

k8s中部署Jenkins、SonarQube、StorageClass部署流程

部署Jenkins 系统环境&#xff1a; • kubernetes 版本&#xff1a;1.23.3 • jenkins 版本&#xff1a;2.172 • jenkins 部署示例文件 Github 地址&#xff1a;https://github.com/my-dlq/blog-example/tree/master/jenkins-deploy 一、设置存储目录 在 Kubenetes 环境下…

[DVWA靶场实战]-SQL注入攻击(命令注入+SQL回显注入+sqlmap工具实现自动化注入)详细教程

原理与内容 1.命令注入原理 以Windows系统的DOS命令为例&#xff0c;DOS命令可以查看本地网络、系统用户、当前目录、字符串查找&#xff0c;也可以复合命令。命令注入就是利用复合命令的特点&#xff0c;通过Web程序&#xff0c;在服务器上&#xff0c;拼接系统命令&#xf…

elk日志索引被锁blocks,日志无法写入

现象&#xff1a; kafka积压&#xff0c;logstash无法将日志写入到es logstash报错&#xff1a; [logstash.outputs.elasticsearch][main][] Retrying failed action {:status>403 :error>{“type”>“cluster_block_exception”, “reason”>“index [] blocked …

昇思MindSpore 应用学习-CycleGAN图像风格迁移互换

日期 心得 昇思MindSpore 应用学习-CycleGAN图像风格迁移互换&#xff08;AI代码学习&#xff09; CycleGAN图像风格迁移互换 模型介绍 模型简介 CycleGAN(Cycle Generative Adversarial Network) 即循环对抗生成网络&#xff0c;来自论文 Unpaired Image-to-Image Trans…

Rust代码答疑报错|Python一对一辅导答疑

Question 你好&#xff0c;我是悦创。 学员答疑&#xff1a; https://code.bornforthis.cn/?id4e72084d-1eaf-44ed-8067-744671491574https://code.bornforthis.cn/?id664ff169-41d6-409f-a05b-02ed42279759 问题代码&#xff1a; // You can bring module paths into sc…

使用python连接neo4j时报错:IndexError: pop from an empty deque的解决办法

遇见这个错&#xff0c;首先可能是python现在的py2neo的版本不对&#xff0c;把2021.1.0版本卸载&#xff0c;下载 py2neo4.2.0版本。我不是&#xff0c;一阵搜&#xff0c;发现需要改配置文件 首先找到你的neo4j的安装路径 在网上看的是&#xff0c;先找到data/dbms/auth文件…

Ins云手机在运营Instagram账号的优势

在数字时代&#xff0c;Instagram成为全球数亿用户的重要社交平台&#xff0c;其超过10亿的用户数量&#xff0c;为企业提供了广阔的营销空间。对于希望拓展海外市场的企业来说&#xff0c;使用Instagram进行引流和推广是一个高效且安全的选择。为了更高效地管理和运营多个Inst…

Python 实现股票指标计算——VR

VR (Volume Ratio) - 成交量变异率 1 公式 AV 股价上升日成交量&#xff1b;AVS N日内AV求和BV 股价下跌日成交量&#xff1b;BVS N日内BV求和CV 股价平盘日成交量&#xff1b;CVS N日内CV求和VR (AVS1/2CVS) ➗ (BVS1/2CVS) ✖ 100MAVR VR的M日简单移动平均 2 数据…

HDU1032——The 3n + 1 problem,HDU1033——Edge,HDU1034——Candy Sharing Game

目录 HDU1032——The 3n 1 problem 题目描述 运行代码 代码思路 HDU1033——Edge 题目描述 运行代码 代码思路 HDU1034——Candy Sharing Game 题目描述 运行代码 代码思路 HDU1032——The 3n 1 problem 题目描述 Problem - 1032 运行代码 #include <iostr…

相信开源的力量,MoonBit 构建系统正式开源

MoonBit 构建系统正式开源 作为由 AI 驱动的云服务和边缘计算开发者平台&#xff0c;MoonBit 自设计之初便注重工具链与语言的协同效果。MoonBit 为开发者提供了一套开箱即用的工具链&#xff0c;包括集成开发环境&#xff08;IDE&#xff09;、编译器、构建系统和包管理器&…

android audio不同音频流,(六)settings内音频流音量调整

&#xff08;1&#xff09;settings内&#xff0c;可设置音频流音量&#xff0c;如下图&#xff1a; &#xff08;2&#xff09;settings调整音量条进度&#xff0c;会触发SeekBarVolumizer对象&#xff1a; SeekBarVolumizer文件路径&#xff1a; frameworks/base/core/java/…

【MySQL进阶之路 | 高级篇】事务的ACID特性

1. 数据库事务概述 事务是数据库区别于文件系统的重要特性之一&#xff0c;当我们有了事务就会让数据库始终保持一致性&#xff0c;同时我们还能通过事务的机制恢复到某个时间点&#xff0c;这样可以保证给已提交到数据库的修改不会因为系统崩溃而丢失。 1.1 基本概念 事务&…

OpenCV图像滤波(1)双边滤波函数bilateralFilter的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 功能描述 bilateralFilter是图像处理和计算机视觉领域中的一种高级图像滤波技术&#xff0c;特别设计用于在去除噪声的同时保留图像的边缘和细节。相比于传…