1. 从一堆热搜词里看永磁同步电机与FOC的真实需求
翻了一圈热搜词,永磁同步电机、FOC、TI、逆变器、死区时间这几个词反复出现,再加上STM32F103RCT6无刷电机FOC驱动代码、CubeMX配置FOC无刷电机、PMSM无感FOC控制、FOC滑模观测器、FOC转子初始位置检测这些长尾词,基本能勾勒出关注这个方向的人到底在找什么。说白了,大家不是想听教科书上讲永磁同步电机有多好,而是想知道:这东西到底怎么转起来的,FOC算法为什么能把转矩做得这么平稳,TI和STM32两条技术路线各自怎么落地,逆变器那六个开关管到底怎么开合,死区时间设多少才不炸管。
我自己是从六步换相一路踩坑踩到FOC的。最早拿STM32F103RCT6搭无刷电机驱动,用六步换相能转,但低速抖动大、噪声明显、转矩脉动让人难受。后来切到FOC,电流环一上,电机立刻安静下来,低速也能平稳输出大转矩。再后来接触TI的InstaSPIN方案和C2000系列,发现TI在电机控制上的积累确实深,很多底层细节人家已经封装好了,但如果不理解原理,出了问题照样抓瞎。
这篇内容适合几类人看:正在做电机控制项目但被FOC数学推导卡住的工程师,想从六步换相升级到FOC但不知道从哪下手的嵌入式开发者,用STM32或TI芯片做逆变器方案但被死区时间和电流采样搞晕的人,以及想理解PMSM无感FOC控制、滑模观测器、转子初始位置检测这些具体技术点的朋友。我会把原理、FOC控制、TI方案实现这三块串起来讲,中间穿插参数计算、实操步骤和我自己踩过的坑,尽量让不同基础的人都能拿走能用的东西。
2. 永磁同步电机原理:先搞懂它为什么值得用FOC去控
2.1 永磁同步电机的结构特点与运行机理
永磁同步电机,英文缩写PMSM,核心特征就是转子上的磁场不是靠电流激励产生的,而是靠永磁体。这一点和异步电机有本质区别。异步电机转子磁场需要定子电流感应出来,所以转子总有转差,而PMSM的转子磁场是现成的,只要定子旋转磁场和转子磁场保持同步,电机就能稳定输出转矩。
从结构上看,PMSM分两大类:表贴式和内置式。表贴式永磁体贴在转子表面,交直轴电感基本相等,磁路对称,控制模型简单,适合做表贴式永磁同步电机DSP控制这类入门方案。内置式永磁体嵌在转子内部,交直轴电感不等,会产生磁阻转矩,适合做FOC MTPA控制,也就是最大转矩电流比控制,能进一步榨出转矩。
定子这边是三相绕组,通入三相正弦电流后产生旋转磁场。转子的永磁体磁场被定子旋转磁场拖着走,两者同步旋转。这里有个关键点:如果定子磁场和转子磁场夹角为90度电角度,产生的转矩最大。FOC的核心目标之一,就是通过坐标变换和电流控制,让定子电流矢量始终垂直于转子磁链矢量,从而获得最大转矩输出。
注意:很多人一开始不理解“电角度”和“机械角度”的区别。机械角度是转子实际转过的物理角度,电角度等于机械角度乘以极对数。比如4极电机,极对数是2,转子机械转一圈,电角度转了720度。FOC算法里用的sin和cos,全部是电角度,搞错这个,电机要么不转,要么乱转。
2.2 从abc到dq:坐标变换到底在干什么
FOC算法原理里最绕人的就是坐标变换。我当初看逆变器从abc到dq坐标下的数学推导,公式一堆,看完还是不知道为什么要这么变。后来想明白了,坐标变换的本质就是“换一个视角看问题”。
三相电流ia、ib、ic在空间上互差120度,它们合成的电流矢量是一个在平面上旋转的矢量。Clarke变换把三相静止坐标系abc变成两相静止坐标系αβ,相当于把三个分量压缩成两个正交分量,减少计算量。Park变换再把αβ坐标系旋转到跟随转子磁场的dq坐标系,d轴对准转子磁链方向,q轴垂直于d轴。
变换到dq坐标系之后,原本交流变化的电流量变成了直流量。d轴电流控制磁场强弱,q轴电流控制转矩大小。对于表贴式PMSM,d轴电流通常控制为0,所有电流都用来产生转矩,这就是最简单的id=0控制。对于内置式PMSM,可以给d轴一个负电流,利用磁阻转矩,这就是MTPA控制的思路。
这个变换过程用到的角度就是转子电角度。所以FOC算法中电角度和转子角度的关系必须搞清楚:转子角度是机械角度,电角度等于机械角度乘以极对数,再加上初始位置偏移。无感FOC里,转子角度靠观测器估算,有感FOC里靠编码器或霍尔传感器获取。
2.3 为什么PMSM需要FOC而不是六步换相
六步换相永磁同步电机的做法很简单,用霍尔传感器判断转子位置,每60度电角度换一次相,每次只给两相通电。这种方式实现容易,成本低,但问题很明显:电流不是正弦的,转矩脉动大,低速时尤其明显,噪声也大。
FOC则完全不同。它通过SVPWM调制出三相正弦电流,电流连续平滑,转矩脉动小,低速性能好,效率也高。FOC和SVPWM配合,能让逆变器的直流电压利用率比正弦PWM高出约15%。这就是为什么现在做PMSM无感FOC控制、做电流速度FOC控制,基本都选FOC而不是六步换相。
当然,FOC的代价是算法复杂、对MCU算力有要求、电流采样和转子位置检测更讲究。但STM32F103RCT6这类带DSP指令和硬件浮点单元的芯片,跑FOC已经够用了。TI的C2000系列更是专门为电机控制设计,带CLA协处理器和高速ADC,做FOC非常顺手。
3. FOC控制核心细节:电流环、速度环与观测器
3.1 电流环与速度环的双闭环设计逻辑
FOC控制通常采用双闭环结构:外环是速度环,内环是电流环。速度环根据目标转速和实际转速的偏差,输出q轴电流参考值。电流环再根据q轴和d轴电流的偏差,输出电压参考值,最终交给SVPWM模块生成开关信号。
为什么电流环要放在内环?因为电流响应比速度响应快得多。电流环带宽通常在1kHz到5kHz,速度环带宽在100Hz到500Hz。内环快、外环慢,这样系统稳定,抗扰动能力强。如果反过来,速度环响应太快,电流环跟不上,系统容易振荡。
电流环的PI参数整定有个经验公式。对于表贴式PMSM,d轴和q轴电感相等,电流环PI参数可以按以下方式估算:
// 电流环PI参数估算示例 // Kp_i = Ls * bandwidth_i // Ki_i = Rs * bandwidth_i // 其中Ls为定子电感,Rs为定子电阻,bandwidth_i为电流环带宽(rad/s) float Ls = 0.0005f; // 定子电感 0.5mH float Rs = 0.1f; // 定子电阻 0.1欧姆 float bw_i = 2.0f * 3.14159f * 2000.0f; // 电流环带宽 2kHz float Kp_i = Ls * bw_i; // 约6.28 float Ki_i = Rs * bw_i; // 约1256实际调试时,先把Ki设为0,逐渐增大Kp直到电流响应出现轻微超调,然后再加Ki消除稳态误差。速度环同理,但速度环的Kp和Ki要比电流环小一个数量级左右。
实操心得:我调电流环的时候,习惯先用一个很小的直流电压给电机,让电机堵转,然后给q轴电流一个阶跃指令,用示波器看电流响应。这样能快速判断PI参数是否合适。如果电流上升太慢,增大Kp;如果振荡,减小Kp或增大Ki的积分时间。
3.2 SVPWM调制与死区时间的设置要点
SVPWM是FOC算法的输出级。它把dq坐标系下的电压参考值转换回αβ坐标系,再判断电压矢量落在哪个扇区,计算相邻两个基本矢量的作用时间,最终生成六路PWM信号驱动三相逆变器。
三相两电平逆变器有六个开关管,上下桥臂各三个。同一桥臂的上下管不能同时导通,否则直流母线直接短路,瞬间炸管。所以必须设置死区时间,也就是在上管关断和下管开通之间插入一段延迟,确保上下管不会同时导通。
IGBT的死区时间通常设1到3微秒,MOSFET可以设小一些,0.5到1微秒。死区时间太短,上下管可能直通;太长,输出电压失真,电流波形畸变,低速时尤其明显。死区时间造成的电压误差大约是:
// 死区电压误差估算 // V_error = (T_dead / T_pwm) * V_dc // T_dead为死区时间,T_pwm为PWM周期,V_dc为直流母线电压 float T_dead = 2e-6f; // 死区时间 2微秒 float T_pwm = 50e-6f; // PWM周期 50微秒 (20kHz) float V_dc = 48.0f; // 直流母线电压 48V float V_error = (T_dead / T_pwm) * V_dc; // 约1.92V这个误差在低速小电压输出时占比很大,会导致电流波形畸变。解决办法是做死区补偿,根据电流方向在电压参考值上叠加一个补偿量。TI的电机控制库里有现成的死区补偿模块,STM32这边需要自己写。
3.3 无感FOC与滑模观测器的实现思路
PMSM无感FOC控制的核心难点是转子位置估算。没有编码器或霍尔传感器,怎么知道转子现在在哪?常用方法有滑模观测器、龙伯格观测器、高频注入法等。
FOC滑模观测器的思路是:根据电机电压方程和电流方程,构造一个观测器估算反电动势,再从反电动势中提取转子角度。滑模观测器的优点是鲁棒性强,对参数变化不敏感;缺点是存在抖振,需要加低通滤波器,而滤波器又会引入相位延迟,需要做角度补偿。
滑模观测器的基本方程如下:
// 滑模观测器简化实现 // 估算电流与实际电流的偏差驱动滑模面 // 反电动势估算值从滑模控制量中提取 float e_alpha_est = 0.0f; float e_beta_est = 0.0f; float i_alpha_est = 0.0f; float i_beta_est = 0.0f; // 滑模增益 float K_slide = 100.0f; // 电流估算 i_alpha_est += (V_alpha - Rs * i_alpha_est - e_alpha_est) / Ls * Ts; i_beta_est += (V_beta - Rs * i_beta_est - e_beta_est) / Ls * Ts; // 滑模控制量 float z_alpha = K_slide * sign(i_alpha - i_alpha_est); float z_beta = K_slide * sign(i_beta - i_beta_est); // 反电动势估算(经过低通滤波) e_alpha_est += (z_alpha - e_alpha_est) * wc * Ts; e_beta_est += (z_beta - e_beta_est) * wc * Ts; // 转子角度估算 float theta_est = atan2f(-e_alpha_est, e_beta_est);FOC转子初始位置检测是另一个难点。无感FOC在零速和低速时反电动势很小,滑模观测器无法准确估算角度。常用方法是高频注入法,在d轴注入高频电压信号,通过检测q轴电流响应来判断转子凸极位置。表贴式PMSM凸极率小,高频注入效果有限,所以很多方案会先用开环强拖启动,等转速起来再切换到闭环。
4. TI方案实现:从InstaSPIN到C2000的落地路径
4.1 TI电机控制方案的整体架构与选型
TI在电机控制领域有两套主流方案:一套是基于C2000系列DSP的InstaSPIN方案,另一套是基于MSP430或SimpleLink系列的通用方案。做PMSM FOC控制,C2000是首选,尤其是F28004x、F28002x这些带CLA和高速ADC的型号。
TI官网有完整的电机控制SDK,叫MotorControl SDK,里面包含FOC、SVPWM、滑模观测器、死区补偿、电流采样校准等全套模块。用SysConfig配置TI的SCI、ADC、PWM等外设,生成初始化代码,能省很多时间。TI的CCFG配置文件用来设置芯片的时钟、引脚复用和安全选项,配合SysConfig使用很方便。
不过TI的工具有时候会出幺蛾子。比如TI XDS100V3 Channel A的驱动有感叹号,这是驱动签名问题,需要在设备管理器里手动更新驱动,或者换用XDS110调试器。TI德州仪器的PPC3软件安装包有时候和最新版Windows不兼容,建议在虚拟机里装或者用较老版本的Windows。
注意:TI的InstaSPIN-FOC库是封装好的,调用起来简单,但如果你想改观测器参数或者加自定义补偿,需要理解底层原理。我建议先用InstaSPIN把电机转起来,再逐步替换里面的模块,这样学习曲线最平滑。
4.2 基于C2000的FOC代码框架与关键配置
TI C2000的FOC代码框架通常包含以下几个模块:ADC采样与校准、Clarke/Park变换、电流环PI、速度环PI、SVPWM生成、观测器、保护逻辑。下面是一个简化的代码框架:
// TI C2000 FOC主循环框架 void main(void) { // 系统初始化 InitSysCtrl(); InitGpio(); InitPieCtrl(); InitPieVectTable(); // 外设配置 InitEPwm(); InitAdc(); InitSci(); // 电机参数初始化 motor_params.Rs = 0.1f; motor_params.Ls = 0.0005f; motor_params.flux = 0.01f; motor_params.pole_pairs = 2; // FOC初始化 FOC_init(&foc_handle, &motor_params); // 使能中断 EINT; ERTM; while(1) { // 后台任务:通信、状态机、参数更新 Sci_Communication(); State_Machine(); } } // PWM中断服务函数,执行FOC算法 __interrupt void epwm1_isr(void) { // 读取相电流 foc_handle.Ia = Adc_ReadPhaseA(); foc_handle.Ib = Adc_ReadPhaseB(); foc_handle.Ic = -foc_handle.Ia - foc_handle.Ib; // 读取转子角度(有感)或观测器估算(无感) foc_handle.theta = Encoder_GetAngle() * pole_pairs; // Clarke变换 foc_handle.Ialpha = foc_handle.Ia; foc_handle.Ibeta = (foc_handle.Ia + 2.0f * foc_handle.Ib) * 0.577350269f; // Park变换 foc_handle.Id = foc_handle.Ialpha * cosf(foc_handle.theta) + foc_handle.Ibeta * sinf(foc_handle.theta); foc_handle.Iq = -foc_handle.Ialpha * sinf(foc_handle.theta) + foc_handle.Ibeta * cosf(foc_handle.theta); // 电流环PI foc_handle.Vd = PI_Calc(&pi_d, foc_handle.Id_ref - foc_handle.Id); foc_handle.Vq = PI_Calc(&pi_q, foc_handle.Iq_ref - foc_handle.Iq); // 反Park变换 foc_handle.Valpha = foc_handle.Vd * cosf(foc_handle.theta) - foc_handle.Vq * sinf(foc_handle.theta); foc_handle.Vbeta = foc_handle.Vd * sinf(foc_handle.theta) + foc_handle.Vq * cosf(foc_handle.theta); // SVPWM生成 SVPWM_Calc(&foc_handle); // 清除中断标志 PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; }这段代码里,Clarke变换用的是等幅值变换,系数是2/3和1/√3。Park变换用的角度是电角度。SVPWM模块根据Valpha和Vbeta计算三个比较寄存器的值,最终输出六路PWM。
4.3 逆变器硬件设计与电流采样方案
做逆变器程序设计,硬件设计是绕不开的。三相逆变器的主电路是六个IGBT或MOSFET组成的三相全桥,直流母线加电容滤波,输出接电机三相。栅极驱动芯片选型很关键,IR2136、DRV8301、DRV8323这些都是常用型号。DRV8301自带电流采样放大器和Buck降压,集成度高,适合小功率方案。
电流采样有三种常见方式:单电阻采样、双电阻采样、三电阻采样。单电阻采样成本最低,但采样时机要求严格,需要在PWM特定时刻触发ADC,算法复杂。双电阻采样在上下桥臂各放一个采样电阻,能重构三相电流,是最常用的方案。三电阻采样每相都有采样电阻,精度最高,但成本也最高。
采样电阻的阻值计算要考虑功耗和信噪比。假设最大相电流10A,采样电阻0.01欧姆,功耗是1W,采样电压是0.1V。这个电压太小,需要运放放大。DRV8301内部放大器增益可设,通常设10到20倍,把0.1V放大到1V到2V,正好落在ADC量程内。
实操心得:电流采样最容易被忽略的是采样时刻和PWM的同步。如果ADC采样时刻和PWM开关时刻没对齐,采到的电流要么是开关噪声,要么是续流二极管导通时的电流,完全不能用。TI的方案里,ADC触发源直接配成PWM计数器过零或峰值,STM32这边用定时器触发ADC,也要配成同样的逻辑。
5. STM32方案实现:从CubeMX配置到FOC代码落地
5.1 STM32F103RCT6的FOC资源评估与CubeMX配置
STM32F103RCT6是Cortex-M3内核,72MHz主频,256KB Flash,48KB RAM,带3个ADC、4个定时器、多个USART和SPI。跑FOC够用,但要注意算力分配。FOC算法本身大概需要10到20微秒,如果PWM频率设20kHz,周期50微秒,留给FOC的时间很充裕。但如果还要跑无感观测器、通信协议、保护逻辑,就要精打细算。
CubeMX配置FOC无刷电机的步骤大致如下:先配置时钟树,把系统时钟设到72MHz,ADC时钟设到14MHz或12MHz。然后配置TIM1为PWM输出,三个通道互补输出,死区时间设1到2微秒。配置ADC1和ADC2为规则组扫描模式,由TIM1触发,采样相电流和母线电压。配置USART用于调试和通信。最后配置GPIO用于使能驱动芯片和读取霍尔传感器。
// CubeMX生成的TIM1 PWM配置关键参数 // Prescaler = 0 // Counter Period = 3599 (72MHz / 3600 = 20kHz) // Dead Time = 72 (72 * (1/72MHz) = 1微秒) // PWM Mode = PWM Mode 1 // CH Polarity = High // Complementary Output = Enable死区时间寄存器DTG的值和实际死区时间的关系是:DTG值乘以时钟周期。72MHz时钟周期约13.9纳秒,DTG=72对应约1微秒。这个值要根据驱动芯片和开关管特性调整。
5.2 STM32 FOC代码实现与电流环调试
STM32的FOC代码可以用ST的Motor Control SDK,也可以自己写。ST的SDK叫MC SDK,支持FOC和六步换相,配置工具叫Motor Profiler,能自动测量电机参数。但ST的SDK封装得比较深,想改底层不太方便。我自己的做法是参考ST的SDK,自己写一套精简的FOC代码,这样每个环节都清楚。
// STM32 FOC电流环中断服务函数 void TIM1_UP_IRQHandler(void) { if(TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET) { // 读取电流 Ia = (ADC_GetValue(ADC_Channel_0) - Ia_offset) * Ia_gain; Ib = (ADC_GetValue(ADC_Channel_1) - Ib_offset) * Ib_gain; Ic = -Ia - Ib; // 读取电角度 theta = Encoder_GetElecAngle(); // Clarke变换 Ialpha = Ia; Ibeta = (Ia + 2*Ib) * 0.577350269f; // Park变换 Id = Ialpha * cosf(theta) + Ibeta * sinf(theta); Iq = -Ialpha * sinf(theta) + Ibeta * cosf(theta); // 电流环PI Vd = PI_Calc(&pi_d, Id_ref - Id); Vq = PI_Calc(&pi_q, Iq_ref - Iq); // 反Park变换 Valpha = Vd * cosf(theta) - Vq * sinf(theta); Vbeta = Vd * sinf(theta) + Vq * cosf(theta); // SVPWM SVPWM_Calc(Valpha, Vbeta, &CCR1, &CCR2, &CCR3); TIM_SetCompare1(TIM1, CCR1); TIM_SetCompare2(TIM1, CCR2); TIM_SetCompare3(TIM1, CCR3); TIM_ClearITPendingBit(TIM1, TIM_IT_Update); } }调试电流环的时候,我习惯先用开环模式,给一个固定的电压矢量,让电机堵转,然后观察电流波形。如果电流波形是正弦的,说明SVPWM和采样没问题。然后切到电流闭环,给q轴电流阶跃指令,调PI参数。最后切到速度闭环,调速度环PI。
5.3 无感FOC在STM32上的实现与启动策略
STM32上跑无感FOC,观测器可以用滑模观测器或龙伯格观测器。滑模观测器计算量小,适合STM32F103这类没有硬件浮点的芯片。但F103没有FPU,浮点运算靠软件模拟,速度慢。建议用定点数运算,或者用STM32F4系列带FPU的芯片。
无感FOC的启动策略通常分三段:预定位、开环加速、闭环切换。预定位是给一个固定的d轴电流,把转子拉到已知位置。开环加速是按一定斜率增加电角度和电压,让电机转起来。等转速达到一定值,反电动势足够大,再切换到滑模观测器闭环控制。
// 无感FOC启动状态机 typedef enum { STATE_IDLE, STATE_PREPOSITION, STATE_OPENLOOP, STATE_CLOSEDLOOP, STATE_FAULT } FOC_State_t; void FOC_StateMachine(void) { switch(foc_state) { case STATE_IDLE: if(start_cmd) foc_state = STATE_PREPOSITION; break; case STATE_PREPOSITION: Id_ref = 2.0f; // 给d轴电流 Iq_ref = 0.0f; theta = 0.0f; // 固定角度 if(preposition_timer > 500) // 500ms foc_state = STATE_OPENLOOP; break; case STATE_OPENLOOP: theta += openloop_speed * Ts; Vq = openloop_voltage; if(theta > 2*PI) theta -= 2*PI; if(openloop_speed > switch_speed) foc_state = STATE_CLOSEDLOOP; break; case STATE_CLOSEDLOOP: theta = Observer_GetAngle(); // 正常FOC控制 break; case STATE_FAULT: // 关断PWM,等待复位 break; } }开环加速的斜率很关键。斜率太大,电机可能失步;斜率太小,启动太慢。一般根据电机惯量和负载转矩来调。我通常从10rad/s²开始试,慢慢加大到电机能稳定启动为止。
6. 常见问题与排查技巧实录
6.1 FOC调试中的典型故障与排查思路
做FOC调试,遇到的问题五花八门,但大部分集中在几个地方:电流采样不对、角度不对、PI参数不对、死区时间不对。下面整理一个速查表,方便对照排查。
| 现象 | 可能原因 | 排查方法 | 解决办法 |
|---|---|---|---|
| 电机不转,电流很大 | 角度错误或相序错误 | 检查电角度计算和相序 | 重新校准编码器零位,交换任意两相 |
| 电机抖动,噪声大 | 电流环PI参数不合适 | 观察电流波形 | 减小Kp,增大Ki积分时间 |
| 低速时电流畸变 | 死区时间过长 | 测量死区电压误差 | 减小死区时间或加死区补偿 |
| 高速时失控 | 观测器带宽不足 | 检查反电动势估算 | 增大观测器增益,减小滤波截止频率 |
| 启动失败 | 开环加速斜率太大 | 观察启动电流 | 减小加速斜率,增大预定位时间 |
| 电流采样跳变 | ADC触发时刻不对 | 用示波器看采样时刻 | 调整ADC触发源为PWM过零或峰值 |
| 母线电压波动大 | 母线电容不足 | 测量母线电压纹波 | 增大母线电容,加制动电阻 |
注意:排查故障时,一定要先确保硬件没问题。我遇到过好几次,调了半天软件,最后发现是驱动芯片坏了或者采样电阻虚焊。所以第一步永远是量电压、量波形、确认硬件。
6.2 死区时间与逆变器环流问题的处理经验
逆变器环流是另一个让人头疼的问题。多台逆变器并联运行时,如果载波不同步,或者死区时间不一致,会在逆变器之间产生环流。环流不仅增加损耗,还可能烧毁器件。
解决环流问题,首先要确保所有逆变器的载波同步。可以用同一个时钟源,或者用通信总线同步载波相位。其次,死区时间要一致,补偿策略也要一致。如果环流还是大,可以在逆变器输出加共模电感,增加环流阻抗。
光伏逆变器和储能逆变器里,环流问题更复杂,因为涉及光伏板到逆变器到储能到配电箱接电原理,整个系统的接地和绝缘设计都会影响环流。做组网逆变器PI控制的时候,电流环的PI参数要兼顾环流抑制,有时候需要加谐振控制器专门抑制特定频率的环流。
6.3 工具链与开发环境常见问题
TI的CCS和STM32的Keil是两大主流开发环境。Keil5绑定TI的芯片支持包有时候会出问题,需要手动安装Device Family Pack。TI的SysConfig配置SCI的时候,要注意引脚复用和时钟使能,配错了串口不通。
STM32CubeMX配置FOC的时候,ADC采样时间要设够,太短了采样不准,太长了影响控制周期。一般设1.5到7.5个ADC时钟周期。PWM死区时间在CubeMX里直接填纳秒值,工具会自动算DTG寄存器值。
还有个小坑:STM32F103RCT6的ADC1和ADC2可以同步采样,但配置起来比单ADC复杂。如果只是做双电阻采样,用ADC1扫描两个通道就够了,没必要上双ADC。双ADC适合三电阻采样或者需要同时采样电压和电流的场景。
7. 个人实操体会与后续扩展方向
我在实际做PMSM FOC控制这些年,最大的体会是:原理要懂,但不要陷在公式里出不来。FOC的核心就是坐标变换加PI控制加SVPWM,把这三块搞透,剩下的都是工程细节。工程细节里,电流采样和转子角度是最容易出问题的,把这两个搞定,FOC就成功了一大半。
TI的方案适合快速落地,尤其是InstaSPIN,基本不用调参数就能转。但如果你想深入理解FOC,建议自己从零写一遍代码,哪怕先用STM32F103跑定点数版本,跑通了再换F4或TI的C2000。自己写一遍,比看十遍书都管用。
这个内容后续还可以往几个方向扩展:一是无感FOC的观测器优化,比如用扩展卡尔曼滤波替代滑模观测器,低速性能更好;二是MTPA控制和弱磁控制,适合内置式PMSM和高速应用;三是多电机同步控制,做组网逆变器或者多轴运动控制;四是故障诊断,比如永磁同步电机匝间短路模型构建,用来做早期故障检测。每个方向都够写一篇长文,有机会再展开聊。