问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

基于开源项目HAL STM32F4 +DSP库跑SVPWM开环速度测试

创作时间:
作者:
@小白创作中心

基于开源项目HAL STM32F4 +DSP库跑SVPWM开环速度测试

引用
CSDN
1.
https://blog.csdn.net/weixin_42880082/article/details/139278776

HAL STM32F4 +ARM DSP库跑SVPWM开环速度测试

本篇硬件电路和代码来源于开源项目:
https://github.com/MengYang-x/STM3F401-FOC/tree/main

硬件电路和项目介绍可以在立创开源广场查看:
https://oshwhub.com/shadow27/tai-yang-neng-wu-ren-chuan

测试效果

移植到STM32F446上,采用自制电机驱动板,采用EG3112,上下桥臂采用高电平驱动控制。

通过输出的三路马鞍波波形:

原作者介绍过的内容,这里就不多做介绍了,详情可以前往立创开源主页了解详情。程序这一块,主要针对stm32F4系列。

测试条件

  • STM32F4或者M4内核的相关型号的mcu即可。工程时基于HAL库STM32CubeMX生产的配置工程,移植非常简单。
  • 对于 Cortex-M0 或者 M3 处理器类型,由于没有 FPU 因此无法直接进行浮点运算,只能将浮点数进行Q 规格化(q7、q15 或 Q31)处理,如开平方运算:M0/M3 只能通过迭代法(标准数学函数库)计算,而 M4F直接调用 VSQRT 指令完成。
  • 如果手上只有stm32f1系列的,可以参考《SimpleFOC移植STM32(二)—— 开环控制》实现控制。
  • 或者参考另外一篇文章《HAL STM32F1 通过查表方式实现SVPWM驱动无刷电机测试》

硬件支持条件

  • MCU需要支持浮点运算(FPU)功能。
  • 一块无刷电机驱动板。(可以参考原作者的硬件。)
  • 由于原作者使用的是EG2133驱动芯片,驱动电路中上下桥是连一块的,3路PWM输出即可实现无刷电机转动,如果自己使用的是上下桥独立驱动(6路输出控制),那么需要将定时器的PWM输出通道配置为互补输出通道,(即3路互补输出),同时需要注意输出极性。

必要驱动文件

  • SVPWM开环速度测试,没有使用到,可以屏蔽掉:

  • DSP库文件,可以自己从安装的Keil软件ARM文件夹内找到相关驱动库文件:例如:
    D:\Keil_v5\ARM\CMSIS\DSP_Lib\Source\FastMathFunctions
    或者在
    STM32CubeMX
    ,安装的对应pack包解压文件夹内,:
    C:\Users\Administrator\STM32Cube\Repository\STM32Cube_FW_F4_V1.28.0\Drivers\CMSIS\DSP\Source
    或者标准库
    STM32F4xx_DSP_StdPeriph_Lib_V1.9.0\Libraries\CMSIS\DSP_Lib
    中找到对应的所需驱动文件。

  • Keil ARM路径下位置:
    也可以到ARM官方的GitHub账号(
    https://github.com/ARM-software/CMSIS
    )下载所有ARM Cortex-M内核的DSP外设库。

  • STM32CubeMX,pack解压安装文件位置:
    同样在标准外设库中也可以找到:(后缀带
    f32
    需要FPU硬件支持才能高效运行,后缀为
    q15
    专为无FPU的MCU(如STM32F103)设计,纯整数运算)

数字信号库包含在路径:
STM32F4xx_DSP_StdPeriph_Lib_V1.9.0\Libraries\CMSIS\DSP_Lib

STM32F4xx_DSP_StdPeriph_Lib_V1.9.0\Libraries\CMSIS\Lib
下,或者Keil安装目录下
D:\Keil_v5\ARM\CMSIS\Lib\ARM
将它们拷贝到目标工程文件夹下。其中Lib文件夹中包含的是经过不同编译器编译后能够运行在Cortex-M4内核上的底层数学库,DSP_Lib文件夹中包含的是调用底层函数封装而成的API函数源码:

