蓝桥杯嵌入式国赛笔记(4):多路AD采集

1、前言

蓝桥杯的国赛会遇到多路AD采集的情况,这时候之前的单路采集的方式就不可用了,下面介绍两种多路采集的方式。

以第13届国赛为例

2、方法一(配置通道)

2.1 使用CubeMx配置 

设置IN13与IN17为Single-ended

在Parameter Settings中

        设置Clock Prescaler为Asynchronous clock mode divided by 2

设置Rank-Sampling Time为640.6 Cycles

2.2 bsp_adc.h代码编写

#include "main.h"extern ADC_HandleTypeDef hadc2;void ADC2_Init(void);uint32_t Get_Adc(void);uint32_t Get_PA4(void);
uint32_t Get_PA5(void);

2.3 bsp_adc.c代码编写

每次进行adc采集之前,重新配置一遍参数

  ADC_ChannelConfTypeDef sConfig = {0};sConfig.Channel = ADC_CHANNEL_17;sConfig.Rank = ADC_REGULAR_RANK_1;sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;sConfig.SingleDiff = ADC_SINGLE_ENDED;sConfig.OffsetNumber = ADC_OFFSET_NONE;sConfig.Offset = 0;if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK){Error_Handler();}GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = GPIO_PIN_4;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

记住不要重复进行RCC的配置,否侧会卡死

//这两个,不用加了
__HAL_RCC_ADC12_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();

2.3.1 完整代码

