蓝桥杯嵌入式国赛笔记(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,一经查实,立即删除!

相关文章

Python—面向对象小解(2)

一、面向对象开发的基本使用 根据需求定义类 关键字class 属性 变量 方法 函数 默认函数中必须有个self参数 self(自己)代表当前对象 如何将一项物品放入一个空间内? # 类的定义创建 class itcast:# 指定属性name 大象container 冰箱# 指定数据的处理方法def open_c…

网络工程师:网络可靠性技术

一、可靠性 平均故障间隔时间MTBF(Mean Time Between Failure)和平均修复时间MTTR(Mean Time to Repair)这两个指标来评价系统的可靠性。 1、平均故障间隔时间MTBF MTBF是指一个系统无故障运行平均时间&#xff0c;通常以小时为单位。MTBF越大可靠性越高。 2、平均修复时间MTTR…

内网安全-隧道搭建穿透上线内网穿透-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…

vue3 excel 文件导出

//文件导出 在index.ts 中 export function downloadHandle(url: string,params?:object, filename?: string, method: string GET){ try { downloadLoadingInstance ElLoading.service({ text: "正在生成下载数据&#xff0c;请稍候", background: "rgba…

【计算机视觉 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;我们真的需要 …

Tessy学习系列(一):软件测试的概念介绍与常见的测试策略

相关内容参考自《软件测试的艺术》 一、软件测试的概念 所谓软件测试&#xff0c;就是一个过程或一系列过程&#xff0e;用来确认计算机代码完成了其应该完成的功能不执行其不该有的操作。软件应当是可预测且稳定的&#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进行测评。…

Netty-选择器-监听

归档 GitHub: Netty-选择器-监听 介绍 参考 NioEventLoop 类结构&#xff1a;基础类介绍-NioEventLoop 主要逻辑为&#xff1a;死循环监听 selector总结&#xff1a; 创建的线程是 FastThreadLocalThread 实例 原理 io.netty.channel.nio.NioEventLoop /*** NIO 事件轮循 …

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;

前端常见的页面自适应布局方案

流式布局 使用百分比单位等单位来表示长度和宽度&#xff0c;这样在整体的长度和宽度变化的时候&#xff0c;里面的内容也会发生变化。 使用 % 直接使用百分比&#xff0c;在页面宽度变化的时候会对应放大缩小。 <!DOCTYPE html> <html lang"en"><he…

vue3 RouterLink路由query传参

vue route query传参 一、传参页面,需要传id、title、content三个参数 <ul> <li v-for"news in newsList" :key"news.id"> <!--/news/detail--> <RouterLink :to"{ path:/news/deta…