欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 16481|回復: 8
收起左側

STM32兩輪智能避障小車制作 含keil工程源碼、連線圖

  [復制鏈接]
ID:495511 發表于 2019-3-21 17:08 | 顯示全部樓層 |閱讀模式
這個項目最主要研究了基于STM32F103微處理器的智能小車控制系統的設計。整個系統主要包括STM32F103控制器、電機驅動電路、紅外檢測電路、超聲波避障電路。我們采用STM32F103芯片,采用脈沖寬度調制信號(PWM)來完成對電機的控制,循跡模塊采用紅外探測法進行黑白探測,避障模塊進行障礙物檢測并躲避,超聲波模塊用來檢測小車與障礙物之間的距離,其他外圍電路可用于其他功能的拓展。小車在運行過程中,避障程序優先于循跡程序。

1.介紹
1.1項目介紹
1.2研究目的
1.3設想
1.4研究方法及思路
1.5成果
2.軟硬件設計
2.1智能小車介紹
2.2智能小車的組成部分
2.2.1微處理器
2.2.2傳感器檢測部分
2.2.3超聲波檢測部分
2.2.4機器人的腳
2.3循跡原理
2.3.1紅外探測法
2.3.2循跡方法
2.3.3道路現象分析
2.3.4循跡代碼
2.4避障原理
2.4.1HC-SR04工作原理
2.4.2自由避障策略
2.4.3自由避障代碼
2.5自動駕駛系統總體結構
3.軟硬件調試
3.1軟件調試
3.2硬件調試
4.結論

1.介紹1.1項目介紹

本項目是一個自動駕駛系統的項目,該項目能夠通過提供自動駕駛、對路況智能處理以及其他為行駛系統設計的新功能,根據場景設定完成自動駕駛。該自動駕駛的設備可以是私家汽車, 貨車,也可以是卡車等。

1.2研究目的

設計一個自動駕駛系統,可以在特定地方尋找軌跡,并沿著軌跡行走;可以檢測到障礙物的距離并進行躲避。

1.3設想

假設在校方提供提供的樣機、紅外探測器、超聲波檢測模塊功能正常,電池電量充足,源程序思路代碼均正確,場地軌跡明顯的情況下,我們的小車可以沿著黑色軌跡線持續行走,遇到障礙物時小車停止,移開障礙物后,小車可繼續沿著特定的軌跡行走,直至我們要求其結束。

1.4研究方法及思路

本次實驗我們采取模擬法,使用HL-1 智能小車模擬真實的汽車,進行實驗。實驗過程中,我們模擬不同的路況,例如“T型路”、“十字路”、“斷頭路”等路況,將小車放在相應的位置,觀察其紅外探測的指示燈的亮滅狀況,并記錄下來,分析其對應情況時IO口的輸入情況,得出循跡偽代碼;避障時,我們通過設置障礙物,分析小車遇到障礙物時應做出的回應,得到相應的偽代碼。最終進行整體代碼的分析撰寫。


1.5成果

循跡:小車在特定場景模式下,按照黑色的軌跡行駛;

避障:循跡模式下,小車遇障礙物停止;自由模式下,小車到障礙物的距離大于20cm時直行,小車到障礙物的距離大于10cm小于20cm時右轉;小車到障礙物的距離小于10cm時后退;

文檔:提交技術報告、會議紀要、進度計劃表、任務書組、項目組成員表等文檔

2.軟硬件設計2.1智能小車介紹
  • 智能小車是輪式機器人。
  • 它是一個集環境感知、規劃決策、自動駕駛等功能于一體的綜合系統                           
  • 它是集中運用了計算機、傳感、信息、通信、導航、人工智能及自動控制等技術的綜合體。
圖 1 智能小車整體圖
2.2智能小車的組成部分2.2.1微處理器
圖 2 STM32F103C8主芯片整體圖

