你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【HAL库每天一例】第116例:单轴25GA370直流电机位置式PID旋...

[复制链接]
haohao663 提问时间:2016-9-8 08:53 /
例程下载:
资料包括程序、相关说明资料以及软件使用截图

百度云盘:https://pan.baidu.com/s/1slN8rIt 密码:u6m1
360云盘:http://yunpan.cn/OcPiRp3wEcA92u密码 cfb6
(硬石YS-F1Pro开发板HAL库例程持续更新\5. 软件设计之电机控制(HAL库版本)\有刷直流电机.zip
/**
  ******************************************************************************
  *                           硬石YS-F1Pro开发板例程功能说明
  *
  *  例程名称: YSF1_HAL_MOTOR-046. 单轴25GA370直流电机位置式PID旋转控制(L298N驱动)
  *   
  ******************************************************************************
  * 说明:
  * 本例程配套硬石stm32开发板YS-F1Pro使用。
  *
  * 淘宝:
  * 论坛:硬石电子社区
  * 版权归硬石嵌入式开发团队所有,请勿商用。
  ******************************************************************************
  */

【1】例程简介
【2】跳线帽情况
【3】操作及现象
/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/

main.c文件内容
  1. /* 私有类型定义 --------------------------------------------------------------*/
  2. //定义PID结构体
  3. typedef struct
  4. {
  5.   __IO int      SetPoint;                                 //设定目标 Desired Value
  6.   __IO long     SumError;                                 //误差累计
  7.   __IO double   Proportion;                               //比例常数 Proportional Const
  8.   __IO double   Integral;                                 //积分常数 Integral Const
  9.   __IO double   Derivative;                               //微分常数 Derivative Const
  10.   __IO int      LastError;                                //Error[-1]
  11.   __IO int      PrevError;                                //Error[-2]
  12. }PID;

  13. /* 私有宏定义 ----------------------------------------------------------------*/
  14. /*************************************/
  15. //定义PID相关宏
  16. // 这三个参数设定对电机运行影响非常大
  17. /*************************************/
  18. #define  P_DATA      3.2                                 //P参数
  19. #define  I_DATA      1.1                                //I参数
  20. #define  D_DATA      -0.15                              //D参数


  21. /* 私有变量 ------------------------------------------------------------------*/
  22. __IO uint16_t time_count=0;        // 时间计数,每1ms增加一(与滴定时器频率有关)
  23. __IO uint32_t CaptureNumber=0;     // 输入捕获数
  24. __IO uint8_t  start_flag=0;
  25. __IO double encoder_speed=0;
  26. static PID sPID;
  27. static PID *sptr = &sPID;

  28. /* 扩展变量 ------------------------------------------------------------------*/
  29. /* 私有函数原形 --------------------------------------------------------------*/
  30. void IncPIDInit(void);
  31. int IncPIDCalc(int NextPoint);
  32. unsigned int LocPIDCalc(int NextPoint);

  33. /* 函数体 --------------------------------------------------------------------*/


  34. /**
  35.   * 函数功能: 主函数.
  36.   * 输入参数: 无
  37.   * 返 回 值: 无
  38.   * 说    明: 无
  39.   */
  40. int main(void)
  41. {
  42.   /* 复位所有外设,初始化Flash接口和系统滴答定时器 */
  43.   HAL_Init();
  44.   /* 配置系统时钟 */
  45.   SystemClock_Config();

  46.   KEY_GPIO_Init();
  47.   MX_DEBUG_USART_Init();
  48.   
  49.   IncPIDInit();
  50.   
  51.   ENCODER_TIMx_Init();
  52.   HAL_TIM_Base_Start(&htimx_ENCODER);  
  53.   
  54.   /* 高级控制定时器初始化并配置PWM输出功能 */
  55.   L298N_TIMx_Init();
  56.   /* 启动定时器 */
  57.   HAL_TIM_Base_Start(&htimx_L298N);
  58.   
  59.   HAL_TIM_IC_Start_IT(&htimx_ENCODER,ENCODER_TIM_CHANNELx);
  60.   
  61.   /* 启动定时器通道和互补通道PWM输出 */
  62.   L298N_DCMOTOR_Contrl(1,2,0);
  63.   start_flag=1;
  64.   
  65.   printf("增量式PID算法控制电机旋转\n");
  66.   /* 无限循环 */
  67.   while (1)
  68.   {
  69.     if(KEY1_StateRead()==KEY_DOWN)  // 增速
  70.     {
  71.       /* 设置目标速度 */
  72.       sptr->SetPoint =50;   
  73.     }
  74.     if(KEY2_StateRead()==KEY_DOWN)  // 减速
  75.     {
  76.       /* 设置目标速度 */
  77.       sptr->SetPoint =300;
  78.     }   
  79.   }
  80. }

  81. /**
  82.   * 函数功能: 系统滴答定时器中断回调函数
  83.   * 输入参数: 无
  84.   * 返 回 值: 无
  85.   * 说    明: 每发生一次滴答定时器中断进入该回调函数一次
  86.   */
  87. void HAL_SYSTICK_Callback(void)
  88. {
  89.   if(start_flag) // 等待脉冲输出后才开始计时
  90.   {
  91.     time_count++;         // 每1ms自动增一
  92.     if(time_count==200)
  93.     {
  94.       __IO uint32_t count;
  95.       __IO double cal;
  96.       
  97.       /* 得到编码器计数值,数值越大说明速度越大 */
  98.       count=CaptureNumber;
  99.       CaptureNumber=0;    // 清零,从零开始计数
  100.       
  101.       /* 计数得到位置式PID的位置数值 */
  102.       PWM_Duty=LocPIDCalc(count);      
  103.       if(PWM_Duty>899)PWM_Duty=899;        
  104.       
  105.       // 11:编码器线数(转速一圈输出脉冲数)
  106.       // 34:电机减数比,内部电机转动圈数与电机输出轴转动圈数比,即减速齿轮比      
  107.       cal=sptr->SetPoint;
  108.       printf("\n设定目标速度 -> 编码器在%ds时间计数%d个脉冲\n",time_count,sptr->SetPoint);      
  109.       printf("                相当于实际目标速度为:%0.2f圈/s\n",cal*(1000/time_count)/11/34);
  110.       
  111.       cal=count;
  112.       printf("当前电机速度-> 编码器在%ds时间计数%d个脉冲\n",time_count,count);
  113.       printf("                相当于当前实际速度为:%0.2f圈/s\n",cal*(1000/time_count)/11/34);
  114.       
  115.       printf("设置新的占空比为:%d\n",PWM_Duty);
  116.       
  117.       L298N_DCMOTOR_Contrl(1,2,PWM_Duty);
  118.       time_count=0;      
  119.     }
  120.   }
  121. }

  122. /**
  123.   * 函数功能: 定时器输入捕获中断回调函数
  124.   * 输入参数: htim:定时器句柄
  125.   * 返 回 值: 无
  126.   * 说    明: 无
  127.   */
  128. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
  129. {
  130.   CaptureNumber++;
  131. }


  132. /**************PID参数初始化********************************/
  133. void IncPIDInit(void)
  134. {
  135.     sptr->LastError=0;            //Error[-1]
  136.     sptr->PrevError=0;            //Error[-2]
  137.     sptr->Proportion=P_DATA;      //比例常数 Proportional Const
  138.     sptr->Integral=I_DATA;        //积分常数  Integral Const
  139.     sptr->Derivative=D_DATA;      //微分常数 Derivative Const
  140.     sptr->SetPoint=100;           //设定目标Desired Value
  141. }
  142. /********************增量式PID控制设计************************************/
  143. int IncPIDCalc(int NextPoint)
  144. {
  145.   int iError,iIncpid;                                 //当前误差
  146.   iError=sptr->SetPoint-NextPoint;                    //增量计算
  147.   iIncpid=(sptr->Proportion * iError)                 //E[k]项
  148.               -(sptr->Integral * sptr->LastError)     //E[k-1]项
  149.               +(sptr->Derivative * sptr->PrevError);  //E[k-2]项
  150.               
  151.   sptr->PrevError=sptr->LastError;                    //存储误差,用于下次计算
  152.   sptr->LastError=iError;
  153.   return(iIncpid);                                    //返回增量值
  154. }

  155. /********************位置式 PID 控制设计************************************/
  156. unsigned int LocPIDCalc(int NextPoint)
  157. {
  158.   int iError,dError;
  159.   iError = sptr->SetPoint - NextPoint; //偏差
  160.   sptr->SumError += iError; //积分
  161.   dError = iError - sptr->LastError; //微分
  162.   sptr->LastError = iError;
  163.   return(sptr->Proportion * iError //比例项
  164.   + sptr->Integral * sptr->SumError //积分项
  165.   + sptr->Derivative * dError); //微分项
  166. }
  167. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码



收藏 1 评论1 发布时间:2016-9-8 08:53

举报

1个回答
stary666 回答时间:2016-9-8 10:04:17
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版