前置介绍

多通道读取

在前面单通道的应用中, 就是采集一个通道的 ADC 值, 也就是只采集一个电位器.

而想要采集多个传感器的情况下, 就要用到多通道.

多通道相较于单通道

只不过是把扫描一个通道的值, 变成转换多个通道, 并且依次转换.

项目配置

ADC1 勾选 IN4, 5, 6.

到 ADC1 - Configuration - Parameter Settings

这里要转换多个通道的 ADC 值, 所以需要将 Scan Conversion Mode 配置为使能 (Enable)

但是这里现在点击会发现使能被禁用了.

因为需要先将下面的 Number Of Conversion 的转换通道数设置为对应的 3 个通道.

当下面配置为对应 3 个通道后, 上面的 Scan Conversion Mode自动被配置为了使能 (需要注意配置后, 点击旁边或回车确认配置后即可看到被自动配置), 并且也不能配置为失能模式.

连续转换 (Continuous Conversion Mode) 保持失能, 使用单次软件转换.

Discontinuous Conversion Mode 间断转换模式, 使用多通道读取和轮询, 就需要开启它.
并且下面的通道数 (Number Of Discontinuous Conversions), 转换 1.

意思就是每次只转换一个通道, 然后暂停. (转换 PA4 -> 暂停 -> 手动调用代码 -> 转换 PA5 -> 暂停 -> 转换 PA6 -> 暂停 -> 手动调用代码 -> 转换 PA4 -> ... )

如果设置为 2, 那么就是每转换 2 个通道, 就会暂停. 等待外部触发信号

Rank 设置通道的转换顺序和采样时间

转换顺序依次设置, 采样时间保持默认 (1.5 Cycles)

给三个引脚设置用户标签 (光敏, 红外, 热敏)

代码部分

用到了 USART1 , 记得勾选 Use MicroLIB

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

#include <stdio.h>  // 使用 printf 函数
#include <string.h> // 使用 strncmp

/* 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 */
uint32_t adc_val[3];  // 存储3个通道的ADC数值
float voltage[3];     // 存储3个通道的ADC电压值
/* USER CODE END PV */
  /* USER CODE BEGIN 2 */

  // 启动 ADC 校准
  HAL_ADCEx_Calibration_Start(&hadc1);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    // 依次读取三个通道的数值. 
    for (int i = 0; i < 3; i++)
    {
      // 启动一次 ADC 转换
      HAL_ADC_Start(&hadc1);
      
      if (HAL_ADC_PollForConversion(&hadc1, 50) == HAL_OK)
      {
        // 读取ADC的值
        adc_val[i] = HAL_ADC_GetValue(&hadc1);
      
        // 计算电压值 (参考电压 3.3V, 分辨率 12位)
        voltage[i] = (float)adc_val[i] / 4095 * 3.3f;
      }
    }
    
    printf("光敏(IN4): %.3f V, 反射(IN5): %.3f V, 热敏(IN6): %.3f V \r\n", 
            voltage[0], voltage[1], voltage[2]);
    
    // 每 500 ms 采样一次
    HAL_Delay(500);
/* USER CODE BEGIN 4 */

/**
  * @brief  重定向 printf 的输出到串口
  * @param  ch: 要发送的字符
  * @param  f:  文件指针 (标准库要求的参数, 一般不使用)
  * @retval 返回发送的字符
  */
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
  return ch;
}

/* USER CODE END 4 */

实验现象

改变各个传感器的状态, 电压值发生变化.

热敏传感器, 温度较难改变, 电压变化幅度较小.

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