【从零开始实现stm32无刷电机FOC】【实践】【6/7 CMSIS-DSP】

news2024/9/21 0:38:07

目录

  • 导入CMSIS-DSP库
  • 使用CMSIS-DSP

点击查看本文开源的完整FOC工程
CMSIS-DSP库是ARM开源的、对ARM处理器优化的数学库,本文使用了其提供的三角函数、反park变换函数、park变换函数、clarke变换函数、PID控制器。
CMSIS-DSP原始代码仓库是https://github.com/ARM-software/CMSIS-DSP,官方对其的介绍是一个针对Cortex-M和Cortex-A内核优化的嵌入式系统计算库,此处的DSP不是指的硬件,而是数字处理的意思。
在这里插入图片描述

导入CMSIS-DSP库

本文使用stm32cube编译好的CMSIS-DSP二进制文件,首先在Middleware and Software Packs中选择X-CUBE-ALGOBUILD:在这里插入图片描述
选择安装DSP Library,并且勾选Selection,下图为已经安装好的状态:
在这里插入图片描述
勾选DSP Library Library:
在这里插入图片描述
到此,工程代码里就能够使用CMSIS-DSP库了,只需在要使用DSP库的C源文件加上

#include "arm_math.h"

使用CMSIS-DSP

三角函数:
单独计算sin和cos三角函数,输入弧度rad:

  float32_t arm_sin_f32(float32_t x);
  float32_t arm_cos_f32(float32_t x);

单个函数完成计算sin和cos三角函数,输入角度deg:

  /**
   * @brief  Floating-point sin_cos function.
   * @param[in]  theta   input value in degrees
   * @param[out] pSinVal  points to the processed sine output.
   * @param[out] pCosVal  points to the processed cos output.
   */
  void arm_sin_cos_f32(
        float32_t theta,
        float32_t * pSinVal,
        float32_t * pCosVal);

clarke变换:

  /**
   *
   * @brief  Floating-point Clarke transform
   * @param[in]  Ia       input three-phase coordinate <code>a</code>
   * @param[in]  Ib       input three-phase coordinate <code>b</code>
   * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
   * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
   * @return        none
   */
  __STATIC_FORCEINLINE void arm_clarke_f32(
  float32_t Ia,
  float32_t Ib,
  float32_t * pIalpha,
  float32_t * pIbeta)

clarke变换是将三个相线电流投影到 α \alpha α β \beta β轴,由于三个相线电流相加等于0,因此只需要输入两个相线电流IaIb到clarke变换函数中,输出到pIalphapIbeta

park变换:

  /**
   * @brief Floating-point Park transform
   * @param[in]  Ialpha  input two-phase vector coordinate alpha
   * @param[in]  Ibeta   input two-phase vector coordinate beta
   * @param[out] pId     points to output   rotor reference frame d
   * @param[out] pIq     points to output   rotor reference frame q
   * @param[in]  sinVal  sine value of rotation angle theta
   * @param[in]  cosVal  cosine value of rotation angle theta
   * @return     none
   *
   * The function implements the forward Park transform.
   *
   */
  __STATIC_FORCEINLINE void arm_park_f32(
  float32_t Ialpha,
  float32_t Ibeta,
  float32_t * pId,
  float32_t * pIq,
  float32_t sinVal,
  float32_t cosVal)

park变换是将 α \alpha α β \beta β轴投影到dq轴,此处的sinValcosVal为转子角度的sin和cos值。

反park变换:

   /**
   * @brief  Floating-point Inverse Park transform
   * @param[in]  Id       input coordinate of rotor reference frame d
   * @param[in]  Iq       input coordinate of rotor reference frame q
   * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
   * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
   * @param[in]  sinVal   sine value of rotation angle theta
   * @param[in]  cosVal   cosine value of rotation angle theta
   * @return     none
   */
  __STATIC_FORCEINLINE void arm_inv_park_f32(
  float32_t Id,
  float32_t Iq,
  float32_t * pIalpha,
  float32_t * pIbeta,
  float32_t sinVal,
  float32_t cosVal)

反park变换是将dq轴投影到 α \alpha α β \beta β轴,此处的sinValcosVal为转子角度的sin和cos值。