Lib文件夹中包含的底层库包括:

    arm_cortexM4lf_math.lib	//---->stm32f4 DSP库跑SVPWM开环速度测试需要使用到的
    arm_cortexM4bf_math.lib
    arm_cortexM4l_math.lib
    arm_cortexM4b_math.lib
    arm_cortexM3l_math.lib
    arm_cortexM3b_math.lib
    arm_cortexM0l_math.lib
    arm_cortexM0b_math.lib

对应工程中所用到的:
arm_cortexM4lf_math.lib
库文件来源。

STM32F4 DSP和标准外设库(STSW-STM32065) ST官网下载地址:
https://www.st.com.cn/zh/embedded-software/stsw-stm32065.html

当前stm32F4 最新版本:
STSW-STM32065 STM32F4 DSP and standard peripherals library 1.9.0

链接:https://pan.baidu.com/s/1J8VD2re8SRWOGnZXZKcyvQ?pwd=o5an 
提取码:o5an

工程中配置的重要一步:需要添加相对于的宏,来开启DSP库进行浮点运算和math计算 “
__CC_ARM,__TARGET_FPU_VFP, __FPU_PRESENT=1U, ARM_MATH_CM4

SVPWM实现,DC转AC逆变代码核心函数

// FOC核心函数:输入Uq、Ud和电角度,输出三路PWM
// Uq 范围:0—6.928; MAX:  U0*sqrt3/3 (sqrt平方根),
//需要注意:Uq值设置越大,力矩越大,电流越大,电机发热越大。
void setPhaseVoltage(float Uq, float Ud, float angle_el)
{
    static float Ts = 1.0f;
    float Ta, Tb, Tc;
    float t1, t2, t3, t4, t5, t6, t7;
    float sum, k_svpwm;
    angle_el = _normalizeAngle(angle_el);
    // Park逆变换
    float U_alpha = -Uq * arm_sin_f32(angle_el) + Ud * arm_cos_f32(angle_el);
    float U_beta = Uq * arm_cos_f32(angle_el) + Ud * arm_sin_f32(angle_el);
    // 扇区判断
    float K = sqrt3 * Ts / Udc; // SVPWM调制比
    float u1 = U_beta * K;
    float u2 = (0.8660254f * U_alpha - 0.5f * U_beta) * K; // sqrt(3)/2 = 0.8660254
    float u3 = (-0.8660254f * U_alpha - 0.5f * U_beta) * K;
    uint8_t sector = (u1 > 0.0f) + ((u2 > 0.0f) << 1) + ((u3 > 0.0f) << 2); // sector = A + 2B + 4C
    // 非零矢量和零矢量作用时间的计算
    switch(sector) {
        case 3: // 扇区1
            t4 = u2;
            t6 = u1;
            sum = t4 + t6;
            if(sum > Ts) { // 过调制处理
                k_svpwm = Ts / sum;
                t4 *= k_svpwm;
                t6 *= k_svpwm;
            }
            t7 = (Ts - t4 - t6) / 2.0f;
            Ta = t4 + t6 + t7;
            Tb = t6 + t7;
            Tc = t7;
            break;
        case 1: // 扇区2
            t2 = -u2;
            t6 = -u3;
            sum = t2 + t6;
            if(sum > Ts) {
                k_svpwm = Ts / sum;
                t2 *= k_svpwm;
                t6 *= k_svpwm;
            }
            t7 = (Ts - t2 - t6) / 2.0f;
            Ta = t6 + t7;
            Tb = t2 + t6 + t7;
            Tc = t7;
            break;
        case 5: // 扇区3
            t2 = u1;
            t3 = u3;
            sum = t2 + t3;
            if(sum > Ts) {
                k_svpwm = Ts / sum;
                t2 *= k_svpwm;
                t3 *= k_svpwm;
            }
            t7 = (Ts - t2 - t3) / 2.0f;
            Ta = t7;
            Tb = t2 + t3 + t7;
            Tc = t3 + t7;
            break;
        case 4: // 扇区4
            t1 = -u1;
            t3 = -u2;
            sum = t1 + t3;
            if(sum > Ts) {
                k_svpwm = Ts / sum;
                t1 *= k_svpwm;
                t3 *= k_svpwm;
            }
            t7 = (Ts - t1 - t3) / 2.0f;
            Ta = t7;
            Tb = t3 + t7;
            Tc = t1 + t3 + t7;
            break;
        case 6: // 扇区5
            t1 = u3;
            t5 = u2;
            sum = t1 + t5;
            if(sum > Ts) {
                k_svpwm = Ts / sum;
                t1 *= k_svpwm;
                t5 *= k_svpwm;
            }
            t7 = (Ts - t1 - t5) / 2.0f;
            Ta = t5 + t7;
            Tb = t7;
            Tc = t1 + t5 + t7;
            break;
        case 2: // 扇区6
            t4 = -u3;
            t5 = -u1;
            sum = t4 + t5;
            if(sum > Ts) {
                k_svpwm = Ts / sum;
                t4 *= k_svpwm;
                t5 *= k_svpwm;
            }
            t7 = (Ts - t4 - t5) / 2.0f;
            Ta = t4 + t5 + t7;
            Tb = t7;
            Tc = t5 + t7;
            break;
        default:
            break;
    }
   //  printf("[Ta,Tb,Tc]:%f,%f,%f\r\n", Ta, Tb, Tc);
    Set_PWM(Ta, Tb, Tc); // 配置输出三路PWM,驱动无刷电机转动
}

