PID算法控制PWM占空比的代码详解

2023-10-29

PID算法控制PWM占空比

PID算法控制PWM占空比的代码

PID控制的算法代码C++,其中输出控制函数可以依据各自的项目需要进行改写。

#include<string.h>
#include<stdio.h>
typedef struct PID {
double SetPoint; // 设定目标Desired value
double Proportion; // 比例常数Proportional Const
double Integral; // 积分常数Integral Const
double Derivative; // 微分常数Derivative Const
double LastError; // Error[-1]

double PrevError; // Error[-2]
double SumError; // Sums of Errors
} PID;

/*====================================================================================================
PID计算函数
=====================================================================================================*/
double PIDCalc( PID *pp, double NextPoint )
{
    double dError, Error;
    Error = pp->SetPoint - NextPoint; // 偏差
    pp->SumError += Error; // 积分
    dError = pp->LastError - pp->PrevError; // 当前微分
    pp->PrevError = pp->LastError;
    pp->LastError = Error;
    return (pp->Proportion * Error // 比例项
    + pp->Integral * pp->SumError // 积分项
    + pp->Derivative * dError );         // 微分项
}

/*====================================================================================================
PID结构体变量初始化函数
=====================================================================================================*/
void PIDInit (PID *pp)
{
memset ( pp,0,sizeof(PID));
}

/*====================================================================================================
读取输入变量函数(在此设定为固定值100)
======================================================================================================*/
double sensor (void)  
{
return 100.0;
}

/*====================================================================================================
输出变量控制函数
======================================================================================================*/
void actuator(double rDelta)  
{
//用户自定义,可自行决定的
}

//主函数
void main(void)
{
    PID sPID; // PID Control Structure
    double rOut; // PID Response (Output)
    double rIn; // PID Feedback (Input)
    PIDInit ( &sPID ); // Initialize Structure
    sPID.Proportion = 0.5; // Set PID Coefficients
    sPID.Integral = 0.5;
    sPID.Derivative = 0.0;
    sPID.SetPoint = 100.0; // Set PID Setpoint
    for (;;)
    {                                   // Mock Up of PID Processing
        rIn = sensor ();                // 读取输入变量函数(Read Input )
        rOut = PIDCalc ( &sPID,rIn );   // PID计算函数(Perform PID Interation)
        actuator ( rOut );              // 输出变量控制函数(Effect Needed Changes)
    }
}

PWM控制函数

//############################################################
#ifndef EPWM_int_H
#define EPWM_int_H
#include "DSP2833x_Project.h"

void EPWM3_int(void); //三对PWM初始化
void HVDMC_Protection(void); //PWM的保护初始化
void  PWMDAC_int(void);   // pwm做为RC滤波的DAC输出
void  Svpwm_Outpwm(void); // SVPWM调试波形输出
void START_CAR(void);  // 开始电机控制开PWM
void STOP_CAR(void);   // 停电机控制关PWM

extern Uint16 PWM_HalfPerMax;

#endif  // end of EPWM_int_H definition
//############################################################

#include "Main_PMSM_QEncoder.h"

#define ISR_FREQUENCY     12.5
#define SYSTEM_FREQUENCY  150

float32 T = 0.001/ISR_FREQUENCY;

Uint16   PWM_PeriodMax=0, PWM_HalfPerMax=0 ,PWM_Deadband=0 ;

