嵌入式知识---如何配置定时器的时基单元,如何配置输出通道

手把手教你配置定时器时基单元和输出通道

📋 配置总览(两步走)

第一步:配置时基单元(定时器的"心脏")

第二步:配置输出通道(定时器的"嘴巴")

  1. 第一步:配置时基单元(定时器的心跳)

🎯 时基单元是什么?

就是定时器的基本计时设置,包括:

  • 时钟从哪里来?

  • 计到多少数算一次?

  • 计数方式(向上/向下)?

🛠️ 配置步骤(以STM32 HAL库为例)

复制代码
// 1. 定义定时器句柄
TIM_HandleTypeDef htim2;

// 2. 配置时基单元
htim2.Instance = TIM2;                    // 用哪个定时器(TIM2)
htim2.Init.Prescaler = 72 - 1;            // 预分频器:72分频
htim2.Init.CounterMode = TIM_COUNTERMODE_UP; // 计数方式:向上计数
htim2.Init.Period = 1000 - 1;             // 自动重装载值:计到1000
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; // 时钟分频:不分频
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; // 自动重装载

📊 参数含义解释

参数 通俗解释 例子说明

Prescaler 时钟分频系数 72MHz ÷ (72-1+1) = 1MHz<br>(原来是72MHz,除以72后变成1MHz)

Period 计多少次溢出 从0数到999,一共1000次

CounterMode 怎么数数 从0往上数(0,1,2...)

ClockDivision 内部时钟分频 通常用DIV1(不分)

🧮 计算定时时间

总定时时间 = (Prescaler+1) × (Period+1) ÷ 系统时钟频率

例子:

Prescaler = 72-1 = 71

Period = 1000-1 = 999

系统时钟 = 72MHz

定时时间 = (71+1) × (999+1) ÷ 72,000,000

= 72 × 1000 ÷ 72,000,000

= 0.001秒 = 1ms

  1. 第二步:配置输出通道(控制引脚)

🎯 输出通道是什么?

让定时器能控制某个引脚输出信号。

(这里穿插一下:PWM模式与向上计数区别的理解

计数模式 = 电梯怎么运行

  • 向上计数:只向上运行
  • 向下计数:只向下运行
  • 中央对齐:先上到顶,再下到底

PWM模式 = 电梯门开关规则

  • 模式1:低于5楼开门
  • 模式2:高于5楼开门

比如:计数模式:0 → 1 → 2 → ... → 999
PWM规则:当计数 < 比较值时输出高电平
结果:从0开始产生PWM波

计数模式:999 → 998 → 997 → ... → 0
PWM规则:当计数 < 比较值时输出高电平
结果:从999开始产生PWM波)

🛠️ 配置步骤(PWM输出为例)

复制代码
// 1. 定义输出通道结构体
TIM_OC_InitTypeDef sConfigOC = {0};

// 2. 配置输出通道参数
sConfigOC.OCMode = TIM_OCMODE_PWM1;       // 模式:PWM模式1
sConfigOC.Pulse = 500;                    // 比较值:决定占空比
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; // 极性:高电平有效
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;  // 快速模式:禁用

// 3. 应用配置到具体通道
HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);

📊 输出通道参数解释

参数 通俗解释 例子说明

OCMode 输出模式 PWM模式1:计数<比较值时输出有效电平

Pulse 比较值 决定占空比大小(0~Period)

(定时器核心工作原理:
CNT计数器:0 → 1 → 2 → 3 ... → ARR(自动重装载值)

└─ 当 CNT < CCR(Pulse) 时:输出高电平(PWM模式1)
CNT ≥ CCR(Pulse) 时:输出低电平)

OCPolarity 输出极性 HIGH:有效电平为高;LOW:有效电平为低

OCFastMode 快速模式 通常禁用,需要快速响应时启用

🧮 计算占空比

占空比 = Pulse ÷ (Period+1) × 100%

例子:

Pulse = 500

Period = 999 (实际是-1=999)