STM32CubeMX配置

选择一个高级定时器:(注意这里是按照原作者的EG2133驱动芯片配置的,上下桥驱动控制端连一块,进行配置的)

采用自制驱动板EG3112,上下桥独立驱动,定时器配置互补通道输出:

需要注意一点的是:采用互补通道输出控制方式,这里的死区时间参数,保持默认配置值
0
,如果配置了死区时间,反而对无刷电机的控制造成影响。

为了查看输出波形,还需要配置一个串口,方便观察波形。

SVPWM开环速度测试工程说明

待测试电机参数配置:
motor.c
中修改测试电机的极对数。

极对数测量
如果知道电机型号,可以找到对应资料查阅多更好。如果无刷电机外转子不是全部密封,看的到外转子内壁上永磁体的,可以直接自己数出来。上门贴了有多少块强磁铁,即可得到此数据。对应外转子密封看不到内壁磁体的测量方法:

  • 如果有示波器的情况下,用示波器的探头夹住电机的一根线,另一根接探头,然后旋转电机一圈,截取波形,数下峰的个数(上下峰都算),为偶数值除以2,就是电机的极对数。
  • 有低压直流可调电源情况下,限制一定的电流,加载一个小电压到三相中的任意两相,用手转动电机一圈,有稳定位置的个数就是极对。

SVPWM开环速度参数设定:

OpenVelocity(6.0f); //数值越大,电机旋转的速度越快

对于采用3路PWM互补输出方式驱动控制:

// 使能TIMx的通道
void PWM_Init(void)
{
    HAL_TIM_Base_Start(&htim1);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
    HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1);
    HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_2);
    HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_3);
}

串口数据观测

设置:添加波形图控件到主窗口

设置串口端口号以及数据类型:

打开串口,并添加数据到波形图控件中:

最终测试效果:

需要注意一点,所测得的马鞍波形,并不代表实际电机真实的驱动转动效果,电机的运转效果与驱动电路和电机参数有关,这个波形是理论推导得来的理想模型。

在SVPWM开环速度测试运行下,无刷电机的U-V-W相波形:

MCU 定时器对应输出通道的PWM驱动波形:

这里的PWM频率,通过示波器测得是15.2K,对应的是程序中定时器输出通道:
PWM频率 = MAIN_CLK/(ARR*2)(没有进行分频,中心对齐方式)

H桥NMOS管栅极驱动波形:

移植工程测试源码

基于STM32F446 MIAN FOSC=180MHz,

链接:https://pan.baidu.com/s/1IidjgkeSnOLZg-Dq4Snm9Q?pwd=842c
提取码:842c

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号