#include "tim4.h"
void TIM4_Init(void)
{
// 开启时钟
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; // 使用 TIM4 的 GPIOB 时钟
// 配置 PB6 为浮空输入 CNF 01 MODE 00
GPIOB->CRL &= ~GPIO_CRL_MODE6;
GPIOB->CRL &= ~GPIO_CRL_CNF6_1;
GPIOB->CRL |= GPIO_CRL_CNF6_0; // 浮空输入
// 定时器时基部分
// 预分频71
TIM4->PSC = 71;
// 自动重装载值 1000
TIM4->ARR = 65535; // 65535 是最大值,计数到这个值后会重装载
// 向上计数
TIM4->CR1 &= ~TIM_CR1_DIR;
// TI1输入选择直通
TIM4->CR2 &= ~TIM_CR2_TI1S;
// 输入滤波器
TIM4->CCMR1 &= ~TIM_CCMR1_IC1F; // 无滤波
// 配置边沿检测器极性上升沿触发
TIM4->CCER &= ~TIM_CCER_CC1P;
// 配置边沿检测器极性下降沿触发
TIM4->CCER |= TIM_CCER_CC2P;
// 选择通道1的输入映射为TI1 01
TIM4->CCMR1 &= ~TIM_CCMR1_CC1S; // 清除 CC1S 位
TIM4->CCMR1 |= TIM_CCMR1_CC1S_0;
// 选择通道2的输入映射为TI1 10
TIM4->CCMR1 |= TIM_CCMR1_CC2S; // 清除 CC2S 位
TIM4->CCMR1 &= ~TIM_CCMR1_CC2S_0;
// 预分频器
TIM4->CCMR1 &= ~TIM_CCMR1_IC1PSC; // 无预分频
TIM4->CCMR1 &= ~TIM_CCMR1_IC2PSC; // 无预分频
// 配置触发输入信号101
TIM4->SMCR |= TIM_SMCR_TS; // 清除 TS 位
TIM4->SMCR &= ~TIM_SMCR_TS_1; // 选择触发输入为 TI1
// 配置从模式为复位模式100
TIM4->SMCR &= ~TIM_SMCR_SMS; // 清除 SMS 位
TIM4->SMCR |= TIM_SMCR_SMS_2; // 设置为复位模式
// 通道1输入捕获使能
TIM4->CCER |= TIM_CCER_CC1E;
// 通道2输入捕获使能
TIM4->CCER |= TIM_CCER_CC2E;
}
void TIM4_START(void)
{
TIM4->CR1 |= TIM_CR1_CEN; // 启动定时器
}
void TIM4_STOP(void)
{
TIM4->CR1 &= ~TIM_CR1_CEN;
}
// 获取 输入 周期为ms
double TIM4_GETPWMCYCLE(void)
{
return TIM4->CCR1 / 1000.0; // 假设计数器时钟为 1MHz
}
double TIM4_GETPWMFREQ(void)
{
return 1000000.0 / TIM4->CCR1;
}
double TIM4_GetDutyCycle(void)
{
return (TIM4->CCR2 * 1.0) / TIM4->CCR1; // 假设 CCR2 是捕获的高电平时间
}
定时器 TIM4 被配置为从模式复位模式(TIM_SMCR_SMS = 100
),并且触发输入选择为 TI1(TIM_SMCR_TS
设置为 101)。
1. 复位模式的触发机制
- 在复位模式下,计数器 (CNT) 会在检测到指定的触发输入事件时立即清零。
TIM_SMCR_TS
被设置为 101,表示触发输入源是 TI1 的边沿(上升沿或下降沿取决于TIM_CCER_CC1P
和TIM_CCER_CC2P
的极性配置)。TIM_CCER_CC1P = 0
(上升沿触发),TIM_CCER_CC2P = 1
(下降沿触发):- 通道 1 (CC1) 捕获 TI1 的上升沿。
- 通道 2 (CC2) 捕获 TI1 的下降沿。
2. 代码中的配置
- 触发输入 TI1:
TIM_SMCR_TS = 101
选择 TI1 作为触发源。TI1 是输入 PWM 信号的滤波和映射后的信号。 - 复位模式:
TIM_SMCR_SMS = 100
计数器会在 TI1 的上升沿触发时复位。 - CNT 行为:计数器从 0 开始计数,当 TI1 检测到上升沿时,CNT 会立即清零。
3. 高电平与复位的关系
- PWM 信号的高电平是从上升沿开始到下降沿结束。
- 在你的配置中,复位是由 TI1 的上升沿触发的(因为
TIM_CCER_CC1P = 0
选择上升沿)。这意味着:- 当 PWM 信号从低电平跳到高电平(上升沿发生)时,计数器 (CNT) 会被复位。
- 复位发生在高电平的开始时刻,而不是整个高电平期间。
- 之后,CNT 会从 0 开始计数,直到下一次触发或达到 ARR。
4. 代码中的捕获逻辑
TIM4->CCR1
捕获上升沿时间(高电平开始)。TIM4->CCR2
捕获下降沿时间(高电平结束)。- 由于 CNT 在每次上升沿复位,
CCR1
总是记录 0(或很小的值),CCR2
记录高电平持续时间。