PID控制器:
CMSIS-DSP库中的PID控制器是增量式PID。
位置式PID就是直观地分别将P、I、D控制器的各自输出加起来:
u ( t ) = K p e ( t ) + K i ∑ i = 0 t ( e ( i ) ∗ Δ T ) + K d [ e ( t ) − e ( t − 1 ) ] Δ T u(t) = K_p e(t) + K_i \sum_{i=0}^{t} (e(i)*\Delta T) + K_d \frac{[e(t) - e(t-1)]} {\Delta T} u(t)=Kpe(t)+Kii=0t(e(i)ΔT)+KdΔT[e(t)e(t1)]
为了方便计算,这里将 Δ T \Delta T ΔT当作为1,在 K i K_i Ki K d K_d Kd系数上缩放回去就好了。
增量式PID理念是将PID的输出是上次PID输出的基础上加上之前两次的累计误差:
u ( t ) = u ( t − 1 ) + Δ u ( t ) u(t) =u(t-1) +\Delta u(t) u(t)=u(t1)+Δu(t)
Δ u ( t ) = u ( t ) − u ( t − 1 ) = K p e ( t ) + K i ∑ i = 0 t e ( i ) + K d [ e ( t ) − e ( t − 1 ) ] − ( K p e ( t − 1 ) + K i ∑ i = 0 t − 1 e ( i ) + K d [ e ( t − 1 ) − e ( t − 2 ) ] ) = K p [ e ( t ) − e ( t − 1 ) ] + K i e ( t ) + K d [ e ( t ) − 2 e ( t − 1 ) + e ( t − 2 ) ] = A 0 ⋅ e [ n ] + A 1 ⋅ e [ n − 1 ] + A 2 ⋅ e [ n − 2 ] 其中 { A 0 = K p + K i + K d A 1 = − K p − 2 K d A 2 = K d \Delta u(t) =u(t) -u(t-1)= K_p e(t) + K_i \sum_{i=0}^{t} e(i) + K_d [e(t) - e(t-1)]\\ -(K_p e(t-1) + K_i \sum_{i=0}^{t-1} e(i) + K_d [e(t-1) - e(t-2)])\\ = K_p [e(t) - e(t-1)] + K_i e(t) + K_d [e(t) - 2e(t-1) + e(t-2)]\\ = A_0⋅e[n]+A_1⋅e[n−1]+A_2⋅e[n−2]\\ 其中 \begin{cases} A_0=K_p+K_i+K_d\\ A_1=-K_p-2K_d\\ A_2=K_d \end{cases} Δu(t)=u(t)u(t1)=Kpe(t)+Kii=0te(i)+Kd[e(t)e(t1)](Kpe(t1)+Kii=0t1e(i)+Kd[e(t1)e(t2)])=Kp[e(t)e(t1)]+Kie(t)+Kd[e(t)2e(t1)+e(t2)]=A0e[n]+A1e[n1]+A2e[n2]其中 A0=Kp+Ki+KdA1=Kp2KdA2=Kd
A 0 , A 1 , A 2 ,本次误差 e [ n ] ,上次误差 e [ n − 1 ] ,上上次误差 e [ n − 2 ] ,上一次的 P I D 输出 u ( t − 1 ) A_0,A_1,A_2,本次误差e[n],上次误差e[n-1],上上次误差e[n-2],上一次的PID输出u(t-1) A0A1A2,本次误差e[n],上次误差e[n1],上上次误差e[n2],上一次的PID输出u(t1)均为已知数,增量式PID的输出 u ( t ) u(t) u(t)也就能够计算出来了。
从增量式PID公式 Δ u ( t ) = K p [ e ( t ) − e ( t − 1 ) ] + K i e ( t ) + K d [ e ( t ) − 2 e ( t − 1 ) + e ( t − 2 ) ] \Delta u(t) = K_p [e(t) - e(t-1)] + K_i e(t) + K_d [e(t) - 2e(t-1) + e(t-2)] Δu(t)=Kp[e(t)e(t1)]+Kie(t)+Kd[e(t)2e(t1)+e(t2)]可以看出,当被控参数突然受到大的扰动时,不像位置式PID的P项 K p ∗ e ( t ) K_p*e(t) Kpe(t)会产生一个大的输出,增量式PID的 K p [ e ( t ) − e ( t − 1 ) ] K_p [e(t) - e(t-1)] Kp[e(t)e(t1)]输出是不大的,因此增量式PID对被控参数变化的输出比较平滑,不会突变,当然响应没有位置式PID快。
在代码上,首先需要创建一个PID控制器:

arm_pid_instance_f32 pid_position;

然后设置PID控制器的PID参数:

pid_position.Kp = 1.2;
pid_position.Ki = 0.01;
pid_position.Kd = 2.1;

然后调用函数初始化PID控制器:

/**
 * @brief  Initialization function for the floating-point PID Control.
 * @param[in,out] *S points to an instance of the PID structure.
 * @param[in]     resetStateFlag  flag to reset the state. 0 = no change in state & 1 = reset the state.
 * @return none.
 * \par Description:
 * \par
 * The <code>resetStateFlag</code> specifies whether to set state to zero or not. \n
 * The function computes the structure fields: <code>A0</code>, <code>A1</code> <code>A2</code>
 * using the proportional gain( \c Kp), integral gain( \c Ki) and derivative gain( \c Kd)
 * also sets the state variables to all zeros.
 */

void arm_pid_init_f32(
  arm_pid_instance_f32 * S,
  int32_t resetStateFlag)

其中参数resetStateFlag为0时,会清空PID控制器内部保存的增量式数据: e [ n ] , e [ n − 1 ] , e [ n − 2 ] e[n],e[n-1],e[n-2] e[n],e[n1],e[n2]
一般初始化的用法是:

arm_pid_init_f32(&pid_position, false);

此时就能够调用函数计算PID输出值了:

  /**
   * @brief         Process function for the floating-point PID Control.
   * @param[in,out] S   is an instance of the floating-point PID Control structure
   * @param[in]     in  input sample to process
   * @return        processed output sample.
   */
  __STATIC_FORCEINLINE float32_t arm_pid_f32(
  arm_pid_instance_f32 * S,
  float32_t in)

其中参数S是PID控制器,参数in是被控参数的差值,返回PID控制器的输出值。


至此,所有准备工作就绪,我们了解了理论推导、FOC特定外设的配置和数学库的使用,接下来进入从零开始实现stm32无刷电机FOC工程代码讲解。
点击查看本文开源的完整FOC工程

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Boot1(概要 入门 Spring Boot 核心配置 YAML JSR303数据校验 )

目录 一、Spring Boot概要 1. SpringBoot优点 2. SpringBoot缺点 二、Spring Boot入门开发 1. 第一个SpringBoot项目 项目创建方式一&#xff1a;使用 IDEA 直接创建项目 项目创建方式二&#xff1a;使用Spring Initializr 的 Web页面创建项目 &#xff08;了解&#…

cms wpscan使用方式--kali linux

WPScan是一个用于WordPress安全审计和漏洞扫描的工具&#xff0c;可以通过以下命令来使用WPScan&#xff1a; 扫描一个网站&#xff1a; wpscan --url http://example.com扫描一个网站并指定用户名和密码&#xff1a; wpscan --url http://example.com --useradmin --passwo…

Windows FFmpeg 开发环境搭建

FFmpeg 开发环境搭建 FFmpeg命令行环境搭建使用FFmpeg官方编译的库Windows编译FFmpeg1. 下载[msys2](https://www.msys2.org/#installation)2. 安装完成之后,将安装⽬录下的msys2_shell.cmd中注释掉的 rem set3. 修改pacman 镜像源并安装依赖4. 下载并编译源码 FFmpeg命令行环境…

2024年7月17日(nodejs,npm设置国内镜像,vue脚手架,远程管理ssh,踢出用户,scp命令,ssh免密登录)

1、安装nodejs服务 nodejs是一个运行1环境&#xff0c;和javajdk运行环境格式一样 [roota ~]# yum -y install nodejs.x86_64 安装完成之后&#xff0c;使用node -v 查看版本 [roota ~]# node -v v16.20.2 2、简易服务器的环境安装npm 安装包管理器 npm node packae manger [ro…

Odoo17架构概述

多层架构 Odoo遵循多层架构&#xff0c;这意味着演示&#xff0c;业务逻辑和数据存储是分开的。更具体地说&#xff0c;它使用三层架构。 UI展示层 UI表示层是 HTML5、JavaScript 和 CSS 的组合。 应用程序的最顶层是用户界面。界面的主要功能是将任务和结果转换为用户可以理…

人工智能导论-机器学习

机器学习概述 概述 本章主要介绍的机器学习的概念、发展历程、发展趋势、相关应用&#xff0c;着重拓展机监督学习和无监督学习的相关知识。 重点&#xff1a;机器学习的定义和应用&#xff1b; 难点&#xff1a;机器学习算法及分类。 机器学习 - 重要性 MachineLeaning出…

Java 网络编程(TCP编程 和 UDP编程)

1. Java 网络编程&#xff08;TCP编程 和 UDP编程&#xff09; 文章目录 1. Java 网络编程&#xff08;TCP编程 和 UDP编程&#xff09;2. 网络编程的概念3. IP 地址3.1 IP地址相关的&#xff1a;域名与DNS 4. 端口号&#xff08;port&#xff09;5. 通信协议5.1 通信协议相关的…

0718vscode问答

终于来到 qt # Question 多态 # Answer 多态是面向对象编程中的一个重要概念&#xff0c;指的是同一个接口可以有多种不同的实现方式。多态性允许我们使用一个统一的接口来处理不同类型的对象&#xff0c;从而提高代码的灵活性和可扩展性。 在Java中&#xff0c;多态可以通过以…

Gradio从入门到精通(9)---状态组件

文章目录 前言一、Error 组件初始化参数 二、Warning 组件初始化参数 三、Info 组件初始化参数 四、进度条&#xff08;Progress bars&#xff09;示例代码总结 前言 Gradio 提供了多种组件和功能&#xff0c;用于构建交互式界面和处理用户输入。以下是一些关键组件的使用和示…

Spring Boot集成syslog快速入门Demo

1.什么syslog&#xff1f; Syslog-ng是由Balabit IT Security Ltd.维护的一套开源的Unix和类Unix系统的日志服务套件。它是一个灵活的、可伸缩的系统日志记录程序。对于服务器日志集中收集&#xff0c;使用它是一个不错的解决方案。syslog-ng (syslog-Next generation) 是sysl…

<数据集>混凝土缺陷检测数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;7353张 标注数量(xml文件个数)&#xff1a;7353 标注数量(txt文件个数)&#xff1a;7353 标注类别数&#xff1a;6 标注类别名称&#xff1a;[exposed reinforcement, rust stain, Crack, Spalling, Efflorescence…

UniVue@v1.5.0版本发布:里程碑版本

前言 以后使用UniVue都推荐使用1.5.0以后的版本&#xff0c;这个版本之后&#xff0c;更新的速度将会放缓。 希望这个框架能够切实的帮助大家更好的开发游戏&#xff0c;做出一款好游戏&#xff01;本开源项目采用的开源协议为MIT协议&#xff0c;完全开源化&#xff0c;以后也…

关于黑马商城微服务拆分

1.拆分流程 大差不差分为 创建module-依赖-启动类-配置yml文件-抽取代码-数据库-配置启动项-测试 2.微服务的好处 在测试的时候明显感觉到微服务的好处 不用启动所有的项目 只是单纯一个模块比如支付就可以自己调试 非常便捷而且易开发 抽取的公共模块api也不用启动就能测试 …

Python创建Excel表和读取Excel表的基础操作

下载openpyxl第三方库 winr打开命令行输入cmd 这个如果不行可以试试其他方法&#xff0c;在运行Python代码的软件里也有直接下载的地方&#xff0c;可以上网搜索 创建Excel表 示例代码&#xff1a;最后要记得保存&#xff0c;可以加一句提示语句。 import openpyxl lst[100,…

双非一本嵌入式方向怎么学?

双非一本&#xff08;非“985”和“211”工程重点建设的本科院校&#xff09;的学生在学习嵌入式方向时&#xff0c;可以通过以下步骤和策略来系统地学习和提升自己。我收集归类了一份嵌入式学习包&#xff0c;对于新手而言简直不要太棒&#xff0c;里面包括了新手各个时期的学…

基于HAL库的stm32的OLED显示屏显示(IIC)

OLED OLED&#xff0c;即有机发光二极管( Organic Light Emitting Diode )。OLED由于同时具备自发光&#xff0c;不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性&#xff0c;被认为是下一代的平面显示器…

网络原理(中)

前言&#x1f440;~ 上一章我们介绍了传输层协议的报文格式以及协议机制&#xff0c;今天接着介绍其他层的协议 网络层 IP协议 地址管理 路由选择 数据链路层 DNS&#xff08;域名解析系统&#xff09; 如果各位对文章的内容感兴趣的话&#xff0c;请点点小赞&#xff0…

高中数学:立体几何-动态图形问题

例题1 解析 求最值&#xff0c;显然&#xff0c;是不等式问题 思路就是&#xff0c;把题目中的条件&#xff0c;翻译成一个函数&#xff0c;然后&#xff0c;利用不等式&#xff0c;求函数的最值。 例题2 解析 先用空间想象力&#xff0c;想象一下这一题的变化过程。 我们&…

Air780E 短信(短消息)测试

一、硬件信息和工具 AIR780E 开发板 usb转ttl工具串口软件文档 二、短消息基本流程 4G模块发短信基本流程如下: 1、设置为TEXT模式2、查询当前的TEXT模式短信参数3、查询字符集4、发短信给测试手机号5、输入具体信息内容发送三、指令测试 打开串口助手&#xff0c;通过usb转…

NLP教程:1 词袋模型和TFIDF模型

文章目录 词袋模型TF-IDF模型词汇表模型 词袋模型 文本特征提取有两个非常重要的模型&#xff1a; 词集模型&#xff1a;单词构成的集合&#xff0c;集合自然每个元素都只有一个&#xff0c;也即词集中的每个单词都只有一个。 词袋模型&#xff1a;在词集的基础上如果一个单词…