当前位置: 首页 > news >正文

【STM32】ADC|多通道ADC采集

本次实现的是ADC实现数字信号与模拟信号的转化,数字信号时不连续的,模拟信号是连续的。

1.ADC转化的原理

模拟-数字转换技术使用的是逐次逼近法,使用二分比较的方法来确定电压值
在这里插入图片描述
当单片机对应的参考电压为3.3v时,0~ 3.3v(模拟信号)对应0~4095(数字信号),假如我们知道一个数字信号的值为x,那么他对应的模拟信号
x/4095=y/3.3
y就是x对应的模拟信号
假如要确定0.8v对应的数字信号的值
在这里插入图片描述
他会将0.8v电压保存在电容中,然后先和3.3v的一半对应的1.65v(2048)做比较,如果小于1.65v的话,12位最高位就是0,因为1000 0000 0000 对应的就是2048

在这里插入图片描述
接着就是和1.65的一半比较,0.825v(1024)>0.8v,所以12位中倒数第二高位就是0,因为0.825(1024)对应二进制就是0100 0000 0000
在这里插入图片描述
接着0.8v和0.825的一半比较->0.4125v(512),0.8v>0.4125v,所以第三位为1,因为512对应的二进制为0010 00000000
在这里插入图片描述
按这个方法依次确定0.8v对应的12位的二进制数,然后这个二进制对应的十进制就是0.8v对应的数字信号的值
所以对应的过程是1.启动ADC 2.采样&转换 3.获取&计算,针对STM32F103C8T6芯片有10个外部通道,和两个内部通道(内部温度传感器,内部参考电压)进行ADC的转化,ADC1和ADC2,两个转化结构,每个转化结构都有一个注入组和一个规则组,我们现在只讲讲规则组,我们要对一个通道的电压值进行采集的时候,我们需要将这个通道注册进这个通道中,当启动ADC,然后采样转化的电压值就会放在规则通道数据寄存器(12位二进制值)中,等待获取

2.实操

