基于DSP的三相开关霍尔永磁同步电机控制
0 前言
本文本应该是一篇 记录我使用DSP28377D控制一个基于三相开关霍尔传感器的高速永磁同步电机全过程的长文,但大部分零散的知识点我都已经写成单独的博客了,所以本文更像是一个知识框架的梳理。本文最终目的是实现高速PMSM的电流-速度双闭环,将电机速度控制在80r/s左右,精度越高越好。
1 硬件的理解
图1 硬件连接
如图1所示,被控对象是一个永磁同步电机,然后在永磁同步电机定子的底部,安装了三个三相对称的开关型霍尔传感器,可以用于检测电机的转速和电角度。 永磁同步电机的输入电压,是由一个型号为DRV8322DKD的驱动芯片给出的三相电压输出。该芯片主要的作用是把三相PWM输入波形,转换成三相电压输出。另外,提供便捷的测量三相电流的通道,而电流的采集是用的型号为MAX40056FAUA/V的芯片, 拿到了三相电机的电流、转速以及电角度,DSP要作为控制器需要去设计相应的控制算法,然后输出相应的三相PWM波形,形成闭环。 每当DSP输出一次PWM波形的时候,可以同时触发下一次的电流采集转换。这令电流环的实现就非常的丝滑,不得不说DSP在这点上的设计还是很好的。
2 DSP底层外设驱动学习
对于初学DSP的人来讲,在DSP的底层驱动外设之前,一个完美的DSP28377D程序框架搭建是基础中的基础。这部分的内容在本文就不展开讲了,请参考DSP_基于TMS320F28377D双核芯片和CCS7.40的编程入门_江湖上都叫我秋博的博客-CSDN博客_tms320f28377
另外,根据图1可以总结出,要实现PMSM的速度环控制,需要掌握的DSP底层外设驱动包括三个部分,我已经把坑全部填完了,请参考下面三篇博客。
2.1 ADC模块的使用
DSP_TMS320F28377D_ADC学习笔记_江湖上都叫我秋博的博客-CSDN博客
2.2 ePWM模块的使用
DSP_TMS320F28377D_ePWM学习笔记_江湖上都叫我秋博的博客-CSDN博客
2.3 eCAP模块的使用
DSP_TMS320F28377D_eCAP学习笔记_江湖上都叫我秋博的博客-CSDN博客
如果要把DSP部分的内容扩充更详细、更丰富,对定时器的使用、系统的中断配置也是需要补充的,两个部分的坑,我尽快填上。
2.4 CPU Timer模块的使用
关于定时器实现 <获取代码块运算时间>的功能,也是可以浅看一下。量化某代码段的运行时间对于一个系统而言,也是比较重要的,而不是你觉得它能在多少时间内运行完。
DSP_TMS320F28377D_使用定时器实现<获取代码块运算时间>的功能_江湖上都叫我秋博的博客-CSDN博客
当然,定时器对于控制系统而言更重要的作用,是实现系统的软分频功能。利用软分频得到的固定频率标志,可以便捷的实现控制器的离散化控制。
DSP_TMS320F28377D_CPU Timer学习笔记_江湖上都叫我秋博的博客-CSDN博客
2.5 PIE及中断模块的使用
DSP中的很多模块(例如ADC、eCAP、CPU Timer)都需要使用中断,因此中断配置的学习也是一个必不可少的基础知识,下面还需要填个坑。
3 永磁同步电机控制
在学习了必要的DSP基础知识之后,更多的重心就要放到控制相关的内容,与控制相关的内容可以大概分为5个部分,传感器的标定与解算、永磁同步电机的FOC控制、被控对象系统辨识、电流环与速度环的PI控制器设计、控制精度优化。下面将会展开讲本人对于这5个部分内容的理解。
3.1 传感器的标定与解算
对于本文所涉及的三相开关霍尔永磁同步电机,它包含的传感器主要有两个,一个是三相开关霍尔,一个是电流采集传感器(或芯片)。
3.1.1三相开关霍尔
三相开关霍尔用于获取电机的电角度与电机的机械转速,对于这部分知识,我也单独写了一篇博客。
传感器_三相-双极性-开关型-霍尔传感器 速度+电角度解算理解_开关型霍尔传感器_江湖上都叫我秋博的博客-CSDN博客
这篇博客写的还有点瑕疵,我再补充一下我的标定办法。
3.1.2电流采集
关于电路采集传感器,是用电流采集芯片。此系统使用该芯片采集了电机ia和ib的两相电流。
关于电流采集芯片的使用,碰巧在之前的工作中也记录了,参考下面这篇博客。
STM32_ADC模块及针对芯片MAX40056FAUA/V+的使用_江湖上都叫我秋博的博客-CSDN博客
为什么系统只采集电机的ia和ib两相的电流,不采集ic呢?我也在另一篇博客中写了一些我自己的理解。
STM32_FOC_1_Clarke变换计算iα和iβ为何仅用ia ib两相电流_αβ变换电压电流_江湖上都叫我秋博的博客-CSDN博客
下面在补充一下去零偏的方法。
3.2 永磁同步电机的FOC控制
对于初学者学习FOC控制来讲,华为的天才少年稚晖君写了一篇很好的文章,值得反复阅读。
【自制FOC驱动器】深入浅出讲解FOC算法与SVPWM技术 - 知乎 (zhihu.com)
本人对FOC的理解很浅,直接贴电流环开环代码做个备份,感兴趣的朋友也可以借鉴一下,老鸟朋友如果看出有什么问题,也希望你们不要吝啬给我指出(评论或者私信都可以哟)。
void currentopenloop(void){float TempVar1 = 0.0f;float TempVar2 = 0.0f;theta = getElecAngle1();sin_theta = __sin(theta);cos_theta = __cos(theta);// Anti-ParkV_Alpha = (id*cos_theta - iq*sin_theta);V_Beta = (id*sin_theta + iq*cos_theta);// 确定扇区TempVar1 = V_Alpha * 0.86602540378444f;TempVar2 = V_Beta * 0.5f;SectorJudgmentFactor1 = TempVar1 - TempVar2;SectorJudgmentFactor2 = - TempVar1 - TempVar2;SectorNum = 0;if( V_Beta >= 0)SectorNum = SectorNum + 1;if( SectorJudgmentFactor1 >= 0 )SectorNum = SectorNum + 2;if( SectorJudgmentFactor2 >= 0 )SectorNum = SectorNum + 4;// 计算中间变量X Y ZMiddleTerm_X = V_Beta;MiddleTerm_Y = TempVar1 + TempVar2;MiddleTerm_Z = -TempVar1 + TempVar2;// ? where is √3*Ts/Vdc ?// 作用时间计算switch(SectorNum){case 0:t_cm1 = 0;t_cm2 = 0;t_cm3 = 0;break;case 1: /*Sector 1: t_1st = Z and t_2nd = Y (Tcm1/2/3 ---> Tb,Ta,Tc)*/t_first = MiddleTerm_Z;t_second = MiddleTerm_Y;// 过调制处理if(t_first + t_second > 1){t_firstaddsecond = t_first + t_second;t_first = __divf32(t_first,t_firstaddsecond);t_second = __divf32(t_second,t_firstaddsecond);}t_a = (1 - t_first - t_second) * 0.5; // ? why not (Ts - t_first - t_second) / 4t_b = t_a + t_first;t_c = t_b + t_second;t_cm1 = t_b;t_cm2 = t_a;t_cm3 = t_c;break;case 2: /*Sector 2: t_1st = Y and t_2nd = -X (Tcm1/2/3 ---> Ta,Tc,Tb)*/t_first = MiddleTerm_Y;t_second = -MiddleTerm_X;// 过调制处理if(t_first + t_second > 1){t_firstaddsecond = t_first + t_second;t_first = __divf32(t_first,t_firstaddsecond);t_second = __divf32(t_second,t_firstaddsecond);}t_a = (1 - t_first - t_second) * 0.5; // ? why not (Ts - t_first - t_second) / 4t_b = t_a + t_first;t_c = t_b + t_second;t_cm1 = t_a;t_cm2 = t_c;t_cm3 = t_b;break;case 3: /*Sector 3: t_1st = -Z and t_2nd = X (Tcm1/2/3 ---> Ta,Tb,Tc)*/t_first = -MiddleTerm_Z;t_second = MiddleTerm_X;// 过调制处理if(t_first + t_second > 1){t_firstaddsecond = t_first + t_second;t_first = __divf32(t_first,t_firstaddsecond);t_second = __divf32(t_second,t_firstaddsecond);}t_a = (1 - t_first - t_second) * 0.5; // ? why not (Ts - t_first - t_second) / 4t_b = t_a + t_first;t_c = t_b + t_second;t_cm1 = t_a;t_cm2 = t_b;t_cm3 = t_c;break;case 4: /*Sector 4: t_1st = -X and t_2nd = Z (Tcm1/2/3 ---> Tc,Tb,Ta)*/t_first = -MiddleTerm_X;t_second = MiddleTerm_Z;// 过调制处理if(t_first + t_second > 1){t_firstaddsecond = t_first + t_second;t_first = __divf32(t_first,t_firstaddsecond);t_second = __divf32(t_second,t_firstaddsecond);}t_a = (1 - t_first - t_second) * 0.5; // ? why not (Ts - t_first - t_second) / 4t_b = t_a + t_first;t_c = t_b + t_second;t_cm1 = t_c;t_cm2 = t_b;t_cm3 = t_a;break;case 5: /*Sector 5: t_1st = X and t_2nd = -Y (Tcm1/2/3 ---> Tc,Ta,Tb)*/t_first = MiddleTerm_X;t_second = -MiddleTerm_Y;// 过调制处理if(t_first + t_second >= 1){t_firstaddsecond = t_first + t_second;t_first = __divf32(t_first,t_firstaddsecond);t_second = __divf32(t_second,t_firstaddsecond);}t_a = (1 - t_first - t_second) * 0.5; // ? why not (Ts - t_first - t_second) / 4t_b = t_a + t_first;t_c = t_b + t_second;t_cm1 = t_c;t_cm2 = t_a;t_cm3 = t_b;break;case 6: /*Sector 6: t_1st = -Y and t_2nd = -Z (Tcm1/2/3 ---> Tb,Tc,Ta)*/t_first = -MiddleTerm_Y;t_second = -MiddleTerm_Z;// 过调制处理if(t_first + t_second >= 1){t_firstaddsecond = t_first + t_second;t_first = __divf32(t_first,t_firstaddsecond);t_second = __divf32(t_second,t_firstaddsecond);}t_a = (1 - t_first - t_second) * 0.5; // ? why not (Ts - t_first - t_second) / 4t_b = t_a + t_first;t_c = t_b + t_second;t_cm1 = t_b;t_cm2 = t_c;t_cm3 = t_a;break;default:break;}EPwm1Regs.CMPA.bit.CMPA = (Uint16)(t_cm1*EPWM1_TIMER_TBPRD);EPwm2Regs.CMPA.bit.CMPA = (Uint16)(t_cm2*EPWM2_TIMER_TBPRD);EPwm3Regs.CMPA.bit.CMPA = (Uint16)(t_cm3*EPWM3_TIMER_TBPRD);
}
3.3 被控对象系统辨识
谈起被控对象辨识,简直说多了都是泪啊,这个控制系统竟然没有留和上位机的通信接口,我以前写过一个基于串口通信的控制调试软件,里面就包含了系统辨识的功能,而且是集美貌与才华于一身的软件,我还给她取了一个名字:Angela。Angela就像我的女儿一样,必须给大家介绍一下。
Angela运行视频
Angela不仅支持DSP,她还有一个同卵双胞胎AngelaS(支持在STM32平台上使用),AngelaS用到的核心技术之一可以参考STM32_上位机高效通信技术_stm32用v9如何使用上位机_江湖上都叫我秋博的博客-CSDN博客。
好了,收!别过度沉迷Angela,安利结束。 回过头来,我们还需要面对现实。得益于CCS强大的功能,虽然DSP没有留和上位机的通信接口,但是我们仍然可以实现无通信接口系统辨识。详情请看如下三篇博客。
DSP_CCS7实现变量的导出与MatLAB读取_ccs怎么导出数组数据_江湖上都叫我秋博的博客-CSDN博客
DSP_定义一个大的全局数组_探索之路_江湖上都叫我秋博的博客-CSDN博客
DSP_无通信接口系统辨识_江湖上都叫我秋博的博客-CSDN博客
3.4 电流环与速度环的PI控制器设计
辨识完了被控对象,设计控制器还不是轻轻松松,本小节的内容,并不会告诉大家PI参数怎么整定(这个我也不会),但是我会告诉大家一个利用MatLAB设计PI控制器的小技巧。这东西还是有点妙的。
在我们辨识得到的被控对象之后
可以利用sisotool把辨识得到的被控对象导入
导入被控对象后,就可以自动整定PI参数
使用上诉提到的方法得到PI控制器,基本的闭环控制一般都没问题,包括id iq电流环、速度环。但是要想得到更好的精度,那就需要微调和各种优化了。
3.5 控制精度优化
由于三相开关霍尔所得到的电角度分辨率太低!(真的是低得扣脚了),另外我对FOC的电流环、速度环优化控制方法学习不够,所以速度环闭环精度总是达不到理想的效果,为了达到更好的速度环闭环精度,我调了接近两周的控制参数。下面总结一下我认为有效的优化方法。
1、优化电角度估计(匀速模型) | √ |
2、电流环不加惯性环节 | √ |
3、id、iq添加前馈去耦合(但各参数我都不知道,就瞎调了几个参数) | × |
4、ia、ib、ic、id、iq添加低通滤波(我做实验是真的没效果) | × |
5、提高电流环开环执行频率(有提升,但不大) | √ |
6、ia ib的电流采集使用多通道,然后取均值的方式 | × |
7、ia ib的电流解算的偏置量,使用取前1000个电机不运行数据的均值 | × |
8、电流环的控制器设计成二阶(两个积分环节) | × |
各位大佬有什么好的文献或者优化思路,望不吝赐教,评论区|私信 走起。
4 结束语
放个电机的运行视频吧,精度还不够,大家看个热闹吧
PMSM运行视频
另外,前面内容需要填的坑,我会尽快填上的。
愿我们共同进步! 感谢您的阅读,欢迎留言讨论、收藏、点赞、分享。
相关文章:

