STM32的ADC模式及其应用例程介绍

news/2024/11/23 5:44:19/

STM32的ADC模式及其应用例程介绍


  • 📍ST官方相关应用笔记介绍资料:https://www.stmcu.com.cn/Designresource/detail/application_note/705947
  • 📌相关例程资源包:STSW-STM32028https://www.st.com/zh/embedded-software/stsw-stm32028.html

✨官方所给的例程是基于标准库下的工程。对于HAl STM32CubeMX工程此功能的代码在网上最多,而基于标准库下的介绍该功能的相关配置很少,如果想学习和研究基于标准库来使用ADC功能,这是一个不错的资源例程,几乎包含了所有ADC功能实现已经应用方式。

  • 📑例程包含说明文档,涉及单路以及多路ADC通道数据获取,双ADC模式下,交替、注入转换方式等内容的介绍和使用。
  • 📋相关例程列表:
    在这里插入图片描述
  • 📐本文只抽取其中的SingleChannelContinuous单通道连续转换模式,采用DMA传输方式,进行功能测试。

所给的例程代码,已经帮我们配置了其功能代码,我们只需要做的是,添加调试串口,将对应的数据,通过串口打印出来,查看其结果是否符合预期。

  • 🚩所提供的资源案例采用的是STM32F107,个人采用的是STM32F103进行测试。

📓单通道连续转换模式

单通道连续转换模式可在常规通道转换中对单个通道进行连续不断的转换。

  • 此连续模式允许 ADC 在后台工作。因此,ADC 可在没有任何 CPU 干预的情况下连续转换通道。此外,还可以在循环模式下使用 DMA,从而降低 CPU 负载。
    注: 本应用笔记提供了一个固件示例:SingleChannelContinuous。该示例使用两种方法:
    DMA 和中断。要选择其中一种方法,只需在 main.c 文件中注释或取消注释 #define
    USE_DMA_Transfer。
  • 📝配置代码如下:
int main(void)
{/* System clocks configuration ---------------------------------------------*/RCC_Configuration();delay_init();	    	 //延时函数初始化	 /* GPIO configuration ------------------------------------------------------*/GPIO_Configuration();uart_init(115200);	 	//串口初始化printf("Hello World \r\n");
#ifndef   USE_DMA_Transfer /* NVIC configuration ------------------------------------------------------*/NVIC_Configuration();#else /* DMA1 channel1 configuration ---------------------------------------------*/DMA_DeInit(DMA1_Channel1);DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC1ConvertedValue;DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;DMA_InitStructure.DMA_BufferSize = 1;DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;DMA_InitStructure.DMA_Priority = DMA_Priority_High;DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;DMA_Init(DMA1_Channel1, &DMA_InitStructure);  /* Enable DMA1 channel1 */DMA_Cmd(DMA1_Channel1, ENABLE);
#endif/* ADC1 configuration ------------------------------------------------------*/ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//禁止触发检测,使用软件触发ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐ADC_InitStructure.ADC_NbrOfChannel = 1;//1个通道ADC_Init(ADC1, &ADC_InitStructure);/* ADC1 regular channels configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_28Cycles5);  //采样时间  #ifdef   USE_DMA_Transfer   /* Enable ADC1 DMA */ADC_DMACmd(ADC1, ENABLE);
#else/* Enable ADC1 EOC interupt */ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
#endif  /* Enable ADC1 */ADC_Cmd(ADC1, ENABLE);/* Enable ADC1 reset calibaration register */   ADC_ResetCalibration(ADC1);/* Check the end of ADC1 reset calibration register */while(ADC_GetResetCalibrationStatus(ADC1));/* Start ADC1 calibaration */ADC_StartCalibration(ADC1);/* Check the end of ADC1 calibration */while(ADC_GetCalibrationStatus(ADC1));/* Start ADC1 Software Conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE);while (1){printf("ADC1ConvertedValue:%d \r\n",ADC1ConvertedValue);delay_ms(1000);}
}
  • 🌿此案例采用的是ADC1中的递14通道,对应的输入引脚为PC4:
    在这里插入图片描述
  • 📜调节定位器,测试输出结果
    在这里插入图片描述

📗扫描方式多通道连续转换

  • 🌿对应的例程:ScanContinuous

通道配置:

  /* ADC1 regular channel11, channel14, channel16 and channel17 configurations */ ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_41Cycles5);//PC1ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 2, ADC_SampleTime_239Cycles5);//内部参考电压ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 3, ADC_SampleTime_239Cycles5);//内部温度传感器ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 4, ADC_SampleTime_1Cycles5);//PC4

在这里插入图片描述

