在原来的电机任务的基础上增加一个测量速度,修改pwm输出的任务,
通过PID 转速能稳定在 设定值范围 浮动, 速度高时候 抖动比较厉害,可能跟 pid 参数有关,或者电机的性能有关,而且声音也比较大,下一步学 foc 看 会不会比较静音
INT16U BLDC_PWM=0;
INT32U gHallCnt=0;
#define PWM_TEST (PWM_PAUSE-BLDC_PWM)
void RunMotorTask(void)
{
INT8U hallcur,hallold=0xff;
INT16U cnt=0;
SysTick_CounterCmd(SysTick_Counter_Enable); //系统时钟开始计数
DcMotorTim1Init(PWM_PAUSE,1000);
SetPinState(GPIOC,GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8,GPIO_Mode_IPU);
OSQPost(OSQDebug,(void*)'0');
do{
OSTimeDly(1);
hallcur=(GPIOC->IDR>>6)&0x07;
if(hallcur!=hallold && hallcur!=0 && hallcur!=7)
{
hallold=hallcur;
Hall2UVW[hallcur]();
cnt=0;
//记录脉冲数
++gHallCnt;
}
if(++cnt>=OS_TICKS_PER_SEC/10) Hall2UVW[hallcur]();
}while(1);
}
void PidTask(void *pdata)
{
//INT8U err;
INT32U hallcnt=0,speed;
S_PID pid;
pid.target=60;
pid.kp=200;
pid.ki=20;
pid.kd=80;
pid.integral=0;
do{
//计算单位时间内的脉冲数差值,就是速度
speed=gHallCnt-hallcnt;
hallcnt+=speed;
printf("%X %d %d\r\n",BLDC_PWM,speed,pid.integral);
//通过 pid 算法 获取pwm 的输出
BLDC_PWM=GetPid(speed,&pid);
OSTimeDly(OS_TICKS_PER_SEC/10);
}while(1);
}
PID算法如下
#define PID_DIV 100
typedef struct{
INT32S kp; //比例常数
INT32S ki; //积分常数
INT32S kd; //微分常数
INT32S target; //目标值
INT32S cur; //当前值
INT32S integral; //积分差值
INT32S offsetprev; //上次偏差值
}S_PID;
INT32S GetPid(INT16S _newData,S_PID *pid)
{
INT32S ret;
INT32S bias=pid->target-_newData;
pid->cur=_newData; //记录当前值
pid->integral+=bias;
ret=pid->kp*bias+pid->ki*pid->integral-pid->kd*(bias-pid->offsetprev);
pid->offsetprev=bias;
return ret/PID_DIV;
}