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);
    }
  }
}
相关推荐
hazy1k1 小时前
MSPM0L1306 从零到入门:第六章 UART —— 让单片机与世界“对话”
stm32·单片机·嵌入式硬件·物联网·51单片机·esp32·iot
qq_7391753693 小时前
开源基于STC8的智能浇花与温湿度报警系统
c语言·stm32·单片机·嵌入式硬件
清月电子3 小时前
充电宝新规适配方案:KT6368A 蓝牙芯片应用技术说明
人工智能·单片机·嵌入式硬件·物联网
Lay_鑫辰3 小时前
西门子1200PLC控制禾川X5ER伺服配置AC4模式全流程
运维·人工智能·单片机·嵌入式硬件·自动化
就是蠢啊3 小时前
51单片机——多文件结构模板
单片机·嵌入式硬件·51单片机
Bona Sun3 小时前
单片机手搓掌上游戏机(二十一)—pico运行doom之修改编译
c语言·c++·单片机·游戏机
意法半导体STM324 小时前
STM32N6 如何配置EMMC启动 LAT1581
stm32·单片机·嵌入式硬件·mcu·嵌入式ai·stm32n6·stm32开发
逆小舟4 小时前
【STM32】IIC→OLED显示
stm32·单片机·嵌入式硬件
Geek__19924 小时前
STM32F103 ADC DMA采样与均值滤波处理实战指南
c语言·stm32