FOC电机驱动开发踩坑记录

server/2024/10/19 8:41:52/

关键技术

  • SVPWM电机磁场控制
  • 电流采样
  • park变换和Clark变换
  • 滑膜观测器(无感FOC

SVPWM_6">SVPWM电机磁场控制

SVPWM主要思想是通过精确的对UVW三相电流的分时控制,来控制转子的合成力矩,达到目标方向,常用的是6分区的设计,SVPWM是一种通过工程设计出来的处理程序,不是算法,主要参考实现的博客:
https://blog.csdn.net/qlexcel/article/details/74787619
示例代码:

// 使用查找表来替代三角函数的计算(示例,需要根据实际需要生成表格)
#define SIN_TABLE_SIZE 720 // 假设我们使用720项的查找表
float sinTable[SIN_TABLE_SIZE]; // 预先计算的正弦表
float cosTable[SIN_TABLE_SIZE]; // 预先计算的余弦表// 初始化正弦和余弦查找表
void initTrigTables() {for (int i = 0; i < SIN_TABLE_SIZE; ++i) {sinTable[i] = sinf((TWO_PI * i) / SIN_TABLE_SIZE);cosTable[i] = cosf((TWO_PI * i) / SIN_TABLE_SIZE);}
}void SVPWM(float Uq, float Ud, float angle) {if (Uq>0){angle = normalizeAngle(angle);}else{angle = normalizeAngle(angle);}// 使用查找表获取正弦和余弦表int index = (int)((angle / TWO_PI) * SIN_TABLE_SIZE) % SIN_TABLE_SIZE;float sin_angle = sinTable[index]; // sinf(angle_el);float cos_angle = cosTable[index]; // cosf(angle_el);float ua, ub;inverse_park_transform(Ud, Uq, &ua, &ub, cos_angle, sin_angle);float ts = 1.0;float udc = voltage_supply;float u1, u2, u3;inverse_clark_transflorm(ua, ub, &u1, &u2, &u3);int A = u1 > 0 ? 1 : 0;int B = u2 > 0 ? 1 : 0;int C = u3 > 0 ? 1 : 0;int N = 4 * A + 2 * B + C;int sector = 0;int sector_map[7] = {0, 6, 4, 5, 2, 1, 3}; // 0 index not usedsector = sector_map[N];float K = SQRT3_OVER_2 * ts / udc;float t1, t2, t3, t4, t5, t6, t7, k;switch (sector) {case 1:t4 = u3 * K;t6 = u1 * K;if (t4 + t6 > ts) {k = ts / (t4 + t6);t4 *= k;t6 *= k;}t7 = (ts - t4 - t6) / 2.0;ta = t4 + t6 + t7;tb = t6 + t7;tc = t7;break;case 2:t2 = -u3 * K;t6 = -u2 * K;if (t2 + t6 > ts) {k = ts / (t2 + t6);t2 *= k;t6 *= k;}t7 = (ts - t2 - t6) / 2.0;tb = t2 + t6 + t7;ta = t6 + t7;tc = t7;break;case 3:t2 = u1 * K;t3 = u2 * K;if (t2 + t3 > ts) {k = ts / (t2 + t3);t2 *= k;t3 *= k;}t7 = (ts - t2 - t3) / 2.0;tb = t2 + t3 + t7;tc = t3 + t7;ta = t7;break;case 4:t1 = -u1 * K;t3 = -u3 * K;if (t1 + t3 > ts) {k = ts / (t1 + t3);t1 *= k;t3 *= k;}t7 = (ts - t1 - t3) / 2.0;tc = t1 + t3 + t7;tb = t3 + t7;ta = t7;break;case 5:t1 = u2 * K;t5 = u3 * K;if (t1 + t5 > ts) {k = ts / (t1 + t5);t1 *= k;t5 *= k;}t7 = (ts - t1 - t5) / 2.0;tc = t1 + t5 + t7;ta = t5 + t7;tb = t7;break;case 6:t4 = -u2 * K;t5 = -u1 * K;if (t4 + t5 > ts) {k = ts / (t4 + t5);t4 *= k;t5 *= k;}t7 = (ts - t4 - t5) / 2.0;ta = t4 + t5 + t7;tc = t5 + t7;tb = t7;break;default:ta = tb = tc = 0.0;break;}__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, (uint32_t)(ta/ts*MAX_DUTY_CYCLE));__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, (uint32_t)(tb/ts*MAX_DUTY_CYCLE));__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, (uint32_t)(tc/ts*MAX_DUTY_CYCLE));
}

电流采样

电机的三相电流采样有3种采样的方法,1种是3相电流全部采样,好处是能采到三相的实时真实电流,缺点是成本是最高的;第二种是2相电流采样,通过3相电流之和为0可以算出第3相的电流,好处是降低了一些成本,缺点是精度没有3相的高;第三种是在总的电路上采样总电流,通过算法算出3相电流的值,好处是成本是最低的,缺点是精度也是最差的;
电机的电流采样电阻的采样位置有3种:1. 输出电流采样,优点是能够实时采到三相电流,缺点是对于采样器件例如INI181的电压耐受范围有要求,电压承受能力不够可能会导致器件损坏;2. 低压区域采样,优点是对应器件的电压承受能力要求低,缺点是需要精确控制采样的时间,采样时间必须在H桥的下臂导通时进行采样,否则采样不到正确的电流;3. 母线电流采样,仅在有效矢量时刻进行电流采样,同样存在采样盲区。

park变换和Clark变换

park变换和Clark变换为经典的变换,可以从很多博客上看原理,代码示例如下:

 #include "main.h"
#include "tools.h"
#define SQRT3_OVER_2 0.866void clark_transform(float u1, float u2, float u3, float *ualpha, float *ubeta){*ualpha = 0.66666*(u1 - 0.5*u2 - 0.5*u3);*ubeta = 0.6666*(u2*SQRT3_OVER_2 - SQRT3_OVER_2 * u3);
}void inverse_clark_transflorm(float ualpha, float ubeta, float *u1, float *u2, float *u3){*u1 = ualpha;*u2 = -0.5*ualpha + SQRT3_OVER_2 * ubeta;*u3 = -0.5*ualpha - SQRT3_OVER_2 * ubeta;
}
void park_transform(float ialpha, float ibeta, float cos_angle, float sin_angle, float *id, float *iq){*id = ialpha * cos_angle + ibeta * sin_angle;*iq = -ialpha * sin_angle + ibeta *cos_angle;
}
void inverse_park_transform(float id, float iq, float *ialpha, float *ibeta, float cos_angle, float sin_angle){*ialpha = id * cos_angle - iq * sin_angle;*ibeta = id * sin_angle + iq * cos_angle;
}

