STM32之ADC

这篇具有很好参考价值的文章主要介绍了STM32之ADC。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

ADC

ADC介绍

ADC全称: Analog-to-Digital Converter,指模拟/数字转换器,是指将连续变化的模拟信号转换为 离散的数字信号。

STM32之ADC

ADC的性能指标

  • 量程:能测量的电压范围。

  • 分辨率:ADC能辨别的最小模拟量,通常以输出二进制数的位数表示,比如:8、10、12、16位等。位数越多,分辨率越高,一般来说分辨率越高,转化时间越长。

  • 转化时间:从转换开始到获得稳定的数字量输出所需要的时间称为转换时间。

ADC的特性

  • 12位精度下转换速度可高达1MHZ,即1微秒。

  • 供电电压:VSSA:0V;VDDA:24V~3.6V。

  • ADC输入范围:VREF- ≤ VIN ≤ VREF+(一般VREF和VSSA接在一起,即0V;VREF+和VDDA接在一起,即3.3V,所以一般ADC输入范围为0V~3.3V)。

  • 采样时间可配置,采样时间越长,转换结果相对越准确,但是转换速度就越慢。

  • ADC的数据结果是12位,可以左对齐或右对齐方式存储在16位数据寄存器中。

ADC时钟

由时钟控制器提供的ADCCLK时钟和PCLK2(APB2时钟)同步。

ADC通道

  • STM32F103C8T6总共两个ADC(ADC1、ADC2),每个ADC有18个转换通道:其中有16个外部通道,2个内部通道(温度传感、内部参考电压)。

  • 外部的16个通道在转换时又分为规则通道和注入通道,其中规则通道最多有16路,注入通道最多有4路。

  • 规则组:正常排队的人。

  • 注入组:有特权的人(军人、孕妇),可以插队(优先处理)。

STM32之ADC

ADC转换顺序

每个ADC只有一个数据寄存器,16个通道一起共用这个寄存器,所以需要指定规则转换通道的转换顺序。

规则通道

  • 规则通道中的转换顺序由三个寄存器(SQR1、SQR2、SQR3)控制,它们都是32位寄存器。

  • SQRx寄存器控制着转换通道的数目和转换顺序,只要在对应的寄存器位SQRx中写入相应的通道,这个通道就是第x个转换。

STM32之ADC

注入通道

  • 注入通道的转换由一个寄存器(JSQR)控制,它是一个32位寄存器。

  • 注入序列的转换顺序是从JSQx[4:0](x = 4 - JL[1:0])开始。

  • 只有当JL=4的时候,注入通道的转换顺序才会按照]SQ1、JSQ2、JSQ3、JSQ4的顺序执行。

STM32之ADC

ADC触发方式

  • 可以通过向控制寄存器ADC-CR2的ADON位写1来开启ADC转换,写0停止ADC转换。

  • 也可以通过外部事件(如定时器)进行ADC转换。

ADC转换时间

  • ADC是挂载在APB2总线(PCLK2) 上的,经过分频器得到ADC时钟(ADCCLK),最高14MHz。文章来源地址https://www.toymoban.com/news/detail-448264.html

  • 转换时间 = 采样时间 + 12.5个周期

  • 12.5个周期是固定的,一般我们设置 PCLK2=72M,经过ADC预分频器能分频到最大的时钟只能是12M,采样周期设置为 1.5个周期,算出最短的转换时间为1.17us。

ADC转化模式

单次转换/连续转换

  • 单次转换:只转换一次。

  • 连续转换::转换一次之后,立马进行下一次转换。

扫描模式

  • 关闭扫描模式:只转换ADC_SQRx或ADC_JSQR选中的第一个通道。

  • 打开扫描模式:转换所有被ADC_SQRx或ADC_JSQR选中的所有通道。如果开启了连续转换,即每个通道转换一次后又回到第一个通道重新开始转换。

模拟看门狗

当被ADC转换的模拟电压低于低阈值或者高于高阈值时,ADC的模拟看门狗状态位被设置,如果使能了AWDIE位将会产生中断。

STM32之ADC

使用ADC读取烟雾传感器(MQ-2)的值

STM32的hal库关于ADC的函数

HAL_ADC_Start()

启动某个ADC的转换。

原型:
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)

参数
ADC_HandleTypeDef* hadc:ADC句柄

实例:
HAL_ADC_Start(&hadc1); //启动ADC1的转换

HAL_ADC_PollForConversion()

等待某个ADC转换完成。

原型:
HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)

参数:
ADC_HandleTypeDef* hadc:ADC句柄
uint32_t Timeout:超时时间

实例:
HAL_ADC_PollForConversion(&hadc1,100); //等待ADC1的转换完成,只等待100ms

HAL_ADC_GetValue()

读取某个ADC转换完成的数据。

原型:
uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc)

参数:
ADC_HandleTypeDef* hadc:ADC句柄

实例:
uint32_t smoke_value = 0;

smoke_value = HAL_ADC_GetValue(&hadc1); //读取ADC1转换完成的数据到smoke_value

烟雾传感器(MQ-2)与STM32F103C8T6板子接线

在STM32F103C8T6的产品手册中找到板子上的ADC1通道0的接口。

STM32之ADC
  • 3.3V <-> VCC

  • GND <-> GND

  • PA0 <-> AO

STM32CubeMX相关配置

配置SYS

STM32之ADC

配置RCC

ADC是挂载在APB2总线(PCLK2) 上的,经过分频器得到ADC时钟(ADCCLK),最高14MHz。

STM32之ADC
STM32之ADC

配置串口信息(UART1)

STM32之ADC

配置ADC

