打印
[其他ST产品]

stm32直流电机PID控制hal库(Cubemx)

[复制链接]
手机看帖
扫描二维码
随时随地手机跟帖
61
花间一壶酒sd|  楼主 | 2023-10-27 01:15 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
DataScop_DP.c
#include "DataScop_DP.h"

unsigned char DataScope_OutPut_Buffer[42] = {0};           //串口发送缓冲区
//函数说明:将单精度浮点数据转成4字节数据并存入指定地址
//附加说明:用户无需直接操作此函数
//target:目标单精度数据
//buf:待写入数组
//beg:指定从数组第几个元素开始写入
//函数无返回
void Float2Byte(float *target,unsigned char *buf,unsigned char beg)
{
    unsigned char *point;
    point = (unsigned char*)target;          //得到float的地址
    buf[beg]   = point[0];
    buf[beg+1] = point[1];
    buf[beg+2] = point[2];
    buf[beg+3] = point[3];
}
//函数说明:将待发送通道的单精度浮点数据写入发送缓冲区
//Data:通道数据
//Channel:选择通道(1-10)
//函数无返回
void DataScope_Get_Channel_Data(float Data,unsigned char Channel)
{
        if ( (Channel > 10) || (Channel == 0) ) return;  //通道个数大于10或等于0,直接跳出,不执行函数
  else
  {
     switch (Channel)
                {
      case 1:  Float2Byte(&Data,DataScope_OutPut_Buffer,1); break;
      case 2:  Float2Byte(&Data,DataScope_OutPut_Buffer,5); break;
                  case 3:  Float2Byte(&Data,DataScope_OutPut_Buffer,9); break;
                  case 4:  Float2Byte(&Data,DataScope_OutPut_Buffer,13); break;
                  case 5:  Float2Byte(&Data,DataScope_OutPut_Buffer,17); break;
                  case 6:  Float2Byte(&Data,DataScope_OutPut_Buffer,21); break;
                  case 7:  Float2Byte(&Data,DataScope_OutPut_Buffer,25); break;
                  case 8:  Float2Byte(&Data,DataScope_OutPut_Buffer,29); break;
                  case 9:  Float2Byte(&Data,DataScope_OutPut_Buffer,33); break;
                  case 10: Float2Byte(&Data,DataScope_OutPut_Buffer,37); break;
                }
  }         
}
//函数说明:生成 DataScopeV1.0 能正确识别的帧格式
//Channel_Number,需要发送的通道个数
//返回发送缓冲区数据个数
//返回0表示帧格式生成失败
unsigned char DataScope_Data_Generate(unsigned char Channel_Number)
{
        if ( (Channel_Number > 10) || (Channel_Number == 0) ) { return 0; }  //通道个数大于10或等于0,直接跳出,不执行函数
  else
  {       
         DataScope_OutPut_Buffer[0] = ';  //帧头
               
         switch(Channel_Number)   
   {
                 case 1:   DataScope_OutPut_Buffer[5]  =  5; return  6;  
                 case 2:   DataScope_OutPut_Buffer[9]  =  9; return 10;
                 case 3:   DataScope_OutPut_Buffer[13] = 13; return 14;
                 case 4:   DataScope_OutPut_Buffer[17] = 17; return 18;
                 case 5:   DataScope_OutPut_Buffer[21] = 21; return 22;  
                 case 6:   DataScope_OutPut_Buffer[25] = 25; return 26;
                 case 7:   DataScope_OutPut_Buffer[29] = 29; return 30;
                 case 8:   DataScope_OutPut_Buffer[33] = 33; return 34;
                 case 9:   DataScope_OutPut_Buffer[37] = 37; return 38;
     case 10:  DataScope_OutPut_Buffer[41] = 41; return 42;
   }         
  }
        return 0;
}

使用特权

评论回复
62
花间一壶酒sd|  楼主 | 2023-10-27 01:16 | 只看该作者
DataScop_DP.h
#ifndef __DATA_PRTOCOL_H
#define __DATA_PRTOCOL_H

extern unsigned char DataScope_OutPut_Buffer[42];           //待发送帧数据缓存区


void DataScope_Get_Channel_Data(float Data,unsigned char Channel);    // 写通道数据至 待发送帧数据缓存区

unsigned char DataScope_Data_Generate(unsigned char Channel_Number);  // 发送帧数据生成函数


#endif

使用特权

评论回复
63
花间一壶酒sd|  楼主 | 2023-10-27 01:16 | 只看该作者
这里我们需要上位机软件,软件在群文件中可以获取;
为了防止发生串口发送和上位机解析的错误,我们将it.c的定时器中断中串口发送注释。

使用特权

评论回复
64
花间一壶酒sd|  楼主 | 2023-10-27 01:16 | 只看该作者

然后可以对自己的pid进行调整,本例中pid调节达到预期效果设置每0.01s产生26个脉冲。

