標題: 智能車雙車追逐與超車系統(tǒng)設(shè)計報告與STM32程序源碼 [打印本頁]

作者: 帥氣的昵稱    時間: 2018-6-11 16:50
標題: 智能車雙車追逐與超車系統(tǒng)設(shè)計報告與STM32程序源碼
2018年大學(xué)第九屆TI
大學(xué)生電子設(shè)計競賽設(shè)計報告

參賽序號

B-02

參賽題目

雙車追逐與超車系統(tǒng)(B題)

參賽隊員

*

指導(dǎo)教師

劉*

報告日期



      本系統(tǒng)以設(shè)計題目的要求為目的,采用 STM32F103開發(fā)板機作為步進電機的控制核心, 用脈沖精確的控制步進電機, 使之能在要求范圍內(nèi)轉(zhuǎn)動相應(yīng)的角度。 同時控制光電傳感器進行賽道數(shù)據(jù)的采集,進而對步進電機進行相應(yīng)的控制。




雙車追逐與超車系統(tǒng)(B題)
1系統(tǒng)設(shè)計
1.1  設(shè)計要求
1.1.1 總體要求
1.1.2 基本部分
1.1.3 發(fā)揮部分
2系統(tǒng)方案
2.1 驅(qū)動電機的論證與選擇
2.2 人機交互與輸入模塊的論證與選擇
3系統(tǒng)總體設(shè)計
3.1系統(tǒng)硬件的設(shè)計
3.1.1系統(tǒng)總體框圖
3.1.2 輸入模塊與電路原理圖
3.1.3 輸出模塊與電路原理圖
3.1.4 人機交互模塊與電路原理圖
3.2系統(tǒng)軟件的設(shè)計
3.2.1程序功能描述與設(shè)計思路
3.2.2程序流程圖
附錄1:源程序
附錄2:參考文獻


雙車追逐與超車系統(tǒng)B
本科組
1系統(tǒng)設(shè)計
1.1  設(shè)計要求
1.1.1 總體要求
設(shè)計兩輛智能小車。甲車車頭緊靠起點標志線,乙車車尾緊靠邊界,甲、乙兩輛小車同時啟動,先后通過起點標志線,在行車道內(nèi)同向而行,實現(xiàn)雙車追逐與超車功能,跑道如圖1所示。
圖1.1  跑道圖

1.1.2 基本部分

(1)甲車、乙車分別從起點標志線開始,在行車道各正常行駛一圈(15分)。

(2)甲、乙兩輛小車在圖1所示位置同時啟動,開始雙車追逐,在甲車通過超車標志區(qū)時視為雙車追逐結(jié)束。此過程中,兩車間距始終小于30cm(20分)。

(3)甲、乙兩車在完成基礎(chǔ)要求(2)時的行駛時間小于10秒(10分)。

(4)完成基礎(chǔ)要求(2)后,乙車通過超車標志線后在超車區(qū)內(nèi)實現(xiàn)超車功能,并先于甲車到達終點標志線,即實現(xiàn)乙車超過甲車,若超車時間小于5秒,得25分。(25分)。


1.1.3 發(fā)揮部分

(1)在完成基礎(chǔ)要求(4)后,甲,乙兩車繼續(xù)行駛第二圈,要求甲車通過超車標志線后實現(xiàn)超車功能(20分)。

(2)甲,乙兩車行駛第二圈總時間不超過10秒(10分)。

2系統(tǒng)方案
本系統(tǒng)主要由輸入模塊、輸出模塊、人機交互模塊組成,下面分別論證這幾個模塊的選擇。
2.1 驅(qū)動電機的論證與選擇
方案一:采用直流電機作為系統(tǒng)的主要動力機構(gòu),直流電機是日常生活中比較常用 的電機類型,可以采用L298N 芯片對直流電機的控制,但直流電機無法精確控制;本次設(shè)計要用到兩個電機相互配合來控制小車轉(zhuǎn)彎的角度以及雙車追逐之間的距離,要求很高的精度,直流電機較難實現(xiàn)。
方案二:舵機。 舵機體積小, 安裝方便,其轉(zhuǎn)動的角度用脈沖來進行控制,能做到精確轉(zhuǎn)動,且轉(zhuǎn)動力矩比同質(zhì)量的直流電機或步進電機都大,轉(zhuǎn)動的范圍有限, 不適合本系統(tǒng)。
方案三:采用步進電機作為系統(tǒng)的主要動力機構(gòu),步進電機通過脈沖控制,每次可以走一個很小的角度,這就可以滿足本題精確控制小車轉(zhuǎn)彎的角度以及雙車追逐之間的距離的要求。