滑膜观测器

通过使用上面的技术和代码,可以做到有感FOC的控制了,但是想要不使用转子位置传感器的话还要在控制时使用一些算法。常用的无感FOC控制算法有滑膜控制器、龙博格观测器,基本都是靠观测器加锁相环来实现对转子角度位置的估计,但是都会有一些问题,滑膜控制器的问题是可能会出现电机震荡,可以通过调整参数的大小来降低震荡的幅度但一定会有。滑膜变阻器的MATLAB仿真图如下:
在这里插入图片描述

踩坑记录

  • park变换与反变换和clark变换与反变换要对应好,SVPWM中的变换必须和电流采样时的每条线的顺序都相同;
  • 电流采样时使用的是下桥采样,需要控制好采样时间,采样时间要在下桥臂导通的时候采样;
  • 使用中心对称的PWM模式;

http://www.ppmy.cn/server/126436.html

相关文章

行为设计模式 -策略设计模式- JAVA

策略设计模式 一 .简介二. 案例2.1 抽象策略&#xff08;Strategy&#xff09;类2.2 具体策略&#xff08;Concrete Strategy&#xff09;类2.3 环境&#xff08;Context&#xff09;类2.4 测试 三. 结论3.1 优缺点3.2 使用场景 前言 这是我在这个网站整理的笔记,有错误的地方请…

关于鸿蒙next 调用系统权限麦克风

使用app的时候都清楚&#xff0c;想使用麦克风、摄像头&#xff0c;存储照片等&#xff0c;都需要调用系统的权限&#xff0c;没有手机操作系统权限你也使用不了app所提供的功能&#xff0c;虽然app可以正常打开&#xff0c;但是你需要的功能是没办法使用的。今天把自己在鸿蒙学…

51单片机的光照强度检测【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机LCD1602显示模块光照传感器按键蜂鸣器LED等模块构成。适用于光照强度检测、光照强度测量报警等相似项目。 可实现功能: 1、LCD1602实时显示光照强度信息 2、光照强度传感器&#xff08;电位器模拟&#xff09;采集光照信息 3、可…

Docker Init 实战详解:从入门到精通

1. 引言 在容器化应用开发的世界里,Docker 一直是首选工具。然而,对于初学者来说,创建 Dockerfile 和设置 Docker 环境可能是一个挑战。为了简化这个过程,Docker 引入了 docker init 命令。本文将深入探讨 Docker Init 的方方面面,从其诞生背景到高级应用,为您提供全面的…

玩转springboot之springboot定制化tomcat

定制化tomcat springboot中是集成了tomcat容器的&#xff0c;如何定制化内置的tomcat呢&#xff1f;springboot提供了定制化的接口 1.5.x版本 在1.5.x版本中使用的是EmbeddedServletContainerCustomizer接口来进行定制化的 public class MyTomcatCustomizer implements Embedde…

爬虫入门 Selenium使用

爬虫入门 & Selenium使用 特别声明&#x1f4e2;&#xff1a;本教程只用于教学&#xff0c;大家在使用爬虫过程中需要遵守相关法律法规&#xff0c;否则后果自负&#xff01;&#xff01;&#xff01; 项目代码&#xff1a;https://github.com/ziyifast/ziyifast-code_inst…

56 门控循环单元(GRU)_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录门控循环单元&#xff08;GRU&#xff09;门控隐状态重置门和更新门候选隐状态隐状态 从零开始实现初始化模型参数定义模型训练与预测 简洁实现小结练习 门控循环单元&#xff08;GRU&#xff09; 之前我们讨论了如何在循环神经网络中计算梯…

MySQL--数据库约束(详解)

目录 一、前言二、概念三、数据库约束3.1 约束类型3.1.1 NOT NULL 约束3.1.2 UNIQUE (唯一&#xff09;3.1.3 DEFAULT&#xff08;默认&#xff09;3.1.4 PRIMARY KEY&#xff08;主键&#xff09;3.1.5 FOREIGN KEY&#xff08;外键&#xff09;3.1.6 CHECK 四、总结 一、前言…