使用特权

评论回复
65
花间一壶酒sd|  楼主 | 2023-10-27 01:16 | 只看该作者
pid控制位置
上一节中我们使用pi增量式来控制电机的转速,当然你也可以自己增加d项,这个也比较简单,这一章我们将使用pid的位置式来控制电机的位置(位置式并不是来控制位置的,相关的基础知识可在百度中查询)
有了上面的pi速度调节的经验后我们在实现pid位置调节的时候就可以轻车熟路了。

使用特权

评论回复
66
花间一壶酒sd|  楼主 | 2023-10-27 01:18 | 只看该作者
对相关函数进行编写
main.c
/*
*位置控制的相关全局变量
*
*/
int CurrentPosition,Target_Position=260;//当前位置(从转动位置开始现在的总脉冲数+加-减),预期位置
int moto_position;//电机pwm变量
float Position_KP=120,Position_KI=0.1,Position_KD=500; //PID系数

使用特权

评论回复
67
花间一壶酒sd|  楼主 | 2023-10-27 01:18 | 只看该作者
it.c
在中断服务函数中我们把原来的Control_function() 函数注释掉换为:Control_Position();

使用特权

评论回复
68
花间一壶酒sd|  楼主 | 2023-10-27 01:18 | 只看该作者
control.c

我们先外部声明(extern)一下刚刚在main.c中创建的全局变量
现在我们编写位置控制函数:
/*
*        函数功能: 位置算法
*        入口参数:无
*        返回值:无
*/
void Control_Position(void)
{
        CurrentPosition+=Encoder_count;//将编码器读取的(速度)积分得到位置
        moto_position=Position_PID(CurrentPosition,Target_Position);    //===位置PID控制器
        limiting_Pwm();                                                                                                                                                                         //===PWM限幅
        Set_Pwm(moto_position);
       
}

/*
*        函数功能:位置式PID控制器
*        入口参数:编码器测量位置信息,目标位置
*        返回  值:电机PWM
*        根据位置式离散PID公式
*        pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]
*        e(k)代表本次偏差
*        e(k-1)代表上一次的偏差  
*        ∑e(k)代表e(k)以及之前的偏差的累积和;其中k为1,2,,k;
*        pwm代表输出
**************************************************************************/
int Position_PID (int position,int target)
{        
         static float Bias,Pwm,Integral_bias,Last_Bias;
         Bias=target-position;                                  //计算偏差
         Integral_bias+=Bias;                                         //求出偏差的积分
         if(Integral_bias>3000)Integral_bias=3000;                                //对积分 限幅
         if(Integral_bias<-3000)Integral_bias=-3000;                //积分限幅 防止到达目标位置后过冲
         Pwm=Position_KP*Bias+Position_KI*Integral_bias+Position_KD*(Bias-Last_Bias);       //位置式PID控制器
         Last_Bias=Bias;                                       //保存上一次偏差
         return Pwm;                                           //增量输出
}

使用特权

评论回复
69
花间一壶酒sd|  楼主 | 2023-10-27 01:18 | 只看该作者
控制电机转动位置的公式
本例程式10ms读取一次编码器(100HZ),我使用的电机的减速比为10,霍尔编码器的精度为13,又我们式AB双相的所以我们是4倍频,那么电机转一圈编码器读取为 10×13×4=520 我的设置的为260,自然就是正向转动半圈。

使用特权

评论回复
70
chenqianqian| | 2023-10-27 07:47 | 只看该作者
一看开头以为是原创,看到末尾结果是转载。

使用特权

评论回复
71
童雨竹| | 2023-12-1 07:09 | 只看该作者

PCB也会使电源工作不稳定

使用特权

评论回复
72
Wordsworth| | 2023-12-1 08:12 | 只看该作者

这些交流电流的峰值有可能是连续输入或输出直流电流的2~5倍

使用特权

评论回复
73
Clyde011| | 2023-12-1 09:15 | 只看该作者

让PCB顶层和底层一样,将它们通过一些过孔(或通孔)连接

使用特权

评论回复
74
Uriah| | 2023-12-1 12:14 | 只看该作者

电源中都有一个交流电压最大的节点

使用特权

评论回复
75
帛灿灿| | 2023-12-1 14:10 | 只看该作者

功率开关管交流电流环路

使用特权

评论回复
76
Bblythe| | 2023-12-1 15:13 | 只看该作者

一个地是连接控制集成电路和与之相关的无源器件的地

使用特权

评论回复
77
周半梅| | 2023-12-1 17:09 | 只看该作者

传送交流信号的引线要尽可能短且宽

使用特权

评论回复
78
Pulitzer| | 2023-12-1 18:12 | 只看该作者

引线上的电压降比较大

使用特权

评论回复
79
周半梅| | 2023-12-1 19:15 | 只看该作者

电容工作在额定的纹波电流下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则