单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:11776|回复:15
打印上一主题下一主题

STM32寻迹小车pid调速源码

 [复制链接]
跳转到指定楼层
楼主
ID:282271发表于 2018-2-5 10:09|只看该作者回帖奖励
寻迹小车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. ……………………

  281. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
巡线.rar(116.53 KB, 下载次数: 364)


评分

黑币 +5
收起理由
+ 5

查看全部评分

沙发
ID:370991发表于 2018-7-13 16:18|只看该作者
楼上讲得很有道理 楼主辛苦
板凳
ID:370991发表于 2018-7-13 16:20|只看该作者
寻迹小车的代码希望能帮到我
地板
ID:370991发表于 2018-7-13 16:40|只看该作者
智能小车寻迹代码 希望有用
5#
ID:371003发表于 2018-7-13 16:51|只看该作者
资源很给力
6#
ID:388219发表于 2018-8-20 16:56|只看该作者
智能小车寻迹代码 希望有用
7#
ID:427436发表于 2018-12-6 18:56|只看该作者
寻迹小车的代码希望能帮到我
8#
ID:427227发表于 2018-12-21 09:27|只看该作者
楼主资料给力啊  谢谢
9#
ID:251494发表于 2019-4-5 11:37|只看该作者
支持一下。
10#
ID:343570发表于 2019-4-11 00:05|只看该作者
很厉害一直在找这个
11#
ID:525606发表于 2019-5-1 15:59|只看该作者
这是灰度传感器吗?
12#
ID:571026发表于 2019-6-24 17:30|只看该作者
楼主辛苦,很详细,很有帮助
13#
ID:480712发表于 2019-6-25 09:55|只看该作者
这是那个软件的
14#
ID:500189发表于 2019-10-28 14:25|只看该作者
楼主的灰度放到哪些位置了
15#
ID:648762发表于 2020-10-6 15:28|只看该作者
这个是用什么IDE开发的
16#
ID:588322发表于 2020-10-15 23:30|只看该作者
学习,刚好要用到电机调速方面的资料

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

Powered by 单片机教程网