STM32F103C8主芯片

  •    內核:ARM 32位的Cortex-M3 CPU 工作頻率72MHz                           
  •    存儲器:64KB閃存程序存儲器、20KB的SRAM
  •    電源電壓:2.0V~3.6V
  •    數據轉換器:2個12位AD轉換器(10個輸入通道)
  •    調試模式:串行單線調試(SWD)和JTAG接口
2.2.2傳感器檢測部分
圖 3 紅外反射傳感器整體圖

紅外反射傳感器

  •    檢測距離:1mm~8mm
  •    比較器輸出數字開關量(0和1)
  •    配多圈可調精密電位器調節靈敏度
  •    工作電壓:3.3V~5V

傳感器的紅外發射二極管不斷發射紅外線,當發射出的紅外線沒有被反射回來或被反射回來強度不大時,比較器的輸出端為高電平,指示燈熄滅;當紅外線被反射回來且強度足夠大時,比較器的輸出端為低電平,指示燈被點亮。

2.2.3超聲波檢測部分
圖 4 HC-SR04整體圖

HC-SR04引腳

  • VCC供5V電源
  • GND為地線
  • TRIG觸發控制信號輸入
  • ECHO回響信號輸出
表 1  HC-SR04電器參數

電氣參數

HC-SR04聲波模塊

工作電壓

DC  5V

工作電流

15mA

輸入觸發信號

10us的TTL脈沖

輸出回響

輸出TTL電平信號信號,與射程成比例



2.2.4機器人的腳
圖 5 LN98N集成電機驅動整體圖
  •    機械部分

車輪為三個,前輪是兩個主動輪,后輪是一個從動輪

  •    電機部分
  •   兩個直流電機
  •   L298N集成電機驅動芯片
  •   工作電壓:5V

微控制器產生PWM信號給L298N,通過調節方波的占空比來控制電機的轉速。兩個電機轉速相同時小車前進或后退;轉速不同時小車轉彎;兩個電機反向等速運轉時,小車原地轉圈。

2.3循跡原理

小車循跡指的是小車在白色地板上循黑線行走,通常采取的方法是紅外探測法。

2.3.1紅外探測法

利用紅外線在不同顏色的物體表面具有不同的反射強度的特點,在小車行駛過程中不斷地向地面發射紅外光,當紅外光遇到白色紙質地板時發生漫反射,反射光被裝在小車上的接收管接收;如果遇到黑線則紅外光被吸收,小車上的接收管接收不到紅外光。單片機就是否收到反射回來的紅外光為依據來確定黑線的位置和小車的行走路線。

2.3.2循跡方法

采用與路面顏色有較大差別的線條(白色路面上有條黑色曲線)作引導線,當循跡傳感器照到黑線時輸出高電平1,照到白色時輸出低電平0。

圖 6 循跡示意圖
2.3.3道路現象分析
路徑名稱
路徑圖示
小車操作



循跡直行


尋跡直行,沿著當前黑色路徑指示直行

L彎左轉

循跡左轉90度,沿著當前黑色路徑指示直行

L彎右轉

循跡右轉90度,沿著當前黑色路徑指示直行

T型路口按命令轉彎

遇到T型路口,根據命令轉彎。命令左轉,向左轉彎;命令右轉,向右循跡轉彎。

            

              十字路口

遇到十字路口,根據命令行駛。左轉,右轉直行

斷頭路

遇到斷頭路,左轉180度調頭

圖表 1   道路狀態模擬

我們采用三路循跡,共8中狀態指示,對應狀況如下所示

表 2    紅外檢測狀態分析

指示燈A、C、E
代號
回應
000
OUT
掉頭(‘u’)
001
R
右轉(‘r’)
010
M
執行(‘f’)
011
MR
右轉(‘r’)
100
L
左轉(‘l’)
101
LR

110
LM
左轉(‘l’)
111
LMR
右轉(‘r’)

備注:我們設計的線路之間有一定的距離,LR狀態不會出現

