1.引言
有如下两种情况:
情况1:
同一个定时器的两个通道1和2,通道1产生PWM脉冲,用于电机控制。通道2捕获
别的设备产生的PWM脉冲。根据奈奎斯特采样定理,定时器捕获的频率至少时输入的频率2倍。
情况2:
同一个定时器的两个通道1和2,通道1产生PWM脉冲。通道2捕获 通道1产生的PWM脉冲。这种情况时行不通的。
2.奈奎斯特采样定理
3.输入的信号频率和定时器时钟频率、预分频值等之间的关系
案例1:测量1kHz PWM脉冲
计算:
定时器计算频率fcn t> fpwm * 2 * (ICF+1)
fcnt> 1000 * 2 * (ICF+1)
定时器计算频率fcnt = ftimer/(PSC+1) >1000 * 2 * (ICF+1)
ftimer/(PSC+1) >10002(ICF+1)
如果已知 ftimer=200Mhz,ICF=0, 则
200 * 1000 * 1000/(PSC+1) >1000 * 2
则:
PSC < 100 * 1000 -1
4.定时器捕获PWM脉冲的条件与频率关系
4.1 条件约束
各参数对捕获的影响
4.2. 参数配置算法
// PWM捕获参数自动配置函数
void config_pwm_capture(uint32_t expected_freq)
{
// 1. 计算最小所需f_cnt
uint32_t min_fcnt = expected_freq * 10; // 10倍过采样
// 2. 获取定时器时钟
uint32_t timer_clk = rcu_clock_freq_get(CK_TIMER);
// 3. 计算PSC
uint32_t psc = (timer_clk + min_fcnt/2) / min_fcnt - 1;
if(psc > 0xFFFF) psc = 0xFFFF;
// 4. 计算实际f_cnt
uint32_t actual_fcnt = timer_clk / (psc + 1);
// 5. 配置滤波器 (经验公式)
uint8_t icf;
if(expected_freq > 1000000) icf = 0;
else if(expected_freq > 100000) icf = 2;
else if(expected_freq > 10000) icf = 4;
else icf = 6;
// 6. 应用配置
timer_prescaler_config(TIMERx, psc, TIMER_PSC_RELOAD_NOW);
timer_autoreload_value_config(TIMERx, 0xFFFF);
timer_ic_filter_config(TIMERx, TIMER_CHy, icf);
// 7. 计算实际可测范围
uint32_t max_freq = actual_fcnt / (2 * (icf + 1));
uint32_t min_freq = actual_fcnt / (0x10000 * 0x10000);
printf("Configured for %.1fkHz PWM\n", expected_freq/1000.0);
printf("Measurable range: %.3fHz - %.3fMHz\n",
min_freq, max_freq/1000000.0);
}
4.3. 临界频率处理技术
当 4≤fcntfpwm<104 \leq \frac{f_{cnt}}{f_{pwm}} < 104≤fpwmfcnt<10 时:
// 在捕获中断中
void TIMERx_IRQHandler(void)
{
// 使用多次捕获平均
#define N_SAMPLES 16
static uint32_t samples[N_SAMPLES];
static uint8_t index = 0;
if(capture_event) {
// 仅存储有效捕获
samples[index++] = capture_value;
if(index >= N_SAMPLES) {
// 计算中值滤波
uint32_t sorted[N_SAMPLES];
memcpy(sorted, samples, sizeof(samples));
bubble_sort(sorted, N_SAMPLES);
uint32_t median = sorted[N_SAMPLES/2];
// 更新测量值
update_measurement(median);
index = 0;
}
}
}
4.4. 超高频处理技术
当 (fcntfpwm≈2\frac{f_{cnt}}{f_{pwm}} \approx 2fpwmfcnt≈2)
// 使用定时器从模式
void config_high_freq_capture(void)
{
// 1. 配置为复位模式
timer_slave_mode_select(TIMERx, TIMER_SLAVE_MODE_RESET);
// 2. 设置触发源为捕获事件
timer_input_trigger_source_select(TIMERx, TIMER_SMCFG_TRGSEL_CI0RED);
// 3. 配置双边沿捕获
timer_ic_parameter_struct ic_cfg;
ic_cfg.icpolarity = TIMER_IC_POLARITY_BOTH_EDGE;
// ...其他配置
timer_input_capture_config(TIMERx, TIMER_CHy, &ic_cfg);
// 4. 启用DMA传输捕获值
timer_dma_enable(TIMERx, TIMER_DMA_CH0D);
dma_init(DMAx, DMA_CHy, ...);
}
4.5特殊场景处理
- 低频PWM捕获 (fpwm<1Hzf_{pwm} < 1\text{Hz}fpwm<1Hz)
```c
// 在溢出中断中
void TIMERx_UP_IRQHandler(void)
{
static uint32_t overflow_count = 0;
if(timer_interrupt_flag_get(TIMERx, TIMER_INT_FLAG_UP)) {
overflow_count++;
timer_interrupt_flag_clear(TIMERx, TIMER_INT_FLAG_UP);
}
}
// 在捕获中断中
void TIMERx_CC_IRQHandler(void)
{
static uint32_t last_capture = 0;
static uint32_t last_overflow = 0;
uint32_t current_capture = timer_channel_capture_value_register_read(TIMERx, TIMER_CHy);
uint32_t overflow_diff = overflow_count - last_overflow;
// 计算真实周期(考虑溢出)
uint32_t period = overflow_diff * (ARR + 1) + (current_capture - last_capture);
last_capture = current_capture;
last_overflow = overflow_count;
}
- 高噪声环境捕获
// 自适应滤波器调整
void adjust_filter_based_on_noise(void)
{
static uint32_t last_values[4];
static uint8_t index = 0;
// 存储最近4个脉宽值
last_values[index++] = current_pulse;
if(index >= 4) index = 0;
// 计算变异系数
float mean = (last_values[0]+last_values[1]+last_values[2]+last_values[3])/4.0f;
float variance = 0;
for(int i=0; i<4; i++) {
variance += pow(last_values[i]-mean, 2);
}
float std_dev = sqrt(variance/4);
float cv = std_dev / mean; // 变异系数
// 根据噪声水平调整滤波器
uint8_t new_icf = timer_ic_filter_get(TIMERx, TIMER_CHy);
if(cv > 0.1) { // 高噪声
new_icf = min(new_icf + 1, 15);
} else if(cv < 0.01) { // 低噪声
new_icf = max(new_icf - 1, 0);
}
timer_ic_filter_config(TIMERx, TIMER_CHy, new_icf);
}