#include "ADC/bsp_adc.h"
/********************************************************************************* @file    adc.c* @brief   This file provides code for the configuration*          of the ADC instances.******************************************************************************* @attention** <h2><center>&copy; Copyright (c) 2024 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:*                        opensource.org/licenses/BSD-3-Clause********************************************************************************//* Includes ------------------------------------------------------------------*//* USER CODE BEGIN 0 *//* USER CODE END 0 */ADC_HandleTypeDef hadc2;/* ADC2 init function */
void ADC2_Init(void)
{/* USER CODE BEGIN ADC2_Init 0 *//* USER CODE END ADC2_Init 0 */ADC_ChannelConfTypeDef sConfig = {0};/* USER CODE BEGIN ADC2_Init 1 *//* USER CODE END ADC2_Init 1 *//** Common config*/hadc2.Instance = ADC2;hadc2.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;hadc2.Init.Resolution = ADC_RESOLUTION_12B;hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;hadc2.Init.GainCompensation = 0;hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;hadc2.Init.LowPowerAutoWait = DISABLE;hadc2.Init.ContinuousConvMode = DISABLE;hadc2.Init.NbrOfConversion = 1;hadc2.Init.DiscontinuousConvMode = DISABLE;hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;hadc2.Init.DMAContinuousRequests = DISABLE;hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED;hadc2.Init.OversamplingMode = DISABLE;if (HAL_ADC_Init(&hadc2) != HAL_OK){Error_Handler();}/** Configure Regular Channel*/sConfig.Channel = ADC_CHANNEL_17;sConfig.Rank = ADC_REGULAR_RANK_1;sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;sConfig.SingleDiff = ADC_SINGLE_ENDED;sConfig.OffsetNumber = ADC_OFFSET_NONE;sConfig.Offset = 0;if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK){Error_Handler();}/* USER CODE BEGIN ADC2_Init 2 *//* USER CODE END ADC2_Init 2 */}void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(adcHandle->Instance==ADC2){/* USER CODE BEGIN ADC2_MspInit 0 *//* USER CODE END ADC2_MspInit 0 *//* ADC2 clock enable */__HAL_RCC_ADC12_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/**ADC2 GPIO ConfigurationPA4     ------> ADC2_IN17PA5     ------> ADC2_IN13*/GPIO_InitStruct.Pin = GPIO_PIN_4;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/* USER CODE BEGIN ADC2_MspInit 1 *//* USER CODE END ADC2_MspInit 1 */}
}void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{if(adcHandle->Instance==ADC2){/* USER CODE BEGIN ADC2_MspDeInit 0 *//* USER CODE END ADC2_MspDeInit 0 *//* Peripheral clock disable */__HAL_RCC_ADC12_CLK_DISABLE();/**ADC2 GPIO ConfigurationPA4     ------> ADC2_IN17PA5     ------> ADC2_IN13*/HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4);/* USER CODE BEGIN ADC2_MspDeInit 1 *//* USER CODE END ADC2_MspDeInit 1 */}
}uint32_t Get_Adc(void)
{uint32_t Adc_Value;HAL_ADC_Start(&hadc2);HAL_Delay(1);Adc_Value = HAL_ADC_GetValue(&hadc2);return Adc_Value;
}
uint32_t Get_PA4(void)
{ADC_ChannelConfTypeDef sConfig = {0};sConfig.Channel = ADC_CHANNEL_17;sConfig.Rank = ADC_REGULAR_RANK_1;sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;sConfig.SingleDiff = ADC_SINGLE_ENDED;sConfig.OffsetNumber = ADC_OFFSET_NONE;sConfig.Offset = 0;if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK){Error_Handler();}GPIO_InitTypeDef GPIO_InitStruct = {0};/**ADC2 GPIO ConfigurationPA4     ------> ADC2_IN17PA5     ------> ADC2_IN13*/GPIO_InitStruct.Pin = GPIO_PIN_4;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);return Get_Adc();
}
uint32_t Get_PA5(void)
{ADC_ChannelConfTypeDef sConfig = {0};sConfig.Channel = ADC_CHANNEL_13;sConfig.Rank = ADC_REGULAR_RANK_1;sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;sConfig.SingleDiff = ADC_SINGLE_ENDED;sConfig.OffsetNumber = ADC_OFFSET_NONE;sConfig.Offset = 0;if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK){Error_Handler();}GPIO_InitTypeDef GPIO_InitStruct = {0};/**ADC2 GPIO ConfigurationPA4     ------> ADC2_IN17PA5     ------> ADC2_IN13*/GPIO_InitStruct.Pin = GPIO_PIN_5;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);return Get_Adc();
}/* USER CODE BEGIN 1 *//* USER CODE END 1 *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

2.4 测试

 

测试结果表明实验成功。  

3、方法二(扫描模式)

3.1 使用CubeMx配置

设置IN13与IN17为Single-ended

在Parameter Settings中

        设置Clock Prescaler为Synchronous clock mode divided by 2

这里要将Number Of Conversion设置为2

这样就可以采集两个不同的通道了 

 

3.2 bsp_adc.h代码编写

因为需要循环采集两个ADC值,所以GetADC函数的参数是一个uint32_t指针类型 

#include "main.h"extern ADC_HandleTypeDef hadc2;void ADC2_Init(void);
void GetADC(uint32_t *ADC_Val);

3.3 bsp_adc.c代码编写

HAL_ADC_Start之后,在for循环内进行连续的HAL_ADC_GetValue,在这之前先等待一下不然可能出现通道AD对应错误的情况。

void GetADC(uint32_t *ADC_Val)
{HAL_ADC_Start(&hadc2);int i;for(i=0;i<2;i++){HAL_Delay(1);ADC_Val[i] = HAL_ADC_GetValue(&hadc2);}
}

3.3.1 完整代码

#include "ADC/bsp_adc.h"
ADC_HandleTypeDef hadc2;
void ADC2_Init(void)
{/* USER CODE BEGIN ADC2_Init 0 *//* USER CODE END ADC2_Init 0 */ADC_ChannelConfTypeDef sConfig = {0};/* USER CODE BEGIN ADC2_Init 1 *//* USER CODE END ADC2_Init 1 *//** Common config*/hadc2.Instance = ADC2;hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;hadc2.Init.Resolution = ADC_RESOLUTION_12B;hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;hadc2.Init.GainCompensation = 0;hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE;hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;hadc2.Init.LowPowerAutoWait = DISABLE;hadc2.Init.ContinuousConvMode = DISABLE;hadc2.Init.NbrOfConversion = 2;hadc2.Init.DiscontinuousConvMode = DISABLE;hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;hadc2.Init.DMAContinuousRequests = DISABLE;hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED;hadc2.Init.OversamplingMode = DISABLE;if (HAL_ADC_Init(&hadc2) != HAL_OK){Error_Handler();}/** Configure Regular Channel*/sConfig.Channel = ADC_CHANNEL_17;sConfig.Rank = ADC_REGULAR_RANK_1;sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;sConfig.SingleDiff = ADC_SINGLE_ENDED;sConfig.OffsetNumber = ADC_OFFSET_NONE;sConfig.Offset = 0;if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK){Error_Handler();}/** Configure Regular Channel*/sConfig.Channel = ADC_CHANNEL_13;sConfig.Rank = ADC_REGULAR_RANK_2;if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK){Error_Handler();}/* USER CODE BEGIN ADC2_Init 2 *//* USER CODE END ADC2_Init 2 */}void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(adcHandle->Instance==ADC2){/* USER CODE BEGIN ADC2_MspInit 0 *//* USER CODE END ADC2_MspInit 0 *//* ADC2 clock enable */__HAL_RCC_ADC12_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/**ADC2 GPIO ConfigurationPA4     ------> ADC2_IN17PA5     ------> ADC2_IN13*/GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/* USER CODE BEGIN ADC2_MspInit 1 *//* USER CODE END ADC2_MspInit 1 */}
}void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{if(adcHandle->Instance==ADC2){/* USER CODE BEGIN ADC2_MspDeInit 0 *//* USER CODE END ADC2_MspDeInit 0 *//* Peripheral clock disable */__HAL_RCC_ADC12_CLK_DISABLE();/**ADC2 GPIO ConfigurationPA4     ------> ADC2_IN17PA5     ------> ADC2_IN13*/HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4|GPIO_PIN_5);/* USER CODE BEGIN ADC2_MspDeInit 1 *//* USER CODE END ADC2_MspDeInit 1 */}
}void GetADC(uint32_t *ADC_Val)
{HAL_ADC_Start(&hadc2);int i;for(i=0;i<2;i++){HAL_Delay(1);ADC_Val[i] = HAL_ADC_GetValue(&hadc2);}
}

