51单片机 简易光电循迹小车
前言
應學校暑期課程要求,也作為和小組成員完成一次對51單片機的練手,制作了簡易的光電小車,完成了循跡功能,下面包括較為詳細的小車搭建過程以及完整代碼。
硬件部分準備
電源
可充電的電池組是智能車的唯一動力來源。一般要求額定電壓在7.2—9.6V 之間。可充電電池按化學組成分類,有鉛酸、鎳鎘、鎳氫、鋰離子、鋰聚合物等不同類型,其主要指標為電壓、容量等。然而在選擇可充電電池時,除考慮電壓和容量,還應根據應用著重考慮電池的放電能力。電池放電能力習慣上以 C 為單位進行評價,C 即電池容量。智能車競速的特點要求充電電池要有大容量、高放電能力的特點。常見的可充電電池有鎳鎘充電電池、鎳氫充電電池、鋰離子充電電池等
1)鎳鎘充電電池的單個電壓較低,僅有 1.2V;而且鎳鎘金屬會污染環境,電池的記憶效應嚴重,能量密度較低,現在基本已經被淘汰,因此不適合使用。
2)鎳氫充電電池的單個電壓也為 1.2V,它的記憶效應稍微比鎳鎘充電電池輕微,但是自放電現象嚴重,能量密度中等;好處是價格便宜,應用廣泛。
3)鋰離子充電電池,單個電壓為 3.6V,無記憶效應,能量密度高。
綜上,我們選擇型號為 18650 的鋰離子電池作為電源,能量密度高,而且只需兩塊即可達到額定電壓為 7.2V 的要求。
降壓模塊
因為供電需求不同,我們還需要使用降壓模塊實現7.2V到5V的電壓轉換,此次我們采用了LM2596S(一定注意正負極)
控制模塊
對于智能車的控制模塊,我們選擇最為熟悉的 STC89C51 單片機,它是一款基于 8 位單片機處理芯片 STC89C51RC 的系統。采用STC89C51 單片機作為系統的主控芯片,通過預先寫入 STC89C51 中的控制程序來控制小車的運動,進而達到對智能小車的控制。另外,STC89C51 的供電電壓為 5V,可通過 7.2V 電源經過降壓模塊來給單片機進行供電。
驅動模塊
在智能小車兩個前輪上各安裝一個直流電機(小黃電機),分別控制小車的兩個輪子的轉速。當兩個輪子的轉速不同時,根據慣性,小車會轉彎;當兩個輪子的轉速相同時,小車將直行。我們采用LM298N 實現對直流電機的驅動,其內部設有兩個 H 橋高電壓大電流全橋式驅動器。通過單片機將 PWM 脈沖信號傳輸給 L298N 電機驅動芯片,從而達到控制直流電機的速度、停止和正反轉向,保證小車能夠實現沿著預先設置的軌道行走、躲避障礙物以及自動糾正偏離。
檢測模塊
智能車的檢測模塊主要分為三種:攝像頭、電磁、光電。本次課設中我們選擇 TCRT5000 光電傳感器作為檢測模塊。TCRT5000 是一款紅外反射式光電開關。傳感器采用高發射功率紅外光電二極管和高靈敏度光電晶體管組成,常用于黑白線檢測的場合。
整體實現框圖
程序部分準備
定時器部分
void Timer1_10ms(void) { TMOD |= 0x10 ; //使用模式 1 TH0 = (65536 - 10000)/256; //取高 8 位 TL0 = (65536 - 10000)%256; //取低 8 位 共定時 10ms TR1 = 1; //打開定時器 1 開關 EA = 1; //打開中斷總開關 ET1 = 1; //打開定時器中斷 1 的開關 } void Timer1_Isr(void) interrupt 3 { static unsigned char i = 0; TH0 = (65536 - 10000)/256; //重載初值 TL0 = (65536 - 10000)%256; i++; if(i == 11) //100ms 反轉一次 {//所需控制內容——PWM 定時 }PWM控制電機轉速
原理
電機本質上是一個電感元件,那么數字信號表現在電機上就是平均值。平均電壓越大,電機轉的越快。而通過 PWM 輸出不同占空比數字電壓信號,即不同電壓值的模擬信號,便能控制電機在不同轉速下轉動。
電機輸出端引腳是高電平電機就可以轉動,當輸出端高電平時,電機會轉動,但是是一點一點的提速,在高電平突然轉向低電平時,電機由于電感有防止電流突變的作用是不會停止的,會保持這原有的轉速,以此往復,電機的轉速就是周期內輸出的平均電壓值,所以實質上我們調速是將電機處于一種,似停非停,似全速轉動又非全速轉動的狀態。
功能框圖
后期
成品及局部展示
整體造型
主控和驅動
光電管檢測部分
電源管理
黑膠帶制作簡易車道
調試及效果
初始調試建議光電小車時,采用了差速控制的方法,在模擬車道上能夠實現較好的轉彎的功能,但問題是無法很好的通過急彎。為此,想到了使一側的車輪反轉,另一側車輪正轉以獲得最大程度的轉速差,至此小車能夠比較好的通過所有模擬的彎道。在一次次調試的過程中,將電機驅動引腳的占空比提高,并將周期縮小,小車獲得了更高的車速,與此同時小車的過彎性能降低了,為了解決這個問題,經過大量依賴程序的調試并沒有獲得很好的效果。于是我們想到了改變小車光電管的位置,以提前感知彎道,將兩對光電管改為“八”字構,并將最外側的一對光電管向前伸展,最終獲得了比較好的效果。
CODE
最后附上所有代碼
#主程序部分 #include"stc15.h" #include"start_set.h" #include"motor.h" #include"time.h" void main() { time_start(); while(1){if(left2==0&&left1==0&&right1==0&&right2==0)//?±DDstraight(count1,650,count2,650);else if(left2==0&&left1==1&&right1==0&&right2==0)//×óD?×astraight(count1,1,count2,1000);else if(left2==0&&left1==0&&right1==1&&right2==0)//óòD?×astraight(count1,1000,count2,1);else if(left2==1&&left1==1&&right1==0&&right2==0)//×ó′ó×aacute_left(count1,800,count2,800);else if(left2==0&&left1==0&&right1==1&&right2==1)//óò′ó×aacute_right(count1,800,count2,800);else if(left2==1&&left1==0&&right1==0&&right2==0)//×ó?±×a{acute_left(count1,1000,count2,1000);}else if(left2==0&&left1==0&&right1==0&&right2==1)//óò?±×a{acute_right(count1,1000,count2,1000);}} }# 電機控制部分 #include"stc15.h" void left_motor(int count1,int time1) {IN1=1;IN2=0;if ( count1<time1)ENA=1;elseENA=0; } void right_motor(int count2,int time2) {IN3=0;IN4=1;if ( count2<time2)ENB=1;elseENB=0; } void back_left(int count1,int time1) {IN1=0;IN2=1;if(count1<time1)ENA=1;elseENA=0; } void back_right(int count2,int time2) {IN3=1;IN4=0;if ( count2<time2)ENB=1;elseENB=0; } void straight(int count1,int time1,int count2,int time2) {right_motor(count2,time2);left_motor(count1,time1); } void acute_left(int count1,int time1,int count2,int time2) {back_left(count1,time1);right_motor(count2,time2); } void acute_right(int count1,int time1,int count2,int time2) {left_motor(count1,time1);back_right(count2,time2); }# 初始化 #include"stc15.h" sbit ENA=P0^0; sbit IN1=P0^1; sbit IN2=P0^2; sbit ENB=P1^0; sbit IN3=P1^1; sbit IN4=P1^2; sbit left1=P2^3; sbit left2=P2^4; sbit right1=P2^1; sbit right2=P2^2; int count1=0; int count2=0; void time_start(void) {TMOD=0x00;TH0=(65536-120)/256;TL0=(65536-120)%256;EA=1;ET0=1;TR0=1;TH1=(65536-120)/256;TL1=(65536-120)%256;EA=1;ET1=1;TR1=1; }# 定時中斷 #include"stc15.h" #include"intrins.h" void timer0()interrupt 1 {TH0=(65536-120)/256;TL0=(65536-120)%256;count1++;if(count1>1000)count1=0; } void timer1()interrupt 3 {TH1=(65536-120)/256;TL1=(65536-120)%256;count2++;if(count2>=1000)count2=0; }參考其他博主的資料
https://blog.csdn.net/qq_37369201/article/details/84065322
https://blog.csdn.net/luoqisimieji/article/details/103107314
https://blog.csdn.net/Qinlong_Stm32/article/details/104161667
https://blog.csdn.net/qq_45467083/article/details/103975788
https://blog.csdn.net/li707414287/article/details/98721120
總結
以上是生活随笔為你收集整理的51单片机 简易光电循迹小车的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OPPO终止自研芯片业务!小米王化:确实
- 下一篇: 感知机-梯度下降