綜合以上三種方案,選擇方案三。

2.2 人機交互與輸入模塊的論證與選擇
              應(yīng)題目要求,按鍵作為人機交互模塊,光電傳感器對賽道數(shù)據(jù)進行采集。這兩個模塊固定。
3系統(tǒng)總體設(shè)計3.1系統(tǒng)硬件的設(shè)計3.1.1系統(tǒng)總體框圖
系統(tǒng)總體框圖如圖所示
圖3.1  系統(tǒng)總體框圖
3.1.2 輸入模塊與電路原理圖
              光電傳感器作為數(shù)據(jù)采集端。
圖3.2  紅外光電傳感器實物圖
圖3.3  紅外光電傳感器原理圖
3.1.3 輸出模塊與電路原理圖
              步進電機空系統(tǒng)的執(zhí)行端。
圖3.4 步進電機實物圖
圖3.5 步進電機驅(qū)動電路圖

3.1.4 人機交互模塊與電路原理圖
              按鍵KEY用于人機交互。
圖3.6 按鍵電路圖
3.2系統(tǒng)軟件的設(shè)計3.2.1程序功能描述與設(shè)計思路

1、程序功能描述

根據(jù)題目要求軟件部分主要實現(xiàn)按鍵控制小車按指定距離走完一圈和超車功能。

2、程序設(shè)計思路

我們從系統(tǒng)設(shè)計出發(fā),根據(jù)硬件系統(tǒng)設(shè)計,將軟件設(shè)計分為硬件層、驅(qū)動層、應(yīng)用層。這樣設(shè)計符合模塊化思想,有助于代碼調(diào)試、閱讀、學(xué)習(xí)。

3.2.2程序流程圖

1、主程序流程圖

2、轉(zhuǎn)圈與追逐功能流程圖

3、超車功能流程圖

4、直走子程序流程圖

5、轉(zhuǎn)彎子程序流程圖
6、超車子程序流程圖

