标题:
STM32 PID精准控制电机转到指定位置源程序
[打印本页]
作者:
吴浩
时间:
2019-4-23 21:43
标题:
STM32 PID精准控制电机转到指定位置源程序
步进电机转到指定位置
单片机源程序如下:
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "beep.h"
#include "encoder.h"
#include "timer.h"
int main(void)
{
vu8 key=0;
delay_init(); //延时函数初始化
uart_init(9600); //=====串口初始化
Encoder_Init_TIM2(); //=====编码器接口
TIM6_Int_Init(99,7199); //10MS进入一次中断
TIM3_PWM_Init(7199,0); //不分频。PWM频率=72000000/900=80Khz
while(1)
{
key=KEY_Scan(0); //得到键值
if(key)
{
switch(key)
{
case WKUP_PRES: //控制蜂鸣器
LED0=!LED0;
break;
case KEY2_PRES: //控制LED0翻转
LED0=!LED0;
break;
case KEY1_PRES: //控制LED1翻转
LED1=!LED1;
break;
case KEY0_PRES: //同时控制LED0,LED1翻转
LED0=!LED0;
LED1=!LED1;
break;
}
}else delay_ms(10);
}
}
复制代码
#include "control.h"
#define PI 3.141592653
#include "sys.h"
int Encoder,Target_position=10280; //Encoder编码器的脉冲计数,相当于实际速度 Target_velocity目标速度 一周1040脉冲 初始位置10000在encoder.c中设置
int Moto; //电机PWM变量 应是Motor的 向Moto致敬
void TIM6_IRQHandler(void) //TIM6中断 函数实现了编码器角速度线速度的计算 10MS进入一次中断
{
if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否
{
TIM_ClearITPendingBit(TIM6, TIM_IT_Update ); //清除TIMx更新中断标志
Encoder=Read_Encoder(2);
printf("位置%d\r\n",Encoder);
Moto=Position_PID(Encoder,Target_position); //===位置PID控制器
Xianfu_Pwm(); //===PWM限幅
Set_Pwm(Moto); //===赋值给PWM寄存器
}
}
/**************************************************************************
函数功能:赋值给PWM寄存器
入口参数:PWM
返回 值:无
**************************************************************************/
void Set_Pwm(int moto1)
{
if(moto1<0) IN2=1, IN1=0; //换向引脚
else IN2=0, IN1=1;
TIM_SetCompare2(TIM3,myabs(moto1));
}
/**************************************************************************
函数功能:限制PWM赋值
入口参数:无
返回 值:无
**************************************************************************/
void Xianfu_Pwm(void)
{
int Amplitude=5000; //===PWM满幅是7200 限制在7100
if(Moto<-Amplitude) Moto=-Amplitude;
if(Moto>Amplitude) Moto=Amplitude;
}
/**************************************************************************
函数功能:绝对值函数
入口参数:int
返回 值:unsigned int
**************************************************************************/
int myabs(int a)
{
int temp;
if(a<0) temp=-a;
else temp=a;
return temp;
}
/**************************************************************************
函数功能:增量PI控制器
入口参数:编码器测量值,目标速度
返回 值:电机PWM
根据增量式离散]]PID公式
pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]
e(k)代表本次偏差
e(k-1)代表上一次的偏差 以此类推
pwm代表增量输出
在我们的速度控制闭环系统里面,只使用PI控制
pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)
**************************************************************************/
int Position_PID (int Encoder,int Target)
{
float Position_KP=10,Position_KI=0.1,Position_KD=40;
static float Bias,Pwm,Integral_bias,Last_Bias;
Bias=Encoder-Target; //计算偏差
Integral_bias+=Bias; //求出偏差的积分
Pwm=Position_KP*Bias+Position_KI*Integral_bias+Position_KD*(Bias-Last_Bias); //位置式PID控制器
Last_Bias=Bias; //保存上一次偏差
return Pwm; //增量输出
}
复制代码
所有资料51hei提供下载:
PID精准控制电机转到指定位置.7z
(191.75 KB, 下载次数: 311)
2019-4-23 21:59 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
djdltao
时间:
2019-4-24 21:22
楼主很用心,很好的资料
作者:
ccczx
时间:
2019-4-30 14:01
才学习电机,还有很多不懂的地方啊。
作者:
刺眼的光景
时间:
2019-7-11 20:09
下载学习学习
作者:
jiangkeqin_sy
时间:
2019-9-12 20:36
肯定要学习
作者:
prettytank
时间:
2019-9-12 20:54
收藏下,感觉一定会用到
作者:
router123
时间:
2019-9-14 13:39
非常好谢谢
作者:
wdliming
时间:
2019-9-14 16:07
正好用到~~
作者:
河鼓
时间:
2020-5-26 16:51
刚刚好,向大佬学习
作者:
swustlx86
时间:
2020-6-1 02:08
好资料,51黑有你更精彩!!!
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1