2.3.4循跡代碼
圖 7   循跡代碼截圖
2.4避障原理2.4.1HC-SR04工作原理
  • 給超聲波模塊接入電源和地。
  • 給脈沖觸發引腳(trig)輸入一個長為20us的高電平方波。
  • 輸入方波后,模塊會自動發射8個40KHz的聲波,與此同時回波引腳(echo)端的電平會由0變為1;(此時應該啟動定時器計時)
  • 當超聲波返回被模塊接收到時,回波引 腳端的電平會由1變為0;(此時應該停止定時器計數),定時器記下的這個時間即為超聲波由發射到返回的總時長。
  •   根據聲音在空氣中的速度為344米/秒,即可計算出所測的距離
2.4.2自由避障策略
表 3自由避障策略分析
當前距離(curDis)/cm
應答策略/代號
10<curDis <20
掉頭(‘u’)
curDis<10
后退(‘b’)
curDis >20
直行(‘f’)

2.4.3自由避障代碼
圖 8  自由避障程序截圖
2.5自動駕駛系統總體結構

圖 8  自動駕駛系統總體結構
3.軟硬件調試3.1軟件調試

系統開發條件:Keil 5.26.2.0

下載工具:J-Link 6.20

3.2硬件調試

小車連線:

·電源

              小車J2 –VCC 接stm32控制板JP2- +5V

              小車J2 –GND接stm32控制板JP2- GN

              小車J2 –VCC接紅外控制板VCC

小車J2 –GND接紅外控制板GND

·驅動

              小車J3-IN1接stm32控制板JP3-PB10

              小車J3-IN2接stm32控制板JP3-PB11

              小車J3-IN3接stm32控制板JP3-PB12

              小車J3-IN4接stm32控制板JP3-PB13

              小車J3-EN1接stm32控制板JP3-3.3V

              小車J3-EN2接stm32控制板JP3-3.3V

·紅外信號輸出

              紅外控制板D01接stm32控制板J2-PB5

              紅外控制板D02接stm32控制板J2-PB6

              紅外控制板D03接stm32控制板J2-PB7

·超聲波輸入輸出

              超聲波模塊接小車J6

              小車J4-P2.0接stm32控制板PA0

              小車J4-P2.1接stm32控制板PA4

4.結論

