找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1906|回复: 1
收起左侧

STM32单片机PID调速程序

[复制链接]
ID:493513 发表于 2019-3-18 20:56 | 显示全部楼层 |阅读模式
PID调速

单片机源程序如下:
  1. #include "adc.h"
  2. #include "common.h"
  3. #include "usart.h"
  4. #include "L298N.h"
  5. #include "senser.h"
  6. #include "NVIC.h"
  7. #include "ir1838.h"
  8. #include "DMA.h"

  9. #define kP 11
  10. #define kdI 200 //nI除数 kI=1/kdI
  11. #define kD 120
  12. #define kdPID 28//PID除数
  13. #define D_INTERVAL 1200
  14. #define I_INTERVAL 15

  15. #define ONLINE_MINVAL 25
  16. #define POSVAL_MAX SENSER_MAXVAL*2//位置量值域(-POSVAL_MAX,POSVAL_MAX)

  17. #define SPEED_MIN 1700
  18. #define SPEED_NORMAL 1950
  19. #define SPEED_MAX 2000

  20. #define CHECK_WAIT_TIMEOUT 100000

  21. extern u16 ADC_DataBuffer[ADC_DMA_BUFFER_LENGTH];
  22. extern u32 senVals[3];

  23. u16 mod=0;

  24. int main()
  25. {
  26.         s32 PID;

  27.         s32 nP=0;
  28.         s32 nI=0;
  29.         s32 nD=0;

  30.         s32 nLastP=0;
  31.        
  32.         u32 nDC=D_INTERVAL;
  33.         u32 nIC=I_INTERVAL;
  34.        
  35.         s32 carSpeed=SPEED_NORMAL;
  36.        
  37.         u32 checkWait=0;
  38.         u8 adjustMod=100;

  39.         common_init();
  40.         ADC_init();
  41.         #ifdef USART_ON
  42.                 usart_init();
  43.         #endif
  44.         L298N_init();
  45.         #ifdef IR_CTRL_
  46.                 IR1838_init();
  47.         #else
  48.                 //mod=1;
  49.         #endif
  50.         DMA_init();
  51.         NVIC_init();
  52.        
  53.         delayms(120);//等待DMA将 adc_buffer 填满,避免senser校准值出错(如果有0会导致minvs不正确)
  54.        
  55.         while (1)
  56.         {
  57.                 #ifdef IR_CTRL_
  58.                         Ircordpro();
  59.                 #endif

  60.                 switch (mod)
  61.                 {
  62.                 case 0:
  63.                         //等待车被放上跑道
  64.                         senVals[0]=ADC_DMA_getVal(0);
  65.                         senVals[1]=ADC_DMA_getVal(1);
  66.                         senVals[2]=ADC_DMA_getVal(2);
  67.                         #ifdef USART_ON
  68.                                 #define LSHIFTBIT        9
  69.                                 #define        SENVALGATE        9
  70.                         //printDebug("senVals[0]=",senVals[0]);
  71.                         //printDebug("senVals[1]=",senVals[1]);
  72.                         //printDebug("senVals[2]=",senVals[2]);
  73.                         //printDebug("-------------\n",0);
  74.                         if(senVals[2]>SENVALGATE)
  75.                         {
  76.                                 senVals[2]-=SENVALGATE;
  77.                         }
  78.                         else
  79.                         {
  80.                                 senVals[2]=0;
  81.                         }
  82.                         senVals[2]<<=LSHIFTBIT;
  83.                        
  84.                         L298N_setLS(senVals[2]);
  85.                         L298N_setRS(senVals[2]);
  86.                         //delayms(3000);
  87.                         continue;
  88.                         #endif
  89.                         if (senVals[0]>SENSER_ORIGIN_MIN&&senVals[0]>SENSER_ORIGIN_MIN&&senVals[0]>SENSER_ORIGIN_MIN)//车被提起
  90.                         {
  91.                                 checkWait=CHECK_WAIT_TIMEOUT;
  92.                                 adjustMod=100;
  93.                                 L298N_setLS(0);
  94.                                 L298N_setRS(0);
  95.                         }
  96.                         else
  97.                         {
  98.                                 if(adjustMod==100)
  99.                                 {
  100.                                         adjustMod=0;
  101.                                         Senser_reset();
  102.                                 }
  103.                         }
  104.                        
  105.                         switch (adjustMod)
  106.                         {
  107.                         case 0:
  108.                                 if (checkWait)
  109.                                 {
  110.                                         checkWait--;
  111.                                 }
  112.                                 else
  113.                                 {
  114.                                         adjustMod=1;
  115.                                         beep(900,300);
  116.                                 }
  117.                                 break;
  118.                         case 1:
  119.                                 //将左传感器移动到线上
  120.                                 L298N_setLS(1400);
  121.                                 L298N_setRS(0);
  122.                                 if(senVals[0]>SENSER_ORIGIN_MIN)
  123.                                 {
  124.                                         adjustMod=2;
  125.                                 }
  126.                                 break;
  127.                         case 2:
  128.                                 //将左传感器移动到线右边
  129.                                 if(senVals[0]<SENSER_ORIGIN_MIN)
  130.                                 {
  131.                                         L298N_setLS(0);
  132.                                         L298N_setRS(0);
  133.                                         adjustMod=3;
  134.                                         beep(900,300);
  135.                                 }
  136.                                 break;
  137.                         case 3:
  138.                                 //左转开始扫描,直到右传感在线上
  139.                                 L298N_setLS(0);
  140.                                 L298N_setRS(1400);
  141.                                 if(senVals[2]>SENSER_ORIGIN_MIN)
  142.                                 {
  143.                                         adjustMod=4;
  144.                                 }
  145.                                 break;
  146.                         case 4:
  147.                                 //直到右传感器移动到线左边
  148.                                 if(senVals[2]<SENSER_ORIGIN_MIN)
  149.                                 {
  150.                                         adjustMod=5;
  151.                                         beep(900,300);
  152.                                 }
  153.                                 break;
  154.                         case 5:
  155.                                 //右转直到中间传感器在线上
  156.                                 L298N_setLS(1400);
  157.                                 L298N_setLS(0);
  158.                                 if(senVals[1]>SENSER_ORIGIN_MIN)
  159.                                 {
  160.                                         beep(800,300);
  161.                                         delayms(10);
  162.                                         beep(600,300);
  163.                                         delayms(10);
  164.                                         beep(600,300);
  165.                                         delayms(10);
  166.                                         beep(600,300);
  167.                                         mod=1;
  168.                                 }
  169.                         }
  170.                        
  171.                         if(adjustMod==3||adjustMod==4)
  172.                         {
  173.                                 //校正
  174.                                 Senser_getsv(0);
  175.                                 Senser_getsv(1);
  176.                                 Senser_getsv(2);
  177.                         }
  178.                 case 1:
  179.                         Senser_getsv(0);
  180.                         Senser_getsv(1);
  181.                         Senser_getsv(2);
  182.                        
  183.                         /* ------------P------------ */
  184.                         /* 计算位置 */
  185.                         if (senVals[1]>ONLINE_MINVAL)
  186.                         {
  187.                                 //线在中间传感器下
  188.                                 if (carSpeed<SPEED_MAX)
  189.                                 {
  190.                                         //加速
  191.                                         carSpeed++;
  192.                                 }

  193.                                 if (senVals[0]>ONLINE_MINVAL)
  194.                                 {
  195.                                         //中间偏左
  196.                                         nP=POSVAL_MAX/2-senVals[1];
  197.                                 }
  198.                                 else
  199.                                 {
  200.                                         //中间偏右
  201.                                         nP=senVals[1]-POSVAL_MAX/2;
  202.                                 }
  203.                         }
  204.                         else if (senVals[0]>ONLINE_MINVAL)
  205.                         {
  206.                                 //线在左边传感器偏左
  207.                                 nP=POSVAL_MAX-senVals[0];
  208.                         }
  209.                         else if (senVals[2]>ONLINE_MINVAL)
  210.                         {
  211.                                 //线在右边传感器偏右
  212.                                 nP=senVals[2]-POSVAL_MAX;
  213.                         }
  214.                         else
  215.                         {
  216.                                 //线离开传感器检测范围
  217.                                 if (carSpeed>SPEED_MIN)
  218.                                 {
  219.                                         //减速
  220.                                         carSpeed--;
  221.                                 }
  222.                                 if (nP<0)
  223.                                 {
  224.                                         nP=-POSVAL_MAX;
  225.                                 }
  226.                                 else
  227.                                 {
  228.                                         nP=POSVAL_MAX;
  229.                                 }
  230.                         }
  231.                         //nP/=4;
  232.                        
  233.                         /* ------------I------------ */
  234.                         if(nIC)
  235.                         {
  236.                                 nIC--;
  237.                         }
  238.                         else
  239.                         {
  240.                                 nIC=I_INTERVAL;
  241.                                
  242.                                 if(nP>ONLINE_MINVAL||nP<-ONLINE_MINVAL)
  243.                                 {
  244.                                         nI+=nP/20;//nI=9*nI/10;
  245.                                 }
  246.                                 else
  247.                                 {
  248.                                         nI=0;
  249.                                 }
  250.                         }
  251.                        
  252.                         /* ------------D------------ */
  253.                         if(nDC)
  254.                         {
  255.                                 nDC--;
  256.                         }
  257.                         else
  258.                         {
  259.                                 nDC=D_INTERVAL;
  260.                                
  261.                                 nD=nP-nLastP;
  262.                                 nLastP=nP;
  263.                         }
  264.                        
  265.                         /* PID */
  266.                         PID=nP*kP + nI/kdI + nD*kD;
  267.                         PID/=kdPID;
  268.                        
  269.                         L298N_setSpeed(carSpeed,PID);
  270.                        
  271.                         /*
  272.                         printDebug("nP=",nP*kP);
  273.                         printDebug("nI=",nI/kdI);
  274.                         printDebug("nD=",nD*kD);
  275.                         printDebug("PID=",PID);
  276.                         printChar('\n',USART2);
  277.                        
  278.                         printDebug("LS=",TIM4->CCR3);
  279.                         printDebug("RS=",TIM4->CCR4);
  280.                         printChar('\n',USART2);
  281.                        
  282.                         printDebug("senVals[0]=",senVals[0]);
  283.                         printDebug("senVals[1]=",senVals[1]);
  284.                         printDebug("senVals[2]=",senVals[2]);
  285.                         printChar('\n',USART2);
  286.                         //delayms(1000);
  287.                         // */

  288.                         break;
  289.                 case 3:
  290.                         L298N_setLS(0);
  291.                         L298N_setRS(0);
  292.                         break;
  293.                 }
  294. #ifdef DEBUG
  295.                 /*
  296.                                 printDebug("lsen=",senVals[0]);
  297.                                 printDebug("rsen=",senVals[1]);
  298.                                 printDebug("pid=",PID);
  299.                                 printChar('\n',USART2);
  300.                                 delayms(1000);
  301.                 */

  302.                 /*
  303.                                 L298N_setLS(800);
  304.                                 L298N_setRS(800);
  305.                                 ledp=!ledp;
  306.                                 delayms(2000);
  307.                 */
  308. #endif
  309.         }

  310.         //return 0;
  311. }
复制代码

所有资料51hei提供下载:
PID调速.rar (116.53 KB, 下载次数: 36)
回复

使用道具 举报

ID:1 发表于 2019-3-19 18:26 | 显示全部楼层
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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