个人技术分享

一、电位器模块

(1)资源介绍

        🔅原理图 

        蓝桥杯物联网竞赛实训平台提供了一个拓展接口 CN2,所有拓展模块均可直接安装在 Lora 终端上使用;

图1        拓展接口

         电位器模块电路原理图如下所示:

图2        电位器模块电路原理图

         通过两张电路图连接可知,引脚资源配置情况为:

表1 引脚资源配置情况
Pot & LED MCU
AIN1 PB1
AIN2 PB0
LD1 PB6
LD2 PB7
        🔅采集原理

        在 STM32L071 系列微控制器中嵌入了原生的12位模数转换器,通过硬件过采样扩展到16位模数转换器。它有多达19个多路复用通道,允许它测量来自16个外部和3个内部来源的信号。各种通道的 A/D 转换可以在单、连续、扫描或不连续模式下进行。ADC的结果存储在左对齐或右对齐的16位数据寄存器中。
        16个外部通道在转换时分为注入通道和规则通道:

  • 规则通道:

        最多有16路,相当于正常运行的程序,平时ADC的转换都是使用规则通道来实现的;

  • 注入通道:

        最多有4路,相当于中断,当注入通道需要转换时,规则通道的转换就会停止,优先执行注入通道的转换,当注入通道转换完成后,再继续执行规则通道的转换。

(2)STM32CubeMX 软件配置


🔅“工程建立、时钟树配置、Debug 串行线配置、代码生成配置” 在下文中有讲解,这里不再赘述❗️

【蓝桥杯——物联网设计与开发】基础模块1- GPIO输出icon-default.png?t=N7T8https://blog.csdn.net/m0_63116406/article/details/135604705?spm=1001.2014.3001.5502

1️⃣点击 "Analog" → 点击 "ADC"→勾选通道 "IN8" 和 "IN9"

图3        ADC通道配置


2️⃣在 "ADC" 的参数设置栏中,找到 "Low Power Auto wait" 并选择 "Enabled" 进行使能;

图4        修改ADC配置


3️⃣初始化 OLED;(配置步骤在下文中有讲解,这里不再赘述);

【蓝桥杯——物联网设计与开发】基础模块6 - OLED

4️⃣生成代码即可;

(3)代码编写

🟢️main 函数

/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "oled.h"
/* USER CODE END Includes */

/* USER CODE BEGIN PV */
uint8_t puc_oled[17];	// OLED显示数组
uint16_t pui_adc[2];	// ADC采集数组
/* USER CODE END PV */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* 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_ADC_Init();
  MX_I2C3_Init();
  /* USER CODE BEGIN 2 */
	/* OLED初始化 */
	OLED_Init();
	/* ADC校正 */
	HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		/* 启动ADC */
		HAL_ADC_Start(&hadc);
		/* ADC转换 */
		if(HAL_ADC_PollForConversion(&hadc, 10) == HAL_OK)
			pui_adc[1]= HAL_ADC_GetValue(&hadc);		// 读取ADC值
		if(HAL_ADC_PollForConversion(&hadc, 10) == HAL_OK)
			pui_adc[0]= HAL_ADC_GetValue(&hadc);		// 读取ADC值
		/* OLED显示 */
		sprintf((char*)puc_oled, "RP1:%.2fV", pui_adc[0] * 3.3 / 4095);
		OLED_ShowString(0, puc_oled);
		sprintf((char*)puc_oled, "RP2:%.2fV", pui_adc[1] * 3.3 / 4095);
		OLED_ShowString(2, puc_oled);
		HAL_Delay(200);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

(4)实验现象

        旋转旋钮,对应的电压值发生变化。


二、ADC接口函数封装

🟡️ADC初始化校正

/* ADC校正 */
HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED);

        ⚠️该函数调用放在ADC初始化函数中。若不进行校正,会导致采集的电压值有误!

🟡️ADC采集函数

void ADC_Colt(uint16_t *puc_adc)
{
	/* 启动ADC */
	HAL_ADC_Start(&hadc);
	/* ADC转换 */
	if(HAL_ADC_PollForConversion(&hadc, 10) == HAL_OK)
		puc_adc[1]= HAL_ADC_GetValue(&hadc);		// 读取ADC值
	if(HAL_ADC_PollForConversion(&hadc, 10) == HAL_OK)
		puc_adc[0]= HAL_ADC_GetValue(&hadc);		// 读取ADC值
}

🔴ADC采集接口函数调用实例

/* 采集任务函数 */
void Task_Colt(void)
{
	/* 200ms进入一次 */
	if(cnt_colt < 200)	return;
	cnt_colt = 0;
	/* ADC采集 */
	ADC_Colt(pui_adc);
	/* 数据转换 */
	pui_adc[0] = pui_adc[0] * 330 / 4095;
	pui_adc[1] = pui_adc[1] * 330 / 4095;
}

三、踩坑日记

(1)LowPowerAutoWait模式

        🔅LowPowerAutoWait:配置是否使用低功耗自动延迟等待模式,*可选参数为 ENABLE DISABLE,当使能时,仅当一组内所有之前的数据已处理完毕时,才开始新的转换,适用于低频应用。该模式仅用于 ADC 的轮询模式,不可用于 DMA 以及中断