这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » LAUNCHXL-F280049C+实现的是数字电源的控制1

共1条 1/1 1 跳转至

LAUNCHXL-F280049C+实现的是数字电源的控制1

高工
2025-07-15 09:35:52     打赏

本程序主要还是要实现的是数字电源的控制,主要使用到的是epwm+compare+CLA+Sci fifo,控制的方式是电压电流双环的模式,将外环电压环的运行放在定时器中执行(执行的频率是65kHz),内环电流环的执行频率是 185kHz,为我将其放在了CLA中执行。

电源的过流方式是是使用OST模式,使用DAC级联compare级联epwm模式进行pwm的关断。使用两组epwm波产生两组互补带死去的PWM波来进行逆变的驱动。使用一组pwm波进行Buck开关管的控制。OST的触发挂在Buck的这组PWM波上

通讯上使用SCI+FIFO的方式进行通讯。将需要发送的数据装填到FIFO中,达到一定的容量之后再进行数据的发送,这样可以避免频繁的进入到发送中断当中去。使用modbus 的通信方式,便于程序后期的上板调试。


1.     定时器和CLA部分

使用C2000微控制器CLA(控制律加速器)配置界面。

bb2d95a2-5c29-422c-8242-60f355da471c.png


说明:

CLA模块核心功能

多任务并行调度

8个独立任务(Task 1-8)可同时启用,每个任务支持:

专用中断向量(如CLA_MVECT_1对应Task1)。

独立触发源(如ADCB1触发Task1)。

优先级配置(通过中断向量号隐式定义)。


硬件加速控制算法

实时计算:CLA作为协处理器,独立于主CPU运行PID、FOC等算法。

低延迟响应:中断触发到任务执行的延迟<100ns(典型值)。


 外设直接交互

数据输入:直接从ADC(如ADCB1)获取采样数据,无需CPU介入。

输出控制:通过PWM/XBAR模块直接驱动功率器件。


配置界面关键操作

 全局参数设置

时钟分频:调节CLA内核时钟(与主CPU时钟同步/异步)。

内存保护:配置CLA代码/数据区的访问权限。

任务级配置

中断绑定:为每个任务选择触发源(如EPWM、ADC、GPIO)。

代码链接:指定任务函数入口(如Cla1Task1对应汇编/C函数)。

 资源管理

寄存器映射:查看CLA专用寄存器(如MR0-MR3)的分配状态。

共享内存:配置CLA与主CPU的数据交换缓冲区。


CLA sysconfig代码配置

// Loop1控制任务定义在共享文件中,供CPU和CLA共同调用,避免代码重复
static inline void loop1_task(void) {
    // GCK注释:使用过采样(4次采样取平均)降低ADC噪声
    sense_data.loop1 = (ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER0) + 
                        ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER1) + 
                        ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER2) + 
                        ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER3)) >> 2;  // 右移2位等效于除以4

    // 仅在软件标志位完成且模式开关为1时执行控制(安全条件判断)
    if ((soft_Flag_Finish == 1) && (MODE_SWITCH == 1)) {
        // GCK注释:使用位置式PID计算电流环输出,内部已做输出限幅
        // 输入:PID结构体指针、电流参考值、实际电流值(0.04 * 3.3为电压系数,4096为ADC满量程)
        control_out_data.loop1 = Dcl_runPI_L4(&pi_loop1, 
                                            ref_data.loop1, 
                                            (0.04f * 3.30f * (sense_data.loop1 / 4096.0f)));

        // 计算PWM占空比(1.0f为比例系数,可根据硬件调整)
        duty_loop1 = 1.0f * control_out_data.loop1;

        // 将控制输出存入缓冲区(用于后续分析或调试)
        duty_buffer[cnt] = control_out_data.loop1;
        cnt++;

        // 每3次中断计算一次移动平均值(进一步平滑输出)
        if (cnt == 3) {
            cnt = 0;
            // 可在此添加平均值计算逻辑(如:duty_avg = (duty_buffer[0]+duty_buffer[1]+duty_buffer[2])/3)
        }
    }
}

9acd3cd6-5ea1-4043-9cc1-597c8f3a7815.png


 求和与PWM占空比更新逻辑代码

// ==== 高效求均值与饱和处理 ====
// 1. 计算3次中断的占空比总和(避免多次除法提升效率)
sum = duty_buffer[0] + duty_buffer[1] + duty_buffer[2];

// 2. 使用乘法替代除法求均值(0.333f ≈ 1/3,编译器可能优化为快速浮点乘)
average_duty = sum * 0.333f;

// 3. 上下限饱和保护(防止PWM占空比超限)
average_duty = (average_duty > 0.9f) ? 0.8f : average_duty;  // 超上限时强制降为80%
average_duty = (average_duty < 0.1f) ? 0.1f : average_duty;   // 超下限时锁定10%

// ==== PWM占空比更新 ====
// 4. 更新EPWM1的COMPA寄存器(互补PWM场景)
//    公式:(1.0f - duty) * PERIOD 用于生成互补对称波形(如H桥驱动)
EPWM_setCounterCompareValue(
    EPWM1_BASE, 
    EPWM_COUNTER_COMPARE_A,
    (uint16_t)((1.0f - average_duty) * EPWM1_PERIOD)  // 硬件自动重装载
);

