引言
在汽车电子控制系统中,精确的时序控制是实现各种功能的基础。无论是发动机点火时序、电机PWM控制,还是传感器采样定时,都需要强大而灵活的定时器系统支持。YTM32B1ME0x集成了丰富的定时器资源,包括增强定时器(eTMR)、周期定时器(pTMR)、低功耗定时器(lpTMR)等,为汽车应用提供了全面的时序解决方案。
定时器系统架构概览
定时器资源配置
YTM32B1ME0x提供了多层次的定时器架构:
定时器类型 | 数量 | 主要特性 | 应用场景 |
---|---|---|---|
TMR | 1个 | 32位计数,4个比较通道 | 系统定时、延时 |
pTMR | 1个(4通道) | 32位周期定时器 | 周期性任务调度 |
lpTMR | 1个 | 16位低功耗定时器 | 低功耗模式计时 |
eTMR | 6个 | 增强定时器,PWM生成 | 电机控制、PWM输出 |
RTC | 1个 | 实时时钟 | 时间记录、定时唤醒 |
PTU | 2个 | 可编程触发单元 | 事件触发、同步 |
定时器系统架构图
┌─────────────────────────────────────┐ │ 时钟源选择 │ │ FIRC/SIRC/FXOSC/SXOSC/PLL │ └─────────────────┬───────────────────┘ │ ┌─────────────────┼───────────────────┐ │ ▼ │ │ ┌─────────────────┐ │ │ │ 时钟分频器 │ │ │ └─────────────────┘ │ │ │ │ ┌───────────┼─────────────────┼───────────────────┼───────────┐ ▼ ▼ ▼ ▼ ▼ ┌────────┐ ┌────────┐ ┌────────────┐ ┌────────┐ ┌────────┐ │ TMR │ │ pTMR │ │ eTMR │ │ lpTMR │ │ RTC │ │ 系统 │ │ 周期 │ │ 增强 │ │ 低功耗 │ │ 实时 │ │ 定时器 │ │ 定时器 │ │ 定时器 │ │ 定时器 │ │ 时钟 │ └────────┘ └────────┘ └────────────┘ └────────┘ └────────┘ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ ┌────────┐ ┌────────┐ ┌────────────┐ ┌────────┐ ┌────────┐ │ 中断 │ │ 中断 │ │ PWM输出 │ │ 唤醒 │ │ 闹钟 │ │ 生成 │ │ 生成 │ │ 捕获/比较 │ │ 信号 │ │ 中断 │ └────────┘ └────────┘ └────────────┘ └────────┘ └────────┘
增强定时器(eTMR)深度解析
eTMR核心特性
增强定时器是YTM32B1ME0x最强大的定时器模块,特别适合电机控制和PWM应用:
主要特性:
-
16位计数器:支持向上、向下、中心对齐计数
-
8个通道:每个通道支持输入捕获、输出比较、PWM生成
-
死区时间控制:防止功率器件直通
-
故障保护:硬件故障检测和保护
-
正交解码器:支持编码器接口
-
同步功能:多个eTMR可以同步工作
eTMR配置与初始化
// eTMR配置结构 typedef struct { uint32_t prescaler; // 预分频器 uint32_t period; // 周期值 uint32_t count_mode; // 计数模式 bool auto_reload; // 自动重载 uint32_t clock_source; // 时钟源 } etmr_config_t; // eTMR初始化 void etmr_init(eTMR_Type *etmr, etmr_config_t *config) { // 使能eTMR时钟 enable_etmr_clock(etmr); // 配置预分频器 etmr->PSC = config->prescaler; // 配置自动重载值 etmr->ARR = config->period; // 配置计数模式 etmr->CR1 = (etmr->CR1 & ~eTMR_CR1_CMS_MASK) | eTMR_CR1_CMS(config->count_mode); // 配置自动重载预装载 if (config->auto_reload) { etmr->CR1 |= eTMR_CR1_ARPE; } // 生成更新事件以加载配置 etmr->EGR |= eTMR_EGR_UG; // 清除更新标志 etmr->SR &= ~eTMR_SR_UIF; } // eTMR启动 void etmr_start(eTMR_Type *etmr) { etmr->CR1 |= eTMR_CR1_CEN; } // eTMR停止 void etmr_stop(eTMR_Type *etmr) { etmr->CR1 &= ~eTMR_CR1_CEN; }
PWM生成配置
// PWM配置结构 typedef struct { uint32_t channel; // PWM通道 uint32_t mode; // PWM模式 uint32_t polarity; // 输出极性 uint32_t duty_cycle; // 占空比 bool complementary_output; // 互补输出使能 uint32_t dead_time; // 死区时间 } etmr_pwm_config_t; // 配置PWM输出 void etmr_configure_pwm(eTMR_Type *etmr, etmr_pwm_config_t *config) { volatile uint32_t *ccmr_reg; volatile uint32_t *ccr_reg; // 选择对应的寄存器 if (config->channel <= 2) { ccmr_reg = &etmr->CCMR1; ccr_reg = &etmr->CCR1 + (config->channel - 1); } else { ccmr_reg = &etmr->CCMR2; ccr_reg = &etmr->CCR1 + (config->channel - 1); } // 配置PWM模式 uint32_t ccmr_shift = ((config->channel - 1) % 2) * 8; *ccmr_reg = (*ccmr_reg & ~(0xFF << ccmr_shift)) | (eTMR_CCMR_OCM_PWM1 << (ccmr_shift + 4)) | (eTMR_CCMR_OCPE << (ccmr_shift + 3)); // 设置比较值(占空比) *ccr_reg = config->duty_cycle; // 配置输出极性 if (config->polarity == eTMR_POLARITY_HIGH) { etmr->CCER &= ~(eTMR_CCER_CC1P << ((config->channel - 1) * 4)); } else { etmr->CCER |= (eTMR_CCER_CC1P << ((config->channel - 1) * 4)); } // 使能输出 etmr->CCER |= (eTMR_CCER_CC1E << ((config->channel - 1) * 4)); // 配置互补输出 if (config->complementary_output) { etmr->CCER |= (eTMR_CCER_CC1NE << ((config->channel - 1) * 4)); // 配置死区时间 etmr->BDTR = (etmr->BDTR & ~eTMR_BDTR_DTG_MASK) | eTMR_BDTR_DTG(config->dead_time); } // 使能主输出 etmr->BDTR |= eTMR_BDTR_MOE; } // 更新PWM占空比 void etmr_set_pwm_duty(eTMR_Type *etmr, uint32_t channel, uint32_t duty) { volatile uint32_t *ccr_reg = &etmr->CCR1 + (channel - 1); *ccr_reg = duty; } // 获取PWM占空比 uint32_t etmr_get_pwm_duty(eTMR_Type *etmr, uint32_t channel) { volatile uint32_t *ccr_reg = &etmr->CCR1 + (channel - 1); return *ccr_reg; }
输入捕获配置
// 输入捕获配置 typedef struct { uint32_t channel; // 捕获通道 uint32_t polarity; // 捕获极性 uint32_t selection; // 输入选择 uint32_t prescaler; // 输入预分频 uint32_t filter; // 输入滤波 } etmr_input_capture_config_t; void etmr_configure_input_capture(eTMR_Type *etmr, etmr_input_capture_config_t *config) { volatile uint32_t *ccmr_reg; // 选择对应的寄存器 if (config->channel <= 2) { ccmr_reg = &etmr->CCMR1; } else { ccmr_reg = &etmr->CCMR2; } // 配置输入捕获模式 uint32_t ccmr_shift = ((config->channel - 1) % 2) * 8; *ccmr_reg = (*ccmr_reg & ~(0xFF << ccmr_shift)) | (config->selection << ccmr_shift) | (config->prescaler << (ccmr_shift + 2)) | (config->filter << (ccmr_shift + 4)); // 配置捕获极性 if (config->polarity == eTMR_POLARITY_RISING) { etmr->CCER &= ~(eTMR_CCER_CC1P << ((config->channel - 1) * 4)); } else { etmr->CCER |= (eTMR_CCER_CC1P << ((config->channel - 1) * 4)); } // 使能捕获 etmr->CCER |= (eTMR_CCER_CC1E << ((config->channel - 1) * 4)); } // 读取捕获值 uint32_t etmr_get_capture_value(eTMR_Type *etmr, uint32_t channel) { volatile uint32_t *ccr_reg = &etmr->CCR1 + (channel - 1); return *ccr_reg; }
电机控制应用实例
三相BLDC电机控制
// BLDC电机控制结构 typedef struct { eTMR_Type *etmr; // 使用的eTMR实例 uint32_t pwm_frequency; // PWM频率 uint32_t dead_time; // 死区时间 uint16_t duty_cycle[3]; // 三相占空比 uint8_t hall_state; // 霍尔传感器状态 int32_t speed_rpm; // 转速(RPM) bool direction; // 旋转方向 } bldc_motor_t; // BLDC电机初始化 void bldc_motor_init(bldc_motor_t *motor) { // 配置eTMR基本参数 etmr_config_t etmr_cfg = { .prescaler = 0, .period = SystemCoreClock / motor->pwm_frequency - 1, .count_mode = eTMR_COUNT_MODE_CENTER_ALIGNED, .auto_reload = true, .clock_source = eTMR_CLOCK_INTERNAL }; etmr_init(motor->etmr, &etmr_cfg); // 配置三相PWM输出 for (uint32_t phase = 0; phase < 3; phase++) { etmr_pwm_config_t pwm_cfg = { .channel = phase * 2 + 1, // 通道1,3,5 .mode = eTMR_PWM_MODE1, .polarity = eTMR_POLARITY_HIGH, .duty_cycle = 0, .complementary_output = true, .dead_time = motor->dead_time }; etmr_configure_pwm(motor->etmr, &pwm_cfg); } // 配置霍尔传感器输入捕获 configure_hall_sensors(motor); // 启动eTMR etmr_start(motor->etmr); } // 六步换相表 static const uint8_t commutation_table[8][3] = { {0, 0, 0}, // 无效状态 {1, 0, 2}, // 霍尔状态1 {2, 1, 0}, // 霍尔状态2 {2, 0, 0}, // 霍尔状态3 {0, 2, 1}, // 霍尔状态4 {0, 0, 1}, // 霍尔状态5 {0, 1, 2}, // 霍尔状态6 {0, 0, 0} // 无效状态 }; // BLDC换相控制 void bldc_commutation(bldc_motor_t *motor, uint8_t hall_state) { const uint8_t *phase_state = commutation_table[hall_state]; for (uint32_t phase = 0; phase < 3; phase++) { uint32_t channel = phase * 2 + 1; switch (phase_state[phase]) { case 0: // 关闭 etmr_set_pwm_duty(motor->etmr, channel, 0); // 禁用互补输出 motor->etmr->CCER &= ~(eTMR_CCER_CC1E << (channel - 1) * 4); motor->etmr->CCER &= ~(eTMR_CCER_CC1NE << (channel - 1) * 4); break; case 1: // 上桥臂导通 etmr_set_pwm_duty(motor->etmr, channel, motor->duty_cycle[phase]); motor->etmr->CCER |= (eTMR_CCER_CC1E << (channel - 1) * 4); motor->etmr->CCER &= ~(eTMR_CCER_CC1NE << (channel - 1) * 4); break; case 2: // 下桥臂导通 etmr_set_pwm_duty(motor->etmr, channel, 0); motor->etmr->CCER &= ~(eTMR_CCER_CC1E << (channel - 1) * 4); motor->etmr->CCER |= (eTMR_CCER_CC1NE << (channel - 1) * 4); break; } } } // 霍尔传感器中断处理 void hall_sensor_interrupt_handler(bldc_motor_t *motor) { uint8_t new_hall_state = read_hall_sensors(); if (new_hall_state != motor->hall_state) { // 计算转速 static uint32_t last_time = 0; uint32_t current_time = get_system_time(); if (last_time > 0) { uint32_t time_diff = current_time - last_time; motor->speed_rpm = calculate_rpm(time_diff); } // 执行换相 bldc_commutation(motor, new_hall_state); motor->hall_state = new_hall_state; last_time = current_time; } }
步进电机控制
// 步进电机控制结构 typedef struct { eTMR_Type *etmr; // 定时器实例 uint32_t step_frequency; // 步进频率 uint32_t current_step; // 当前步数 uint32_t target_steps; // 目标步数 bool direction; // 方向 uint8_t step_mode; // 步进模式 } stepper_motor_t; // 步进电机波形表(全步进) static const uint8_t full_step_table[4] = { 0x09, // A+B- 0x05, // A+B+ 0x06, // A-B+ 0x0A // A-B- }; // 步进电机波形表(半步进) static const uint8_t half_step_table[8] = { 0x09, 0x01, 0x05, 0x04, 0x06, 0x02, 0x0A, 0x08 }; void stepper_motor_init(stepper_motor_t *stepper) { // 配置定时器用于步进脉冲生成 etmr_config_t etmr_cfg = { .prescaler = SystemCoreClock / 1000000 - 1, // 1MHz时钟 .period = 1000000 / stepper->step_frequency - 1, .count_mode = eTMR_COUNT_MODE_UP, .auto_reload = true, .clock_source = eTMR_CLOCK_INTERNAL }; etmr_init(stepper->etmr, &etmr_cfg); // 配置PWM输出用于相位控制 for (uint32_t phase = 0; phase < 4; phase++) { etmr_pwm_config_t pwm_cfg = { .channel = phase + 1, .mode = eTMR_PWM_MODE1, .polarity = eTMR_POLARITY_HIGH, .duty_cycle = 0, .complementary_output = false, .dead_time = 0 }; etmr_configure_pwm(stepper->etmr, &pwm_cfg); } // 使能更新中断 stepper->etmr->DIER |= eTMR_DIER_UIE; NVIC_EnableIRQ(eTMR0_IRQn); etmr_start(stepper->etmr); } // 步进电机中断处理 void stepper_motor_interrupt_handler(stepper_motor_t *stepper) { if (stepper->current_step < stepper->target_steps) { // 更新步进位置 if (stepper->direction) { stepper->current_step++; } else { stepper->current_step--; } // 更新相位输出 uint8_t step_index; if (stepper->step_mode == STEPPER_FULL_STEP) { step_index = stepper->current_step % 4; update_stepper_phases(stepper, full_step_table[step_index]); } else { step_index = stepper->current_step % 8; update_stepper_phases(stepper, half_step_table[step_index]); } } else { // 到达目标位置,停止 etmr_stop(stepper->etmr); } }
周期定时器(pTMR)应用
任务调度系统
// 任务调度结构 typedef struct { void (*task_function)(void); uint32_t period_ms; uint32_t last_run_time; bool enabled; } scheduled_task_t; // 任务调度器 typedef struct { pTMR_Type *ptmr; scheduled_task_t tasks[MAX_TASKS]; uint32_t task_count; uint32_t system_tick; } task_scheduler_t; void task_scheduler_init(task_scheduler_t *scheduler) { // 配置pTMR为1ms周期 scheduler->ptmr->MCR |= pTMR_MCR_EN; // 使能pTMR // 配置通道0为1ms定时 scheduler->ptmr->CH_TSV[0] = SystemCoreClock / 1000 - 1; // 1ms scheduler->ptmr->CH_TCR[0] |= pTMR_TCR_TEN | pTMR_TCR_TIE; // 使能定时器和中断 scheduler->system_tick = 0; scheduler->task_count = 0; NVIC_EnableIRQ(pTMR0_CH0_IRQn); } // 添加调度任务 bool add_scheduled_task(task_scheduler_t *scheduler, void (*task_func)(void), uint32_t period_ms) { if (scheduler->task_count >= MAX_TASKS) { return false; } scheduled_task_t *task = &scheduler->tasks[scheduler->task_count]; task->task_function = task_func; task->period_ms = period_ms; task->last_run_time = 0; task->enabled = true; scheduler->task_count++; return true; } // pTMR中断处理(1ms系统滴答) void pTMR0_CH0_IRQHandler(void) { task_scheduler_t *scheduler = get_task_scheduler(); // 清除中断标志 scheduler->ptmr->CH_TFR[0] |= pTMR_TFR_TIF; // 更新系统滴答 scheduler->system_tick++; // 检查并执行到期任务 for (uint32_t i = 0; i < scheduler->task_count; i++) { scheduled_task_t *task = &scheduler->tasks[i]; if (task->enabled && (scheduler->system_tick - task->last_run_time) >= task->period_ms) { task->task_function(); task->last_run_time = scheduler->system_tick; } } }
低功耗定时器(lpTMR)应用
低功耗唤醒系统
// 低功耗定时器配置 typedef struct { lpTMR_Type *lptmr; uint32_t wakeup_period_ms; bool pulse_counter_mode; void (*wakeup_callback)(void); } lptmr_wakeup_t; void lptmr_wakeup_init(lptmr_wakeup_t *wakeup) { // 选择时钟源(SXOSC 32.768kHz) wakeup->lptmr->PRS = (wakeup->lptmr->PRS & ~lpTMR_PRS_CLKSEL_MASK) | lpTMR_PRS_CLKSEL_SXOSC; // 配置预分频器 wakeup->lptmr->PRS = (wakeup->lptmr->PRS & ~lpTMR_PRS_PRES_MASK) | lpTMR_PRS_PRES_DIV1024; // 32Hz // 计算比较值 uint32_t compare_value = (wakeup->wakeup_period_ms * 32) / 1000; wakeup->lptmr->CMP = compare_value; // 配置为时间计数模式 wakeup->lptmr->CTRL &= ~lpTMR_CTRL_MODE; // 使能中断 wakeup->lptmr->DIE |= lpTMR_DIE_IE; NVIC_EnableIRQ(lpTMR0_IRQn); // 启动定时器 wakeup->lptmr->CTRL |= lpTMR_CTRL_EN; } // 进入低功耗模式 void enter_low_power_with_wakeup(lptmr_wakeup_t *wakeup) { // 配置唤醒定时器 lptmr_wakeup_init(wakeup); // 保存系统状态 save_system_context(); // 进入Standby模式 SCR |= SCR_SLEEPDEEP_Msk; __WFI(); // 唤醒后恢复 restore_system_context(); } // lpTMR中断处理 void lpTMR0_IRQHandler(void) { lptmr_wakeup_t *wakeup = get_lptmr_wakeup(); // 清除中断标志 wakeup->lptmr->STS |= lpTMR_STS_CCF; // 执行唤醒回调 if (wakeup->wakeup_callback) { wakeup->wakeup_callback(); } }
实时时钟(RTC)应用
时间管理系统
// RTC时间结构 typedef struct { uint8_t seconds; uint8_t minutes; uint8_t hours; uint8_t day; uint8_t month; uint16_t year; uint8_t weekday; } rtc_time_t; // RTC闹钟结构 typedef struct { rtc_time_t alarm_time; bool enabled; void (*alarm_callback)(void); } rtc_alarm_t; void rtc_init(void) { // 使能SXOSC作为RTC时钟源 SCU->SXOSC_CTRL |= SCU_SXOSC_CTRL_SXOSC_EN; while (!(SCU->STS & SCU_STS_SXOSC_VALID)); // 配置RTC时钟源 RTC->CR = (RTC->CR & ~RTC_CR_CLKSEL_MASK) | RTC_CR_CLKSEL_SXOSC; // 使能RTC RTC->CR |= RTC_CR_EN; // 等待同步 while (!(RTC->SR & RTC_SR_RDY)); } void rtc_set_time(rtc_time_t *time) { // 进入配置模式 RTC->CR |= RTC_CR_CFG; while (!(RTC->SR & RTC_SR_CFG)); // 设置时间寄存器 RTC->TSR = (time->seconds) | (time->minutes << 8) | (time->hours << 16) | (time->day << 24); RTC->TDR = (time->month) | (time->year << 8) | (time->weekday << 24); // 退出配置模式 RTC->CR &= ~RTC_CR_CFG; while (RTC->SR & RTC_SR_CFG); } void rtc_get_time(rtc_time_t *time) { uint32_t tsr = RTC->TSR; uint32_t tdr = RTC->TDR; time->seconds = tsr & 0xFF; time->minutes = (tsr >> 8) & 0xFF; time->hours = (tsr >> 16) & 0xFF; time->day = (tsr >> 24) & 0xFF; time->month = tdr & 0xFF; time->year = (tdr >> 8) & 0xFFFF; time->weekday = (tdr >> 24) & 0xFF; } // 设置RTC闹钟 void rtc_set_alarm(rtc_alarm_t *alarm) { // 配置闹钟时间 RTC->TAR = (alarm->alarm_time.seconds) | (alarm->alarm_time.minutes << 8) | (alarm->alarm_time.hours << 16) | (alarm->alarm_time.day << 24); // 使能闹钟中断 if (alarm->enabled) { RTC->IER |= RTC_IER_TAIE; NVIC_EnableIRQ(RTC_IRQn); } }
定时器同步与级联
多定时器同步
// 定时器同步配置 typedef struct { eTMR_Type *master_timer; eTMR_Type *slave_timers[4]; uint32_t slave_count; uint32_t sync_mode; } timer_sync_config_t; void configure_timer_synchronization(timer_sync_config_t *sync_cfg) { // 配置主定时器 sync_cfg->master_timer->CR2 |= eTMR_CR2_MMS_UPDATE; // 更新事件作为触发输出 // 配置从定时器 for (uint32_t i = 0; i < sync_cfg->slave_count; i++) { eTMR_Type *slave = sync_cfg->slave_timers[i]; // 配置触发输入 slave->SMCR = (slave->SMCR & ~eTMR_SMCR_TS_MASK) | eTMR_SMCR_TS_ITR0; // 内部触发0 // 配置从模式 slave->SMCR = (slave->SMCR & ~eTMR_SMCR_SMS_MASK) | eTMR_SMCR_SMS_TRIGGER; // 触发模式 } // 同时启动所有定时器 sync_cfg->master_timer->CR1 |= eTMR_CR1_CEN; }
性能优化与调试
定时器性能监控
// 定时器性能统计 typedef struct { uint32_t interrupt_count; uint32_t max_interrupt_latency; uint32_t avg_interrupt_latency; uint32_t overflow_count; } timer_performance_stats_t; void monitor_timer_performance(eTMR_Type *etmr, timer_performance_stats_t *stats) { static uint32_t last_interrupt_time = 0; uint32_t current_time = get_system_time(); if (etmr->SR & eTMR_SR_UIF) { stats->interrupt_count++; // 计算中断延迟 if (last_interrupt_time > 0) { uint32_t latency = current_time - last_interrupt_time; if (latency > stats->max_interrupt_latency) { stats->max_interrupt_latency = latency; } // 更新平均延迟 stats->avg_interrupt_latency = (stats->avg_interrupt_latency + latency) / 2; } last_interrupt_time = current_time; etmr->SR &= ~eTMR_SR_UIF; // 清除标志 } // 检查溢出 if (etmr->SR & eTMR_SR_UIF) { stats->overflow_count++; } } // 定时器调试信息 void debug_timer_status(eTMR_Type *etmr) { printf("Timer Debug Information:\n"); printf("CR1: 0x%08X\n", etmr->CR1); printf("SR: 0x%08X\n", etmr->SR); printf("CNT: %d\n", etmr->CNT); printf("ARR: %d\n", etmr->ARR); printf("PSC: %d\n", etmr->PSC); for (int i = 0; i < 4; i++) { printf("CCR%d: %d\n", i+1, (&etmr->CCR1)[i]); } }
总结
YTM32B1ME0x的定时器系统为汽车电子应用提供了全面而强大的时序控制解决方案。通过合理配置和使用各种定时器资源,可以实现精确的PWM控制、电机驱动、任务调度等功能。
关键优势:
-
丰富的定时器资源:多种类型定时器满足不同应用需求
-
强大的PWM功能:支持互补输出、死区控制、故障保护
-
灵活的配置选项:多种计数模式、时钟源、触发方式
-
低功耗支持:lpTMR支持低功耗模式下的定时功能
-
同步能力:多定时器可以同步工作
最佳实践建议:
-
根据应用需求选择合适的定时器类型
-
合理配置PWM频率和死区时间
-
实施定时器性能监控和调试
-
在电机控制中充分利用硬件保护功能
-
优化中断处理以减少系统开销
在下一篇文章中,我们将深入探讨YTM32B1ME0x的模拟外设,包括ADC、DAC、比较器等,了解如何实现精确的模拟信号处理。
本文是YTM32B1ME0x芯片深度解读系列的第六篇,详细介绍了定时器系统的架构设计和PWM控制应用。