這個(gè)項(xiàng)目最主要研究了基于STM32F103微處理器的智能小車控制系統(tǒng)的設(shè)計(jì)。整個(gè)系統(tǒng)主要包括STM32F103控制器、電機(jī)驅(qū)動(dòng)電路、紅外檢測(cè)電路、超聲波避障電路。我們采用STM32F103芯片,采用脈沖寬度調(diào)制信號(hào)(PWM)來完成對(duì)電機(jī)的控制,循跡模塊采用紅外探測(cè)法進(jìn)行黑白探測(cè),避障模塊進(jìn)行障礙物檢測(cè)并躲避,超聲波模塊用來檢測(cè)小車與障礙物之間的距離,其他外圍電路可用于其他功能的拓展。小車在運(yùn)行過程中,避障程序優(yōu)先于循跡程序。
1.介紹
1.1項(xiàng)目介紹
1.2研究目的
1.3設(shè)想
1.4研究方法及思路
1.5成果
2.軟硬件設(shè)計(jì)
2.1智能小車介紹
2.2智能小車的組成部分
2.2.1微處理器
2.2.2傳感器檢測(cè)部分
2.2.3超聲波檢測(cè)部分
2.2.4機(jī)器人的腳
2.3循跡原理
2.3.1紅外探測(cè)法
2.3.2循跡方法
2.3.3道路現(xiàn)象分析
2.3.4循跡代碼
2.4避障原理
2.4.1HC-SR04工作原理
2.4.2自由避障策略
2.4.3自由避障代碼
2.5自動(dòng)駕駛系統(tǒng)總體結(jié)構(gòu)
3.軟硬件調(diào)試
3.1軟件調(diào)試
3.2硬件調(diào)試
4.結(jié)論
1.介紹1.1項(xiàng)目介紹本項(xiàng)目是一個(gè)自動(dòng)駕駛系統(tǒng)的項(xiàng)目,該項(xiàng)目能夠通過提供自動(dòng)駕駛、對(duì)路況智能處理以及其他為行駛系統(tǒng)設(shè)計(jì)的新功能,根據(jù)場(chǎng)景設(shè)定完成自動(dòng)駕駛。該自動(dòng)駕駛的設(shè)備可以是私家汽車, 貨車,也可以是卡車等。 1.2研究目的設(shè)計(jì)一個(gè)自動(dòng)駕駛系統(tǒng),可以在特定地方尋找軌跡,并沿著軌跡行走;可以檢測(cè)到障礙物的距離并進(jìn)行躲避。 1.3設(shè)想假設(shè)在校方提供提供的樣機(jī)、紅外探測(cè)器、超聲波檢測(cè)模塊功能正常,電池電量充足,源程序思路代碼均正確,場(chǎng)地軌跡明顯的情況下,我們的小車可以沿著黑色軌跡線持續(xù)行走,遇到障礙物時(shí)小車停止,移開障礙物后,小車可繼續(xù)沿著特定的軌跡行走,直至我們要求其結(jié)束。 1.4研究方法及思路本次實(shí)驗(yàn)我們采取模擬法,使用HL-1 智能小車模擬真實(shí)的汽車,進(jìn)行實(shí)驗(yàn)。實(shí)驗(yàn)過程中,我們模擬不同的路況,例如“T型路”、“十字路”、“斷頭路”等路況,將小車放在相應(yīng)的位置,觀察其紅外探測(cè)的指示燈的亮滅狀況,并記錄下來,分析其對(duì)應(yīng)情況時(shí)IO口的輸入情況,得出循跡偽代碼;避障時(shí),我們通過設(shè)置障礙物,分析小車遇到障礙物時(shí)應(yīng)做出的回應(yīng),得到相應(yīng)的偽代碼。最終進(jìn)行整體代碼的分析撰寫。
1.5成果循跡:小車在特定場(chǎng)景模式下,按照黑色的軌跡行駛; 避障:循跡模式下,小車遇障礙物停止;自由模式下,小車到障礙物的距離大于20cm時(shí)直行,小車到障礙物的距離大于10cm小于20cm時(shí)右轉(zhuǎn);小車到障礙物的距離小于10cm時(shí)后退; 文檔:提交技術(shù)報(bào)告、會(huì)議紀(jì)要、進(jìn)度計(jì)劃表、任務(wù)書組、項(xiàng)目組成員表等文檔 2.軟硬件設(shè)計(jì)2.1智能小車介紹- 智能小車是輪式機(jī)器人。
- 它是一個(gè)集環(huán)境感知、規(guī)劃決策、自動(dòng)駕駛等功能于一體的綜合系統(tǒng) 。
- 它是集中運(yùn)用了計(jì)算機(jī)、傳感、信息、通信、導(dǎo)航、人工智能及自動(dòng)控制等技術(shù)的綜合體。
圖 1 智能小車整體圖 2.2智能小車的組成部分2.2.1微處理器圖 2 STM32F103C8主芯片整體圖 STM32F103C8主芯片 - 內(nèi)核:ARM 32位的Cortex-M3 CPU 工作頻率72MHz
- 存儲(chǔ)器:64KB閃存程序存儲(chǔ)器、20KB的SRAM
- 電源電壓:2.0V~3.6V
- 數(shù)據(jù)轉(zhuǎn)換器:2個(gè)12位AD轉(zhuǎn)換器(10個(gè)輸入通道)
- 調(diào)試模式:串行單線調(diào)試(SWD)和JTAG接口
2.2.2傳感器檢測(cè)部分圖 3 紅外反射傳感器整體圖 紅外反射傳感器 - 檢測(cè)距離:1mm~8mm
- 比較器輸出數(shù)字開關(guān)量(0和1)
- 配多圈可調(diào)精密電位器調(diào)節(jié)靈敏度
- 工作電壓:3.3V~5V
傳感器的紅外發(fā)射二極管不斷發(fā)射紅外線,當(dāng)發(fā)射出的紅外線沒有被反射回來或被反射回來強(qiáng)度不大時(shí),比較器的輸出端為高電平,指示燈熄滅;當(dāng)紅外線被反射回來且強(qiáng)度足夠大時(shí),比較器的輸出端為低電平,指示燈被點(diǎn)亮。 2.2.3超聲波檢測(cè)部分圖 4 HC-SR04整體圖 HC-SR04引腳 - VCC供5V電源
- GND為地線
- TRIG觸發(fā)控制信號(hào)輸入
- ECHO回響信號(hào)輸出
表 1 HC-SR04電器參數(shù) | | | | | | | | | 輸出TTL電平信號(hào)信號(hào),與射程成比例 |
2.2.4機(jī)器人的腳圖 5 LN98N集成電機(jī)驅(qū)動(dòng)整體圖 車輪為三個(gè),前輪是兩個(gè)主動(dòng)輪,后輪是一個(gè)從動(dòng)輪 - 兩個(gè)直流電機(jī)
- L298N集成電機(jī)驅(qū)動(dòng)芯片
- 工作電壓:5V
微控制器產(chǎn)生PWM信號(hào)給L298N,通過調(diào)節(jié)方波的占空比來控制電機(jī)的轉(zhuǎn)速。兩個(gè)電機(jī)轉(zhuǎn)速相同時(shí)小車前進(jìn)或后退;轉(zhuǎn)速不同時(shí)小車轉(zhuǎn)彎;兩個(gè)電機(jī)反向等速運(yùn)轉(zhuǎn)時(shí),小車原地轉(zhuǎn)圈。 2.3循跡原理小車循跡指的是小車在白色地板上循黑線行走,通常采取的方法是紅外探測(cè)法。 2.3.1紅外探測(cè)法利用紅外線在不同顏色的物體表面具有不同的反射強(qiáng)度的特點(diǎn),在小車行駛過程中不斷地向地面發(fā)射紅外光,當(dāng)紅外光遇到白色紙質(zhì)地板時(shí)發(fā)生漫反射,反射光被裝在小車上的接收管接收;如果遇到黑線則紅外光被吸收,小車上的接收管接收不到紅外光。單片機(jī)就是否收到反射回來的紅外光為依據(jù)來確定黑線的位置和小車的行走路線。 2.3.2循跡方法采用與路面顏色有較大差別的線條(白色路面上有條黑色曲線)作引導(dǎo)線,當(dāng)循跡傳感器照到黑線時(shí)輸出高電平1,照到白色時(shí)輸出低電平0。 圖 6 循跡示意圖 2.3.3道路現(xiàn)象分析 | | | | | | | | 循跡左轉(zhuǎn)90度,沿著當(dāng)前黑色路徑指示直行 | | | 循跡右轉(zhuǎn)90度,沿著當(dāng)前黑色路徑指示直行 | | | 遇到T型路口,根據(jù)命令轉(zhuǎn)彎。命令左轉(zhuǎn),向左轉(zhuǎn)彎;命令右轉(zhuǎn),向右循跡轉(zhuǎn)彎。 | 十字路口
| | 遇到十字路口,根據(jù)命令行駛。左轉(zhuǎn),右轉(zhuǎn)直行 | | | 遇到斷頭路,左轉(zhuǎn)180度調(diào)頭 |
圖表 1 道路狀態(tài)模擬
我們采用三路循跡,共8中狀態(tài)指示,對(duì)應(yīng)狀況如下所示 表 2 紅外檢測(cè)狀態(tài)分析
備注:我們?cè)O(shè)計(jì)的線路之間有一定的距離,LR狀態(tài)不會(huì)出現(xiàn)
2.3.4循跡代碼圖 7 循跡代碼截圖 2.4避障原理2.4.1HC-SR04工作原理- 給超聲波模塊接入電源和地。
- 給脈沖觸發(fā)引腳(trig)輸入一個(gè)長(zhǎng)為20us的高電平方波。
- 輸入方波后,模塊會(huì)自動(dòng)發(fā)射8個(gè)40KHz的聲波,與此同時(shí)回波引腳(echo)端的電平會(huì)由0變?yōu)?;(此時(shí)應(yīng)該啟動(dòng)定時(shí)器計(jì)時(shí))
- 當(dāng)超聲波返回被模塊接收到時(shí),回波引 腳端的電平會(huì)由1變?yōu)?;(此時(shí)應(yīng)該停止定時(shí)器計(jì)數(shù)),定時(shí)器記下的這個(gè)時(shí)間即為超聲波由發(fā)射到返回的總時(shí)長(zhǎng)。
- 根據(jù)聲音在空氣中的速度為344米/秒,即可計(jì)算出所測(cè)的距離。
2.4.2自由避障策略
表 3自由避障策略分析
2.4.3自由避障代碼圖 8 自由避障程序截圖 2.5自動(dòng)駕駛系統(tǒng)總體結(jié)構(gòu)
圖 8 自動(dòng)駕駛系統(tǒng)總體結(jié)構(gòu) 3.軟硬件調(diào)試3.1軟件調(diào)試系統(tǒng)開發(fā)條件:Keil 5.26.2.0 下載工具:J-Link 6.20 3.2硬件調(diào)試小車連線: ·電源 小車J2 –VCC 接stm32控制板JP2- +5V 小車J2 –GND接stm32控制板JP2- GN 小車J2 –VCC接紅外控制板VCC 小車J2 –GND接紅外控制板GND ·驅(qū)動(dòng) 小車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 ·紅外信號(hào)輸出 紅外控制板D01接stm32控制板J2-PB5 紅外控制板D02接stm32控制板J2-PB6 紅外控制板D03接stm32控制板J2-PB7 ·超聲波輸入輸出 超聲波模塊接小車J6 小車J4-P2.0接stm32控制板PA0 小車J4-P2.1接stm32控制板PA4 4.結(jié)論本次項(xiàng)目設(shè)計(jì)了中央處理模塊、電機(jī)驅(qū)動(dòng)模塊、避障模塊和循跡模塊。其中中央處理模塊的芯片是stm32f103,電機(jī)驅(qū)動(dòng)模塊的主要芯片是LM293D,避障模塊的主要器件是HC-SR04,循跡模塊的主要器件是五個(gè)紅外探測(cè)器(IR)。通過各模塊之間的配合以及軟件和硬件設(shè)計(jì)的結(jié)合,使得最終設(shè)計(jì)出的小車具有循跡功能和避障功能,即能沿軌跡黑線前進(jìn),不會(huì)偏出軌跡,并且當(dāng)探測(cè)到障礙物時(shí)可停止前進(jìn),且探測(cè)距離大于10cm。最終完成了該項(xiàng)目的設(shè)想預(yù)期。
- #include <stdio.h>
-
- extern void CarInit(void);
- extern void DebugInit(void);
- extern void TimerInit(void);
- extern void CheckTimer(void);
-
- int main()
- {
- TimerInit(); // 系統(tǒng)任務(wù)定時(shí)器初始化
- CarInit(); // 小車各模塊初始化
- DebugInit();
-
- while(1)
- {
- CheckTimer(); // 開始執(zhí)行定時(shí)任務(wù)
- }
- }
- timer.c
- #include "stm32f10x.h"
-
- void TimerInit()
- {
- RCC->APB2ENR |= 1 << 11;
-
- TIM1->PSC = 36000 - 1;
- TIM1->ARR = 65535;
- TIM1->CR1 = 0x81;
- }
-
- static unsigned short TimeGet()
- {
- return TIM1->CNT;
- }
-
-
- struct timer
- {
- void (*proc)(void);
- int reload;
- unsigned short begin;
- unsigned short duration;
- };
-
- #define TIMER_CNT_MAX 8
- static struct timer tmr[TIMER_CNT_MAX];
- static int tmr_cnt=0;
-
- int SetTimer(unsigned short duration, void (*proc)(void) , int reload)
- {
- if (tmr_cnt >= TIMER_CNT_MAX)
- {
- return 0;
- }
- tmr[tmr_cnt].begin = TimeGet();
- tmr[tmr_cnt].duration = duration;
- tmr[tmr_cnt].proc = proc;
- tmr[tmr_cnt].reload = reload;
- tmr_cnt++;
- return 1;
- }
-
- // CheckTimer為主程序循環(huán)調(diào)用函數(shù),執(zhí)行定時(shí)事務(wù)
- void CheckTimer()
- {
- int tmr_idx=0;
- int i=0;
- unsigned short now = TimeGet();
-
- while (tmr_idx < tmr_cnt)
- {
- if ((unsigned short)(now - tmr[tmr_idx].begin) >= tmr[tmr_idx].duration)
- {
- if (tmr[tmr_idx].proc)
- (*tmr[tmr_idx].proc)();
- if (tmr[tmr_idx].reload)
- {
- tmr[tmr_idx].begin = now;
- tmr_idx++;
- }
- else
- {
- for (i=tmr_idx; i<tmr_cnt-1; i++)
- tmr[i] = tmr[i+1];
- tmr_cnt--;
- }
- }
- else
- tmr_idx++;
- }
- }
-
- 3.motor.c
-
- #include "stm32f10x.h"
-
- struct motor
- {
- enum {STOP, FORWARD, BACKWARD} state;
- int forward_opcode;
- int backward_opcode;
- };
-
- static struct motor left_motor, right_motor;
-
- void MotorInit()
- {
- RCC->APB2ENR |= 1 << 3;
- GPIOB->CRH &= 0xff0000ff;
- GPIOB->CRH |= 0x00333300; //PB10 左后退 , PB11 左前進(jìn), PB12 右前進(jìn), PB13 右后退
- GPIOB->BSRR = ((1 << 10) | (1 << 11) | (1 << 12) | (1 << 13)) << 16;
-
- left_motor.state = STOP;
- left_motor.forward_opcode = 1 << 11;
- left_motor.backward_opcode = 1 << 10;
-
- right_motor.state = STOP;
- right_motor.forward_opcode = 1 << 12;
- right_motor.backward_opcode = 1 << 13;
- }
-
- //對(duì)某電機(jī)施加前轉(zhuǎn)驅(qū)動(dòng)電平
- static void MotorRotateForward(struct motor *pmotor)
- {
- if (pmotor->state != FORWARD)
- {
- GPIOB->BSRR = (pmotor->backward_opcode << 16) | pmotor->forward_opcode;
- pmotor->state = FORWARD;
- }
- }
-
- //對(duì)某電機(jī)施加后轉(zhuǎn)驅(qū)動(dòng)電平
- static void MotorRotateBackward(struct motor *pmotor)
- {
- if(pmotor->state != BACKWARD)
- {
- GPIOB->BSRR = (pmotor->forward_opcode << 16) | pmotor->backward_opcode;
- pmotor->state = BACKWARD;
- }
- }
-
- //對(duì)某電機(jī)停止驅(qū)動(dòng)電平
- static void MotorStop(struct motor *pmotor)
- {
- if (pmotor->state != STOP)
- {
- GPIOB->BSRR = (pmotor->forward_opcode | pmotor->backward_opcode) << 16;
- pmotor->state = STOP;
- }
- }
-
- //電機(jī)控制函數(shù)
- //輸入?yún)?shù):電機(jī)標(biāo)識(shí)字符'r'或’l'(右或左) 操作代碼字符'f'、'b'或's'(正轉(zhuǎn)、反轉(zhuǎn)或靜止)
- void MotorControl(char motor, char op_cmd)
- {
- struct motor *pmotor;
-
- if (motor == 'r')
- pmotor = &right_motor;
- else if (motor == 'l')
- pmotor = &left_motor;
- else
- return;
- if (op_cmd == 'f')
- MotorRotateForward(pmotor);
- if (op_cmd == 'b')
- MotorRotateBackward(pmotor);
- if (op_cmd == 's')
- MotorStop(pmotor);
- }
- wheel.c
- #include "stm32f10x.h"
-
- extern void MotorInit(void);
- static void WheelDrive(void);
- extern void MotorControl(char motor, char op_cmd);
- extern int SetTimer(unsigned short duration, void (*proc)(void) , int reload);
-
- struct wheel
- {
- unsigned short period;
- unsigned short duty;
- unsigned short current;
- unsigned char motor;
- unsigned char dir;
- };
-
- static struct wheel wheel_left, wheel_right;
- static enum{STOP, FORWARD, BACKWARD, LEFT, RIGHT, U_TURN} state;
-
- // WheelInit是對(duì)小車的車輪要的外部接口進(jìn)行初始化。
- void WheelInit()
- {
- MotorInit();
-
- wheel_left.period = 50;
- wheel_left.duty = 15;
- wheel_left.current = wheel_left.period;
- wheel_left.dir = 's';
- wheel_left.motor = 'l';
-
- wheel_right.period = 50;
- wheel_right.duty = 15;
- wheel_right.current = wheel_right.period;
- wheel_right.dir = 's';
- wheel_right.motor = 'r';
-
- state = STOP;
-
- SetTimer(2, WheelDrive, 1); // 每1ms執(zhí)行一次
- }
-
- static void WheelRun(struct wheel *pwheel, char dir)
- {
- if((dir != 'f') && (dir != 'b'))
- return;
- pwheel->dir = dir;
- pwheel->current++;
- if (pwheel->current >= pwheel->period)
- pwheel->current = 0;
- if (pwheel->current < pwheel->duty)
- MotorControl(pwheel->motor, pwheel->dir);
- if(pwheel->current >= pwheel->duty)
- MotorControl(pwheel->motor, 's');
- }
-
- static void WheelStop (struct wheel *pwheel)
- {
- if(pwheel->dir == 's')
- return;
- pwheel->dir = 's';
- pwheel->current = pwheel->period;
- MotorControl(pwheel->motor, 's');
- }
-
- // WheelDrive是根據(jù)工作狀態(tài)來設(shè)定小車的前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)及停止,
- // 主要是操控WheelRun和WheelStop兩個(gè)函數(shù)實(shí)現(xiàn)所需要的功能。
- static void WheelDrive()
- {
- switch(state)
- {
- case FORWARD:
- WheelRun(&wheel_right, 'f');
- WheelRun(&wheel_left, 'f');
- break;
-
- case BACKWARD:
- WheelRun(&wheel_right, 'b');
- WheelRun(&wheel_left, 'b');
- break;
-
- case LEFT:
- WheelRun(&wheel_right, 'f');
- WheelStop(&wheel_left);
- break;
-
- case RIGHT:
- WheelStop(&wheel_right);
- WheelRun(&wheel_left, 'f');
- break;
-
- case STOP:
- WheelStop(&wheel_right);
- WheelStop(&wheel_left);
- break;
-
- case U_TURN:
- WheelRun(&wheel_right, 'b');
- WheelRun(&wheel_left, 'f');
- break;
- }
- }
- // WheelControl外部采用命令方式改變車的工作狀態(tài)
- void WheelControl(char cmd)
- {
- switch(cmd)
- {
- case 'f':
- state = FORWARD;
- break;
-
- case 'b':
- state = BACKWARD;
- break;
-
- case 'l':
- state = LEFT;
- break;
-
- case 'r':
- state = RIGHT;
- break;
-
- case 's':
- state = STOP;
- break;
-
- case 'u':
- state = U_TURN;
- break;
- }
- }
-
- void SpeedChange(unsigned char mode)
- {
- if (mode)
- {
- wheel_left.duty = 35;
- wheel_right.duty = 35;
- }
- else
- {
- wheel_left.duty = 15;
- wheel_right.duty = 15;
- }
- }
- detection.c
-
- #include "stm32f10x.h"
- #include <stdio.h>
-
- static void UpdateDistance(void);
- extern void SpeedChange(unsigned char mode);
- extern int SetTimer(unsigned short duration, void (*proc)(void) ,int reload);
-
- static unsigned char TIM2CaptureFlag; // 輸入捕獲狀態(tài)
- unsigned int curDis = 0xffff; // 當(dāng)前距離
- unsigned char SYSTEM_MODE = 0; // 模式選擇 0--循跡避障,1--自由避障
- char InfraredState;
-
- void DetectionInit()
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- TIM_ICInitTypeDef TIM_ICInitStruct;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
-
- // HC-SR04 Echo PA0 (TIM2_CH1的IC1)
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_ResetBits(GPIOA, GPIO_Pin_0);
-
- // HC-SR04 Trig PA4
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_ResetBits(GPIOA, GPIO_Pin_4);
-
- // LED
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- GPIO_ResetBits(GPIOC, GPIO_Pin_13);
-
- // 左紅外 PB5,中紅外 PB6,右紅外 PB7
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
- // 功能選擇 PB8
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- GPIO_ResetBits(GPIOB, GPIO_Pin_8);
-
- // TIM2
- TIM_TimeBaseStructure.TIM_Period = 0xffff; // 重載計(jì)數(shù)值最大
- TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 計(jì)數(shù)周期1us
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 不分頻
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上計(jì)數(shù)
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
-
- //TIM2_CH1輸入捕獲初始化
- TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; // 使用通道1
- TIM_ICInitStruct.TIM_ICFilter = 0x02; // 不濾波
- TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 不分頻
- TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;// 直接映射到IC1
- TIM_ICInit(TIM2, &TIM_ICInitStruct);
-
- // TIM2 NVIC配置
- NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
-
- TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
- TIM_Cmd(TIM2, ENABLE);
-
- // 100ms更新一次距離
- SetTimer(200, UpdateDistance, 1);
- }
-
- char DetectionGet()
- {
- InfraredState = (GPIOB->IDR >> 5) & 0x7; // 低三位分別為PB5、PB6、PB7的值
- return InfraredState;
- }
-
- void TIM2_IRQHandler(void)
- {
- if((TIM2CaptureFlag & 0x10) == 0) // 是否是新的一次捕獲
- {
- TIM2CaptureFlag |= 0x10; // 捕獲到一次上升沿
- TIM_SetCounter(TIM2, 0);
- TIM_OC1PolarityConfig(TIM2, TIM_ICPolarity_Falling); // 設(shè)置為下降沿捕獲
- }
- else
- curDis = 0.017 * TIM_GetCapture1(TIM2);
- TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); // 清除中斷標(biāo)志位
- }
-
- static void Delay20Us()
- {
- int i = 0;
- for (; i <= 231; i++);
- }
-
- static void UpdateDistance()
- {
- TIM2CaptureFlag = 0;
- TIM_OC1PolarityConfig(TIM2, TIM_ICPolarity_Rising);
-
- // Trig
- GPIO_SetBits(GPIOA, GPIO_Pin_4);
- Delay20Us();
- GPIO_ResetBits(GPIOA, GPIO_Pin_4);
-
- // 系統(tǒng)模式選擇
- if (GPIOB->IDR & 0x100)
- SYSTEM_MODE = 1;
- else
- SYSTEM_MODE = 0;
- SpeedChange(SYSTEM_MODE);
- }
- track.c
- #include "stm32f10x.h"
- #include <stdio.h>
-
- extern void WheelControl(char cmd);
-
- enum {OUT, R, M, MR, L, LR, LM, LMR};
- extern unsigned int curDis; // 當(dāng)前測(cè)距結(jié)果
- static char lastDetect = M; // 上一次的紅外探測(cè)結(jié)果
- static char uTurnFLag = 0; // 大轉(zhuǎn)彎標(biāo)記
-
- void TrackRun(char detection)
- {
- if (curDis <= 15)
- GPIO_SetBits(GPIOC, GPIO_Pin_13);
- else
- GPIO_ResetBits(GPIOC, GPIO_Pin_13);
-
- // 當(dāng)前距離小于15cm,停車
- if (curDis <= 15)
- {
- WheelControl('s');
- return;
- }
-
- if (detection != OUT)
- uTurnFLag = 0;
-
- // 直行的case
- if (detection == M)
- WheelControl('f');
-
- // 右轉(zhuǎn)的case
- if (detection == R || detection == MR || detection == LMR)
- WheelControl('r');
-
- // 左轉(zhuǎn)的case
- if (detection == L)
- WheelControl('l');
-
- // 大轉(zhuǎn)彎
- if (uTurnFLag)
- WheelControl('u');
-
- // other cases
- if (detection == OUT)
- switch (lastDetect)
- {
- case R:
- WheelControl('r');
- break;
-
- case M:
- uTurnFLag = 1;
- break;
-
- case MR:
- WheelControl('r');
- break;
-
- case L:
- WheelControl('l');
- break;
-
- case LM:
- WheelControl('l');
- break;
- }
-
- if (detection != OUT)
- lastDetect = detection;
- }
- avoid.c
- #include "stm32f10x.h"
-
- extern void WheelControl(char cmd);
-
- extern unsigned int curDis;
-
- void ObstacleAvoid()
- {
- if (curDis <= 20)
- GPIO_SetBits(GPIOC, GPIO_Pin_13);
- else
- GPIO_ResetBits(GPIOC, GPIO_Pin_13);
-
- if (curDis >= 10 && curDis <= 20) // 滿足 10cm <= dist <= 20cm
- WheelControl('u'); // 則右轉(zhuǎn)
-
- if (curDis < 10) // 滿足 dist < 10cm
- WheelControl('b'); // 則后退
-
- if (curDis > 20)
- WheelControl('f'); // 其他case則直行
- }
- car.c
- #include "stm32f10x.h"
- #include <stdio.h>
-
- static void CarRun (void);
- extern void WheelInit(void);
- extern char DetectionGet(void);
- extern void DetectionInit(void);
- extern void ObstacleAvoid(void);
- extern void TrackRun(char detection);
- extern int SetTimer(unsigned short duration, void (*proc)(void) , int reload);
-
- extern unsigned char SYSTEM_MODE;
-
- void CarInit()
- {
- WheelInit(); // 車輪初始化
- DetectionInit(); // 傳感器初始化(紅外和超聲波)
- SetTimer(2, CarRun, 1); // 每1ms執(zhí)行一次CarRun
- }
-
- static void CarRun()
- {
- char det = DetectionGet();
- if (SYSTEM_MODE)
- ObstacleAvoid();
- else
- TrackRun(det);
- }
復(fù)制代碼
底板網(wǎng)上購(gòu)得,技術(shù)文檔、源碼在附件中
全部資料51hei下載地址:
Smart_Car_Lib_Ver.7z
(191.29 KB, 下載次數(shù): 203)
2019-3-23 01:49 上傳
點(diǎn)擊文件名下載附件
技術(shù)報(bào)告.docx
(1.09 MB, 下載次數(shù): 123)
2019-3-21 17:05 上傳
點(diǎn)擊文件名下載附件
小車連線new.pdf
(855.94 KB, 下載次數(shù): 147)
2019-3-21 17:05 上傳
點(diǎn)擊文件名下載附件
|