PID控制步进电机转速仿真及c程序
- 格式:docx
- 大小:55.79 KB
- 文档页数:8
PID控制步进电机转速仿真及c程序
#include
#include"lcd1602.h"
sfr T2MOD = 0x0c9;
#define uchar unsigned char
#define uint unsigned int
sbit Q0 = P2^4;
sbit Q1 = P2^5;
sbit Q2 = P2^6;
sbit Q3 = P2^7;
sbit PWM= P1^7;
sbit UP= P1^0;
sbit DOWM= P1^1;
sbit GORB= P2^3; //换相
sbit ADDSPEED = P1^2;
sbit SUBSPEED= P1^3;
uint tuint = 65535;
uint tpwm = 1;//pwm周期为10000us tpwm变量表示pwm高电平时间,也相当于占空比(仿真时,频率高时,电机反应慢。在实物上要加大频率)
uchar t1_flag = 0;
uint pulse = 0;
uint t0_flag = 0;
uchar t2_flag = 0;
bit t2_over = 0;
bit Just_Get = 1;
#define ZZ { Q0 = 0;Q1 = 0;Q2 = 1;Q3 = 1;}//正转
#define FZ { Q0 = 1;Q1 = 1;Q2 = 0;Q3 = 0;}//反转
#define STOP{ Q0 = 1;Q1 = 0;Q2 = 1;Q3 = 0;}//停止
//禁止出现Q0 = 0;Q1 = 1;Q2 = 0;Q3 = 1; 不然会烧掉mos管
//************************ PID ************************************* float now = 0,bef = 0,bbef = 0; //本次采样值,上次采样值,上上次采样值float err_now,err_bef,err_bbef;//当前偏差,上次偏差,上上次偏差float error_add = 0;//所有偏差之和
float set = 25;//设定值
float kp = 25;
float ki = 25;
float kd = 0;
//*****************************************************************
void delayms(uint ms)//延时?个ms
{
uchar a,b,c;
while(ms--)
{
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
}
void timer_init()
{
EA = 1;
ET0 = 1;
ET1 = 1;
ET2 = 1;
TMOD = 0x15; //定时器0 计数模式定时器1模式1
T2MOD = 0x01;
TH0 = TL0 = 255;
TH2 = 0x3C;
TL2 = 0xB0;//50MS
}
void timer1() interrupt 3
{
if(t1_flag == 0)
{
t1_flag = 1;
PWM = 1;
TH1 = (tuint - tpwm + 1)/256;
TL1 = (tuint - tpwm + 1)%256;
}
else
{
t1_flag = 0;
PWM = 0;
TH1 = (tuint - 10000 + tpwm + 1)/256;
TL1 = (tuint - 10000 + tpwm + 1)%256;
}
}
void timer0() interrupt 1
{
TH0 = TL0 = 255;
t0_flag++;
}
void timer2() interrupt 5
{
TF2 = 0;
TH2 = 0x3C;
TL2 = 0xB0;//50MS
t2_flag++;
if(t2_flag == 2)
{
TR0 = 0;
TR2 = 0;
t2_flag = 0;
t2_over = 1;//表示100ms时间到
}
}
void GetPulse()
{
t0_flag = 0;
t2_flag = 0;
TH0 = TL0 = 255;
TH2 = 0x3C;
TL2 = 0xB0;//50MS
TR0 = 1;
TR2 = 1;
}
int PID()//增量式PID
{
int change;
err_now = set - now;
err_bef = set - bef;
err_bbef = set - bbef;
change = kp*(err_now - err_bef) + ki*err_now + kd*(err_now - 2*err_bef + err_bbef);
/*
if(set >= now)
{
if(set - now > 1)
change = kp*(err_now -err_bef) + ki*err_now + kd*(err_now -2*err_bef + err_bbef);
else
change = 0.2*kp*(err_now - err_bef) + 0.5*ki*err_now + kd*(err_now - 2*err_bef + err_bbef);
}
else if(now > set)
{
if(now - set > 1)
change = kp*(err_now -err_bef) + ki*err_now + kd*(err_now -2*err_bef + err_bbef);
else
change = 0.2*kp*(err_now - err_bef) + 0.5*ki*err_now + kd*(err_now - 2*err_bef + err_bbef);