找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 9335|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

智能車雙車追逐與超車系統(tǒng)設(shè)計(jì)報(bào)告與STM32程序源碼

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
2018年大學(xué)第九屆TI
大學(xué)生電子設(shè)計(jì)競(jìng)賽設(shè)計(jì)報(bào)告

參賽序號(hào)

B-02

參賽題目

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

參賽隊(duì)員

*

指導(dǎo)教師

劉*

報(bào)告日期



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




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


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

1.1.2 基本部分

(1)甲車、乙車分別從起點(diǎn)標(biāo)志線開(kāi)始,在行車道各正常行駛一圈(15分)。

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

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

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


1.1.3 發(fā)揮部分

(1)在完成基礎(chǔ)要求(4)后,甲,乙兩車?yán)^續(xù)行駛第二圈,要求甲車通過(guò)超車標(biāo)志線后實(shí)現(xiàn)超車功能(20分)。

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

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

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

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

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

1、程序功能描述

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

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

我們從系統(tǒng)設(shè)計(jì)出發(fā),根據(jù)硬件系統(tǒng)設(shè)計(jì),將軟件設(shè)計(jì)分為硬件層、驅(qū)動(dòng)層、應(yīng)用層。這樣設(shè)計(jì)符合模塊化思想,有助于代碼調(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()){                //判斷按鍵是否松開(kāi)
  15.                         case KEY0_PRES:                        //KEY0松開(kāi)
  16.                                 start(20, 50);                //小車起步
  17.                                 start(20, 20);
  18.                                 functionOne();                //功能一
  19.                                 break;
  20.                         case KEY1_PRES:                //KEY1松開(kāi)
  21.                                 break;
  22.                         case WKUP_PRES:                //WKUP_PRES松開(kāi)
  23.                                 start(20, 50);        //小車起步
  24.                                 start(20, 20);
  25.                                 functionThree();        //功能三
  26.                                 count = 0;                //重新計(jì)數(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);                        //延時(shí)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);        //延時(shí)
  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;                //給標(biāo)志線計(jì)數(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){                //判斷是否到達(dá)終點(diǎn)
  127.                         break;
  128.                 }
  129.                 trunLeft(0);        //左轉(zhuǎn)
  130.                 if(num == 8){                //判斷是否到達(dá)超車區(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){                //判斷是否到達(dá)終點(diǎn)
  174.                         break;
  175.                 }
  176.                 trunLeft(0);                //左轉(zhuǎn)
  177.                 if(val == 8){                //判斷是否進(jìn)入超車區(qū)
  178.                         overCar();                //超車
  179.                 }
  180.         }
  181. }

  182. void functionOne(void){                //功能一
  183.         while(1){
  184.                 lineRun();                //直線走
  185.                 if(num == 10){                //判斷是否到達(dá)終點(diǎn)
  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)動(dòng)直到左邊光電傳感器掃描到標(biāo)志線
  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)動(dòng)直到右邊光電傳感器掃描到標(biāo)志線
  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){                //確保左右光電傳感器計(jì)數(shù)值在經(jīng)過(guò)第一條標(biāo)志線后一致
  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){                //判斷是否到達(dá)終點(diǎn)
  310.                         break;
  311.                 }
  312.                 //在第2、3、4、9、10標(biāo)志線處調(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ù):無(wú)
  329. * 返回參數(shù):無(wú)
  330. *
  331. */
  332. void System_Init(void){
  333.         
  334.         Stm32_Clock_Init(9);                                          //初始化系統(tǒng)時(shí)鐘               
  335.         delay_init(72);                                                                        //初始化延時(shí)
  336.         MOTOR_Init();                                                                                //初始化電機(jī)接口                                                                          
  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)


評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表