• STM32 CubeMX ADC采集 单通道,多通道,内部温度(轮询,DMA,中断)(HAL库)


    STM32 CubeMX ADC采集(HAL库)



    ADC介绍

    12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部
    信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右
    对齐方式存储在16位数据寄存器中。
    模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。
    ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生。

    ADC主要特征

    ● 12位分辨率(最小识别电压)
    ● 转换结束、注入转换结束和发生模拟看门狗事件时产生中断
    ● 单次和连续转换模式
    ● 从通道0到通道n的自动扫描模式
    ● 自校准
    ● 带内嵌数据一致性的数据对齐
    ● 采样间隔可以按通道分别编程
    ● 规则转换和注入转换均有外部触发选项
    ● 间断模式
    ● 双重模式(带2个或以上ADC的器件)
    ● ADC转换时间:
    ─ STM32F103xx增强型产品:时钟为56MHz时为1μs(时钟为72MHz为1.17μs)
    ─ STM32F101xx基本型产品:时钟为28MHz时为1μs(时钟为36MHz为1.55μs)
    ─ STM32F102xxUSB型产品:时钟为48MHz时为1.2μs
    ─ STM32F105xx和STM32F107xx产品:时钟为56MHz时为1μs(时钟为72MHz为1.17μs)
    ● ADC供电要求:2.4V到3.6V
    ● ADC输入范围:VREF- ≤ VIN ≤ VREF+
    ● 规则通道转换期间有DMA请求产生。


    在这里插入图片描述

    Vref+的电压(2.4~3.6)就是ADC参考电压2.4V(相当于秤砣)

    最小识别电压值:2.4/4096≈0.6mv(不考虑误差)

    在这里插入图片描述

    一、STM32 CubeMX设置

    开启连续扫描使能,1.5采样周期
    在这里插入图片描述
    我们设置 PCLK2=72M,经过 ADC 预分频器能分频到最大的时钟只能是 12M,采样周期设置为 1.5 个周期,算出最短的转换时间为 1.17us,
    在这里插入图片描述

    二、代码部分

    HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout);
    
    • 1
      HAL_ADCEx_Calibration_Start(&hadc1);    //AD校准
      HAL_ADC_Start_IT(&hadc1); //开启ADC中断转换
      ADC_Value =HAL_ADC_GetValue(&hadc1);
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    在这里插入图片描述

    三,单通道轮询采样速度

    测试方法:
    {(adc转换时间+io反转时间)-io反转时间} =adc转换速度

    在这里插入图片描述

    在这里插入图片描述

    IO口直接反转
    在这里插入图片描述
    在这里插入图片描述
    测得实际转换时间:3us-0.3us=2.7.us

    理论值:上面我们设置ADC时钟12Mhz,采样一次最短时间位1.17us
    注释:

    可编程的通道采样时间:TCONV = 采样时间+ 12.5个周期
    **例如**:
    当ADCCLK=14MHz,采样时间为1.5周期
     TCONV = 1.5 + 12.5 = 14周期 = **1μs**
     我们设置 PCLK2=72M,经过 ADC 预分频器能分频到最大的时钟只能是 12M,采样周期设置为 1.5 个周期,算出最短的转换时间为 1.17us,
    
    • 1
    • 2
    • 3
    • 4
    • 5

    四、内部温度传感器

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    	HAL_ADC_Start(&hadc1);	//启动ADC转换
    	HAL_ADC_PollForConversion(&hadc1,10);	//等待转换完成,10ms表示超时时间
     AD_Value = HAL_ADC_GetValue(&hadc1);	//读取ADC转换数据(12位数据)
     
    //		HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8);
    		Vol_Value = AD_Value*(3.3/4096);	//AD值乘以分辨率即为电压值
    	printf("ADC1_IN16 VOL value: %.2fV\r\n",Vol_Value);
    	Temperature = (1.43 - Vol_Value)/0.0043 + 25;	//根据公式算出温度值
    	printf("MCU Internal Temperature: %.2f\r\n",Temperature);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    多通道轮询方式

    设置 CubeMX

    在这里插入图片描述
    在这里插入图片描述

    修改代码部分

    在这里插入图片描述

    int main(void)
    {
      /* USER CODE BEGIN 1 */
    int aa=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 */
      HAL_ADCEx_Calibration_Start(&hadc1);    //AD校准
     
    //	printf("Test int:   i = %d\r\n", aa);		// printf输出int型数据
     int  ADC_value[5];
     char i=0;
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
    		for(i=0;i<5;i++)
    		{
    		   HAL_ADC_Start(&hadc1);     //启动ADC转换
    		   HAL_ADC_PollForConversion(&hadc1, 50);   //等待转换完成,50为最大等待时间,单位为ms
    			 ADC_value[i]=HAL_ADC_GetValue(&hadc1);
    		}
        
    		printf("ADC value 0 PA0: %d \r\n",ADC_value[0]);
    		printf("ADC value 1 PA1: %d \r\n",ADC_value[1]);
    		printf("ADC value 2 PA2: %d \r\n",ADC_value[2]);
    		printf("ADC value 3 PA3: %d \r\n",ADC_value[3]);
    		printf("ADC value 4 PA4: %d \r\n",ADC_value[4]);
    		HAL_Delay(1000);
    // AD_Value = HAL_ADC_GetValue(&hadc1);	//读取ADC转换数据(12位数据)
    // 
    		HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8);
    //		Vol_Value = AD_Value*(3.3/4096);	//AD值乘以分辨率即为电压值
    //	aa
    //	Temperature = (1.43 - Vol_Value)/0.0043 + 25;	//根据公式算出温度值
    //	printf("MCU Internal Temperature: %.2f\r\n",Temperature);
     
      }
      /* USER CODE END 3 */
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    实验现象

    PA0接地;PA1接VCC;PA2接地;PA3浮空;PA4浮空

    在这里插入图片描述

    总结

    以上就是今天要讲的内容,本文仅仅简单介绍了ADC的使用,而ADC提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 相关阅读:
    Windows使用模拟器启动AOSP源码编译的镜像
    【算法|动态规划No.31 | 01背包问题】01背包模板题
    陕西秦创原创新驱动平台案例解读
    字符串中不同整数的数目【简单难度】
    vue 项目代码混淆配置(自定义插件适用)带配置项注释
    网易数帆开源Arctic,lceberg、Hive上增加更多实时场景
    83 # 静态服务中间件 koa-static 的使用以及实现
    我帮厂商找BUG系列之华大(小华)HC32F460——PWM输出占空比错误与解决方案
    【Java实战项目】【超详细过程】—大饼的图片服务器2
    作为优秀的DBA,究竟需要掌握多少种数据库?
  • 原文地址:https://blog.csdn.net/weixin_46039185/article/details/133658030