占空比 = 500 ÷ 1000 × 100% = 50%

  1. 完整配置代码示例(LED呼吸灯)

    #include "stm32f1xx_hal.h"

    TIM_HandleTypeDef htim2;
    TIM_OC_InitTypeDef sConfigOC = {0};

    // 步骤1:配置时基单元
    void TIM2_Init(void) {
    htim2.Instance = TIM2;
    htim2.Init.Prescaler = 72 - 1; // 72分频,得到1MHz
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim2.Init.Period = 1000 - 1; // 计1000个数,1ms溢出
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    HAL_TIM_Base_Init(&htim2);
    }

    // 步骤2:配置输出通道(PWM)
    void TIM2_PWM_Init(void) {
    // 配置PWM通道
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 0; // 初始占空比0%
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

    复制代码
     // 应用到通道1
     HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);
     
     // 步骤3:开启PWM输出
     HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);

    }

    // 步骤4:改变占空比(让LED呼吸)
    void LED_Breathing(void) {
    static uint16_t pwm_val = 0;
    static int8_t dir = 1; // 方向:1增加,-1减少

    复制代码
     // 改变比较值
     __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, pwm_val);
     
     // 更新PWM值
     pwm_val += dir;
     
     // 边界检查
     if(pwm_val >= 1000) dir = -1;
     if(pwm_val <= 0) dir = 1;
     
     HAL_Delay(1);  // 延迟1ms,让呼吸效果可见

    }

    int main(void) {
    // 初始化HAL库
    HAL_Init();

    复制代码
     // 初始化系统时钟(配置为72MHz)
     SystemClock_Config();
     
     // 初始化定时器
     TIM2_Init();
     TIM2_PWM_Init();
     
     // 主循环
     while(1) {
         LED_Breathing();
     }

    }

  2. 快速配置指南(抄作业用)

情景1:1ms定时中断

Prescaler = 72 - 1; // 72MHz/72 = 1MHz

Period = 1000 - 1; // 1ms中断

情景2:1秒定时

Prescaler = 7200 - 1; // 72MHz/7200 = 10KHz

Period = 10000 - 1; // 1秒中断

情景3:20Hz PWM(舵机控制)

Prescaler = 720 - 1; // 72MHz/720 = 100KHz

Period = 5000 - 1; // 20Hz频率

Pulse = 250; // 5%占空比(最小角度)

// Pulse = 375; // 7.5%占空比(中间角度)

// Pulse = 500; // 10%占空比(最大角度)

  1. 常见问题解答

Q: 为什么要Prescaler-1和Period-1?

A: 因为从0开始计数。如果设置Prescaler=72,实际是73分频。

Q: 什么时候用向上计数,什么时候用向下计数?

A: 通常用向上计数。PWM输出一般用中央对齐模式(向上向下计数)。

Q: PWM频率怎么计算?

PWM频率 = 定时器时钟 ÷ [(Prescaler+1) × (Period+1)]

例子:定时器时钟72MHz,Prescaler=72-1,Period=1000-1

PWM频率 = 72MHz ÷ (72 × 1000) = 1KHz

  1. 调试技巧

  2. 先调时基单元:用示波器看中断引脚输出

  3. 再调输出通道:用示波器看PWM波形

  4. 验证计算:

// 计算实际频率

uint32_t timer_clock = 72000000; // 72MHz

uint32_t prescaler = 72;

uint32_t period = 1000;

uint32_t freq = timer_clock / (prescaler * period);

printf("PWM频率: %lu Hz", freq);

🎯 总结口诀

配置定时器,两步走:

一时基,二通道,顺序记牢。

时基管心跳,分频最重要,

计满就溢出,时间刚刚好。

通道管输出,模式要选对,

PWM最常见,占空比可调。

先算频率,再调占空,

测试验证,一步步搞。

按照这个步骤,你就能成功配置定时器了!

相关推荐
Katecat996632 小时前
尿液样本中细胞与非细胞成分检测分类系统实现
单片机·分类·数据挖掘
2401_863318633 小时前
基于单片机的恒温箱设计
单片机·嵌入式硬件
ベadvance courageouslyミ3 小时前
嵌入式硬件基础
嵌入式硬件·51单片机·嵌入式·数码管·二极管
范纹杉想快点毕业4 小时前
欧几里得算法与扩展欧几里得算法,C语言编程实现(零基础全解析)
运维·c语言·单片机·嵌入式硬件·算法
2301_773730314 小时前
嵌入式—51单片机day1
单片机·嵌入式硬件·51单片机
代码游侠4 小时前
学习笔记——嵌入式与51单片机学习
单片机·嵌入式硬件·学习·51单片机
zy135380675734 小时前
12V输入5V/2A输出升降压芯片AH4002
科技·单片机·物联网·fpga开发·硬件工程·智能电视
代码游侠4 小时前
学习笔记——嵌入式系统与51单片机核心
笔记·单片机·嵌入式硬件·学习·51单片机
一枝小雨4 小时前
【OTA专题】15 实现App后台无感下载固件
stm32·单片机·嵌入式·ota·bootloader