基于凌鸥LKS32MC037鱼缸用FOC潜水泵控制器

  随着老百姓生活水平的提高,室内养殖观赏型鱼类的人越来越多,这就催生了鱼缸内小型潜水泵的市场发展。
早期鱼缸潜水泵都采用的方波驱动的控制器。随着技术的进步和芯片成本的下降,本文介绍的基于无感FOC算法潜水泵控制器已经成熟应用并且大批量产,
新型的正弦波FOC控制器相比较早期的方波控制器有如下几点优点:

   平滑水流: 正弦波控制器可以产生平滑的电流输出,从而驱动潜水泵产生平滑的水流,有助于水族生物的健康生长。
   节能: 正弦波控制器能够以更高效的方式驱动潜水泵,节省能源并降低能源消耗成本。
   精确控制: 正弦波控制器可以精确控制潜水泵的转速和水流量,根据需要调节水流强度,提供更好的水族环境。
   减少噪音: 正弦波控制器驱动的潜水泵通常运行更平稳,产生的噪音相对较少,提供一个更安静的水族环境。
   长寿命: 正弦波控制器的稳定输出可以减少潜水泵的振动和磨损,延长潜水泵的使用寿命。
   
本控制器采用国产凌鸥芯片LKS32MC037电机开发平台,采用先进的FOC算法,FOC(Field-Oriented Control,场向量控制)是一种电机控制技术,
旨在实现对三相交流电机的精确控制。在无感FOC水泵控制器中,该技术被应用于控制水泵的电机,以实现更高效、更精确的水流控制。
实现潜水泵的小功率低噪声平稳运行。

主要代码实现如下:

## 1.主代码函数框架
 
程序框架主要由,State_machine状态机接口模块,Foc_Control控制模块,Fault故障检测模块。

整体框架如下图:
Static_machine程序模块主要由以下函数模块:

Task_Scheduler()时间片执行函数组成,包含1ms任务调度,
主要包括FaultCheck()函数模块和sys_state_machine()状态机函数模块。
10ms,100ms的时间调度,用来处理反应不是特别快的进程。


Foc_Control控制模块主要由以下函数模块:
McPWM0_IRQhandler()中断处理函数,包含FOC_Model函数进程模块。
Foc_Model()模块包含AdcSampleCal(),OpenCloseAngleSwitch(),CurrentLoopReg(),
Svpwm()等Foc控制模块的主要组成部分,能实现FOC的电流检测,检测Clark,Park变化,
以及DQ方向轴上的电流环,最后输出产生SVPWM电压信号。

Foc_control控制模块的矢量电机控制的框架包括坐标转换、电流控制、磁场定向、速度调节和闭环控制等步骤,
通过精确控制电机的电流和转矩,实现对电机的高效、高性能的控制。

## 2.Foc控制算法  
## 2.1 FOC框图
无感FOC控制软件主运动控制包含速度环+D轴电流环+Q轴电流环+SVPWM模块组成,
采用目标速度和当前测量的速度值Error产生速度环的输入,与设定的速度Ramp进行比较,运行速度环,
通过最大速度的限制.速度环的输出作为Q轴电流环的输入,
D轴电流环的设定值恒为0。经过两路电流环的计算,输入到反PARK变换,最后经过SVPWM模块,生成3路三路相差120度的交流波形。


## 2.2 无感观测器
软件模块 FluxObserveParaCalc() 用于估计系统状态变量,它基于系统的数学模型和测量输出,
通过一个动态补偿器来估计系统的状态,并输出估计值。龙贝格观测器通过观测系统的输出,如电压或电流,
以及已知的系统模型,推断系统的内部状态变量,例如电网频率和相位。通过比较实际输出和观测器估计的输出,可以不断调整观测器的参数,
使其逼近实际状态。PLL算法(Phase-Locked Loop):原理: PLL算法是一种用于跟踪信号频率和相位的闭环控制技术。
它通过比较输入信号和本地参考信号的相位差,并根据相位差的变化调整本地参考信号的频率和相位,使其与输入信号同步。
龙伯格观测器+PLL收敛算法,适用于大部分的水泵驱动方案,硬件要求低,启动稳定,能满足大部分需求!
本观测器已批量匹配应用三段式 Align+OpenLoop+CloseLoop无感启动方式.


