feat(ADC): 重构ADC采样系统以支持同步电流采集

- 将ADC缓冲区从6通道减少到3通道,专门用于MCU温度、DRV温度和VBUS监测
- 实现了注入组ADC同步采样,通过TIMER1 TRGO触发三相电流同时采样
- 添加了PWM中心对齐模式以提供更好的采样窗口
- 在FOC控制器中增加了ADC错误检查和三相公共模偏置消除
- 优化了电流采样更新机制,使用中断驱动的数据搬运
- 调整了ADC通道配置,规则组用于后台温度/VBUS采样,注入组用于PWM同步电流采样
This commit is contained in:
cbb
2026-05-16 13:09:57 +08:00
parent 12b2577d6b
commit c6e00e1a49
4 changed files with 116 additions and 78 deletions
+12 -15
View File
@@ -10,7 +10,7 @@
#include "initial.h"
volatile u32 total_us100_counter = 0; // 总计数器,每 100 微秒增加 1
extern u16 adc_value[7];
extern u16 adc_value[3];
extern FOC_Controller FOC;
extern TaskScheduler scheduler;
extern CAN_transmiter CAN0_transmiter;
@@ -59,6 +59,7 @@ void nvic_config(void) {
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
/* 使能 TIMER2 中断,设置抢占优先级为 1,子优先级为 1 */
nvic_irq_enable(TIMER2_IRQn, 0, 1);
nvic_irq_enable(ADC0_1_IRQn, 0, 0);
nvic_irq_enable(TIMER1_IRQn, 0, 2);
}
@@ -216,7 +217,8 @@ void timer1_pwm_config(void) {
// 配置 TIMER1 基本参数
timer_struct_para_init(&timer_initpara);
timer_initpara.prescaler = TIMER1_PRESCALER; // 预分频器
timer_initpara.counterdirection = TIMER_COUNTER_UP; // 向上计数
timer_initpara.alignedmode = TIMER_COUNTER_CENTER_BOTH; // 中心对齐,给采样留对称平台窗
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = TIMER1_PERIOD; // 计数周期
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_init(TIMER1, &timer_initpara);
@@ -231,9 +233,9 @@ 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% 位置触发中断
// 配置第四个通道 (CH3) 为固定采样点,只用于导出 ADC 触发
timer_ocinitpara.outputstate =
TIMER_CCX_DISABLE; // 不输出 PWM 波形,仅用于触发中断
TIMER_CCX_DISABLE; // 不输出 PWM 波形,仅用于比较事件
timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_channel_output_config(TIMER1, TIMER_CH_3, &timer_ocinitpara);
@@ -244,13 +246,16 @@ void timer1_pwm_config(void) {
timer_channel_output_mode_config(TIMER1, TIMER_CH_3,
TIMER_OC_MODE_PWM0); // CH3 也设为 PWM 模式
/* 将 CH3 预装载比较点作为 TRGO 导出,供 ADC injected 组同步采样 */
timer_master_output_trigger_source_select(TIMER1, TIMER_TRI_OUT_SRC_O3CPRE);
timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_0,
TIMER1_DEFAULT_PULSE);
timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1,
TIMER1_DEFAULT_PULSE);
timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_2,
TIMER1_DEFAULT_PULSE);
// 设置 CH3 比较值为 PWM 周期 x% 位置
// 设置 CH3 为固定 ADC 采样点,避免与三相 PWM duty 耦合
timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_3,
TIMER1_CH3_COMPARE_VALUE);
@@ -258,26 +263,18 @@ void timer1_pwm_config(void) {
timer_primary_output_config(TIMER1, ENABLE);
timer_auto_reload_shadow_enable(TIMER1);
// 使能 CH3 比较中断
timer_interrupt_enable(TIMER1, TIMER_INT_CH3);
// 启动 TIMER1
timer_enable(TIMER1);
}
// 添加 TIMER1-PWM 中断处理函数
// CH3 现在仅作为 TRGO 采样点保留;采样完成由 ADC injected 中断接管
/**
* @brief TIMER1 中断处理函数
* @return void
*/
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);
// 例如触发 ADC 采样或其他操作
}
}
@@ -313,4 +310,4 @@ void Set_3Pwm(float duty_cycle0, float duty_cycle1, float duty_cycle2) {
TIMER_CH0CV(TIMER1) = (uint32_t)(duty_cycle0 * TIMER1_PERIOD);
TIMER_CH1CV(TIMER1) = (uint32_t)(duty_cycle1 * TIMER1_PERIOD);
TIMER_CH2CV(TIMER1) = (uint32_t)(duty_cycle2 * TIMER1_PERIOD);
}
}