找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6028|回复: 4
收起左侧

stm32f4单片机编码器读数以及PID初步测试程序,大家相互学习!

[复制链接]
ID:357526 发表于 2018-11-24 20:53 | 显示全部楼层 |阅读模式
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "led.h"
  4. #include "lcd.h"
  5. #include "pid.h"
  6. #include "exti.h"
  7. #include "key.h"
  8. #include "timer.h"
  9. #include "motor.h"
  10. #include "pid.h"
  11. #include "usart.h"
  12. struct PID pid;
  13. extern u32 LL,RR,S_L,S_R,TT,speed_lcd,set_speed;
  14. extern int  pwm_i,pwm_j,wk_up;;
  15. float KP=0.5;//控制比例
  16. float KI=0.1;//积分系数  
  17. float KD=0.0;//微分系数  

  18. void key_scanf(void)  //按键PWM调节
  19. {   
  20. if(KEY0==0)      //KEY_0 ->KI
  21. {
  22.   delay_ms(10); //消抖
  23.   if(KEY0==0)   
  24.   {  
  25.    if(wk_up!=3) KD+=0.01;
  26.    if(wk_up==3) KD-=0.01;
  27.    
  28.    if(KD<=0)  KD=0.00;
  29.   }  
  30. }

  31. if(KEY1==0)         //KEY_1 ->KD
  32. {
  33.   delay_ms(10); //消抖
  34.   if(KEY1==0)   
  35.   {
  36.    if(wk_up!=2) KI+=0.01;
  37.    if(wk_up==2) KI-=0.01;
  38.       if(KI<=0)  KI=0.00;   
  39.   }
  40. }

  41.   
  42. if(KEY2==0)         //KEY_2 ->KP
  43. {
  44.   delay_ms(10); //消抖
  45.   if(KEY2==0)   
  46.   {
  47.    if(wk_up!=1) KP+=0.01;
  48.    if(wk_up==1) KP-=0.01;
  49.    
  50.    if(KP<=0)  KP=0.00;
  51.   }
  52. }


  53. if(WK_UP==1)         //KEY_2 ->KP
  54. {
  55.   delay_ms(10); //消抖
  56.   if(WK_UP==1)   
  57.   {
  58.        wk_up+=1;
  59.      if(wk_up==4)  wk_up=0;
  60.   }
  61. }
  62. }

  63. void PID_Init(void)
  64. {
  65. pid.limit=0.0;//限幅
  66.   
  67. pid.e_current=0.0;//当前偏差
  68. pid.e_his=0.0;//历史偏差总和
  69. pid.e_last=0.0;//上次偏差
  70. pid.e_llast=0.0;//上上次偏差

  71. pid.target_out=0.0;//目标输出
  72. pid.real_out=0.0;
  73. }

  74. //算法数据实现
  75. float PID_Data(float set_speed)
  76. {
  77. float out_speed;
  78. pid.real_out=(float)LL;
  79. pid.target_out=set_speed;//设定的速度值给target_out处理

  80. pid.e_current=pid.target_out-pid.real_out;//计算当前误差  real_out需要外部调入
  81. //pid.e_his+=pid.e_current;//重复调用记录开机以来的历史误差

  82. out_speed=KP*(pid.e_current-pid.e_last)+KI*pid.e_current+KD*(pid.e_current-2*pid.e_last+pid.e_llast);//计算公式
  83. pid.real_out=pid.real_out+out_speed;//叠加再输出

  84. pid.e_llast=pid.e_last;//为下次数据处理准备;
  85. pid.e_last=pid.e_current;//为下次数据处理准备;

  86. return out_speed;//输出目标调节PWM值
  87. }