// 5. 更新BUCK变换器的PWM占空比(非互补模式)
//    直接写入占空比(占空比 = 高电平时间 / 周期)
EPWM_setCounterCompareValue(
    BUCK_BASE, 
    EPWM_COUNTER_COMPARE_A,
    (uint16_t)(average_duty * BUCK_PERIOD)  // 如BUCK_PERIOD=1000,duty=0.5 → 500
);


db233d85-8591-4878-9282-ef0cd1916c66.png


CLA的中断函数

CLA的触发源为ADCB1定时器,我的ADCB1采样的是Buck上的电流。


 ADC_BUCK_VoI 和 ADC_PFC_VoI_In 的配置信息

144df5ff-44fc-496f-9d61-417a8af3f960.png

多通道高优先级采样

双通道独立配置,ADC_BUCK_VoI:用于BUCK变换器输出电压采样。ADC_PFC_VoI_In:用于PFC(功率因数校正)输入电压/电流采样。

高优先级模式(High Priority Mode SOCs),确保关键信号的采样实时性,抢占普通ADC任务资源。

硬件触发与中断协同

触发源灵活配置,通过 Start of Conversion Configurations 绑定PWM或GPIO触发信号。

中断驱动处理,使能 ADC Interrupt 2(INT_ADC_BUCK_VoI2),触发后执行 loop2ISR 服务程序。脉冲模式(Pulse Mode):中断仅触发一次,需重新使能(降低CPU负载)。


电压采样ADC中断的配置

ADC中断服务程序

interrupt void loop2ISR(void) {
    // 1. 测试IO(调试用,可注释掉)
    GPIO_writePin(myGPIO0, 1);  // 触发示波器捕获中断时刻

    // 2. 读取4次ADC过采样结果并求平均(降噪)
    sense_data.loop2 = (ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0) + 
                        ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER1) + 
                        ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER2) + 
                        ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER3)) >> 2;  // 右移2位等效于除以4

    // 3. 电压值计算(两种等效方式)
    // 方式1:分步计算(清晰但稍慢)
    control_out_data.voltage = (float)(((sense_data.loop2 / 4096.0f) * 3.3f) * 0.801f) * 235000.0f;
    // 方式2:合并系数(快速版,0.1893f = 3.3 * 0.801 * 235000/4096)
    control_out_data.voltage = (float)(sense_data.loop2 * 0.1893f);

    // 4. 软启动完成且模式开关为恒压模式时执行控制
    if ((soft_Flag_Finish == 1) && (MODE_SWITCH == 1)) {
        // 外环电压控制(Type3控制器输出)
        control_out_data.loop2 = type3_control(ref_data.loop2, control_out_data.voltage);

        // 5. 电流环参考值计算(补偿-0.15V并限流)
        // 优化:用整数运算避免浮点耗时(3us -> 0.5us)
        ref_data.loop1 = (100 * control_out_data.loop2 - 15) * 0.01f;  // 等效于 (loop2 - 0.15)

        // 注:电流环限流已在type3_control()内部实现,此处无需重复
    }

    // 6. 清除中断标志(根据硬件手册要求)
    ADC_clearInterrupt(ADCARESULT_BASE, ADC_INT_NUMBER2);
    GPIO_writePin(myGPIO0, 0);  // 调试IO复位
}

a7a2fd04-3dbe-4c1c-954e-6afea60b6a39.png


// 空行或注释行(图中未显示具体内容)

// 内环电流参考值(ref_data.loop1)的限幅处理
// - 上限保护:超过40.0时钳位到60.0(防止过流损坏硬件)
// - 下限保护:低于1.0时钳位到1.0(维持最小工作电流)
ref_data.loop1 = (ref_data.loop1 > 40.0f) ? 60.0f : ref_data.loop1;  // 上限60.0A
ref_data.loop1 = (ref_data.loop1 < 1.0f) ? 1.0f : ref_data.loop1;    // 下限1.0A


// 调试GPIO复位(标记中断结束)
GPIO_writePin(myGPIO0, 0);  // 拉低GPIO电平,用于示波器测量中断执行时间

// 清除ADC中断标志位
ADC_clearInterruptStatus(ADC_BUCK_VoL_BASE, ADC_INT_NUMBER1);  // 清除ADC模块中断标志

// 清除PIE中断组应答标志
Interrupt_clearACKGroup(INT_ADC_BUCK_VoL_2_INTERRUPT_ACK_GROUP);  // 允许后续中断触发


// 重新使能全局中断(若之前有禁用)
EINT;  // 等效于 __enable_irq()(恢复中断响应)

cefeb0fb-4576-4058-95ff-7878c31ffc00.png


电压采样ADC中断函数

这里使用ADCB的中断来进行电压环type3控制器函数的运算。


CLA执行时序和ADC中断执行时序逻辑分析仪测试

60e9aa85-e8f4-431e-aba4-88cd36c5a348.png

上图中,第一个通道是CLA执行的时序,第二个通道是ADC中断执行的时序,基本上CLA执行三次,ADC中断执行一次,这样可以保证我内环电流环的运行频率比外环电压环的频率快。




共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]