3.4 测试

 

测试结果表明实验成功。 

4、总结

本文介绍了两种不同的AD多通道采集的办法,并实现了相关代码以及进行了验证,效果表明成功实现了多路的AD采集功能。 

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

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

相关文章

内网安全-隧道搭建穿透上线内网穿透-nps自定义上线内网渗透-Linux上线-cs上线Linux主机

目录 内网安全-隧道搭建&穿透上线内网穿透-nps-自定义-上线NPS工具介绍搭建过程 nps原理介绍MSF上线CS上线 内网渗透-Linux上线-cs上线Linux主机1.下载插件2.导入插件模块3.配置监听器4.服务端配置5.配置C2监听器并生成木马6.执行木马 内网安全-隧道搭建&穿透上线 内网…

2024年新算法-秘书鸟优化算法(SBOA)优化BP神经网络回归预测

2024年新算法-秘书鸟优化算法(SBOA)优化BP神经网络回归预测 亮点&#xff1a; 输出多个评价指标&#xff1a;R2&#xff0c;RMSE&#xff0c;MSE&#xff0c;MAPE和MAE 满足需求&#xff0c;分开运行和对比的都有对应的主函数&#xff1a;main_BP, main_SBOA, main_BPvsBP_SB…

【计算机视觉 Mamba】MambaOut: Do We Really Need Mamba for Vision?

MambaOut: Do We Really Need Mamba for Vision? 在视觉任务上我们需要Mamba吗? 论文地址 代码地址 知乎解读&#xff1a;王牌飞行员申请出战&#xff01; 知乎解读&#xff1a;Mamba 模型解读 (一)&#xff1a;MambaOut&#xff1a;在视觉任务中&#xff0c;我们真的需要 …

Langchain-Chatchat之pdf转markdown格式

文章目录 背景开发环境loader文本解析步骤markdown格式的文本为什么选择markdown格式测试markdown格式提取表格原pdf表格markdown格式的表格 测试markdown格式的知识库运行项目修改文件加载器loader 其他问题运行项目报错查看系统当前的max_user_watches修改sysctl.conf配置 图…

AWS迁移与传输之AMS/MGN

AWS Application Migration Service&#xff08;AWS Application Migration Service简称为AWS MGN&#xff0c;MGN是migration的缩写。&#xff09;是一项全面的迁移服务&#xff0c;旨在帮助企业将其本地服务器和虚拟机迁移到云端&#xff0c;包括AWS和VMware Cloud on AWS。 …

OrangePi AIpro初体验:开启嵌入式开发之旅

概述 随着物联网和智能设备时代的到来&#xff0c;单板电脑因其独特的优势成为创新项目和教育实践的重要工具。在众多单板电脑中&#xff0c;香橙派以其出色的性能和亲民的价格&#xff0c;十分吸引博主这初涉嵌入式开发的新手。博主有幸被CSDN邀请对OrangePi AIpro进行测评。…

vivado设置Vscode为默认编辑器

D:\vscode\Microsoft VS Code\Code.exe -g [file name]:[line number]

鸿蒙ArkUI-X跨平台开发:【资源分类与访问】

资源分类与访问 应用开发过程中&#xff0c;经常需要用到颜色、字体、间距、图片等资源&#xff0c;在不同的设备或配置中&#xff0c;这些资源的值可能不同。 应用资源&#xff1a;借助资源文件能力&#xff0c;开发者在应用中自定义资源&#xff0c;自行管理这些资源在不同…

