一、实验现象
系统上电后先进行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);
}
}
}