void EPWM3_int(void)
{
	  PWM_PeriodMax=SYSTEM_FREQUENCY*1000000*T/2;
	  PWM_HalfPerMax=PWM_PeriodMax/2;
	  PWM_Deadband  =2.0*SYSTEM_FREQUENCY;
	  EALLOW;
      EPwm1Regs.TBCTL.bit.SYNCOSEL = 0;
      EPwm2Regs.TBCTL.bit.SYNCOSEL = 0;
      EPwm3Regs.TBCTL.bit.SYNCOSEL = 0;

      EPwm1Regs.TBCTL.bit.PHSEN = 1;
      EPwm2Regs.TBCTL.bit.PHSEN = 1;
      EPwm3Regs.TBCTL.bit.PHSEN = 1;

      EPwm1Regs.TBPRD = PWM_PeriodMax;    //  6000
      EPwm2Regs.TBPRD = PWM_PeriodMax;
      EPwm3Regs.TBPRD = PWM_PeriodMax;

      EPwm1Regs.TBPHS.half.TBPHS = 0;
      EPwm2Regs.TBPHS.half.TBPHS = 0;
      EPwm3Regs.TBPHS.half.TBPHS = 0;

      EPwm1Regs.TBCTL.all = 0xA00A;
      EPwm2Regs.TBCTL.all = 0xA00A;
      EPwm3Regs.TBCTL.all = 0xA00A;

      EPwm1Regs.CMPCTL.all = 0;
      EPwm2Regs.CMPCTL.all = 0;
      EPwm3Regs.CMPCTL.all = 0;

      EPwm1Regs.AQCTLA.all = 0x0090;
      EPwm2Regs.AQCTLA.all = 0x0090;
      EPwm3Regs.AQCTLA.all = 0x0090;

      EPwm1Regs.DBCTL.all = 0x000B;  // 0x0003
      EPwm2Regs.DBCTL.all = 0x000B;  // 全一致  低电平
      EPwm3Regs.DBCTL.all = 0x000B;

      EPwm1Regs.DBFED =  PWM_Deadband;
      EPwm1Regs.DBRED =  PWM_Deadband;
      EPwm2Regs.DBFED =  PWM_Deadband;
      EPwm2Regs.DBRED =  PWM_Deadband;
      EPwm3Regs.DBFED =  PWM_Deadband;
      EPwm3Regs.DBRED =  PWM_Deadband;

      EPwm1Regs.PCCTL.all = 0;
      EPwm2Regs.PCCTL.all = 0;
      EPwm3Regs.PCCTL.all = 0;

      EPwm1Regs.TZSEL.all = 0;
      EPwm2Regs.TZSEL.all = 0;
      EPwm3Regs.TZSEL.all = 0;

      EDIS;                         /* Disable EALLOW*/
}

// GPIO12引脚硬件过流触发保护引脚,硬件母线电流与电压比较低电平有效保护关闭6路PWM
void HVDMC_Protection(void)
{
      EALLOW;

      EPwm1Regs.TZSEL.bit.CBC6=0x1;
      EPwm2Regs.TZSEL.bit.CBC6=0x1;
      EPwm3Regs.TZSEL.bit.CBC6=0x1;

      EPwm1Regs.TZSEL.bit.OSHT1   = 1;  //enable TZ1 for OSHT
      EPwm2Regs.TZSEL.bit.OSHT1   = 1;  //enable TZ1 for OSHT
      EPwm3Regs.TZSEL.bit.OSHT1   = 1;  //enable TZ1 for OSHT

      EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
      EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWMxB will go low

      EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
      EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWMxB will go low

      EPwm3Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
      EPwm3Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWMxB will go low

      EDIS;

//************************** End of Prot. Conf. ***************************//
}

void  Svpwm_Outpwm(void)
{
	 // Tabc=0.5*Svpwmdq.Tabc+0.5
   EPwm1Regs.CMPA.half.CMPA = _IQmpy(PWM_HalfPerMax,Svpwmdq.Ta)+ PWM_HalfPerMax;
   EPwm2Regs.CMPA.half.CMPA = _IQmpy(PWM_HalfPerMax,Svpwmdq.Tb)+ PWM_HalfPerMax;
   EPwm3Regs.CMPA.half.CMPA = _IQmpy(PWM_HalfPerMax,Svpwmdq.Tc)+ PWM_HalfPerMax;
}

void STOP_CAR(void)           //  上下桥臂 全为低
{
	EALLOW;
	 EPwm1Regs.DBCTL.bit.POLSEL = 0;
	 EPwm2Regs.DBCTL.bit.POLSEL = 0;
	 EPwm3Regs.DBCTL.bit.POLSEL = 0;

	 EPwm1Regs.AQCSFRC.all = 0x05;
	 EPwm2Regs.AQCSFRC.all = 0x05;
	 EPwm3Regs.AQCSFRC.all = 0x05;
	 EDIS;
}