本次項目設計了中央處理模塊、電機驅動模塊、避障模塊和循跡模塊。其中中央處理模塊的芯片是stm32f103,電機驅動模塊的主要芯片是LM293D,避障模塊的主要器件是HC-SR04,循跡模塊的主要器件是五個紅外探測器(IR)。通過各模塊之間的配合以及軟件和硬件設計的結合,使得最終設計出的小車具有循跡功能和避障功能,即能沿軌跡黑線前進,不會偏出軌跡,并且當探測到障礙物時可停止前進,且探測距離大于10cm。最終完成了該項目的設想預期。



  1. #include <stdio.h>

  2. extern void CarInit(void);
  3. extern void DebugInit(void);
  4. extern void TimerInit(void);
  5. extern void CheckTimer(void);

  6. int main()
  7. {
  8.   TimerInit();    // 系統任務定時器初始化
  9.   CarInit();      // 小車各模塊初始化
  10.   DebugInit();

  11.   while(1)
  12.   {
  13.     CheckTimer(); // 開始執行定時任務
  14.   }
  15. }
  16. timer.c
  17. #include "stm32f10x.h"

  18. void TimerInit()
  19. {
  20.               RCC->APB2ENR |= 1 << 11;

  21.               TIM1->PSC = 36000 - 1;
  22.               TIM1->ARR = 65535;
  23.               TIM1->CR1 = 0x81;
  24. }

  25. static unsigned short TimeGet()
  26. {
  27.   return TIM1->CNT;
  28. }


  29. struct timer
  30. {
  31.   void (*proc)(void);
  32.   int reload;
  33.   unsigned short begin;
  34.   unsigned short duration;
  35. };

  36. #define TIMER_CNT_MAX 8
  37. static struct timer tmr[TIMER_CNT_MAX];
  38. static int tmr_cnt=0;

  39. int SetTimer(unsigned short duration, void (*proc)(void) , int reload)
  40. {
  41.   if (tmr_cnt >= TIMER_CNT_MAX)
  42.   {
  43.     return 0;
  44.   }
  45.   tmr[tmr_cnt].begin = TimeGet();
  46.   tmr[tmr_cnt].duration = duration;
  47.   tmr[tmr_cnt].proc = proc;
  48.   tmr[tmr_cnt].reload = reload;
  49.   tmr_cnt++;
  50.   return 1;
  51. }

  52. // CheckTimer為主程序循環調用函數,執行定時事務
  53. void CheckTimer()
  54. {
  55.   int tmr_idx=0;
  56.   int i=0;
  57.   unsigned short now = TimeGet();

  58.   while (tmr_idx < tmr_cnt)
  59.   {
  60.     if ((unsigned short)(now - tmr[tmr_idx].begin) >= tmr[tmr_idx].duration)
  61.     {
  62.       if (tmr[tmr_idx].proc)
  63.         (*tmr[tmr_idx].proc)();
  64.       if (tmr[tmr_idx].reload)
  65.       {
  66.         tmr[tmr_idx].begin = now;
  67.         tmr_idx++;
  68.       }
  69.       else
  70.       {
  71.         for (i=tmr_idx; i<tmr_cnt-1; i++)
  72.           tmr[i] = tmr[i+1];
  73.         tmr_cnt--;
  74.       }
  75.     }
  76.     else
  77.       tmr_idx++;
  78.   }
  79. }

  80. 3.motor.c

  81. #include "stm32f10x.h"

  82. struct motor
  83. {
  84.   enum {STOP, FORWARD, BACKWARD} state;
  85.   int forward_opcode;
  86.   int backward_opcode;
  87. };

  88. static struct motor left_motor, right_motor;

  89. void MotorInit()
  90. {
  91.   RCC->APB2ENR |= 1 << 3;
  92.   GPIOB->CRH &= 0xff0000ff;
  93.   GPIOB->CRH |= 0x00333300; //PB10              左后退 , PB11              左前進, PB12              右前進, PB13  右后退
  94.   GPIOB->BSRR = ((1 << 10) | (1 << 11) | (1 << 12) | (1 << 13)) << 16;
  95.             
  96.   left_motor.state = STOP;
  97.   left_motor.forward_opcode = 1 << 11;
  98.   left_motor.backward_opcode = 1 << 10;

  99.   right_motor.state = STOP;
  100.   right_motor.forward_opcode = 1 << 12;
  101.   right_motor.backward_opcode = 1 << 13;            
  102. }

  103. //對某電機施加前轉驅動電平
  104. static void MotorRotateForward(struct motor *pmotor)
  105. {
  106.               if (pmotor->state != FORWARD)
  107.               {
  108.                 GPIOB->BSRR = (pmotor->backward_opcode << 16) | pmotor->forward_opcode;
  109.                 pmotor->state = FORWARD;
  110.               }
  111. }

  112. //對某電機施加后轉驅動電平
  113. static void MotorRotateBackward(struct motor *pmotor)
  114. {
  115.               if(pmotor->state != BACKWARD)
  116.               {
  117.                 GPIOB->BSRR = (pmotor->forward_opcode << 16) | pmotor->backward_opcode;
  118.                 pmotor->state = BACKWARD;
  119.               }
  120. }

  121. //對某電機停止驅動電平
  122. static void MotorStop(struct motor *pmotor)
  123. {
  124.               if (pmotor->state != STOP)
  125.               {
  126.                 GPIOB->BSRR = (pmotor->forward_opcode | pmotor->backward_opcode) << 16;
  127.                 pmotor->state = STOP;
  128.               }
  129. }

  130. //電機控制函數
  131. //輸入參數:電機標識字符'r'或’l'(右或左)   操作代碼字符'f'、'b'或's'(正轉、反轉或靜止)
  132. void MotorControl(char motor, char op_cmd)
  133. {
  134.   struct motor *pmotor;

  135.   if (motor == 'r')
  136.     pmotor = &right_motor;
  137.   else if (motor == 'l')
  138.     pmotor = &left_motor;
  139.   else
  140.     return;
  141.   if (op_cmd == 'f')
  142.     MotorRotateForward(pmotor);
  143.   if (op_cmd == 'b')
  144.     MotorRotateBackward(pmotor);
  145.   if (op_cmd == 's')
  146.     MotorStop(pmotor);
  147. }
  148. wheel.c
  149. #include "stm32f10x.h"

  150. extern void MotorInit(void);
  151. static void WheelDrive(void);
  152. extern void MotorControl(char motor, char op_cmd);
  153. extern int SetTimer(unsigned short duration, void (*proc)(void) , int reload);

  154. struct wheel
  155. {
  156.   unsigned short period;
  157.   unsigned short duty;
  158.   unsigned short current;
  159.   unsigned char motor;
  160.   unsigned char dir;
  161. };

  162. static struct wheel wheel_left, wheel_right;
  163. static enum{STOP, FORWARD, BACKWARD, LEFT, RIGHT, U_TURN} state;

  164. // WheelInit是對小車的車輪要的外部接口進行初始化。
  165. void WheelInit()
  166. {
  167.               MotorInit();

  168.               wheel_left.period = 50;
  169.               wheel_left.duty = 15;
  170.               wheel_left.current = wheel_left.period;
  171.               wheel_left.dir = 's';
  172.               wheel_left.motor = 'l';
  173.             
  174.               wheel_right.period = 50;
  175.               wheel_right.duty = 15;
  176.               wheel_right.current = wheel_right.period;
  177.               wheel_right.dir = 's';
  178.               wheel_right.motor = 'r';

  179.               state = STOP;
  180.             
  181.               SetTimer(2, WheelDrive, 1); // 每1ms執行一次
  182. }

  183. static void WheelRun(struct wheel *pwheel, char dir)
  184. {
  185.               if((dir != 'f') && (dir != 'b'))
  186.     return;
  187.               pwheel->dir = dir;
  188.               pwheel->current++;
  189.               if (pwheel->current >= pwheel->period)
  190.     pwheel->current = 0;
  191.               if (pwheel->current < pwheel->duty)
  192.     MotorControl(pwheel->motor, pwheel->dir);
  193.               if(pwheel->current >= pwheel->duty)
  194.     MotorControl(pwheel->motor, 's');
  195. }

  196. static void WheelStop (struct wheel *pwheel)
  197. {
  198.               if(pwheel->dir == 's')
  199.   return;
  200.               pwheel->dir = 's';
  201.               pwheel->current = pwheel->period;
  202.               MotorControl(pwheel->motor, 's');
  203. }

  204. // WheelDrive是根據工作狀態來設定小車的前進、后退、左轉、右轉及停止,
  205. // 主要是操控WheelRun和WheelStop兩個函數實現所需要的功能。
  206. static void WheelDrive()
  207. {
  208.   switch(state)
  209.   {
  210.                 case FORWARD:
  211.       WheelRun(&wheel_right, 'f');
  212.       WheelRun(&wheel_left, 'f');
  213.     break;
  214.                
  215.     case BACKWARD:
  216.       WheelRun(&wheel_right, 'b');
  217.       WheelRun(&wheel_left, 'b');
  218.     break;

  219.                 case LEFT:
  220.                   WheelRun(&wheel_right, 'f');
  221.       WheelStop(&wheel_left);
  222.     break;

  223.                 case RIGHT:
  224.       WheelStop(&wheel_right);
  225.       WheelRun(&wheel_left, 'f');
  226.     break;

  227.                 case STOP:
  228.       WheelStop(&wheel_right);
  229.       WheelStop(&wheel_left);
  230.     break;

  231.     case U_TURN:
  232.       WheelRun(&wheel_right, 'b');
  233.       WheelRun(&wheel_left, 'f');
  234.     break;
  235.   }
  236. }
  237. // WheelControl外部采用命令方式改變車的工作狀態
  238. void WheelControl(char cmd)
  239. {
  240.   switch(cmd)
  241.   {
  242.                 case 'f':
  243.       state = FORWARD;
  244.     break;

  245.                 case 'b':
  246.       state = BACKWARD;
  247.     break;

  248.                 case 'l':
  249.       state = LEFT;
  250.     break;

  251.                 case 'r':
  252.       state = RIGHT;
  253.     break;

  254.                 case 's':
  255.       state = STOP;
  256.     break;

  257.     case 'u':
  258.       state = U_TURN;
  259.     break;
  260.   }            
  261. }

  262. void SpeedChange(unsigned char mode)
  263. {
  264.   if (mode)
  265.   {
  266.     wheel_left.duty = 35;
  267.     wheel_right.duty = 35;
  268.   }
  269.   else
  270.   {
  271.     wheel_left.duty = 15;
  272.     wheel_right.duty = 15;
  273.   }
  274. }
  275. detection.c

  276. #include "stm32f10x.h"
  277. #include <stdio.h>

  278. static void UpdateDistance(void);
  279. extern void SpeedChange(unsigned char mode);
  280. extern int  SetTimer(unsigned short duration, void (*proc)(void) ,int reload);

  281. static unsigned char TIM2CaptureFlag; // 輸入捕獲狀態
  282. unsigned int curDis = 0xffff;         // 當前距離
  283. unsigned char SYSTEM_MODE = 0;        // 模式選擇 0--循跡避障,1--自由避障
  284. char InfraredState;

  285. void DetectionInit()
  286. {
  287.   GPIO_InitTypeDef        GPIO_InitStructure;
  288.   NVIC_InitTypeDef        NVIC_InitStructure;
  289.   TIM_ICInitTypeDef       TIM_ICInitStruct;
  290.   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

  291.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
  292.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  293.   // HC-SR04 Echo PA0 (TIM2_CH1的IC1)
  294.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  295.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  296.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  297.   GPIO_ResetBits(GPIOA, GPIO_Pin_0);

  298.   // HC-SR04 Trig PA4
  299.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  300.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  301.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  302.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  303.   GPIO_ResetBits(GPIOA, GPIO_Pin_4);

  304.   // LED
  305.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
  306.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  307.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  308.   GPIO_Init(GPIOC, &GPIO_InitStructure);
  309.   GPIO_ResetBits(GPIOC, GPIO_Pin_13);

  310.   // 左紅外 PB5,中紅外 PB6,右紅外 PB7
  311.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  312.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  313.   GPIO_Init(GPIOB, &GPIO_InitStructure);

  314.   // 功能選擇 PB8
  315.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  316.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  317.   GPIO_Init(GPIOB, &GPIO_InitStructure);
  318.   GPIO_ResetBits(GPIOB, GPIO_Pin_8);

  319.   // TIM2
  320.   TIM_TimeBaseStructure.TIM_Period = 0xffff;                  // 重載計數值最大
  321.   TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;               // 計數周期1us
  322.   TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;     // 不分頻
  323.   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上計數
  324.   TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  325.   //TIM2_CH1輸入捕獲初始化
  326.   TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;               // 使用通道1
  327.   TIM_ICInitStruct.TIM_ICFilter = 0x02;                       // 不濾波
  328.   TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;          // 不分頻
  329.   TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;// 直接映射到IC1
  330.   TIM_ICInit(TIM2, &TIM_ICInitStruct);

  331.   // TIM2 NVIC配置
  332.   NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  333.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  334.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  335.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  336.   NVIC_Init(&NVIC_InitStructure);

  337.   TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
  338.   TIM_Cmd(TIM2, ENABLE);

  339.   // 100ms更新一次距離
  340.   SetTimer(200, UpdateDistance, 1);
  341. }

  342. char DetectionGet()
  343. {
  344.   InfraredState = (GPIOB->IDR >> 5) & 0x7; // 低三位分別為PB5、PB6、PB7的值
  345.   return InfraredState;
  346. }

  347. void TIM2_IRQHandler(void)
  348. {
  349.   if((TIM2CaptureFlag & 0x10) == 0)                       // 是否是新的一次捕獲
  350.   {
  351.     TIM2CaptureFlag |= 0x10;                              // 捕獲到一次上升沿
  352.     TIM_SetCounter(TIM2, 0);
  353.     TIM_OC1PolarityConfig(TIM2, TIM_ICPolarity_Falling);  // 設置為下降沿捕獲
  354.   }
  355.   else
  356.     curDis = 0.017 * TIM_GetCapture1(TIM2);
  357.   TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);                // 清除中斷標志位
  358. }

  359. static void Delay20Us()
  360. {
  361.   int i = 0;
  362.   for (; i <= 231; i++);
  363. }

  364. static void UpdateDistance()
  365. {
  366.   TIM2CaptureFlag = 0;
  367.   TIM_OC1PolarityConfig(TIM2, TIM_ICPolarity_Rising);

  368.   // Trig
  369.   GPIO_SetBits(GPIOA, GPIO_Pin_4);
  370.   Delay20Us();
  371.   GPIO_ResetBits(GPIOA, GPIO_Pin_4);

  372.   // 系統模式選擇
  373.   if (GPIOB->IDR & 0x100)
  374.     SYSTEM_MODE = 1;
  375.   else
  376.     SYSTEM_MODE = 0;
  377.   SpeedChange(SYSTEM_MODE);
  378. }
  379. track.c
  380. #include "stm32f10x.h"
  381. #include <stdio.h>

  382. extern void WheelControl(char cmd);

  383. enum {OUT, R, M, MR, L, LR, LM, LMR};
  384. extern unsigned int curDis; // 當前測距結果
  385. static char lastDetect = M; // 上一次的紅外探測結果
  386. static char uTurnFLag = 0;  // 大轉彎標記

  387. void TrackRun(char detection)
  388. {
  389.   if (curDis <= 15)
  390.     GPIO_SetBits(GPIOC, GPIO_Pin_13);
  391.   else
  392.     GPIO_ResetBits(GPIOC, GPIO_Pin_13);

  393.   // 當前距離小于15cm,停車
  394.   if (curDis <= 15)
  395.   {
  396.     WheelControl('s');
  397.     return;
  398.   }

  399.   if (detection != OUT)
  400.     uTurnFLag = 0;

  401.   // 直行的case
  402.   if (detection == M)
  403.     WheelControl('f');

  404.   // 右轉的case
  405.   if (detection == R || detection == MR || detection == LMR)
  406.     WheelControl('r');

  407.   // 左轉的case
  408.   if (detection == L)
  409.     WheelControl('l');

  410.   // 大轉彎
  411.   if (uTurnFLag)
  412.     WheelControl('u');

  413.   // other cases
  414.   if (detection == OUT)
  415.     switch (lastDetect)
  416.     {
  417.       case R:
  418.         WheelControl('r');
  419.       break;

  420.       case M:
  421.         uTurnFLag = 1;
  422.       break;

  423.       case MR:
  424.         WheelControl('r');
  425.       break;

  426.       case L:
  427.         WheelControl('l');
  428.       break;

  429.       case LM:
  430.         WheelControl('l');
  431.       break;
  432.     }

  433.   if (detection != OUT)
  434.     lastDetect = detection;
  435. }
  436. avoid.c
  437. #include "stm32f10x.h"

  438. extern void WheelControl(char cmd);

  439. extern unsigned int curDis;

  440. void ObstacleAvoid()
  441. {
  442.   if (curDis <= 20)
  443.     GPIO_SetBits(GPIOC, GPIO_Pin_13);
  444.   else
  445.     GPIO_ResetBits(GPIOC, GPIO_Pin_13);

  446.   if (curDis >= 10 && curDis <= 20) // 滿足 10cm <= dist <= 20cm
  447.     WheelControl('u');              // 則右轉

  448.   if (curDis < 10)                  // 滿足 dist < 10cm
  449.     WheelControl('b');              // 則后退

  450.   if (curDis > 20)
  451.     WheelControl('f');              // 其他case則直行
  452. }
  453. car.c
  454. #include "stm32f10x.h"
  455. #include <stdio.h>

  456. static void CarRun (void);
  457. extern void WheelInit(void);
  458. extern char DetectionGet(void);
  459. extern void DetectionInit(void);
  460. extern void ObstacleAvoid(void);
  461. extern void TrackRun(char detection);
  462. extern int  SetTimer(unsigned short duration, void (*proc)(void) , int reload);

  463. extern unsigned char SYSTEM_MODE;

  464. void CarInit()
  465. {
  466.   WheelInit();               // 車輪初始化
  467.   DetectionInit();           // 傳感器初始化(紅外和超聲波)
  468.   SetTimer(2, CarRun, 1);    // 每1ms執行一次CarRun
  469. }

  470. static void CarRun()
  471. {
  472.   char det = DetectionGet();
  473.   if (SYSTEM_MODE)
  474.     ObstacleAvoid();
  475.   else
  476.     TrackRun(det);
  477. }
