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

正点原子STM32H743单片机实现ADC多通道检测

目标

使用STM32CubeMX工具,配置ADC相关参数,实现在STM32H743单片机上获取ADC多通道电压值。共14个ADC引脚,ADC2有5个,ADC3有9个,全部设置单通道

ADC引脚

PF3
PF4
PF5
PF10
PC0
PC2
PC3
PH2
PH3
PA3
PB0
PB1
PA4
PA5
PA6

 STM32cubeMX配置ADC

ADC2配置5个模拟输入IO,多通道轮询,配置各通道参数,使能中断

ADC3配置9个模拟输入IO,多通道轮询,配置各通道参数,使能中断

  时钟频率配置

在处理ADC时发现ADC时钟配置需要处理,可能默认即可,这里试了下是没问题的,一开始使用的HSE作为ADC时钟,导致无法获取ADC参数。在ADC3的属性配置中,Resolution对应12位分辨率有可能错误,如果有问题可以尝试加大改为16位分辨率,不过改动分辨率之后,在代码中就需要修改对应的算法,即12位算法(电压值= adc值*参考电压/2的12次方-1),16位算法(电压值= adc值*参考电压/2的16次方-1)。

 代码

启动adc转换前必须先校准adc,在HAL_ADC_ConvCpltCallback中断回调函数中,处理对应ADC的代码,由于HAL_ADC_Start_IT调用后会一直不间断轮询,通过HAL_ADC_GetValue函数可直接获取ADC值,HAL_ADC_Stop_IT函数作用关闭当前ADC转换。

#define ADC2_CHANNELS 5
#define ADC3_CHANNELS 9uint16_t adc2_values[ADC2_CHANNELS];
uint16_t adc3_values[ADC3_CHANNELS];
volatile uint8_t adc_ready = 0; // 数据就绪标志位void Start_ADC2_DMA(void) {/* 初始化后校准ADC */HAL_ADCEx_Calibration_Start(&hadc2, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED); // 执行ADC校准/* 启动ADC连续转换(不间断轮询) */HAL_ADC_Start_IT(&hadc2);
}void Start_ADC3_DMA(void) {/* 初始化后校准ADC */HAL_ADCEx_Calibration_Start(&hadc3, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED); // 执行ADC校准/* 启动ADC连续转换(不间断轮询) */HAL_ADC_Start_IT(&hadc3);
}void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) {if (hadc->Instance == ADC2)  // 确认是ADC2的转换完成{for (int i = 0; i < ADC2_CHANNELS; i++) {adc2_values[i] = HAL_ADC_GetValue(&hadc2); // 读取转换结果
//			HAL_ADC_PollForConversion(&hadc2, 100);}adc_ready |= 0x01; // 标记ADC2数据就绪HAL_ADC_Stop_IT(&hadc2);} else if (hadc->Instance == ADC3)  // 确认是ADC3的转换完成{for (int i = 0; i < ADC3_CHANNELS; i++) {adc3_values[i] = HAL_ADC_GetValue(&hadc3); // 读取转换结果
//			HAL_ADC_PollForConversion(&hadc3, 100);}adc_ready |= 0x02; // 标记ADC3数据就绪HAL_ADC_Stop_IT(&hadc3);}
}

 AdcTask线程任务当ADC2和ADC3都进行转换之后,在当前线程中处理所有ADC数值并转换为电压值输出打印,结束后清除标志位,等待下次转换触发。该线程使用最小栈内存大小128Words。

void AdcTask(void *argument)
{/* USER CODE BEGIN AdcTask */Start_ADC2_DMA();Start_ADC3_DMA();int i = 0;float voltage;/* Infinite loop */for (;;) {if (adc_ready == 0x03) { // 等待两组ADC数据就绪/* 打印ADC2数据 */for (i = 0; i < ADC2_CHANNELS; i++) {voltage = adc2_values[i] * 3.3f / 4095.0f;printf("ADC2[%d] = %d.%dV\r\n", i, (uint32_t) voltage,(uint32_t) (voltage * 100) % 100);}printf("\n");/* 打印ADC3数据 */for (i = 0; i < ADC3_CHANNELS; i++) {voltage = adc3_values[i] * 3.3f / 4095.0f;printf("ADC3[%d] = %d.%dV\r\n", i, (uint32_t) voltage,(uint32_t) (voltage * 100) % 100);}printf("\n\n");adc_ready = 0; // 清除标志位}osDelay(10);}/* USER CODE END AdcTask */
}

共勉!!!

http://www.xdnf.cn/news/230959.html

相关文章:

  • k8s平台:手动部署Grafana
  • SQL命令二:SQL 高级查询与特殊算法
  • Git从入门到精通-第一章-基础概念
  • 软件性能测试有多关键?能找出潜在问题并确保其顺利运行吗?
  • [250430] Kali Linux 存储库密钥丢失导致所有用户无法正常更新 APT
  • JavaScript:从JS的执行机制到location对象
  • 大语言模型(LLM)应用开发平台Dify详细使用
  • 系统思考:局部最优与全局失衡
  • WHAT - Tailwind CSS + Antd = MetisUI组件库
  • GEO vs SEO:从搜索引擎到生成引擎的优化新思路
  • vs2019 调试看不到std::list 中的值,
  • 上班无聊用python写一个摸鱼小游戏:数字碰撞
  • conda管理python环境
  • 2025年渗透测试面试题总结-拷打题库28(题目+回答)
  • 前端跨域问题详解:原因、解决方案与最佳实践
  • Doris索引机制全解析,如何用高效索引加速数据分析
  • PCB设计工艺规范(一)概述
  • 树莓派智能摄像头实战指南:基于TensorFlow Lite的端到端AI部署
  • Docker进入MySQL之后如何用sql文件初始化数据
  • 阿里云服务迁移实战: 07-其他服务迁移
  • Learning vtkjs之ImageStreamline
  • 【Fifty Project - D21】
  • w314基于java无人超市管理系统设计与实现
  • 【数据库原理及安全实验】实验五 数据库备份与恢复
  • 短视频矩阵系统贴牌开发实战:批量剪辑文件夹功能设计与实现
  • mybatis-plus 枚举实现模版,导入,导出
  • JVM——Java的基本类型的实现
  • 【ArcGISPro学习笔记】布局输出时图例总是有省略号怎么办?
  • 大连理工大学选修课——机器学习笔记(1):概述
  • 【c++】【STL】list详解