void START_CAR(void)   //   上下桥臂 对称互补
{
	EALLOW;
	 EPwm1Regs.DBCTL.bit.POLSEL = 2;
	 EPwm2Regs.DBCTL.bit.POLSEL = 2;
	 EPwm3Regs.DBCTL.bit.POLSEL = 2;

	 EPwm1Regs.AQCSFRC.all = 0x00;
	 EPwm2Regs.AQCSFRC.all = 0x00;
	 EPwm3Regs.AQCSFRC.all = 0x00;
	EDIS;
}

// EPWM6在除正交编码器的永磁同步电机FOC控制中运用  将数字量转换模拟量可以在示波器上显示变化规律
// 其他程序代码做用PWM输出数字量通过RC电阻低通滤波后就可以测到数据波形,例如马鞍矢量波
// https://blog.csdn.net/qq_27334499/article/details/52186336

void  PWMDAC_int(void)  // PWMDAC
{
   EALLOW;
   EPwm6Regs.TBCTL.bit.SYNCOSEL = 0;
   EPwm6Regs.TBCTL.bit.PHSEN = 1;
   EPwm6Regs.TBPRD =4000;
   EPwm6Regs.TBPHS.half.TBPHS = 0;
   EPwm6Regs.TBCTL.all = 0xA00A;
   EPwm6Regs.CMPCTL.all = 0x0000;
   EPwm6Regs.AQCTLA.all = 0x0090;
   EPwm6Regs.AQCTLB.all = 0x0900;
   EPwm6Regs.DBCTL.all = 0x0000;
   EPwm6Regs.PCCTL.all = 0x0000;
   EPwm6Regs.TZSEL.all = 0x0000;
   EPwm6Regs.TZCTL.all = 0x0000;
   EDIS;
}