复制代码
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "led.h"
  4. #include "lcd.h"
  5. #include "pid.h"
  6. #include "exti.h"
  7. #include "key.h"
  8. #include "timer.h"
  9. #include "motor.h"
  10. #include "pid.h"
  11. #include "usart.h"

  12. u32 LL=0,RR=0,S_L=0,S_R=0,TT=0,speed_lcd,mo_dir=0,set_speed_ms_lcd=0;
  13. u32 temp2=0,temp3=0,temp1=0,temp=0;
  14. float R_T=0.0,speed=0.0,SPEED=0.0,set_speed_ms=0.0;
  15. extern float speed,temp5,temp7,Duty,KP,KI,KD;
  16. extern int adc5,adc7,set_speed,temp_P,temp_I,temp_D,temp_PP,temp_II,temp_DD,pwm_i,pwm_j,wk_up;
  17. extern struct PID pid;

  18. void motor_set(void)
  19. {
  20.                   
  21.         TIM_SetCompare1(TIM4,1000);        //修改比较值,修改占空比   PB6
  22.         TIM_SetCompare3(TIM4,1000);        //修改比较值,修改占空比   PA1    电机正  L  and   R    前进

  23.         TIM_SetCompare2(TIM4,pwm_i);        //修改比较值,修改占空比   PB7
  24.         TIM_SetCompare4(TIM4,pwm_i);        //修改比较值,修改占空比   PA5    电机负  L  and   R   后退                                                               
  25.         
  26. /*                                                         
  27.         TIM_SetCompare3(TIM3,PID_Data(i));        //修改比较值,修改占空比   PA1    电机正  L  and   R    前进
  28.         TIM_SetCompare2(TIM3,PID_Data(1000-i));        //修改比较值,修改占空比   PA5    电机负  L  and   R   后退        
  29. */        
  30. }

  31. void motor_reset(void)
  32. {
  33.                         
  34.                         TIM_SetCompare1(TIM4,1);
  35.                         TIM_SetCompare3(TIM4,1);
  36.         
  37.                         TIM_SetCompare2(TIM4,1);
  38.                         TIM_SetCompare4(TIM4,1);   //停车不动                                 
  39. }

  40. void lcd_show(void)
  41. {
  42.                 POINT_COLOR=BLACK;
  43.                
  44.           LCD_ShowString(0,0,100,24,24,"pwm_i   ->:");
  45.                 LCD_ShowxNum(150,0,pwm_i,3,24,0);   LCD_ShowxNum(200,0,pwm_j,3,24,0);//显示i,j        
  46.         
  47.     LCD_ShowString(0,24,100,24,24,"LL  value:");
  48.                 LCD_ShowxNum(150,24,LL,7,24,0);
  49.           LCD_ShowString(0,48,100,24,24,"RR  value:");
  50.                 LCD_ShowxNum(150,48,RR,7,24,0);                              //显示左右编码器的值
  51.         
  52.           LCD_ShowString(0,72,200,24,24,"Speed_L  :");//显示出计算过的速度
  53.           LCD_ShowString(126,72,100,24,24," .  ");
  54.           temp=speed_lcd/100;
  55.     temp1=speed_lcd%1000;        
  56.            LCD_ShowxNum(126,72,temp,1,24,0);
  57.           LCD_ShowxNum(150,72,temp1,2,24,0);
  58.           LCD_ShowString(174,72,100,24,24,"(m/s)");
  59.         
  60.           LCD_ShowString(0,96,200,24,24,"Speed_R  :");
  61.                 LCD_ShowxNum(150,96,S_R,7,24,0);
  62.         
  63.           LCD_ShowString(0,120,100,24,24,"TT value :");
  64.                 LCD_ShowxNum(150,120,TT,7,24,0);

  65.     LCD_ShowString(0,255,200,24,24,"set_LL   :");
  66.                 LCD_ShowxNum(150,255,set_speed,7,24,0);
  67.           LCD_ShowString(0,279,200,24,24,"set_speed:");//显示出计算过的速度
  68.           LCD_ShowString(126,279,100,24,24," .  ");
  69.           temp2=set_speed_ms_lcd/100;
  70.     temp3=set_speed_ms_lcd%1000;        
  71.            LCD_ShowxNum(126,279,temp2,1,24,0);
  72.           LCD_ShowxNum(150,279,temp3,2,24,0);
  73.                 LCD_ShowString(174,279,100,24,24,"(m/s)");
  74.                
  75.                 LCD_ShowString(0,144,260,24,24,"WK_UP    :");
  76.           LCD_ShowxNum(198,144,wk_up,1,24,0);
  77.                                 
  78.                 LCD_ShowString(0,168,260,24,24,"KEY_2   P:");
  79.                 LCD_ShowString(174,168,100,24,24," .   ");
  80.                 temp_P=(int)100*KP;
  81.                 temp_PP=temp_P/100;
  82.                 temp_P=temp_P%100;
  83.     LCD_ShowxNum(174,168,temp_PP,1,24,0);
  84.           LCD_ShowxNum(198,168,temp_P,2,24,0);

  85.                 LCD_ShowString(0,192,260,24,24,"KEY_1   I:");
  86.           LCD_ShowString(174,192,100,24,24," .   ");
  87.                 temp_I=(int)100*KI;
  88.                 temp_II=temp_I/100;
  89.                 temp_I=temp_I%100;
  90.     LCD_ShowxNum(174,192,temp_II,1,24,0);
  91.           LCD_ShowxNum(198,192,temp_I,2,24,0);                 
  92.                
  93.                 LCD_ShowString(0,216,260,24,24,"KEY_0   D:");
  94.           LCD_ShowString(174,216,100,24,24," .   ");
  95.     temp_D=(int)100*KD;
  96.                 temp_DD=temp_D/100;
  97.                 temp_D=temp_D%100;
  98.     LCD_ShowxNum(174,216,temp_DD,1,24,0);
  99.           LCD_ShowxNum(198,216,temp_D,2,24,0);
  100. //                v777=(int)(temp7*1000);
  101. //          v7=(v777/1000);
  102. //    v77=v7%1000;               
  103. //           LCD_ShowxNum(174,216,v7,1,24,0);
  104. //          LCD_ShowxNum(198,216,v77,2,24,0);
  105.                
  106. }
