本帖最后由 Brand2 于 2016-9-21 21:31 编辑
例程名称: YSF1_HAL_MOTOR-045. 单轴25GA370直流电机增量式PID旋转控制(L298N驱动)
*
******************************************************************************
* 说明:
* 本例程配套硬石stm32开发板YS-F1Pro使用。
*
* 淘宝:
* 论坛:硬石电子社区
* 版权归硬石嵌入式开发团队所有,请勿商用。
******************************************************************************
*/
【1】例程简介
【2】跳线帽情况
【3】操作及现象
/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
main.c文件内容
- /* 私有类型定义 --------------------------------------------------------------*/
- //定义PID结构体
- typedef struct
- {
- __IO int SetPoint; //设定目标 Desired Value
- __IO double Proportion; //比例常数 Proportional Const
- __IO double Integral; //积分常数 Integral Const
- __IO double Derivative; //微分常数 Derivative Const
- __IO int LastError; //Error[-1]
- __IO int PrevError; //Error[-2]
- }PID;
- /* 私有宏定义 ----------------------------------------------------------------*/
- /*************************************/
- //定义PID相关宏
- // 这三个参数设定对电机运行影响非常大
- /*************************************/
- #define P_DATA 3.2 //P参数
- #define I_DATA 1.1 //I参数
- #define D_DATA -0.15 //D参数
- /* 私有变量 ------------------------------------------------------------------*/
- __IO uint16_t time_count=0; // 时间计数,每1ms增加一(与滴定时器频率有关)
- __IO uint32_t CaptureNumber=0; // 输入捕获数
- __IO uint8_t start_flag=0;
- __IO double encoder_speed=0;
- static PID sPID;
- static PID *sptr = &sPID;
- int main(void)
- {
- /* 复位所有外设,初始化Flash接口和系统滴答定时器 */
- HAL_Init();
- /* 配置系统时钟 */
- SystemClock_Config();
- KEY_GPIO_Init();
- MX_DEBUG_USART_Init();
- IncPIDInit();
- ENCODER_TIMx_Init();
- HAL_TIM_Base_Start(&htimx_ENCODER);
- /* 高级控制定时器初始化并配置PWM输出功能 */
- L298N_TIMx_Init();
- /* 启动定时器 */
- HAL_TIM_Base_Start(&htimx_L298N);
- HAL_TIM_IC_Start_IT(&htimx_ENCODER,ENCODER_TIM_CHANNELx);
- /* 启动定时器通道和互补通道PWM输出 */
- L298N_DCMOTOR_Contrl(1,2,0);
- start_flag=1;
- printf("增量式PID算法控制电机旋转\n");
- /* 无限循环 */
- while (1)
- {
- if(KEY1_StateRead()==KEY_DOWN) // 增速
- {
- /* 设置目标速度 */
- sptr->SetPoint =50;
- }
- if(KEY2_StateRead()==KEY_DOWN) // 减速
- {
- /* 设置目标速度 */
- sptr->SetPoint =300;
- }
- }
- }
- void HAL_SYSTICK_Callback(void)
- {
- if(start_flag) // 等待脉冲输出后才开始计时
- {
- time_count++; // 每1ms自动增一
- if(time_count==200)
- {
- __IO uint32_t count;
- __IO int para;
- __IO double cal;
- /* 得到编码器计数值,数值越大说明速度越大 */
- count=CaptureNumber;
- CaptureNumber=0; // 清零,从零开始计数
- /* 计数得到增量式PID的增量数值 */
- para=IncPIDCalc(count);
- /* 根据增量数值调整当前电机速度 */
- if((para<-3)||(para>3)) // 不做 PID 调整,避免误差较小时频繁调节引起震荡。
- {
- PWM_Duty +=para;
- }
- if(PWM_Duty>899)PWM_Duty=899;
- // 11:编码器线数(转速一圈输出脉冲数)
- // 34:电机减数比,内部电机转动圈数与电机输出轴转动圈数比,即减速齿轮比
- cal=sptr->SetPoint;
- printf("\n设定目标速度 -> 编码器在%ds时间计数%d个脉冲\n",time_count,sptr->SetPoint);
- printf(" 相当于实际目标速度为:%0.2f圈/s\n",cal*(1000/time_count)/11/34);
- cal=count;
- printf("当前电机速度-> 编码器在%ds时间计数%d个脉冲\n",time_count,count);
- printf(" 相当于当前实际速度为:%0.2f圈/s\n",cal*(1000/time_count)/11/34);
- printf("增量式PID算法计数结果值:%d 设置新的占空比为:%d\n",para,PWM_Duty);
- L298N_DCMOTOR_Contrl(1,2,PWM_Duty);
- time_count=0;
- }
- }
- }
- /**************PID参数初始化********************************/
- void IncPIDInit(void)
- {
- sptr->LastError=0; //Error[-1]
- sptr->PrevError=0; //Error[-2]
- sptr->Proportion=P_DATA; //比例常数 Proportional Const
- sptr->Integral=I_DATA; //积分常数 Integral Const
- sptr->Derivative=D_DATA; //微分常数 Derivative Const
- sptr->SetPoint=100; //设定目标Desired Value
- }
- /********************增量式PID控制设计************************************/
- int IncPIDCalc(int NextPoint)
- {
- int iError,iIncpid; //当前误差
- iError=sptr->SetPoint-NextPoint; //增量计算
- iIncpid=(sptr->Proportion * iError) //E[k]项
- -(sptr->Integral * sptr->LastError) //E[k-1]项
- +(sptr->Derivative * sptr->PrevError); //E[k-2]项
- sptr->PrevError=sptr->LastError; //存储误差,用于下次计算
- sptr->LastError=iError;
- return(iIncpid); //返回增量值
- }
- /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
|