STM32之ADC
STM32之ADC
STM32之ADC

配置工程名称、工程路径

STM32之ADC

选择固件库

STM32之ADC

生成工程

STM32之ADC

使用MicroLIB库

STM32之ADC

main.c文件编写

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

//重写stdio.h文件中的prinft()里的fputc()函数
int fputc(int my_data,FILE *p)
{
    unsigned char temp = my_data;
    //改写后,使用printf()函数会将数据通过串口一发送出去
    HAL_UART_Transmit(&huart1,&temp,1,0xffff);  //0xfffff为最大超时时间
    return my_data;
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
    uint32_t smoke_value = 0;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
        
        //1. 启动ADC1的转换
        HAL_ADC_Start(&hadc1);
        
        //2. 等待ADC1转换的完成,超时时间为100ms
        HAL_ADC_PollForConversion(&hadc1,100);
        
        //3. 读取ADC1转换完成的数据到smoke_value
        smoke_value = HAL_ADC_GetValue(&hadc1);
  
        //4. 将数据打印到串口
        //printf("smokeValue = %d\r\n",smoke_value);
    
        printf("smokeValue = %f\r\n",3.3/4096*smoke_value);
        HAL_Delay(1000);
    }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

到了这里,关于STM32之ADC的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [ECE] Introduction to Digital Logic and Systems

    This course gives science and engineering students exposure to the basic concepts and techniques in digital logic and system design. Topics include digital system concepts, numbering systems and codes, Boolean algebra, logic gates and logic circuit elements, logic functions and simplification, logic circuits design, latches and flip-flops, counters, register

    2024年01月16日
    浏览(60)
  • STM32外设介绍

    STM32F1系列所有外设大致介绍(可参考数据手册中的外设资源表) GPIO:通用的IO口,可用于点灯,读取按键等 AFIO:复用IO口,完成复用功能端口的重定义,中断端口的配置 EXIT:外部中断(配置好外部中断时,当引脚有电平变化时,就可以触发中断,让CPU处理任务) TIM:定时

    2024年02月07日
    浏览(40)
  • STM32-开发板介绍

    市面的开发板有很多,博主有幸了解到一款集成度较高的开发板,朗峰STM32F103RCT6,知名度不高,性价比很高,这是目前唯一一款集成了大量传感器和功能模块的高集成度开发板。 巨大的优势在于,传感器和功能模块的高集成度。为使用者和学习者节省了大量的时间和硬件成

    2024年02月20日
    浏览(23)
  • STM32的中断介绍

    目录 一、STM32中断应用概览 (1)简介 (2)中断编程的顺序: 1.使能中断请求: 2.中断优先级分组: 3.配置NVIC寄存器,初始化NVIC_InitTypeDef; 4.编写中断服务函数 二、EXTI—外部中断/事件控制器 (1)简介 (2)EXTI结构图 (3)初始化结构体成员 (4)程序设计: 1.初始化要连接

    2023年04月19日
    浏览(31)
  • STM32的外设介绍

    我们主要学习的就是STM32的外设,通过程序配置外设来完成我们想要的功能。在这个表中,前两个深颜色的是位于杠M3内核里面的外设,剩下的都是内和外的外设。 NVIC(嵌套向量中断控制器) 这个是内核里面用于管理中断的设备,比如配置中断优先级这些东西。 SysTick(系统

    2024年02月09日
    浏览(36)
  • STM32介绍

    STM32 是意法半导体推出的 32 位 ARM Cortex-M 内核微控制器系列,具有高性能、低功耗、可靠性强等特点,广泛应用于工业控制、智能家居、汽车电子、医疗设备等领域。本文将详细介绍 STM32 系列的特点、性能指标、开发工具和应用领域等方面。 一、STM32 系列的特点 高性能:

    2024年02月08日
    浏览(23)
  • STM32系统结构介绍

            Cortex-M3内核引出三条总线:ICode 指令总线、DCode 数据总线、System 系统总线。ICode总线和DCode总线主要用来连接Flash闪存的(Flash里面存储的就是我们编写的程序),ICode指令总线是用来加载程序指令的,DCode数据总线是用来加载数据的(比如常量和调试数据),Syst

    2024年02月02日
    浏览(18)
  • 1、STM32CubeMX和STM32Cube库(HAL)详细介绍

    目录 前言 STM32Cube生态 STM32Cube 是什么?         STM32Cube 软件工具套件 STM32Cube Embedded 软件 STM32CubeMX ​编辑         也许大家在学习正点原子或者其他32视频和代码的时候都听过HAL库,是的这是ST官方最新的函数库,而以前的标准库已不再更新与发展。而跟随而来的就是

    2024年02月03日
    浏览(59)
  • STM32电源及时钟介绍

    F103VET6 的引角图 在 F103VET6 的引角图中可找到 4950 角, 7475 角, 99100 角, 2728角,10 11角一共 5 对的VDD,VSS,也就是给我们芯片供电的正负电源。 电源框图 STM32的工作电压(VDD)为2.0~3.6V,一般是选择 3.3 V作为 VDD 供电区域的电压值。 然后电压值还会通过内置的电压调节器转

    2024年03月22日
    浏览(40)
  • STM32 定时器介绍

    STM32F103系列单片机定时器主要有:系统定时器SysTick,2个高级定时器TIM1和TIM8,4个通用定时器TIM2/3/4/5,2个基本定时器TIM6和TIM7。下面先简单介绍一下: 基本定时器:基本定时器只能计时,不能产生中断。它们适合于需要简单计时的应用程序。 通用定时器:通用定时器可以配

    2024年02月08日
    浏览(66)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包