haohao663 发表于 2016-9-7 08:48:40

【HAL库每天一例】第115例:单轴25GA370直流电机增量式PID旋...

例程下载:
资料包括程序、相关说明资料以及软件使用截图
百度云盘:https://pan.baidu.com/s/1slN8rIt 密码:u6m1360云盘:http://yunpan.cn/OcPiRp3wEcA92u密码 cfb6(硬石YS-F1Pro开发板HAL库例程持续更新\5. 软件设计之电机控制(HAL库版本)\有刷直流电机.zip)
/**
******************************************************************************
*                           硬石YS-F1Pro开发板例程功能说明
*
*例程名称: 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相关宏
// 这三个参数设定对电机运行影响非常大
/*************************************/
#defineP_DATA      3.2                                 //P参数
#defineI_DATA      1.1                              //I参数
#defineD_DATA      -0.15                              //D参数

/* 私有变量 ------------------------------------------------------------------*/
__IO uint16_t time_count=0;      // 时间计数,每1ms增加一(与滴定时器频率有关)
__IO uint32_t CaptureNumber=0;   // 输入捕获数
__IO uint8_tstart_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项
            -(sptr->Integral * sptr->LastError)   //E项
            +(sptr->Derivative * sptr->PrevError);//E项
            
sptr->PrevError=sptr->LastError;                  //存储误差,用于下次计算
sptr->LastError=iError;
return(iIncpid);                                    //返回增量值
}
/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/



stary666 发表于 2016-9-7 11:32:39

:loveliness::loveliness:
页: [1]
查看完整版本: 【HAL库每天一例】第115例:单轴25GA370直流电机增量式PID旋...