在这里插入图片描述
单片机有一个电位器,通过旋转电位器,使得PA5的输出电压发送变化,我们将其输出到串口上去
在这里插入图片描述
对应的PA5刚好是ADC1的通道5

  char message[50]="";float v=0.0;int value=0;/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){ HAL_ADC_Start(&hadc1);//开启ADC1HAL_ADC_PollForConversion(&hadc1,HAL_MAX_DELAY);//等待转换value=HAL_ADC_GetValue(&hadc1);//从寄存器中获取电压值v=(value/4095.0)*3.3;//转模拟信号sprintf(message,"v:%.2f,value:%d",v,value);HAL_UART_Transmit(&huart2,message,strlen(message),HAL_MAX_DELAY);HAL_Delay(500);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}

在这里插入图片描述
但是发现一个问题,就是电位器扭到头
在这里插入图片描述
最大为3.25v,达不到3.3v,这是因为手册里面说
在这里插入图片描述

  char message[50]="";float v=0.0;int value=0;HAL_ADCEx_Calibration_Start(&hadc1);//校准/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){HAL_ADC_Start(&hadc1);//开启ADC1HAL_ADC_PollForConversion(&hadc1,HAL_MAX_DELAY);//等待转换value=HAL_ADC_GetValue(&hadc1);//从寄存器中获取电压值v=(value/4095.0)*3.3;//转模拟信号sprintf(message,"v:%.2f,value:%d",v,value);HAL_UART_Transmit(&huart2,(uint8_t*)message,strlen(message),HAL_MAX_DELAY);HAL_Delay(500);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}

在这里插入图片描述
其实还有一种是循环转换,只需要开启一次ADC即可
在这里插入图片描述

  char message[50]="";float v=0.0;int value=0;HAL_ADCEx_Calibration_Start(&hadc1);//校准HAL_ADC_Start(&hadc1);//开启ADC1HAL_ADC_PollForConversion(&hadc1,HAL_MAX_DELAY);//等待转换/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){value=HAL_ADC_GetValue(&hadc1);//从寄存器中获取电压值v=(value/4095.0)*3.3;//转模拟信号sprintf(message,"v:%.2f,value:%d",v,value);HAL_UART_Transmit(&huart2,(uint8_t*)message,strlen(message),HAL_MAX_DELAY);HAL_Delay(500);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}

3.ADC多路采集

在前面说过,如果要获取对应通道的电压值,就需要将这个通道注册进规则组中,然后数据准备就绪, HAL_ADC_PollForConversion函数不断的检测ADC状态寄存器中转换结束标志位(EOC)是否为1,如果是,转换完成,将转换的值放入规则通道数据寄存器中,然后调用HAL_ADC_GetValue读取规则通道数据寄存器,然后对应的ADC状态寄存器中的转换结束标志位置0.
在多采集中需要将多个通道打开实现转换,会按照规则组注册顺序,依次将对应通道的电压值放入规则通道数据寄存器,然后写到内存中。
我们可以使用DMA来对规则通道数据寄存器的值搬运到内存,当搬运完成,就会触发DMA完成中断,进行处理转换后的值
本次实现热敏电阻,电位器,单片机内部温度,内部参考电压的ADC转换,并通过串口将其发送
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
PA4,PA5 ADC在ADC1的通道4,通道5上,以及内部温度通道,内部参考电压通道
在这里插入图片描述
注意将四个通道的多久采集值调到四个通道转换最大值,确保数据都已经被转换
在这里插入图片描述

uint16_t data[4];
char message[50]="";
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc==&hadc1){sprintf(message,"%d %d %d %d",data[0],data[1],data[2],data[3]);HAL_UART_Transmit(&huart2, (uint8_t*)message,sizeof(message),HAL_MAX_DELAY);}}
int main(void)
{HAL_Init();HAL_ADCEx_Calibration_Start(&hadc1);//校准while (1){HAL_ADC_Start_DMA(&hadc1,(uint32_t*)data,4);//开启ADC,DMA完成搬运调用DMA完成中断中断,在中断中发送转换值到串口HAL_Delay(500);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

在这里插入图片描述
依次是电位器,热敏电阻,内部温度,内部参考电压未转化为模拟电压
除此之外我们可以使用循环转换,和DMA的循环搬运就可以实现开启一次ADC就可以一直将转换后的四个值发送到串口,因为会一直转换,不用知道什么时候转换完成,我们将发送到串口放到while中
在这里插入图片描述

uint16_t data[4];
char message[50]="";int main(void)
{HAL_Init();HAL_ADCEx_Calibration_Start(&hadc1);//校准HAL_ADC_Start_DMA(&hadc1,(uint32_t*)data,4);//开启ADC,DMA完成搬运调用DMA完成中断中断,在中断中发送转换值到串口while (1){sprintf(message,"%d %d %d %d",data[0],data[1],data[2],data[3]);HAL_UART_Transmit(&huart2, (uint8_t*)message,sizeof(message),HAL_MAX_DELAY);HAL_Delay(500);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

在这里插入图片描述

相关文章:

【STM32】ADC|多通道ADC采集

本次实现的是ADC实现数字信号与模拟信号的转化,数字信号时不连续的,模拟信号是连续的。 1.ADC转化的原理 模拟-数字转换技术使用的是逐次逼近法,使用二分比较的方法来确定电压值 当单片机对应的参考电压为3.3v时,0~ 3.3v(模拟信…...

蓝桥杯算法日记|贪心、双指针

3412 545 2928 2128 贪心学习总结: 1、一般经常用到sort(a,an);【a[n]】排序,可以给整数排,也可以给字符串按照字典序排序 2、每次选最优 双指针 有序数组、字符串、二分查找、数字之和、反转字…...

ArcGIS Pro SDK (二十七)自定义许可

ArcGIS Pro SDK (二十七)自定义许可 环境:Visual Studio 2022 + .NET6 + ArcGIS Pro SDK 3.0 文章目录 ArcGIS Pro SDK (二十七)自定义许可1 在Config.xaml中添加扩展配置2 在Module1.cs中实现接口IExtensionConfig1 在Config.xaml中添加扩展配置 <modules><inse…...

通过客户端Chatbox或OpenwebUI访问识别不到本地ollama中的模型等问题的解决

Chatbox和Open WebUI 等无法获取到 Ollama里的模型&#xff0c;主要是由以下原因导致&#xff1a; Ollama 服务未正确暴露给 Docker 容器或客户端模型未正确下载或名称不匹配网络配置或权限问题 排查以上问题的思路首先排查ollama服务是否启动&#xff0c;然后再看端口号 使…...

速度超越DeepSeek!Le Chat 1100tok/s闪电回答,ChatGPT 4o和DeepSeek R1被秒杀?

2023年&#xff0c;当全球科技界还在ChatGPT引发的AI狂潮中沉浮时&#xff0c;一场来自欧洲的"静默革命"正悄然改变游戏规则。法国人工智能公司Mistral AI推出的聊天机器人Le Chat以"比ChatGPT快10倍"的惊人宣言震动业界&#xff0c;其背后承载的不仅是技术…...

JVM速成=。=

JVM跨平台原理 跨平台&#xff1a;一次编译&#xff0c;到处运行 本质&#xff1a;不同操作系统上运行的JVM不一样&#xff0c;只需要把java程序编译成一份字节码文件&#xff0c;JVM执行不同的字节码文件。 Java是高级语言&#xff0c;提前编译一下&#xff08;变成字节码文件…...

Packer 手动修复安装腾讯云插件

文章目录 Packer [腾讯云插件文档](https://developer.hashicorp.com/packer/integrations/hashicorp/tencentcloud) 提供的版本&#xff1a;v1.2.0&#xff0c;目前 Packer 构建镜像时&#xff0c;不支持现有2种[硬盘类型](https://www.tencentcloud.com/zh/document/product/…...

学习总结三十

下头论文 # P10605 下头论文 题目背景 莲子一直在苦恼关于论文的灵感。她为此花了太多时间&#xff0c;以至于没有时间理会她的伙伴梅莉。 题目描述 一天&#xff0c;莲子发现了一个绝妙的点子&#xff0c;并希望通过实验等过程将其完善。具体来说&#xff0c;她需要依次完成 n…...

开发完的小程序如何分包

好几次了&#xff0c;终于想起来写个笔记记一下 我最开始并不会给小程序分包&#xff0c;然后我就各种搜&#xff0c;发现讲的基本上都是开发之前的小程序分包&#xff0c;可是我都开发完要发布了&#xff0c;提示我说主包太大需要分包&#xff0c;所以我就不会了。。。 好了…...

Flutter PIP 插件 ---- Android

在 Flutter Android 应用中实现画中画功能 画中画(Picture-in-Picture, PiP)模式允许您的应用在一个固定在屏幕角落的小窗口中运行,同时用户可以与其他应用进行交互。本指南将介绍如何在 Flutter Android 应用中实现画中画功能,包括其局限性和解决方案。 项目地址 flutter_p…...

【20250211】字符串:459.重复的子字符串

#方法一&#xff1a;暴力求解法 # class Solution: # def repeatedSubstringPattern(self, s): # n len(s) # substr "" # #只重复一次不算“重复多次” # if n < 1: # return False # else: # …...

【DeepSeek学Cuda】矩阵转置:行读取优先还是列读取优先。

目录 **1. 实现A&#xff08;按行读取&#xff0c;按列存储&#xff09;2. 实现B&#xff08;按列读取&#xff0c;按行存储&#xff09;**3. 哪种更好 Professional cuda programming5. "当L1缓存被禁用时&#xff0c;所有内存访问都直接指向全局内存&#xff08;Global …...

如何将3DMAX中的3D文件转换为AutoCAD中的2D图形?

大家好,今天我们来探讨一下如何将3DMAX中的3D文件转换为AutoCAD中的2D图形。无论是出于设计交流、施工准备还是其他实际需求,这种转换在工程设计领域都是一项非常实用的技能。接下来,我将为大家详细介绍几种实现这一转换的方法,帮助大家轻松跨越3D与2D设计之间的鸿沟。让我…...

Softhsm储存安全数据性能整理

目标&#xff1a;存储百万条数据对象 测试方案一&#xff1a;总大小2GB&#xff0c;每个数据对象大小约512KB&#xff0c;总条数4096条&#xff1b; 测试方案一&#xff1a;总大小2GB&#xff0c;每个数据对象大小约256B&#xff0c;总条数8388608条&#xff1b; 测试环境&am…...

【C++】——精细化哈希表架构:理论与实践的综合分析

先找出你的能力在哪里&#xff0c;然后再决定你是谁。 —— 塔拉韦斯特弗 《你当像鸟飞往你的山》 目录 1. C 与哈希表&#xff1a;核心概念与引入 2. 哈希表的底层机制&#xff1a;原理与挑战 2.1 核心功能解析&#xff1a;效率与灵活性的平衡 2.2 哈希冲突的本质&#x…...

【cocos creator】拖拽排序列表

DEMO下载 GameCtrl.ts import ItemCtrl from "./ItemCtrl";const { ccclass, property } cc._decorator;ccclass export default class GameCtrl extends cc.Component {property(cc.Node)content: cc.Node null;property(cc.Node)prefab: cc.Node null;arr []…...

b站——《【强化学习】一小时完全入门》学习笔记及代码(1-3 多臂老虎机)

问题陈述 我们有两个多臂老虎机&#xff08;Multi-Armed Bandit&#xff09;&#xff0c;分别称为左边的老虎机和右边的老虎机。每个老虎机的奖励服从不同的正态分布&#xff1a; 左边的老虎机&#xff1a;奖励服从均值为 500&#xff0c;标准差为 50 的正态分布&#xff0c;即…...

【Mac排错】ls: command not found 终端命令失效的解决办法

【TroubleShooting on Mac】ls: command not found 终端命令失效的解决办法 A Solution to Solve “Command not found” of Terminal on Mac 一直在使用心爱的MacBook Pro的Terminal&#xff0c;并且为她定制了不同的Profile。 这样&#xff0c;看起来她可以在不同季节&…...

探秘Hugging Face与DeepSeek:AI开源世界的闪耀双子星

目录 一、引言&#xff1a;AI 开源浪潮的澎湃二、Hugging Face&#xff1a;AI 开源社区的基石&#xff08;一&#xff09;起源与发展历程&#xff08;二&#xff09;核心技术与特色&#xff08;三&#xff09;在 AI 领域的广泛应用 三、DeepSeek&#xff1a;东方崛起的 AI 新势…...

SkyWalking 10.1.0 实战:从零构建全链路监控,解锁微服务性能优化新境界

文章目录 前言一、集成SkyWalking二、SkyWalking使用三、SkyWalking性能剖析四、SkyWalking 告警推送4.1 配置告警规则4.2 配置告警通知地址4.3 下发告警信息4.4 测试告警4.5 慢SQL查询 总结 前言 在传统监控系统中&#xff0c;我们通过进程监控和日志分析来发现系统问题&…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...