附錄1源程序
  1. #include "main.h"

  2. /*
  3. * 函數(shù)名:main
  4. * 函數(shù)功能:功能選擇
  5. * 入口參數(shù):void
  6. * 返回參數(shù):0
  7. *
  8. */

  9. int main(void)
  10. {        
  11.         System_Init();
  12.         while(1){
  13.                 delay_ms(10);
  14.                 switch(KEY_UP()){                //判斷按鍵是否松開
  15.                         case KEY0_PRES:                        //KEY0松開
  16.                                 start(20, 50);                //小車起步
  17.                                 start(20, 20);
  18.                                 functionOne();                //功能一
  19.                                 break;
  20.                         case KEY1_PRES:                //KEY1松開
  21.                                 break;
  22.                         case WKUP_PRES:                //WKUP_PRES松開
  23.                                 start(20, 50);        //小車起步
  24.                                 start(20, 20);
  25.                                 functionThree();        //功能三
  26.                                 count = 0;                //重新計數(shù)
  27.                                 val = 0;
  28.                                 num = 1;
  29.                                 functionTwo();        //功能二
  30.                                 break;
  31.                 }
  32.         }
  33.   
  34.         return 0;
  35. }

  36. void start(int s, int t){                //小車起步程序
  37.         while(s>0){                //小車走s步
  38.                 delay_ms(t);                        //延時t毫秒
  39.                 motor_start10(3-con1%4);                //左輪反轉(zhuǎn)
  40.                 motor_start11(con2%4);                //右輪正轉(zhuǎn)
  41.                 if(con1 == 600){        //左輪清零
  42.                         con1 = 0;
  43.                 }
  44.                 con1++;
  45.                 if(con2 == 600){        //右輪清零
  46.                         con2 = 0;
  47.                 }
  48.                 con2++;
  49.                 s--;
  50.         }
  51.         delay_ms(2);        //延時
  52. }

  53. void overCar(void){                //超車程序
  54.         int i = 0;
  55.         while(1){                //直走245步
  56.                 delay_ms(5);
  57.                 motor_start10(3-con1%4);  //左輪反轉(zhuǎn)
  58.                 motor_start11(con2%4);                //右輪正轉(zhuǎn)
  59.                 if(con1 == 600){
  60.                         con1 = 0;
  61.                 }
  62.                 con1++;
  63.                 if(con2 == 600){
  64.                         con2 = 0;
  65.                 }
  66.                 con2++;
  67.                 i++;
  68.                 if(i > 245){        
  69.                         i = 0;
  70.                         break;
  71.                 }
  72.         }
  73.         
  74.         trunLeft(20); //左轉(zhuǎn)
  75.         trunRight();        //右轉(zhuǎn)
  76.         
  77.         while(1){                //直走340步
  78.                 delay_ms(3);
  79.                 motor_start10(3-con1%4);
  80.                 motor_start11(con2%4);
  81.                 if(con1 == 600){
  82.                         con1 = 0;
  83.                 }
  84.                 con1++;
  85.                 if(con2 == 600){
  86.                         con2 = 0;
  87.                 }
  88.                 con2++;
  89.                 i++;
  90.                 if(i > 340){
  91.                         i = 0;
  92.                         break;
  93.                 }
  94.         }
  95.         
  96.         trunRight();                //右轉(zhuǎn)
  97.         
  98.         while(1){                //直走30步
  99.                 delay_ms(5);
  100.                 motor_start10(3-con1%4);
  101.                 motor_start11(con2%4);
  102.                 if(con1 == 600){
  103.                         con1 = 0;
  104.                 }
  105.                 con1++;
  106.                 if(con2 == 600){
  107.                         con2 = 0;
  108.                 }
  109.                 con2++;
  110.                 i++;
  111.                 if(i > 30){
  112.                         i = 0;
  113.                         break;
  114.                 }
  115.         }
  116.         
  117.         trunLeft(0);                //左轉(zhuǎn)
  118.         count = 8;                //給標志線計數(shù)器重新賦值為8
  119.         val = 8;
  120.         num = 8;
  121. }

  122. void functionThree(void){                //功能三
  123.         int i = 0;
  124.         while(1){               
  125.                 lineRun();                //直線走
  126.                 if(num == 10){                //判斷是否到達終點
  127.                         break;
  128.                 }
  129.                 trunLeft(0);        //左轉(zhuǎn)
  130.                 if(num == 8){                //判斷是否到達超車區(qū)域
  131.                         while(1){                //直線行駛800步
  132.                                 delay_ms(5);               
  133.                                 motor_start10(3-con1%4);
  134.                                 motor_start11(con2%4);
  135.                                 if(con1 == 600){
  136.                                         con1 = 0;
  137.                                 }
  138.                                 con1++;
  139.                                 if(con2 == 600){
  140.                                         con2 = 0;
  141.                                 }
  142.                                 con2++;
  143.                                 i++;
  144.                                 if(i == 800){
  145.                                         i = 0;
  146.                                         break;
  147.                                 }
  148.                         }
  149.                         while(1){                //減速行駛180步
  150.                                 delay_ms(50);
  151.                                 motor_start10(3-con1%4);
  152.                                 motor_start11(con2%4);
  153.                                 if(con1 == 600){
  154.                                         con1 = 0;
  155.                                 }
  156.                                 con1++;
  157.                                 if(con2 == 600){
  158.                                         con2 = 0;
  159.                                 }
  160.                                 con2++;
  161.                                 i++;
  162.                                 if(i == 180){
  163.                                         i = 0;
  164.                                         break;
  165.                                 }
  166.                         }
  167.                 }
  168.         }
  169. }

  170. void functionTwo(void){                //功能二
  171.         while(1){
  172.                 lineRun();                //直走
  173.                 if(num == 10){                //判斷是否到達終點
  174.                         break;
  175.                 }
  176.                 trunLeft(0);                //左轉(zhuǎn)
  177.                 if(val == 8){                //判斷是否進入超車區(qū)
  178.                         overCar();                //超車
  179.                 }
  180.         }
  181. }

  182. void functionOne(void){                //功能一
  183.         while(1){
  184.                 lineRun();                //直線走
  185.                 if(num == 10){                //判斷是否到達終點
  186.                         break;
  187.                 }
  188.                 trunLeft(0);                //左轉(zhuǎn)
  189.                
  190.         }
  191. }

  192. void trunRight(void){                //右轉(zhuǎn)程序
  193.         int i = 0;
  194.         while(1){                //先直走230步
  195.                 delay_ms(3);
  196.                 motor_start10(3-con1%4);
  197.                 motor_start11(con2%4);
  198.                 if(con1 == 600){
  199.                         con1 = 0;
  200.                 }
  201.                 con1++;
  202.                 if(con2 == 600){
  203.                         con2 = 0;
  204.                 }
  205.                 con2++;
  206.                 i++;
  207.                 if(i == 230){
  208.                         i = 0;
  209.                         break;
  210.                 }
  211.         }
  212.         
  213.         while(1){                //右輪不轉(zhuǎn)左輪轉(zhuǎn)
  214.                 delay_ms(3);
  215.                 motor_start10(3-con1%4);
  216.                 if(con1 == 600){
  217.                         con1 = 0;
  218.                 }
  219.                 con1++;
  220.                 i++;
  221.                 if(i == C3){
  222.                         i = 0;
  223.                         break;
  224.                 }
  225.         }
  226. }


  227. void trunLeft(int c){  //左轉(zhuǎn)程序
  228.         int i = 0;
  229.         while(1){                //先直走165步
  230.                 delay_ms(5);
  231.                 motor_start10(3-con1%4);
  232.                 motor_start11(con2%4);
  233.                 if(con1 == 600){
  234.                         con1 = 0;
  235.                 }
  236.                 con1++;
  237.                 if(con2 == 600){
  238.                         con2 = 0;
  239.                 }
  240.                 con2++;
  241.                 i++;
  242.                 if(i == 165){
  243.                         i = 0;
  244.                         break;
  245.                 }
  246.         }
  247.         
  248.         while(1){        //左輪不轉(zhuǎn)右輪轉(zhuǎn)
  249.                 delay_ms(3);
  250.                 motor_start11(con2%4);
  251.                 if(con2 == 600){
  252.                         con2 = 0;
  253.                 }
  254.                 con2++;
  255.                 i++;
  256.                 if(i == C3-c){
  257.                         i = 0;
  258.                         break;
  259.                 }
  260.         }
  261. }

  262. void right(void){                //向右調(diào)平程序
  263.         while(1){                //左輪轉(zhuǎn)動直到左邊光電傳感器掃描到標志線
  264.                 delay_ms(5);
  265.                 motor_start10(3-con1%4);  
  266.                 if(con1 == 600){
  267.                         con1 = 0;
  268.                 }
  269.                 con1++;
  270.                 if(val==count){
  271.                                 break;
  272.                 }
  273.         }
  274. }

  275. void left(void){                //向左調(diào)平程序
  276.         while(1){                //右輪轉(zhuǎn)動直到右邊光電傳感器掃描到標志線
  277.                 delay_ms(5);
  278.                 motor_start11(con2%4);        
  279.                 con2++;
  280.                 if(con2 == 600){
  281.                         con2 = 0;
  282.                 }
  283.                
  284.                 if(count==val){
  285.                                 break;
  286.                 }
  287.         }
  288. }

  289. void lineRun(void){                //直線走程序
  290.   int value1 = 0;
  291.         int value2 = 0;
  292.         while(1){
  293.                
  294.                 delay_ms(5);
  295.                 motor_start10(3-con1%4);
  296.                 motor_start11(con2%4);
  297.                 if(num == 1&&con1 == 450){                //確保左右光電傳感器計數(shù)值在經(jīng)過第一條標志線后一致
  298.                                 count = num;
  299.                                 val = num;                                
  300.                 }
  301.                 if(con1 == 600){
  302.                         con1 = 0;
  303.                 }
  304.                 con1++;
  305.                 if(con2 == 600){
  306.                         con2 = 0;
  307.                 }
  308.                 con2++;
  309.                 if(num == 10){                //判斷是否到達終點
  310.                         break;
  311.                 }
  312.                 //在第2、3、4、9、10標志線處調(diào)平
  313.                 if((count-value1==1)&&(count==2||count==3||count==4||count==9||count==10)){
  314.                         right();
  315.                         break;
  316.                 }
  317.                 if((val-value2==1)&&(val==2||val==3||val==4||val==9||val==10)){
  318.                         left();
  319.                         break;
  320.                 }
  321.                 value1 = count;
  322.                 value2 = val;
  323.         }
  324. }

  325. /*
  326. * 函數(shù)名:System_Init
  327. * 函數(shù)功能:系統(tǒng)硬件層初始化
  328. * 入口參數(shù):無
  329. * 返回參數(shù):無
  330. *
  331. */
  332. void System_Init(void){
  333.         
  334.         Stm32_Clock_Init(9);                                          //初始化系統(tǒng)時鐘               
  335.         delay_init(72);                                                                        //初始化延時
  336.         MOTOR_Init();                                                                                //初始化電機接口                                                                          
  337.         uart_init(72,9600);                                                        //初始化串口
  338.         KEY_Init();                                                                                        //初始化按鍵
  339. //        LED_Init();
  340.          EXTI_Init();                                                                                //初始化中斷
  341. }
復(fù)制代碼

全部資料51hei下載地址(word格式的論文內(nèi)含清晰圖片)
智能小車追逐超車系統(tǒng).zip (2.86 MB, 下載次數(shù): 33)







歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1