前置介绍
多通道读取
在前面单通道的应用中, 就是采集一个通道的 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 */
实验现象

改变各个传感器的状态, 电压值发生变化.
热敏传感器, 温度较难改变, 电压变化幅度较小.