复制代码

全部资料51hei下载地址:
PID任务二.rar (531.32 KB, 下载次数: 63)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:414834 发表于 2018-11-25 01:20 | 显示全部楼层
楼主设置电机停车的时候为1的占空比,不会损害电机嘛?还有我也在做PID,但是总是一开始就最大值了,有没有什么办法调节,我查找不到问题在哪
回复

使用道具 举报

ID:357526 发表于 2018-11-26 17:19 | 显示全部楼层
风吟轩 发表于 2018-11-25 01:20
楼主设置电机停车的时候为1的占空比,不会损害电机嘛?还有我也在做PID,但是总是一开始就最大值了,有没有 ...

哈哈哈,1000占空比是向上计数的,输出为 0 哈。
PID的话去B站找一下XX老师的视频,我记得是十来讲的,讲得非常不错,注意理解公式就好了。
回复

使用道具 举报

ID:433764 发表于 2018-11-26 21:35 | 显示全部楼层
风吟轩 发表于 2018-11-25 01:20
楼主设置电机停车的时候为1的占空比,不会损害电机嘛?还有我也在做PID,但是总是一开始就最大值了,有没有 ...

首先判断引起输出最大值的原因,是否比例系数设置过大了。
如果不是,判断是否迭代时间设置过短,导致迭代速度太快,系统响应跟不上输出的变化速度,导致积分项增加过快,这种情况可以适当调低迭代速度,或者考虑使用饱和积分。
具体情况要具体分析哈
回复

使用道具 举报

ID:414834 发表于 2018-11-30 19:51 | 显示全部楼层
万物互联 发表于 2018-11-26 21:35
首先判断引起输出最大值的原因,是否比例系数设置过大了。
如果不是,判断是否迭代时间设置过短,导致迭 ...

大佬,我现在PID调出来了,但是有点问题,应该说问题挺大的,跳跃的频率挺大的,而且跳跃的范围也不确定,有什么办法可以让四个电机的速度都相等呢?我现在7200的最大占空比,但是输出的时候占空比的波动范围差不多50左右,还能减少么?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表