找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3696|回复: 0
收起左侧

STM32直流电机闭环调速系统源程序

[复制链接]
ID:324643 发表于 2018-5-9 21:05 | 显示全部楼层 |阅读模式
直流电机闭环调速系统单片机源程序如下:
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "pwm.h"
  6. #include "lcd.h"
  7. #include        "math.h"
  8. #include "touch.h"

  9. extern u8 count;
  10. extern        u8 flag,flag_1;
  11. extern        u32        TIM5CH1_CAPTURE_VAL_Rise;
  12. struct
  13. {
  14.         float        SetSpeed;
  15.         float        ActualSpeed;
  16.         float        err;
  17.         float        last_err;
  18.         float        Kp,Ki,Kd;
  19.         float        integral;
  20.         float        Voltage;
  21.         float        umax;
  22.         float        umin;
  23. }pid;
  24. void        pid_init(void)
  25. {
  26.         pid.SetSpeed=30;
  27.         pid.ActualSpeed=0.0;
  28.         pid.err=0.0;
  29.         pid.last_err=0.0;
  30.         pid.Voltage=0.0;
  31.         pid.integral=0.0;
  32.         pid.Kd=4.1;
  33.         pid.Ki=3.3;
  34.         pid.Kp=15.3;        //11.8
  35.         pid.umax=70;
  36.         pid.umin=10;
  37. }
  38. u16        value;
  39. u8        N=1;
  40. void        pid_realize(void)
  41. {
  42.         int index;
  43. //        pid.SetSpeed=speed;
  44.         pid.err =pid.SetSpeed-pid.ActualSpeed;
  45. //        if(pid.ActualSpeed==30)
  46. //        {
  47. //                N=0;
  48. //        }
  49. //        else{N=1;}
  50.         if(pid.ActualSpeed>pid.umax)
  51.         {
  52.                 if(pid.err>40&&pid.err<20){index=0;}
  53.                 else        
  54.                 {
  55.                         index=1;
  56.                         if(pid.err<0)
  57.                         {
  58.                                 pid.integral+=pid.err;
  59.                         }
  60.                 }        
  61.         }
  62.         else        if(pid.ActualSpeed<pid.umin)
  63.         {
  64.                 if(pid.err>40 && pid.err<20){index=0;}        //abs(pid.err)>80
  65.                 else        
  66.                 {
  67.                         index=1;
  68.                         if(pid.err>0)
  69.                         {
  70.                                 pid.integral+=pid.err;
  71.                         }
  72.                 }        
  73.         }
  74.         else
  75.         {
  76.                 if(pid.err>40&&pid.err<20){index=0;}
  77.                 else        
  78.                 {
  79.                         index=1;
  80.                         pid.integral+=pid.err;
  81.                 }        
  82.         }
  83.         pid.Voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.last_err-pid.err);

  84. //        pid.last_err=pid.next_err;
  85.         pid.last_err=pid.err;
  86.         
  87. }
  88. u8 touch_task(void)
  89. {
  90.                 tp_dev. scan(0);
  91.                 if(tp_dev.sta&TP_PRES_DOWN)                        //触摸屏被按下
  92.                 {
  93.                         tp_dev. scan(0);
  94.                         delay_ms(10);
  95.                         if((tp_dev.x[0]>=20&&tp_dev.x[0]<=70)&&(tp_dev.y[0]<=240&&tp_dev.y[0]>=200))return        1;
  96.                         if((tp_dev.x[0]>=90&&tp_dev.x[0]<=140)&&(tp_dev.y[0]<=240&&tp_dev.y[0]>=200))return        2;
  97.                         if((tp_dev.x[0]>=160&&tp_dev.x[0]<=210)&&(tp_dev.y[0]<=240&&tp_dev.y[0]>=200))return        3;
  98.                         if((tp_dev.x[0]>=20&&tp_dev.x[0]<=70)&&(tp_dev.y[0]<=300&&tp_dev.y[0]>=260))return        4;
  99.                         if((tp_dev.x[0]>=90&&tp_dev.x[0]<=140)&&(tp_dev.y[0]<=300&&tp_dev.y[0]>=260))return        5;
  100.                         if((tp_dev.x[0]>=160&&tp_dev.x[0]<=210)&&(tp_dev.y[0]<=300&&tp_dev.y[0]>=260))return        6;
  101.                 }
  102.                 delay_ms(10);
  103. }
  104. int main(void)
  105. {
  106.         u8 key,pre;
  107.         float temp;
  108.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
  109.         delay_init(168);  //初始化延时函数
  110.         uart_init(115200);//初始化串口波特率为115200
  111.         LCD_Init();
  112.         KEY_Init();
  113.         tp_dev.init();
  114.         TIM5_CH1_Cap_Init(100000,84-1);
  115.          TIM14_PWM_Init(1000-1,84-1);        //84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz.   
  116.         pid_init();
  117.         LCD_ShowString(35,40,200,16,16,"Kp:");
  118.         LCD_ShowString(35,60,200,16,16,"Ki:");
  119.         LCD_ShowString(35,80,200,16,16,"Kd:");
  120.         LCD_ShowString(35,100,200,16,16,"set_speed:");
  121.         LCD_ShowString(35,120,200,16,16,"speed:");
  122.         LCD_ShowString(35,210,200,16,16,"Kd+");
  123.         LCD_ShowString(105,210,200,16,16,"Ki+");
  124.         LCD_ShowString(175,210,200,16,16,"Kp+");
  125.         LCD_ShowString(35,270,200,16,16,"Kd-");
  126.         LCD_ShowString(105,270,200,16,16,"Ki-");
  127.         LCD_ShowString(175,270,200,16,16,"Kp-");
  128.         LCD_ShowString(155,100,200,16,16,"r/s");
  129.         LCD_DrawRectangle(20,200,70,240);
  130.         LCD_DrawRectangle(90,200,140,240);
  131.         LCD_DrawRectangle(160,200,210,240);
  132.         LCD_DrawRectangle(20,260,70,300);
  133.         LCD_DrawRectangle(90,260,140,300);
  134.         LCD_DrawRectangle(160,260,210,300);
  135.         POINT_COLOR = RED;
  136.         LCD_PutString(40,10,"直流电机闭环调速系统",16);
  137.         POINT_COLOR = BLACK;
  138. //        delay_ms(2000);
  139.    while(1) //实现比较值从0-300递增,到300后从300-0递减,循环
  140.         {
  141.                 pre=KEY_Scan(0);
  142.                 switch(pre)
  143.                 {
  144.                         case        1:pid.SetSpeed+=1;break;
  145.                         case        4:pid.SetSpeed-=1;break;
  146.                 }
  147.                 key=touch_task();
  148.                 switch(key)
  149.                 {
  150.                         case        1:pid.Kp+=0.1f;break;
  151.                         case        2:pid.Ki+=0.1f;break;
  152.                         case        3:pid.Kd+=0.1f;break;
  153.                         case        4:pid.Kp-=0.1f;break;
  154.                         case        5:pid.Ki-=0.1f;break;
  155.                         case        6:pid.Kd-=0.1f;break;
  156.                 }
  157.                 LCD_ShowFloatNum(75,40,pid.Kp,1,16,0x80);
  158.                 LCD_ShowFloatNum(75,60,pid.Ki,1,16,0x80);
  159.                 LCD_ShowFloatNum(75,80,pid.Kd,1,16,0x80);
  160.                 LCD_ShowFloatNum(115,100,pid.SetSpeed,1,16,0x80);
  161.                  if(flag==1||flag_1==1)
  162.                 {
  163.                         if(flag==1)
  164.                         {
  165.                                 temp=(1000000)/(count*100000+TIM5CH1_CAPTURE_VAL_Rise);
  166.                                 if(temp<100)
  167.                                 {pid.ActualSpeed=temp;}
  168. //                                if(temp<60)
  169.                                 //        LCD_ShowNum(90,200,count,2,16);
  170.                                 //        LCD_ShowNum(90,180,TIM5CH1_CAPTURE_VAL_Rise,6,16);
  171.                                         LCD_Fill(90,120,240,136,WHITE);
  172.                                                 LCD_ShowFloatNum(90,120,(float)(1000000)/(count*100000+TIM5CH1_CAPTURE_VAL_Rise),2,16,0);
  173.                                 
  174.                         }
  175.                         if(flag_1==1)
  176.                         {
  177.                                 pid.ActualSpeed=0;
  178.                                 LCD_Fill(90,120,240,136,WHITE);
  179.                                 LCD_ShowFloatNum(90,120,(float)0,2,16,0);
  180.                         }
  181.                 pid_realize();
  182. //                        LCD_ShowNum(40,140,count,4,16);
  183.                         TIM5CH1_CAPTURE_VAL_Rise=0;
  184.                         count=0;
  185.                         flag=0;
  186.                         flag_1=0;
  187.                         if(N==0)
  188.                         {
  189.                                 TIM_SetCompare1(TIM14,700+value);
  190.                         }
  191.                         else
  192.                         {
  193.                                 TIM_SetCompare1(TIM14,700+pid.Voltage);
  194.                                 value=pid.Voltage;
  195.                         }
  196.                 }
  197.         }
  198. }
复制代码

所有资料51hei提供下载:
直流电机闭环调速系统.rar (552.1 KB, 下载次数: 57)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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