復制代碼

底板網上購得,技術文檔、源碼在附件中
全部資料51hei下載地址:
Smart_Car_Lib_Ver.7z (191.29 KB, 下載次數: 203)
技術報告.docx (1.09 MB, 下載次數: 123)
小車連線new.pdf (855.94 KB, 下載次數: 147)



評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:266092 發表于 2019-3-29 10:47 | 顯示全部樓層
程序質量很好,學習學習
回復

使用道具 舉報

ID:505045 發表于 2019-5-18 18:20 | 顯示全部樓層
樓主可以發給我郵箱嗎?17382569964@163.COM
回復

使用道具 舉報

ID:591784 發表于 2019-7-28 22:08 | 顯示全部樓層
RocWang 發表于 2019-5-18 18:20
樓主可以發給我郵箱嗎?

你有嗎?能不能也發我一份。992163846@qq.com
回復

使用道具 舉報

ID:588361 發表于 2019-7-29 10:21 | 顯示全部樓層
謝謝樓主分享
回復

使用道具 舉報

ID:657560 發表于 2019-12-6 14:45 | 顯示全部樓層
RocWang 發表于 2019-5-18 18:20
樓主可以發給我郵箱嗎?

你有嗎?能不能也發我一份。1610077438@qq.com    謝謝啦
回復

使用道具 舉報

ID:826937 發表于 2020-10-8 19:52 | 顯示全部樓層
包含proteus的仿真文件么
回復

使用道具 舉報

ID:818895 發表于 2020-10-21 20:48 | 顯示全部樓層
這么好的案例,要好好學習STM32.
回復

使用道具 舉報

9#
無效樓層,該帖已經被刪除
10#
無效樓層,該帖已經被刪除
ID:889199 發表于 2021-4-15 16:41 | 顯示全部樓層
Kvn夢元兒 發表于 2020-10-8 19:52
包含proteus的仿真文件么

不包含proteus文件。——來自已經下載人的評論
回復

使用道具 舉報

12#
無效樓層,該帖已經被刪除
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表