STM32 TIM+ADC实验

一、实验现象

系统上电后先进行3秒延时,然后进入主循环持续采集ADC1的模拟信号。程序将12位ADC原始值转换为0.000V-3.300V的实际电压值显示为第一个数据,同时将电压值乘以0.3系数计算得到第二个数据。

二、示例代码

1. ADC初始化

复制代码
/**
  * @brief  ADC1初始化函数(内部温度传感器)
  */
void MX_ADC1_Init(void)
{
  ADC_ChannelConfTypeDef sConfig = {0};  // ADC通道配置结构体

  /** ADC通用配置 */
  hadc1.Instance = ADC1;                          // 设置ADC实例为ADC1
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;     // 禁用扫描模式(单通道)
  hadc1.Init.ContinuousConvMode = DISABLE;        // 禁用连续转换模式(单次转换)
  hadc1.Init.DiscontinuousConvMode = DISABLE;     // 禁用间断模式
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO; // TIM3触发ADC转换
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;     // 数据右对齐
  hadc1.Init.NbrOfConversion = 1;                 // 转换序列数为1
  
  // 初始化ADC,如果失败则调用错误处理函数
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  /** 配置内部温度传感器通道 */
  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;       // 设置ADC通道为内部温度传感器
  sConfig.Rank = ADC_REGULAR_RANK_1;              // 设置通道在规则组中的排名为第1个
  sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5; // 设置采样时间为55.5个ADC时钟周期
  
  // 配置ADC温度传感器通道,如果失败则调用错误处理函数
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
}

2. TIM初始化

复制代码
/**
  * @brief  TIM3定时器初始化函数(ADC触发源)
  */
void MX_TIM3_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};  // 时钟源配置结构体
  TIM_MasterConfigTypeDef sMasterConfig = {0};      // 主模式配置结构体

  // 定时器基础配置
  htim3.Instance = TIM3;                           // 定时器实例TIM3
  htim3.Init.Prescaler = 7200-1;                   // 预分频值7199(7200分频)
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;     // 向上计数模式
  htim3.Init.Period = 5000-1;                      // 自动重装载值4999
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; // 时钟分频(不分频)
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; // 禁用自动重装载预装载
  
  // 初始化定时器基础配置
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();  // 错误处理
  }

  // 配置时钟源为内部时钟
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();  // 错误处理
  }

  // 配置主模式,设置TIM3更新事件触发ADC转换
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;        // 主模式触发输出为更新事件
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; // 禁用主从模式
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();  // 错误处理
  }
}

3. 主函数

复制代码
uint16_t aaa = 0;     // 存储ADC原始转换值
float vvv = 0.0f;     // 存储计算得到的电压值
float ttt = 0.0f;     // 存储计算得到的温度或其他物理量值

// 系统时钟配置函数声明
void SystemClock_Config(void);

/**
  * @brief  应用程序主函数
  * @retval int
  */
int main(void)
{
  // HAL库初始化
  HAL_Init();

  // 系统时钟配置
  SystemClock_Config();

  // 初始化所有配置的外设
  MX_GPIO_Init();           // GPIO初始化
  MX_ADC1_Init();           // ADC1初始化(配置为内部温度传感器)
  MX_TIM3_Init();           // TIM3定时器初始化(ADC触发源)
  MX_USART1_UART_Init();    // USART1串口初始化
  
  // 执行ADC校准
  HAL_ADCEx_Calibration_Start(&hadc1);
  // 启动ADC转换(等待TIM3触发)
  HAL_ADC_Start(&hadc1);
  // 启动TIM3定时器(产生ADC触发信号)
  HAL_TIM_Base_Start(&htim3);
  // 延时3秒等待系统稳定
  HAL_Delay(3000);

  // 主循环
  while (1)
  {
    // 等待ADC转换完成
    if(HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY) == HAL_OK)
    {
      // 获取ADC转换结果
      aaa = HAL_ADC_GetValue(&hadc1);
      // 将ADC值转换为电压值(12位分辨率,参考电压3.3V)
      vvv = (float)aaa / 4095 * 3.3f;
      // 计算温度或其他物理量(示例计算)
      ttt = vvv * 0.3f;
      // 通过串口输出电压值和计算值
      printf("\r\n%.3f,%.3f\r\n", vvv, ttt);
    }
  }
}
相关推荐
llilian_163 小时前
总线授时卡 CPCI总线授时卡的工作原理及应用场景介绍 CPCI总线校时卡
运维·单片机·其他·自动化
The Electronic Cat6 小时前
树莓派使用串口启动死机
单片机·嵌入式硬件·树莓派
先知后行。8 小时前
常见元器件
单片机·嵌入式硬件
Dillon Dong9 小时前
按位或(|=)的核心魔力:用宏定义优雅管理嵌入式故障字
c语言·stm32
Free丶Chan10 小时前
dsPIC系列-1:dsPIC33点灯 [I/O、RCC、定时器]
单片机·嵌入式硬件
v先v关v住v获v取11 小时前
塔式立体车库5张cad+设计说明书+三维图
科技·单片机·51单片机
Ghost Face...12 小时前
U-Boot与PMON:配置与设备树解析对比
linux·单片机·嵌入式硬件
冲,干,闯12 小时前
操作MCU内存
单片机·嵌入式硬件
猫猫的小茶馆13 小时前
【ARM】从零封装STM32标准库
汇编·arm开发·stm32·单片机·嵌入式硬件·架构