int main(void)
{/* System clocks configuration ---------------------------------------------*/RCC_Configuration();delay_init();	    	 //延时函数初始化/* GPIO configuration ------------------------------------------------------*/GPIO_Configuration();uart_init(115200);	 	//串口初始化printf("Hello World \r\n");/* DMA1 channel1 configuration ---------------------------------------------*/DMA_DeInit(DMA1_Channel1);DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC1ConvertedValue;DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;DMA_InitStructure.DMA_BufferSize = BufferLenght;DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;DMA_InitStructure.DMA_Priority = DMA_Priority_High;DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;DMA_Init(DMA1_Channel1, &DMA_InitStructure);/* Enable DMA1 channel1 */DMA_Cmd(DMA1_Channel1, ENABLE);/* ADC1 configuration ------------------------------------------------------*/ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式ADC_InitStructure.ADC_ScanConvMode = ENABLE;//扫描模式	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//禁止触发检测,使用软件触发ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐	ADC_InitStructure.ADC_NbrOfChannel = BufferLenght;//4个转换在规则序列中 也就是转换规则序列4ADC_Init(ADC1, &ADC_InitStructure);/* ADC1 regular channel11, channel14, channel16 and channel17 configurations */ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_41Cycles5);//PC1ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 2, ADC_SampleTime_239Cycles5);//内部参考电压ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 3, ADC_SampleTime_239Cycles5);//内部温度传感器ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 4, ADC_SampleTime_1Cycles5);//PC4/* Enable ADC1 DMA */ADC_DMACmd(ADC1, ENABLE);/* Enable ADC1 */ADC_Cmd(ADC1, ENABLE);/* Enable TempSensor and Vrefint channels: channel16 and Channel17 */ADC_TempSensorVrefintCmd(ENABLE);/* Enable ADC1 reset calibaration register */ADC_ResetCalibration(ADC1);/* Check the end of ADC1 reset calibration register */while(ADC_GetResetCalibrationStatus(ADC1));/* Start ADC1 calibaration */ADC_StartCalibration(ADC1);/* Check the end of ADC1 calibration */while(ADC_GetCalibrationStatus(ADC1));/* Start ADC1 Software Conversion */ADC_SoftwareStartConvCmd(ADC1, ENABLE);/* Test on Channel 1 DMA1_FLAG_TC flag */while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));/* Clear Channel 1 DMA1_FLAG_TC flag */DMA_ClearFlag(DMA1_FLAG_TC1);while(1){printf("%d - %d - %d - %d \r\n", ADC1ConvertedValue[0], ADC1ConvertedValue[1],ADC1ConvertedValue[2], ADC1ConvertedValue[3]\);//PC1->[0];内部参考电压;温度; PC4->[3]delay_ms(1000);}
}
  • 📋串口打印:
    在这里插入图片描述

👉🏻仅对资源例程中2个例程进行了有效性验证,其他例程没有做烧录测试和功能验证。

📚例程资源(包含中文说明文档)

  • 🔖如需下载未修改过的原例程资源请前往官方下载。
  • 🌿该资源例程修改匹配的是stm32f103芯片。
链接:https://pan.baidu.com/s/1-k9UvL2lSLI2ZlxyoT-FWg 
提取码:7kot

http://www.ppmy.cn/news/790942.html

相关文章

一文搞懂常见的加密算法

加密算法在互联网技术领域中几乎是无处不在,而密码学也是网络安全的重要基础,这篇文章我们就一起来学习下常见的加密算法。 1 为什么要研究加密算法? 在技术方面,加密算法的研究具有重要的意义,主要体现在以下几个方…

excel计算数据时固定某一列或一行或某一值

只需要把要固定的对象采用绝对引用:加 $

SpringBoot 导出Excel 固定表头

//冻结首行sheet.createFreezePane(8, 1);//固定第1行8个列

pandas写入excel指定行_python入门--使用Pandas读取与写入Excel内容

python是最近一门很火的编程语言,简单易上手,无论从事HR、财务、软体开发、网络工程师都有很大帮助,我们可以通过编程语言让繁琐的工作变得轻松简单,今日我向大家分享一个python读取/写入excel表内容的方法(这里我跳过编辑器的介绍…

Excel·VBA按行拆分工作表

对应之前文章《ExcelVBA按列拆分工作表》,对Excel表格数据按照固定行数,将工作表拆分 工作表按行拆分为工作表 Sub 工作表按行拆分为工作表()当前工作表(worksheet)按固定行数拆分为多个工作表,保存在当前工作簿&…

Excel怎么在数据中间隔插入指定行

今天跟大家分享一下Excel怎么在数据中间隔插入指定行 1.如下图我们想要在表格每行数据之间插入表头标题。 2.首先我们选中表格区域 3.点击下图选项(Excel工具箱,百度即可了解详细下载安装信息,本文这里就不做详细解说。) 4.选择【…

java excel 读取一行_一行代码完成 Java的 Excel 读写--easyexcel

最近我在 Github 上查找一个可以快速开发 excel 导入导出工具,偶然发现由阿里开发 easyexcel 开源项目,尝试使用后感觉这款工具挺不错的,下面分享一下我的 easyexcel 案例使用。 1、easyexcel 简介 一般在项目可能会涉及到 Excel 导入和导出&…

excel一列数据中每个数重复固定次数

问题描述:把一些数据每个重复指定次数,比如我想把内容这一列每一个都重复这么多次数 解决方法:采用excel中的Power Query方法,具体方法是数据-自表格区域,在数据来源处选择想要处理的数据,在上载以后会出现…