资源介绍
PID控制电机
#include "msp430x54xA.h"
#include "public.h"
long int num0=0,num1=0,speed=0;
int Error,Error1,Error2;
extern uchar Point_Speed;
/*=====================初始化PID==================*/
void Init_PID(uchar pwm,uint speed0)
{
while(1)
{
keyscan();
PWM(pwm,100-pwm);
display();
write12864_command(0x9B); //显示"自动模式"
Chinese_address("STA");
if(speed>speed0) break;
}
}
/*=====================数字PID算法==================*/
void Digital_PID(uchar SetPoint)
{
double pwm=0;
uint temp=0;
float Kp=0 ,Kd=0 ,Ki=0;
if(SetPoint>0&&SetPoint<=10)
{
Kp=0.015;
Ki=0.025;
Kd=1.25;
}
else if(SetPoint>10&&SetPoint<=20)
{
Kp=0.055;
Ki=1.13;
Kd=1.52;
}
else if(SetPoint>20&&SetPoint<=30)
{
Kp=0.04;
Ki=1.12;
Kd=1.22;
}
else if(SetPoint>30&&SetPoint<=55)
{
Kp=1.355;
Ki=1.12;
Kd=1.42;
}
else if(SetPoint>55)
{
Kp=0.055;
Ki=1.12;
Kd=1.22;
}
while((P1IN&0XFF)==0XFF)
{
Error=SetPoint-speed; //误差值
pwm=(uint)(Kp*Error+Ki*Error1+Kd*Error2+SetPoint);
temp=(uint)pwm;
PWM(temp,100-temp);
Error2=Error1;
Error1=Error;
display();
keyscan();
}
}
void PWM(uint R0 , uint R1)
{
TA1CCR0 = 100; // PWM Period/2
TA1CCTL1 |= OUTMOD_6; // CCR1 toggle/set
TA1CCR1 = R0; // CCR1 PWM duty cycle
TA1CCTL2 |= OUTMOD_6; // CCR2 toggle/set
TA1CCR2 = R1; // CCR2 PWM duty cycle
TA1CTL |= TASSEL_1 + MC_3; // ACLK, up-down mode
}
/***************初始化中断********************/
void Init_interrupt(void)
{
P2REN |= BIT0; //使P2.0上拉
P2OUT |= BIT0; // 使 P2.0 置高
P2IE |= BIT0; // 开启外部中断P2.0
P2IES |= BIT0; // 外部中断上升沿有效
P2IFG &= ~BIT0; // 清除P2.0标志位
}
/***************初始化定时器TA0********************/
void Init_TimerA0(void)
{
TA0CTL|=TASSEL0+TACLR ; //TASSEL0=0x0100(选择辅助时钟) , TACLR=0x0004(清除计数器)
TA0CTL|=MC0; //MC0=0x0010(连续计数模式)
TA0CCTL0|=CCIE; //CCIE=0x0010(捕获/比较使能)
TA0CCR0=8192; //计时250ms
TA0CTL|=TAIFG; //(中断标志位)
TA0CTL&=~0X01; //清除定时器TAIF标志位
_EINT();
}
/********************外部中断服务函数*****************************/
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
num1++;
P2IFG &= ~BIT0; // 清除P2.0标志位
}
/***************定时器TA0中断服务函数,定时250ms中断************************/
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0(void)
{
num0++;
if(num0==4)
{
speed= num1;
//speed=(uint)(num1/2.0);
num0=0;
num1=0;
TA0CTL&=~0X01; //清除定时器TAIF标志位
}
}