全文约5452字,你将看到以下内容:
1 autoMBD电机控制项目概况 过去两个月的时间里,我在NXP S32K144平台上构建了一个基于MBD(基于模型的设计,Model-Based Design)的电机控制框架,该框架上传到了GitHub仓库,仓库位于下面这链接中:
autoMBD Motor Control仓库- From NXP 读者也可以在对话框中回复关键词“MBD电机控制”,即可收到上述链接。 目前该框架还处于较为初级的阶段,在后续的可开发中还会不断改进和完善,增加更多的功能,欢迎持续关注。 现阶段,我在该框架上实现了一个简单的BLDC六步换相的开环控制,并且已经在NXP的电机开发套件MCSPTE1AK144上进行了验证,符合我的设计预期。 电机开发套件MCSPTE1AK144 - From NXP 特别提示:目前我的框架是基于NXP的MBDT硬件支持包开发的,在开发的过程中我发现MBDT存在一些问题,我进行了暂时的修复。如果没有修复这些问题,我的工程直接生成代码、编译可能会报错。后文会详细讲解这些问题如何修复。 提示:该框架和模型属于autoMBD的劳动成果,转载或引用请注明来源和作者,请勿用于商业或不当盈利!感谢支持。 这里简单的阐述一下为什么需要构建一个全新的MBD电机控制架构。 读过我之前文章的读者肯知道,MBDT提供了较为丰富的电机控制模型,BLDC、PMSM、开环/闭环、有感/无感等都有相应的示例模型。 MBDT提供的电机示例工程 - From autoMBD 实际上,我认为这些控制模型只对如何使用MBDT这个工具本身有一定的参考意义。 这些模型给我的感觉是一种面向流程的开发方式,可读性较差。它的这些模型也很难做PIL测试,无法满足MBD的很多开发流程需求。它还有一些其他缺点,比如没有构建数据类型,导致变量定义很繁琐。 从另一个角度来说,这些示例工程的开发逻辑和纯代码开发方式截然不同,虽然实现了电机控制算法,但几乎不会使用模型中的方法构建电机控制软件。 总的来说,我们学习MBDT这个工具可以参考这些模型,但真正的开发,还需要一套适合MBD的架构。 在进入下面的内容之前,请确保正确安装MBDT硬件支持包,安装教程可以参考MBD实战之MBDT 第01期:MBDT快速上手,更多的MBDT教程也可以阅读公众号的历史文章。 2 基于MBD的电机控制框架 下图便是今天的主角——基于MBD的电机控制框架模型: 基于MBD的电机控制框架模型 - From autoMBD 在构建这个框架之前我便在思考:MBD的框架应该是什么样子的?
autoMBD的资源库也更新了一篇NXP关于FreeRTOS的应用笔记,在公众号对话页面选择“MBD->资源”子菜单,或者直接在消息对话框中回复关键词“资源”,即可收到autoMBD资源库分享链接。 从上图可以看到,该框架模型分可以为六个功能区域:
全局变量的定义用到的是Simulink中的Data Store Memory模块,如下图所示: 全局变量定义 - From autoMBD 全局变量的定义是建模过程中遇到的第一个难点,因为它涉及到我们软件开发中最基础的东西——数据类型。 在软件开发中,为了提高开发效率,和代码的可读性,经常需要构建自己的数据类型。做好一个的数据类型设计和定义,有时候反而是代码开发中最麻烦、最耗时间的阶段。但这些是有必要的,甚至是必须的。 在Simulink中可以通过Bus Editor构建自定义数据类型。 Bus Editor - From autoMBD 这里不详细展开介绍如何通过Bus Editor构建自己的数据类型,有问题可以私信与我讨论。 编辑好的数据类型可以保存下来,仓库中的structBLDCMotorCrtl.mat文件就是本项目中创建的所有数据类型。有了自定义数据类型,整个项目只用到了三个模块就定义了全部需要的数据。 每次运行模型、生成代码之前都需要将创建好的数据类型加载到MATLAB的工作空间中,不然会提示报错。
初始化任务执行的是对MCU外设的初始化配置,比如Pin脚、ADC、PDB、SPI、FTM、PIT、中断等。还包括外围IC的初始化,如本项目中的GD3000预驱芯片的初始化是通过TPP模块实现的。 初始化任务中包含的模块如下: 初始化任务 - From autoMBD 细心的读者可能已经发现,上图中的模块明显没有包含所有的外设配置模块。这是因为MBDT设计的模块,有的是配置和执行是在同一个模块中,比如FTM的配置和PWM生成均由FTM PWM Config模块实现: FTM配置模块 - From autoMBD Pin脚的配置也是这样的,这类型的模块,放置在模型的任意位置都会生成相应配置代码,同时它也承担着功能执行的工作。 读者可以打开模型查看具体的各个模块的配置。
在开发过程中,我们往往需要和MCU进行一些交换,比如按键、LED、屏幕等。在本项目中交互接口设置了两个按键(通过GPI边沿检测)和一个周期性的中断(通过PIT实现,处理板上旋钮),如下图所示: 用户接口 - From autoMBD 这些接口都是通过中断服务程序(ISR)执行相应的任务,读者可以打开图中的函数模块查看执行内容。
接下来便是比较核心的状态机任务,如下图所示: 状态机任务 - From autoMBD 状态机StateFlow - From autoMBD 状态机的输入有两个:MotorOnOff和FaultSetClear,分别实现启停电机和处理失效情况。 状态机简而言之就是实现在不同的状态下调用不同的函数/功能。我将状态机分为了三个阶段:
第一和第三个阶段是任何时刻都会执行的,是数据反馈和算法执行的必要步骤。 第二个阶段与控制状态有关,执行的内容也不相同,是数据处理和算法的处理中心,如果要更新算法也只需要在这个阶段更改模型即可。 这三个阶段具体的任务模型如下图所示: 读ADC数据 - From autoMBD 状态切换的相应功能 - From autoMBD 更新FTM(PWM) - From autoMBD 状态机什么时候触发,什么时候执行,以及执行时间的长短,是开发时至关重要的考量因素。它直接关系到控制算法的执行效率和具体实现方式,本项目中状态机的驱动方式如下图所示: 状态机的驱动实现 - From autoMBD 每当FTM计数器到最小值的时候,会产生一个名为init_trig的触发信号,该信号可以启动PDB(Programmable delay block)延时模块开始计数,同时产生一个中断信号,该中断信号即为状态机的驱动信号。 PDB模块计数达到设定的位置时(PDB0设置为1000、1500和2000,PDB1设置为1000和2000),可以触发ADC采样;而中断信号使CPU进入到ISR中处理状态机。 FTM产生的PWM频率为20 kHz,所以状态机也以20 kHz的频率进行运算,一般的应用中,20 kHz的运算频率是完全足够的。常用的还有10 kHz、16 kHz等。 特别注意的是,状态机的总的处理时间绝对不能超过PWM的周期,正常情况下还需要保证一定的安全余量,不然会出现意想不到的后果。 关于MCU的外设模块(FTM、ADC、PDB等)工作原理,可以参考《S32K1xx Series Reference Manual》,该文档在autoMBD的资源库中可以找到。
第五个任务是Hall任务,即采集Hall位置信号的。该任务比较简单,由GPI ISR实现,如下图所示: Hall任务 - From autoMBD
系统任务用来处理一些其他非电机控制的相关任务和功能,例如点灯、通信等等。本项目的系统任务如下图所示: 系统任务 - From autoMBD 系统任务设置了三个部分:
系统任务的驱动是由“仿真步长”决定的,仿真步长在Simulink中是最小运算的时间间隔,是非实时性的。本项目中步长设置为0.001 s,即1 kHz频率。 模型的仿真步长 - From autoMBD 但在生成代码时,仿真步长会自动变成周期性的中断,驱动软件运算。在MCU中,由PIT Channel0生成与仿真步长相同间隔的中断信号,此时为实时信号,驱动整个模型中的非ISR任务。我们可以把该信号称为Step Tick: 系统任务的Step Tick - From autoMBD 实际上我们也可以认为,模型中所有的非ISR任务,都处于PIT Channel0的ISR任务中,所有我把这样的任务称为系统任务。 电机控制框架模型的六个功能区域介绍完了,下面描述的是软件的运行过程。
在电机控制框架下,所有任务的运行过程可以用下面这个图表示: MBD电机控制框架的任务过程 - From autoMBD 上图中,各个任务的中断优先级由下往上逐次增加。 当MCU上电后,软件首先进行外设初始化任务,在初始化的过程中会启动PIT计数器。 我们将PIT启动的时刻称为0.000 s,那么0.001 s时第一次进入系统任务,0.002 s时第一次进入用户旋钮任务(图中未给出)。两秒后,系统任务会启动FTM,从而启动状态机任务。 系统任务和状态机任务是周期性触发的,频率分别为1 kHz和20 kHz。用户按键任务和Hall任务是随机触发的,只有按下按键或Hall信号发生了变化才会进入到相应的任务中。 以上便是目前MBD电机控制框架全部模型介绍,目前已经在该框架上实现了BLDC的开环控制算法。 在此模型的基础上,要开发新的控制算法,例如FOC、无感控制等等,就变得比较方便了,只需要修改状态机任务中的相应功能即可(下一期的目标就是这个)。也可以在系统任务中添加新的功能,例如通信、故障检测等。 3 MBDT的问题修复 正如前面提到的,MBDT的部分代码生成功能存在一些问题,如果不修复这些问题,上述的框架模型是会编译报错的。 MBDT最新版4.2.0 - From NXP 我电脑上安装的MBDT是NXP官方最新版4.2.0,该版本的问题的具体可以描述为:使用StateFlow和自定义的数据类型时,MBDT部分模块的中断ISR生成的代码编译不能通过。 MBDT编译报错 - From autoMBD 实际上,如果我们不在这些模块的ISR中使用StateFlow和自定义的数据类型,上述问题是不会发生的。这也是为什么官方的示例工程没有出现这样的问题。 对于ISR来说,不应该有代码编写的区分,ISR中应该能编写任何合理的代码,没有任何的限制。对应的在MBD中,也应该能在ISR中搭建任何合理的模型,包括使用StateFlow和自定义数据类型,并生成可以正常工作的代码。 所以我觉得不修复这个问题是不满足MBD的要求的。 如果不修复这些问题,也能搭建MBD模型,就像官方例程那样,在有问题模块的ISR中,不使用自定义数据类型,不使用StateFlow搭建模型。 我没有全部测试过,但FTM、PDB的ISR不能使用StateFlow和自定义数据类型,PIT和ADC的ISR可以使用StateFlow和自定义数据类型,其他模块未知。 总之,我选择修复这些模块的问题。要修复这些问题,就涉及到代码生成语言Target Language Compiler(TLC)。因为前没学习过TLC,所以花费了较多的时间在这部分工作上。 Target Language Compiler的工作原理 - From MATLAB 我对TLC学习的还不够深入,也不敢冒充专家讲解这部分内容。后面如果有机会我可是尝试讲一讲TLC。这里就只给大家展示MBDT具体的修复方法。 首先需要找到MBDT的安装位置,默认情况下图这个位置: MBDT安装位置 - From autoMBD 在这个位置中找到NXP_MBDToolbox_S32K1xx\mbdtbx_s32k\blocks文件夹: MBDT模块文件 - From autoMBD 这里的blocks就是所有MBDT模块的底层源文件,包括TLC文件。在本项目中一共需要修复的文件有三个:
修复custom_init - From autoMBD
修复ftm_hall - From autoMBD
#define BLDCctrlBase_IN_NO_ACTIVE_CHILD ((uint8_T)0U) #define BLDCctrlBasedOnMBD_IN_Faults ((uint8_T)1U) #define BLDCctrlBasedOnMBD_IN_Initial ((uint8_T)2U) #define BLDCctrlBasedOnMBD_IN_NormalRun ((uint8_T)2U) #define BLDCctrlBasedOnMBD_IN_Ready ((uint8_T)3U) #define BLDCctrlBasedOnMBD_IN_Run ((uint8_T)4U) #define BLDCctrlBasedOnM_IN_Calibration ((uint8_T)1U) 修复ftm_isr - From autoMBD 完成以上工作后,模型就能正确生成代码了。 Tips: 如果在上述过程中遇到了问题,可以发私信给我一起讨论。 目前的模型适配的是NXP的电机开发套件MCSPTE1AK144,在该平台上可以直接编译本项目的电机框架模型,并生成代码。模型的功能有:
后续我也会在该平台上添加更多的功能,包括通信功能、故障检测功能、FOC、无感算法等等。欢迎持续关注。 4 在S32 DS中使用生成的代码 在MBD实战之MBDT 第3.5期:MBDT实现PIL测试中介绍了如何使用S32 DS下载生成的代码,也提到了IDE的必要性(更多信息可以阅读该文章)。但该方法还是略显繁琐,本项目中给了另一种方法。 在GitHub仓库的ProjectForDS文件夹中可以找到用于本项目的一个DS工程,要使用该工程,可以按照以下步骤: 导入BLDCctrlBasedOnMBD工程 - From autoMBD 需要注意的地方就是,导入Options不要勾选,如下图所示: 不要勾选Options - From autoMBD DS工程中的链接文件夹 - From autoMBD 链接文件夹的实际位置 - From autoMBD 通过链接文件夹的方式,不需要每次生成代码后,重复地复制一次代码,简化了操作步骤,当我们在MATLAB中生成一次代码后,代码就已经更新了。 新建Folder - From autoMBD 在Folder选项中,点击Advanced,选中Linked Folder,选择你想要链接的文件夹即可: 选中Linked Folder - From autoMBD 不过我还是建议使用Variables的相对路径方式,这样可以增强工程的移植性。 查看BLDCctrlBasedOnMBD_mbd_rtw的属性,可以看到它使用的是${PARENT-2-PROJECT_LOC}的变量路径。这样设置后,不管仓库的位置放在那里,只要保证仓库内部的路径没有发生变化,编译就不会报错。 设置相对路径 - From autoMBD 非代码文件移除编译路径 - From autoMBD 具体需要保留的文件和需要移除的文件,可参考MBD实战之MBDT 第3.5期:MBDT实现PIL测试。同样添加include路径的方法不变,也可以参考第3.5期,这里不再赘述。 GitHub仓库中的DS工程已经配置好了,和电机控制框架模型是链接好的,可以直接使用。使用时尽量避免移动仓库内的文件夹,以免产生错误。 我们不需要在S32DS中修改代码,只是使用S32DS编译和下载代码。因为MATLAB下载代码不能调试,通过DS下载代码可以调试、暂停,还可以查看寄存器,这对解决Bug很有帮助。 5 下期预告 下一期我将在现在的电机控制框架上实现FOC控制算法,欢迎持续关注。 |
|