//===========================================================================
// No more.
//===========================================================================

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PID算法控制PWM占空比的代码详解 的相关文章

  • echarts 暂无数据的完美解决办法

    前景 很简单的一个思想 我希望没有数据的时候 不显示图表 并且用empty来替换 但是直接使用v if 会出错 因为调用的时候 拿不到dom了 v if直接把dom干掉了 怎么办呢 直接上步骤 1 第一步 我们应该在每次点击按钮的时候 发送
  • EM算法及其推广---《统计学习方法》第9章

    EM算法是一种迭代算法 用于含有隐变量的概率模型参数的极大似然估计 或极大后验概率估计 EM算法的每次迭代由两步组成 E步求期望值 M步求最大值 EM算法是一种对模型参数的估计 该模型中含有隐变量 EM算法的引入 EM算法 概率模型有时既含
  • 即时通讯(IM)开源项目OpenIM每周迭代版本发布-音视频实时通话-v2.0.4

    介绍 OpenIM每周五发布新版 包括新特性发布 bug修复 同时合并PR 由于2 0版本重构完毕 架构更清晰 代码更规范 先邀请各位参与OpenIM社区建设 包括技术开发 技术分享等 特性开发 性能优化 bug修复等 有兴趣的同学可以加我
  • 使用burpsuite抓不到127.0.0.1本地包(针对Firefox浏览器)

    解决方法一 首先第一步点击浏览器右上角按钮 点击设置 点击常规 设置 按照如图设置 设置完毕后基本能解决问题 如果不行还有第二种解决方式 解决方法二 浏览器地址栏种输入 about config 搜索框输入如下 把值改为true即可 net
  • Spring Cloud微服务-网关(2)

    微服务网关Zuul 为什么需要微服务网关 不同的微服务一般有不同的网络地址 而外部的客户端可能需要调用多个服务的接口才 能完成一个业务需求 比如一个电影购票的收集APP 可能回调用电影分类微服务 用户 微服务 支付微服务等 如果客户端直接和
  • 二叉树的创建、遍历、深度、叶子节点数

    回忆一下 呵呵 include
  • Qt 打开本地文件夹,限定文件类型的两种方式

    需要打开本地文件夹的情况还挺多 比如File下面的open new save等功能 下面介绍两种打开本地文件夹的方式 第一种 QFileDialog getOpenFileName 函数 函数定义如下 QString QFileDialog
  • 树搜索:深度优先和广度优先

    在Android开发中 有时候会遇到多层级列表的显示 如下图 可用RecyclerView实现 其数据源的数据结构是一种树状结构 如下图 现在有两种方法来遍历这种数据结构 深度优先搜索 其过程简要来说是对每一个可能的分支路径深入到不能再深入
  • 基于springboot+vue民宿管理系统+数据库(附源码,说明文档)

    文章目录 开发环境 后端 前端 数据库 系统架构 管理员 用户用例 主要功能 用户功能模块 管理员功能模块 商家用户功能模块 前台首页功能模块 今天为大家带来的是 基于springboot vue民宿管理系统 开发环境 后端 开发语言 Ja
  • 理解线性回归(一)——回归的思想

    理解线性回归 一 回归的思想 1 经典的线性回归 之前介绍的LR回归和SVM算法本质上都和回归有写关联 尤其是LR回归算法 回归的目的是预测数值型的目标值 其核心部分和我们中小学时候学习到的线性拟合是一样的 就是说 假如我们能够建立了回归背
  • 刷脸支付三大优势让人回归万物本源

    3D人脸识别技术已实现检测人脸是否为活体 杜绝图片或视频破解 其高精度 高效率 高安全性催生刷脸支付 刷脸门禁 刷脸乘车 刷脸登机等应用落地 在5G AI引爆的万物互联未来 人回归智能万物的中心 脸成为无缝连接所有生活场景的重要途径 近期大
  • Python及pip安装与报错处理【pip永久换源】

    有帮助的话请点个赞吧 文章目录 安装新版本Python Linux系统 以Ubuntu16 04为例 Windows系统 Win10 pip换源 Linux系统 Windows系统 安装新版本Python Linux系统 以Ubuntu16
  • 微信小程序 引入字体图标 字体 使用base64解决字体请求问题

    在做公司的项目的时候 引入了奥森字体图标 控制台对这个url有报错提示 虽然字体显示正常 但还是想解决这个烦人的报错 试过加载目录中的fontawesome webfont ttf 静态资源但是加载不上 最后把ttf字体转换成base64格
  • 「司库立方」获数亿元C轮融资,持续聚焦司库赛道,引领行业变革

    今天 头部司库玩家 司库立方 宣布成功获得数亿元C轮融资 本轮融资由云晖资本领投 中信建投资本 贵阳创投 神骐资本 58产业基金 跟投 老股东信天创投持续追投 本轮融资资金主要用于迭代产品 加强市场推广 提升客户服务和体验 进一步扩大公司在
  • 史上最简单的SpringCloud教程

    在微服务架构中 根据业务来拆分成一个个的服务 服务与服务之间可以相互调用 RPC 在Spring Cloud可以用RestTemplate Ribbon和Feign来调用 为了保证其高可用 单个服务通常会集群部署 由于网络原因或者自身的原因
  • CAD平台开发和基于此平台的二次开发(数据库部分)

    CAD平台开发分为两大部分 一是底层开发 即CAD数据库的开发 底层类和结构 二是上层开发 界面和功能实现 本人目前在一个开发CAD平台的公司 工作 目前主要接触的是上层开发这一部分 没有底层开发的部分的代码 只有编号的底层数据库的DLL
  • MIPI DSI AP介绍(一)FPGA

    MIPI DSI AP介绍 一 FPGA MIPI DSI Mobile Industry Processor Interface Display Serial Interface 是一种用于移动设备显示的串行接口协议 它的主要特点是高带宽
  • 深入浅出PID控制算法(二)——PID算法离散化和增量式PID算法原理及Matlab仿真

    文章目录 1 PID算法离散化 1 1 位置式PID算法 1 2 增量式PID算法 2 PID编程实现及控制仿真 3 PID调参过程 3 1 确定比例系数Kp 3 2 确定积分时间常数Ti 3 3 确定微分时间常数Td 3 4 系统空载 带
  • C++ 修改/覆盖指定位置的文件内容或者从某个位置开始截断文件

    最新在进行文件方面的功能开发 遇到个这样的问题 1 文件读到中间 然后进行一些修改 2 然后将文件从修改后的地方截断 本以为这是个简单的操作 却花费了好大的功夫 网上并没有这样的例子 一通尝试 现在终于圆满解决了 特地记录一下 方便后来人
  • Linux 系统告警报“ inode”空间不足引起数据库启动失败

    启动数据库报错 错误如下 SQL gt startup nomount pfile oracle admin ecis ecis ora1 ORA 27154 post wait create failed ORA 27300 OS sys

随机推荐