一、實驗現象

系統上電後先進行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);
    }
  }
}