话术巧妙分隔沟通效果更佳看看这个小技巧

客服回复客户咨询&#xff0c;如果遇到比较复杂的问题&#xff0c;经常会有大段的文字回复&#xff0c;用聊天宝的分段符功能&#xff0c;在需要分段的地方点击右上角的“插入分隔符”&#xff0c;就可以在指定位置分段&#xff0c;实现多段发送的目的。 前言 客服回复客户咨询…

干冰清洗机的清洗原理及应用

干冰清洗机的清洗原理及应用可以详细阐述如下&#xff1a; 一、清洗原理 干冰清洗机的清洗原理主要基于干冰的低温冷冻作用。干冰在常温下会迅速升华&#xff0c;吸收大量的热量&#xff0c;使周围的温度迅速降低。当干冰颗粒通过特殊的干冰清洗机喷射到清洗物体表面时&#…

系统架构设计师【第1章】: 绪论 (核心总结)

文章目录 1.1 系统架构概述1.1.1 系统架构的定义及发展历程1.1.2 软件架构的常用分类及建模方法1.1.3 软件架构的应用场景1.1.4 软件架构的发展未来 1.2 系统架构设计师概述1.2.1 架构设计师的定义、职责和任务1.2.2 架构设计师应具备的专业素质1.2.3 架构设计师的知识…

Java入门基础学习笔记45——String使用的注意事项

String使用时的注意事项&#xff1a; 1&#xff09;String对象的内容不可改变&#xff0c;被称为不可变字符串对象。 Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are im…

C++代码使用ClangCL编译注意事项

遇到cmake指定模板类工程使用msvc的clang编译器编译代码&#xff0c;代码变量出现与预期不符的问题&#xff1b; 如下&#xff1a; clangcl将实现放到头文件里则不会出现这样的情况&#xff1b; 最后按照pcl的模板类写法则解决这个问题&#xff1b;

[SCTF2019]Who is he

unity 游戏&#xff0c;直接输入字符串 直接修改 if 判断&#xff0c;看能不能直接输出flag 修改了程序逻辑&#xff0c;但还是输出了 明明已经把这个 if 删了 不知道为什么还会输出这串字符 应该程序还有什么引入吧&#xff0c;看 wp 应该先查一下程序的动态链接库 DLL 是…

瓦罗兰特账号怎么注册 瓦罗兰特延迟高用什么加速器

《瓦罗兰特》&#xff08;Valorant&#xff09;是由拳头游戏&#xff08;Riot Games&#xff09;开发并发行的一款免费的多人在线第一人称射击游戏&#xff08;FPS&#xff09;&#xff0c;它结合了传统的硬核射击机制与英雄角色的能力系统&#xff0c;为玩家提供了独特的竞技体…

【加密与解密(第四版)】第十七章笔记

第十七章 软件保护技术 17.1 防范算法求逆 17.2 抵御静态分析 反汇编算法&#xff1a;线性扫描&#xff08;无法正确地将代码和数据分开&#xff09;、递归进行 巧妙构造代码和数据&#xff0c;在指令流中插入很多“数据垃圾"&#xff0c;干扰反汇编软件的判断&#xf…

为什么要学习c++?

你可能在想&#xff0c;“C&#xff1f;那不是上个时代的产物吗&#xff1f;” 哎呀&#xff0c;可别小看了这位“老将”&#xff0c;它在21世纪的科技舞台上依旧光芒万丈&#xff0c;是许多尖端技术不可或缺的基石&#xff01; 1. 无可替代 c源于c语言&#xff0c;它贴近于硬…

地下停车场FM信号覆盖系统技术原理用与应用

随着我国城市化水平的快速推进与房地产的快速发展&#xff0c;城市停车场称为每栋建筑物的硬性配套建筑&#xff0c;尤其是商业综合体、医院、政府机关、机场、高铁站等场所出现了超大规模停车场&#xff0c;停放车辆可达数千辆&#xff0c;停车场的智能化与信息化水平也越来越…

Java | Leetcode Java题解之第104题二叉树的最大深度

题目&#xff1a; 题解&#xff1a; class Solution {public int maxDepth(TreeNode root) {if (root null) {return 0;}Queue<TreeNode> queue new LinkedList<TreeNode>();queue.offer(root);int ans 0;while (!queue.isEmpty()) {int size queue.size();wh…

Llama模型家族之使用 Supervised Fine-Tuning(SFT)微调预训练Llama 3 语言模型(十) 使用 LoRA 微调常见问题答疑

LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;一&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;二&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;三&#xff09; 基于 LlaMA…