野火STM32_HAL库版课程笔记-TIM触发ADC采集

前置介绍

TRGO 信号 (Trigger Output 触发输出)

是微控制器(如 STM32)中定时器模块产生的一种内部硬件信号。

核心作用是,在不占用 CPU 资源的情况下,精确地触发和同步其他外设的工作

例如启动 ADC(模数转换器)进行采样、更新 DAC(数模转换器)的输出,或者同步其他定时器的启动。

TRGO 典型应用场景 - 定时器周期性触发 ADC 采样
  1. 定时器 被配置为以固定频率(例如每秒1000次)计数。
  2. 每当定时器计数到一个特定值(例如周期结束),它就会自动产生一个 TRGO 信号。
  3. ADC 模块 被配置为监听这个 TRGO 信号。
  4. 一旦 ADC 检测到 TRGO 信号,就立即启动一次数据转换。

通过这种方式,系统可以实现非常稳定、精确且周期性的数据采集,这对于电机控制、音频处理、电源管理等对时序要求极高的应用至关重要。

TIM 触发 ADC 采集内部温度

项目配置

USART1

配置 Mode 为 Asynchronous

TIM3
  1. 勾选 Internal Clock
  2. 设置 Prescaler 为 7200 - 1 , 最终每秒计数一万次
  3. 设置 Counter Period 为 5000 - 1, 即每半秒触发一次 TRGO 信号输出
  4. 设置 Trigger Event Selection 为 Update Event.
ADC1
  1. 勾选 Temperature Sensor Channel 温度传感器通道
  2. Extenal Trigger Conversion Source (外部触发转换源) 设置为 Timer 3 Trigger Out event. (定时器 3 触发外部事件)
  3. Sampling Time (采样时间), 设置为 55.5 Cycles (采样时间长, 数据更稳定准确)

代码部分

因为用到了串口, 记得勾选 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 = 0;     // 存储原始值
float voltage = 0.0f;     // 存储电压值
float temperature = 0.0f; // 存储温度

/* 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 */

/* USER CODE END 0 */

/**
  * @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_TIM3_Init();
  MX_ADC1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  
  // 启动 ADC1 校准
  HAL_ADCEx_Calibration_Start(&hadc1);
  
  // 启动 ADC1 转换
  HAL_ADC_Start(&hadc1);
  
  // 启动 TIM3 基础定时
  HAL_TIM_Base_Start(&htim3);
  
  // 等待芯片传感器稳定
  HAL_Delay(3000);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    
    if (HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY) == HAL_OK) // 等待 ADC 转换完成
    {
      adc_val = HAL_ADC_GetValue(&hadc1);             // 读取原始值
      voltage = (float)adc_val / 4095 * 3.3f;         // 将原始值转换为电压值 (单位 V)
      temperature = (1.43f - voltage) / 0.0043f + 25; // 将电压转换为芯片内部温度 (单位 C)
      
      printf("当前芯片内部温度: %.3f C \r\n", temperature);
      
      // 这里不需要去写延迟, 因为这里是通过 HAL_ADC_PollForConversion 等待定时器每 500ms 触发一次转换, 
      // 如果没有触发完成, 是不会通过的. 
    }      
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

/* 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 */

程序现象

程序运行后, 会先有一段时间的空白期 (进行校准和等待温度传感器稳定)

空白期结束之后, TIM3 每隔 500ms 触发一次 TRGO 信号, 触发 ADC1 采集芯片温度

然后在主程序中等待 ADC1 转换完成后, 将 ADC 原始值转换为电压值, 再转换为温度, 然后通过串口进行输出.

可以将手指放在芯片上, 可以看到温度会有小的变动.

相关推荐
鸽子一号2 分钟前
c#之信号量Semaphore
笔记
kdxiaojie5 分钟前
Linux 驱动研究 —— I2C (5)
linux·运维·笔记·学习
李永奉38 分钟前
杰理可视化SDK开发-【BUG】配置“TWS两边同时按消息使能”功能后,按键单击功能无效失灵
开发语言·单片机·嵌入式硬件·物联网·bug
会周易的程序员38 分钟前
从零构建多核CPU负载自适应控制系统
linux·c++·笔记·物联网·测试工具
执迷不悟8231 小时前
51单片机--中断/定时/PWM
单片机·嵌入式硬件·51单片机
茯苓gao2 小时前
机器人产业的三级火箭:卖电机、卖模组与卖整机,三种商业模式的终局推演
笔记·学习·机器人
LuminousCPP2 小时前
C 语言集中实践全记录:顺序表 + 单链表原理实现与通讯录项目实战【附可运行源码】
c语言·开发语言·数据结构·经验分享·笔记
马里马里奥-2 小时前
大模型应用开发笔记04:LangChain 工具(Tool)与中间件(Middleware)详解
笔记·中间件·langchain
A小调的码农3 小时前
OPENOCD+MSYS+VSCODE:从“灯不亮“到“终于亮了“
ide·vscode·stm32·单片机·编辑器
乐橙开放平台4 小时前
巡店系统笔记:乐橙 listDeviceDetailsByPage 台账 + bindDeviceLive 辅码流最小闭环
网络·笔记·物联网·自动化·音视频·智能家居