基于DSP的三相开关霍尔永磁同步电机控制
0 前言 本文本应该是一篇 记录我使用DSP28377D控制一个基于三相开关霍尔传感器的高速永磁同步电机全过程的长文,但大部分零散的知识点我都已经写成单独的博客了,所以本文更像是一个知识框架的梳理。本文最终目的是实现高速PMSM的电流-速度双闭环&#x…...
Vue和React的对比
1、响应式原理不同 vue:vue会遍历data数据对象,使用Object.definedProperty()将每个属性都转换为getter和setter,每个Vue组件实例都有一个对应的watcher实例,在组件初次渲染的时候会记录组件用到了那些数据,当数据发生…...
移动进阶之高效开发
响应式布局 媒体查询的语法 /* 4.媒体特性 *//* width / max-width / min-width *//* -webkit-device-pixel-ratio / -webkit-max-device-pixel-ratio / -webkit-min-pixel-ratio *//* orientation: landscape / portrait *//* media screen and (min-width: 320px) {body {b…...
用户手册:遥测服务之推送至 TDengine
创建TelemetryService Yaml 文件 apiVersion: shifu.edgenesis.io/v1alpha1 kind: TelemetryService metadata:name: push-endpoint-1namespace: devices spec:telemetrySeriveEndpoint: http://telemetryservice.shifu-service.svc.cluster.localserviceSettings:SQLSetting:…...

软件测试的主要工作内容是什么
平时说起程序员印象中大都是做Java、做前端、做后端,用着非常晦涩难懂的语言。在电脑前哐哐哐,没一会满屏代码显现出来。然而程序员并不全是印象中这样,还有一部分:他们不常写代码,主要去检查代码,是不是出…...

【云原生kubernetes】k8s中job与cronjob使用详解
一、前言 job,顾名思义就是任务,job的概念在很多框架中都有,而且实际业务场景中也使用非常广泛,比如大家熟悉的hadoop,客户端可以向集群提交一个job,然后集群根据一定的调度策略来处理这个job; …...
js-cookie的使用
实际上,cookie本身并不是用来做服务器存储的,关于jscookie存储的理解,可以参考我记录的js的数据存储专栏。 Cookie 是一些数据, 存储于客户端电脑上的文本文件中,其中记录了用户的用户名、密码、浏览的网页、停留的时间等等信息。…...
c++11 关键字 override 使用
写在最前。。。 请支持原创~~ 1. 功能 用在类中成员函数声明的地方,用以标记一个virtual function 是重写另一个 virtual function; 2. 语法 只声明时,override 紧跟参数的右括号,如果是纯虚函数,override 会出现在…...

从16K跳槽到20K,最后算下来年薪却还降了,我笑了····
跳槽时薪资涨了 4000,但年薪总包算下来反而变少了,这是怎么回事? 上周,我星球里一个同学就遇到了这么一个问题,薪资涨了、总包降了,而且谈薪时把自己坑了。 作为一个案例,我觉得对很多人可能会…...

线性表 链表表示
初识链表 用一组物理位置任意的存储单元来存放线性表的数据元素。这组存储单元既可以是连续的,也可以是不连续的,甚至是零散分布在内存中的任意位置上的。链表中元素的逻辑次序和物理次序不一定相同。 在存储自己内容的同时也存储下一个元素的地址。存…...
面试题JavaScript篇(二)
目录 一、内存泄露 1、是什么 2、导致的原因 二、垃圾回收机制的策略 三、浅拷贝和深拷贝 1、浅拷贝 .slice() ...展开运算符 Object.assign(目标对象, 被复制的对象) ...展开运算符 2、深拷贝 structuredClone() 浏览器提供 JSON.parse(JSON.stringify(obj)) …...

项目管理工具dhtmlxGantt甘特图入门教程(十五):从MS项目导入/导出(下)
这篇文章给大家讲解dhtmlxGantt请求大文件导入的大小限制。 dhtmlxGantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表,可满足应用程序的所有需求,是完善的甘特图图表库 DhtmlxGantt正版试用下载(qun 764148812)https:…...

2023 年 6 大智能合约语言
如果你想成为一名 Web3 开发人员,你需要知道如何编写智能合约,智能合约是所有 Web3 应用程序的支柱。 简而言之,智能合约是在区块链网络上部署和执行的计算机程序,提供确定性保证,使多方能够达成一致的、防篡改的结果…...

家用洗地机哪款最好用?全球洗地机十大品牌
近年来,智能家用电器洗地机已经融入到我们生活中了,成为最受欢迎的清洁工具了,家用洗地机吸拖洗一体,不用先扫后拖那么麻烦,只需轻轻一推,就能把扫地、拖地、擦地的活全干了,操作简单࿰…...

【2223sW2】LOG1
写在前面 好好学习,走出宿舍,走向毕设! 一些心路历程记录,很少有代码出现 因为鬼知道哪条代码到时候变成毕设的一部分了咧,还是不要给自己的查重挖坑罢了 23.2.27 文件批量重命名 为了给学姐先整出来一批训练数据&…...
Spring Cloud配置application.yml与bootstrap.yml区别及多profile配置 | Spring Cloud 6
一、前言 Spring Cloud 构建于 Spring Boot 之上,在 Spring Boot 中有两种上下文,一种是 bootstrap,另外一种是 application。 1.1 两者区别 bootstrap.yml/bootstrap.properties 和 application.yml/application.yml 都可以用来配置参数。…...

springboot通过aop实现全局日志(是否自定义注解都可以)
内容参考自以下两个链接1、springboot中使用AOP切面完成全局日志_aop全局日志_邹飞鸣的博客-CSDN博客使用AOP记录日志_aop日志_trusause的博客-CSDN博客第一个链接思路很清晰,讲的也很详细,第二个链接讲了自定义注解为了便于自己理解做了以下整理目录 1.aspectj基本概念 2.添加…...
k8s面试题-进阶
1、简述etcd及其特点etcd是CoreOS团队发起的开源项目,是一个管理配置信息和服务发现(service discovery)的项目,它的目标是构建一个高可用的分布式键值(key-value)数据库,基于Go语言实现。特点&…...

预览版Edge申请微软new Bing失败解决方案
文章目录1.首先需要配置科学上网2.下载预览版Edge浏览器卡它bug!卡它bug!卡它bug!没有申请上ChatGPT的朋友们,试试new Bing吧,更新更强大,关于申请方式,网上已经有很多帖子了,其中一…...

Spring中Bean生命周期及循环依赖
spring中所说的bean对象 与 我们自己new的对象(原始对象)是不同的;bean对象是指spring框架创建管理的我们的对象生命周期即:何时生,何时死1.实例化 Instantiation:spring通过反射机制以及工厂创建出来的原始对象;2.属性…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...