## 3.部分代码
```
int main(void) {

    SoftDelay(50000);     /* 延时等待硬件初始化稳定 10000--2.56ms*/
    __disable_irq();      /* 关闭中断 中断总开关 */
    Hardware_init();      /* 硬件初始化 */
    sys_init();           /* 系统初始化 */
    __enable_irq();       /* 开启总中断 */
    for(;;)
    {
        Task_Scheduler(); /* 任务调度函数,根据时间分片处理 */
    }
}
```
```
/*******************************************************************************
 函数名称:    void Sys_State_Machine(stru_FOC_CtrProcDef *this)
 功能描述:    系统状态机 电机状态各状态切换调度
 输入参数:    无
 输出参数:    无
 返 回 值:    无
 其它说明:
 修改日期      版本号          修改人            修改内容
 -----------------------------------------------------------------------------
 2020/8/5      V1.0           Howlet Li          创建
 *******************************************************************************/
 ```
 ```
void Sys_State_Machine(void)
{
    switch (struFOC_CtrProc.eSysState)
    {
    case IDLE:
    {   /* 空闲状态 */

        if (struFOC_CtrProc.bMC_RunFlg)
        {
            StateInit();

#if (ROTOR_SENSOR_TYPE == ROTOR_SENSORLESS)
            struFOC_CtrProc.eSysState = CHARGE; /* 进入充电状态 */
#else
#if ((ROTOR_SENSOR_TYPE == ROTOR_HALL_SENSOR)||(ROTOR_SENSOR_TYPE ==ROTOR_HALL2SENSORLESS))
            if(GET_HALL_LEARN_STATE())
            {   /* 进入HALL自学习状态 */
                PWMOutputs(MCPWM0, ENABLE);
                struFOC_CtrProc.eSysState = HALL_LEARN;
            }
            else
            {
                StateInit();
                PWMOutputs(MCPWM0, ENABLE);
                struFOC_CtrProc.eSysState = HALL_RUN;   //有Hall运行
            }
#endif
#endif
        }
        break;
    }
    case CHARGE:
    {
        StateCharge();                         //预充电处理函数
        break;
    }
    case BEMF_CHECK:                          /*反电动势检测*/
    {
        StateBemfDirCheck();                  //反电势检测函数
        break;
    }

    case DIR_CHECK:                           //顺逆风检测状态
    {
        StateDirCheck();                      //顺逆风处理函数
        break;
    }
    case INIT:
    {   /* 初始化状态 */
        StateInit();
       
#if (ROTOR_SENSOR_TYPE == ROTOR_SENSORLESS)
        {
            struFOC_CtrProc.eSysState = ALIGN;
        }
#elif (ROTOR_SENSOR_TYPE == ROTOR_HALL_SENSOR)
        {   //纯有感  根据hall 反馈
            struFOC_CtrProc.eSysState = HALL_RUN;
        }

#endif
        break;
    }
    case POS_SEEK:                            //初始位置检测状态
    {
        StatePosSeek();                       //初始位置检测处理函数
        struFOC_CtrProc.eSysState = INIT;

        break ;
    }
    case ALIGN:                                //预定位状态
    {
              PWMOutputs(MCPWM0, ENABLE);
        StateAlign();                          //预定位处理函数

        break ;
    }
    case OPEN_RUN:                                //开环强拖状态
    {
        StateOpen();                          //开环处理函数
        break ;
    }
    case RUN:
    {   /* 运行状态  */

        StateRun();                           //闭环处理函数
        break;
    }
    case HALL_RUN:
    {
        StateHallRun();
        break;
    }

    case HALL_LEARN:
    {
#if ((ROTOR_SENSOR_TYPE == ROTOR_HALL_SENSOR)||(ROTOR_SENSOR_TYPE == ROTOR_HALL2SENSORLESS))
        if(GET_HALL_LEARN_STATE() == HALL_LEARN_FINISH)
        {
            PWMOutputs(MCPWM0, DISABLE);
            SetTimeOut_Counter(struFOC_CtrProc.nSetTimeLeftCnt, STATE_MACHINE_200MS);
            struFOC_CtrProc.eSysState = WAIT;
        }
#endif
        break;
    }
    case BRAKE:
    {   /* 电机刹车状态 */
        StateStop();                          //停止判定处理函数
        SetTimeOut_Counter(struFOC_CtrProc.nSetTimeLeftCnt, STATE_MACHINE_200MS);
        break;
    }
    case BEMF_BRAKE:  /* 反电势刹车处理*/
    {
        StateBemfStop();
        break;
    }
    case WAIT:
    {   /* 等待状态 */
        if (SetTime_IsElapsed(struFOC_CtrProc.nSetTimeLeftCnt))
        {
            struFOC_CtrProc.eSysState = IDLE;
        }

        break;
    }
    case FAULT:
    {   /* 故障状态 */
        StateFault();                         //故障处理函数
        if(stru_Faults.R == 0)
        {
            struFOC_CtrProc.eSysState = IDLE;
        }

        break;
    }
    default:
    {
        break;
    }
    }

    if((struFOC_CtrProc.bMC_RunFlg == 0) && (stru_Faults.R == 0))   //无故障并且启动标志位清0,关闭输出,进入空闲状态
    {
        PWMOutputs(MCPWM0, DISABLE);
        SetTimeOut_Counter(struFOC_CtrProc.nSetTimeLeftCnt, STATE_MACHINE_200MS);
        struFOC_CtrProc.eSysState = WAIT;
    }
}
```
## 4.硬件原理图

