From a7a380583962c674ce0cce08f14187d3b75a06cc Mon Sep 17 00:00:00 2001 From: cbb <2625274797@qq.com> Date: Sat, 22 Nov 2025 02:21:33 +0800 Subject: [PATCH] =?UTF-8?q?feat(ADC):=20=E7=94=B5=E6=B5=81=E9=87=87?= =?UTF-8?q?=E6=A0=B7=E6=94=AF=E6=8C=81=E8=B4=9F=E6=95=B0=20=E5=B0=86=20CUR?= =?UTF-8?q?RENT=5FOFFSET=20=E4=BB=8E=200=20=E4=BF=AE=E6=94=B9=E4=B8=BA=20-?= =?UTF-8?q?1.60f=20=E4=BB=A5=E6=A0=A1=E5=87=86=E7=94=B5=E6=B5=81=E9=87=87?= =?UTF-8?q?=E6=A0=B7=E5=81=8F=E5=B7=AE=E3=80=82=20=E5=90=8C=E6=97=B6?= =?UTF-8?q?=E5=B0=86=20ADC=20=E8=A7=84=E5=88=99=E9=80=9A=E9=81=93=E7=9A=84?= =?UTF-8?q?=E9=87=87=E6=A0=B7=E6=97=B6=E9=97=B4=E4=BB=8E=2055.5=20?= =?UTF-8?q?=E5=91=A8=E6=9C=9F=E8=B0=83=E6=95=B4=E4=B8=BA=2028.5=20?= =?UTF-8?q?=E5=91=A8=E6=9C=9F=EF=BC=8C=E6=8F=90=E9=AB=98=E9=87=87=E6=A0=B7?= =?UTF-8?q?=E5=93=8D=E5=BA=94=E9=80=9F=E5=BA=A6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat(timer): 新增 TIMER1 中断及 PWM 周期位置触发功能 新增 TIMER1_CH3 用于在 PWM 周期特定位置(如 50%)触发中断,并配置相关 NVIC 和中断处理逻辑。 修改 TIMER3 的定时周期注释与实际值一致,为 50 微秒。 重新组织 TIMER2 中断中的任务调度顺序,提升执行效率和逻辑清晰度。 refactor(main): 重构主循环任务处理顺序 调整 main.cpp 中任务执行顺序,确保高优先级任务及时处理。 将部分传感器更新任务移动至更合理的位置,保证数据同步性和控制实时性。 --- Robot_V2/device/ADC.cpp | 12 ++++----- Robot_V2/device/Timer.cpp | 55 +++++++++++++++++++++++++++++++++------ Robot_V2/device/Timer.h | 4 ++- Robot_V2/main.cpp | 28 ++++++++++---------- 4 files changed, 70 insertions(+), 29 deletions(-) diff --git a/Robot_V2/device/ADC.cpp b/Robot_V2/device/ADC.cpp index 4b9d56a..374ee10 100644 --- a/Robot_V2/device/ADC.cpp +++ b/Robot_V2/device/ADC.cpp @@ -11,7 +11,7 @@ constexpr float ADC_SCALE = 3.3f / 4096.0f; constexpr float TEMP_FACTOR = 1000.0f / 4.3f; constexpr float VCC_FACTOR = 11.0f; // constexpr float CURRENT_OFFSET = 0 - 4096.0f / 2.0f; -constexpr float CURRENT_OFFSET = 0; +constexpr float CURRENT_OFFSET = -1.60f; constexpr float CURRENT_FACTOR = 1.0f / 50.0f * 100.0f; // 50倍放大,100倍电流采样电阻, 单位mA constexpr float MAX_TEMP = 150.0f; @@ -86,11 +86,11 @@ void adc_config(void) { /* 配置ADC规则通道 */ adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_16, ADC_SAMPLETIME_239POINT5); - adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_9, ADC_SAMPLETIME_55POINT5); - adc_regular_channel_config(ADC0, 2, ADC_CHANNEL_3, ADC_SAMPLETIME_55POINT5); - adc_regular_channel_config(ADC0, 3, ADC_CHANNEL_4, ADC_SAMPLETIME_55POINT5); - adc_regular_channel_config(ADC0, 4, ADC_CHANNEL_5, ADC_SAMPLETIME_55POINT5); - adc_regular_channel_config(ADC0, 5, ADC_CHANNEL_6, ADC_SAMPLETIME_55POINT5); + adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_9, ADC_SAMPLETIME_28POINT5); + adc_regular_channel_config(ADC0, 2, ADC_CHANNEL_3, ADC_SAMPLETIME_28POINT5); + adc_regular_channel_config(ADC0, 3, ADC_CHANNEL_4, ADC_SAMPLETIME_28POINT5); + adc_regular_channel_config(ADC0, 4, ADC_CHANNEL_5, ADC_SAMPLETIME_28POINT5); + adc_regular_channel_config(ADC0, 5, ADC_CHANNEL_6, ADC_SAMPLETIME_28POINT5); /* ADC触发配置 */ adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, diff --git a/Robot_V2/device/Timer.cpp b/Robot_V2/device/Timer.cpp index d485404..b871816 100644 --- a/Robot_V2/device/Timer.cpp +++ b/Robot_V2/device/Timer.cpp @@ -11,7 +11,6 @@ #include #include - constexpr int TIMER2_PRESCALER = 119; // 120MHz / 120 = 1MHz constexpr int TIMER2_PERIOD = 99; // 1MHz / 100 = 100us constexpr int TIMER3_PRESCALER = 119; // 120MHz / 120 = 1MHz @@ -22,6 +21,8 @@ constexpr int TIMER1_PERIOD = 5999; // 120MHz / (0+1) / (5999+1) = 20kHz constexpr int TIMER1_CH0_PULSE = 0; constexpr int TIMER1_CH1_PULSE = 0; constexpr int TIMER1_CH2_PULSE = 0; +constexpr int TIMER1_CH3_COMPARE_VALUE = + (TIMER1_PERIOD + 1) * 0.5 - 1; // PWM周期50%位置触发中断 static u32 total_us100_counter = 0; // 总计数器,每100微秒增加1 extern u16 adc_value[7]; @@ -42,6 +43,8 @@ void nvic_config(void) { /* 使能TIMER2中断,设置抢占优先级为1,子优先级为1 */ nvic_irq_enable(TIMER2_IRQn, 1, 1); nvic_irq_enable(TIMER3_IRQn, 1, 2); + nvic_irq_enable(TIMER1_IRQn, 2, + 1); // 使能TIMER1中断,抢占优先级2,子优先级1 } /** @@ -94,8 +97,8 @@ void TIMER2_config(void) { void TIMER3_config(void) { /* ---------------------------------------------------------------------------- TIMER3 Configuration: - TIMER3CLK = SystemCoreClock/120 = 1MHz, the period is 10ms(10000/1000000 = - 10ms). + TIMER3CLK = SystemCoreClock/120 = 1MHz, the period is 50us(50/1000000 = + 50us). ---------------------------------------------------------------------------- */ timer_parameter_struct timer_struct; @@ -113,7 +116,7 @@ void TIMER3_config(void) { timer_struct.alignedmode = TIMER_COUNTER_EDGE; /* 边沿对齐模式 */ timer_struct.counterdirection = TIMER_COUNTER_UP; /* 向上计数模式 */ timer_struct.period = - TIMER3_PERIOD; /* 自动重装载值:10000次计数(从0开始计数) */ + TIMER3_PERIOD; /* 自动重装载值:50次计数(从0开始计数) */ timer_struct.clockdivision = TIMER_CKDIV_DIV1; /* 时钟分频值:1分频 */ timer_init(TIMER3, &timer_struct); @@ -158,13 +161,12 @@ void TIMER2_IRQHandler(void) { // 每100us执行一次的操作 total_us100_counter++; - scheduler.taskFlags |= - (1 << TASK_CURRENT_UPDATE) | (1 << TASK_ANGLE_UPDATE) | - (1 << TASK_VELOCITY_UPDATE) | (1 << TASK_MOTOR_CONTROL); + scheduler.taskFlags |= (1 << TASK_ANGLE_UPDATE) | + (1 << TASK_VELOCITY_UPDATE) | + (1 << TASK_MOTOR_CONTROL); switch (total_us100_counter) { // 每1ms执行的代码,负载均衡 case 1: { - mode = FOC.control_mode; scheduler.taskFlags |= (1 << TASK_MCU_TEMP_UPDATE); break; } @@ -180,6 +182,10 @@ void TIMER2_IRQHandler(void) { scheduler.taskFlags |= (1 << TASK_CAN_TRANSMIT); break; } + case 9: { + mode = FOC.control_mode; + break; + } } if (total_us100_counter >= 10) { total_us100_counter = 0; @@ -304,10 +310,18 @@ void timer1_pwm_config(void) { timer_channel_output_config(TIMER1, TIMER_CH_1, &timer_ocinitpara); timer_channel_output_config(TIMER1, TIMER_CH_2, &timer_ocinitpara); + // 配置第四个通道(CH3)用于在PWM周期x%位置触发中断 + timer_ocinitpara.outputstate = + TIMER_CCX_DISABLE; // 不输出PWM波形,仅用于触发中断 + timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_channel_output_config(TIMER1, TIMER_CH_3, &timer_ocinitpara); + // 设置PWM模式和占空比 timer_channel_output_mode_config(TIMER1, TIMER_CH_0, TIMER_OC_MODE_PWM0); timer_channel_output_mode_config(TIMER1, TIMER_CH_1, TIMER_OC_MODE_PWM0); timer_channel_output_mode_config(TIMER1, TIMER_CH_2, TIMER_OC_MODE_PWM0); + timer_channel_output_mode_config(TIMER1, TIMER_CH_3, + TIMER_OC_MODE_PWM0); // CH3也设为PWM模式 timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_0, TIMER1_CH0_PULSE); @@ -315,15 +329,40 @@ void timer1_pwm_config(void) { TIMER1_CH1_PULSE); timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_2, TIMER1_CH2_PULSE); + // 设置CH3比较值为PWM周期x%位置 + timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_3, + TIMER1_CH3_COMPARE_VALUE); // 使能主输出和自动重载 timer_primary_output_config(TIMER1, ENABLE); timer_auto_reload_shadow_enable(TIMER1); + // 使能CH3比较中断 + timer_interrupt_enable(TIMER1, TIMER_INT_CH3); + nvic_irq_enable(TIMER1_IRQn, 0, + 2); // 使能TIMER1中断,抢占优先级2,子优先级1 + // 启动TIMER1 timer_enable(TIMER1); } +// 添加TIMER1中断处理函数 +/** + * @brief TIMER1中断处理函数 + * @return void + */ +extern "C" void TIMER1_IRQHandler(void) { + // 检查CH3比较中断标志并处理 + if (timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH3) != RESET) { + // 清除CH3比较中断标志 + timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_CH3); + + scheduler.taskFlags |= (1 << TASK_CURRENT_UPDATE); + // 在这里添加需要在PWM周期90%位置执行的代码 + // 例如触发ADC采样或其他操作 + } +} + /*! \brief set PWM \param[in] channel: TIMER_CH_0/TIMER_CH_1/TIMER_CH_2/TIMER_CH_3 (valid diff --git a/Robot_V2/device/Timer.h b/Robot_V2/device/Timer.h index 91b8116..908dd70 100644 --- a/Robot_V2/device/Timer.h +++ b/Robot_V2/device/Timer.h @@ -16,6 +16,8 @@ void TIMER3_IRQHandler(void); void timer1_pwm_config(void); void timer1_gpio_config(void); +void TIMER1_IRQHandler(void); // 添加TIMER1中断处理函数声明 + /* 获取系统运行时间 */ uint64_t get_system_runtime_us(void); @@ -24,4 +26,4 @@ uint64_t get_system_runtime_us(void); } #endif -#endif +#endif \ No newline at end of file diff --git a/Robot_V2/main.cpp b/Robot_V2/main.cpp index 80bf9bc..cc50189 100644 --- a/Robot_V2/main.cpp +++ b/Robot_V2/main.cpp @@ -41,6 +41,16 @@ int main(void) { scheduler.taskFlags &= ~currentTasks; // 按照优先级和重要性处理任务 + if (currentTasks & (1 << TASK_CURRENT_UPDATE)) { // 更新电流采样值 + sampler.update_current(); + } + if (currentTasks & (1 << TASK_ANGLE_UPDATE)) { // 更新角度传感器值 + KTH7823.update(); + FOC.rt_angle = KTH7823.getAngle(); + } + if (currentTasks & (1 << TASK_VELOCITY_UPDATE)) { // 更新速度传感器值 + FOC.rt_velocity = Vel_kalman.update(KTH7823.getVelocity()); + } if (currentTasks & (1 << TASK_MOTOR_CONTROL)) { // 电机控制任务(最高优先级) switch (FOC.control_mode) { @@ -65,20 +75,6 @@ int main(void) { } } } - if (currentTasks & (1 << TASK_CURRENT_UPDATE)) { // 更新电流采样值 - sampler.update_current(); - } - if (currentTasks & (1 << TASK_ANGLE_UPDATE)) { // 更新角度传感器值 - KTH7823.update(); - FOC.rt_angle = KTH7823.getAngle(); - } - if (currentTasks & (1 << TASK_VELOCITY_UPDATE)) { // 更新速度传感器值 - FOC.rt_velocity = Vel_kalman.update(KTH7823.getVelocity()); - } - if (currentTasks & (1 << TASK_VBUS_UPDATE)) { // 更新vbus电压值 - sampler.update_vbus_voltage(); - FOC.update_power(); - } if (currentTasks & (1 << TASK_MCU_TEMP_UPDATE)) { // 更新mcu温度传感器值 sampler.update_mcu_temp(); } @@ -89,6 +85,10 @@ int main(void) { if (currentTasks & (1 << TASK_THERMAL_CONTROL)) { // 热量控制 CAN0_transmiter.testfloat_union.f = thermalController.update(); } + if (currentTasks & (1 << TASK_VBUS_UPDATE)) { // 更新vbus电压值 + sampler.update_vbus_voltage(); + FOC.update_power(); + } if (currentTasks & (1 << TASK_CAN_TRANSMIT)) { // CAN通信 CAN0_transmiter.can0_send_flag = SET; CAN0_transmiter.communication_check();