STM32驱动无刷直流电机学习(4)---PID方波控制

在原来的电机任务的基础上增加一个测量速度,修改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;
}

 

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值