批量生产的原理图。

详细请参考 嵌入式老杨的博客  www.youysoft.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/908219.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WMV怎么转MP4?五个简单好用的视频格式转换方法!

WMV格式,全称为Windows Media Video,是由微软公司开发的一种视频文件格式。采用先进的视频压缩技术,能够在保持较高视觉质量的同时,显著减小文件体积,经常被用于在网络环境下即时观看或收听高质量的音视频内容。同时&a…

unity搭建场景学习

unity搭建场景学习 创建场景创建gameobject创建材质,用于给gameobject上色拖拽材质球上色上色原理设置多个材质方式设置贴图的方式 效果设置光滑度一些预览设置菜单渲染模型与碰撞模型网格渲染参数1. materials(材质)2. lighting(光照)3. reflection probes(反射探针…

C++ Qt

一、概念 跨平台的图形应用界面应用程序框架。 二、常用快捷键 快捷键解释F4在对应的.cpp和.h之间快速切换ctrl b编译程序ctrl r运行程序ctrl shift ↑ / ↓向上 / 下移动选中的代码ctrl i自动对齐选中的代码 三、对象树 总结:父控件被析构,包含…

爬虫笔记22——当当网图书详情页静、动态数据爬取

当当网动态数据爬取 静态数据爬取动态数据爬取接口参数的获取 静态数据爬取 进入图书详情,这里的图书数据信息比如标题、价格、图片都是非结构化数据,可以使用xpath语法提取。是很简单的数据采集了,就不细说了。 动态数据爬取 滑到下面这里的…

zip文件加密成图片文件-到解密

加密 1,准备:图片 zip文件 2,新建一个.txt 根据自己的对应文件修改: copy 图片名.后缀/b压缩包名.后缀自定义图片名.后缀注意,图片后缀最后保持一至,测试了 jpg png 压缩包 zip 3,把上…

【深度学习】Bert下载和使用(以bert-base-uncased为例)

【深度学习】Bert下载和使用(以bert-base-uncased为例) 代码报错报错原因解决方法解决步骤1.进入Hugging Face,检索bert-base-uncased2.点击Files and versions3.下载文件4.下载的文件放入文件夹5.代码修改 代码报错 bert BertModel.from_p…

Java基于SpringBoot 的校园外卖点餐平台微信小程序(附源码,文档)

大家好,我是Java徐师兄,今天为大家带来的是Java基于SpringBoot 的校园外卖点餐平台微信小程序。该系统采用 Java 语言 开发,MySql 作为数据库,系统功能完善 ,实用性强 ,可供大学生实战项目参考使用。 博主介…

ES索引:索引管理

索引管理 再讲索引(Index)前,我们先对照下 ElasticSearch Vs 关系型数据库: PUT /customer/_doc/1 {"name": "DLBOY" }系统默认是自动创建索引的 如果我们需要对这个建立索引的过程做更多的控制&#xff1a…

Python小游戏20——超级玛丽

首先,你需要确保你的Python环境中安装了pygame库。如果还没有安装,可以使用以下命令进行安装: bash pip install pygame 运行效果展示 代码展示 python import pygame import sys # 初始化pygame pygame.init() # 设置屏幕尺寸 screen_width …

ZDH权限-扩展支持数据权限

目录 项目源码 预览地址 安装包下载地址 ZDH权限模块 ZDH权限扩展更细粒度方案 第一种方案: 第二种方案: ZDH权限扩展支持数据权限-新增属性 总结 感谢支持 项目源码 zdh_web: GitHub - zhaoyachao/zdh_web: 大数据采集,抽取平台 预览地址 后…

Unity humanoid 模型头发动画失效问题

在上一篇【Unity实战笔记】第二十二 提到humanoid 模型会使原先的头发动画失效,如下图所示: 头发摆动的是generic模型和动画,不动的是humanoid模型和动画 一开始我是尝试过在模型Optimize Game objects手动添加缺失的头发骨骼的,奈…

数据结构之线段树

线段树 线段树(Segment Tree)是一种高效的数据结构,广泛应用于计算机科学和算法中,特别是在处理区间查询和更新问题时表现出色。以下是对线段树的详细解释: 一、基本概念 线段树是一种二叉搜索树,是算法竞…

Kubernetes——part9-2 kubernetes集群java项目上云部署

一、部署前准备工作 1.1 部署项目情况 1.1.1 业务部署架构 单体服务架构分布式服务架构微服务架构超微服务架构 1.1.2 项目涉及第三方服务 关系型数据库系统 MySQL缓存服务 Redis memcache协调服务 zookeeper消息中间件服务 kafka rabbitmq服务注册 服务发现 nacos 1.1.3…

Verilog实现的莫尔斯电码发生器

莫尔斯或者摩尔斯电码(Morse Code),发明于1837年(另有一说是1836年),通过不同的排列顺序来表达不同的英文字母、数字和标点符号,在这里作一简单处理,仅产生点(Dit)和划(Dah),时长在0.25秒之内为点,超过为划…

【输出1到N之间的偶数】

【输出1到N之间的偶数】 C语言实现C实现Java实现Python实现 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 请写程序实现输出1-N之间的所有偶数。 输入 输入一个整数N 输出 如果N<1输出error&#xff0c;否则&#xff0c;输出1-N之间…

Mac上的免费压缩软件-FastZip使用体验实测

FastZip是Mac上的一款免费的压缩软件&#xff0c;分享一下我在日常使用中的体验 压缩格式支持7Z、Zip&#xff0c;解压支持7Z、ZIP、RAR、TAR、GZIP、BZIP2、XZ、LZIP、ACE、ISO、CAB、PAX、JAR、AR、CPIO等所有常见格式的解压 体验使用下来能满足我所有的压缩与解压的需求&a…

华为云计算知识总结——及案例分享

目录 一、华为云计算基础知识二、华为云计算相关案例实战案例一&#xff1a;搭建弹性云服务器&#xff08;ECS&#xff09;并部署Web应用案例二&#xff1a;构建基于OBS的图片存储和分发系统案例三&#xff1a;基于RDS的高可用数据库应用案例四&#xff1a;使用华为云DDoS防护保…

RHCE——DNS域名解析服务器、selinux、防火墙

1、DNS简介 DNS &#xff08; Domain Name System &#xff09;是互联网上的一项服务&#xff0c;它作为将域名和 IP 地址相互映射的一个分布式 数据库&#xff0c;能够使人更方便的访问互联网。 DNS 系统使用的是网络的查询&#xff0c;那么自然需要有监听的 port 。 DNS 使…

使用PostgreSQL进行高效数据管理

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 使用PostgreSQL进行高效数据管理 PostgreSQL简介 安装PostgreSQL 在Ubuntu上安装PostgreSQL 在CentOS上安装PostgreSQL 在macOS上…

实现GUI界面中的logo图片的编码与隐藏

实现GUI界面中的logo图片的编码与隐藏 一、问题描述二、解决办法 一、问题描述 利用PyQt5编写的GUI界面&#xff0c;有时候需要我们添加自定义的图片来作为UI界面的logo&#xff0c;在源码使用时&#xff0c;logo的形式一般不影响使用&#xff0c;但是当我们需要将软件进行打包…