智能寻迹小车的代码
/*------------------------------------------------------
-----------------------小車運行主程序-------------------
--------------------------------------------------------
?
?
簡介:@模塊組成:紅外對管檢測模塊----五組對管,五個信號采集端口
?直流電機驅動模塊----驅動兩個直流電機,另一個輪子用萬向輪
?單片機最小系統------用于燒寫程序,控制智能小車運動
??@功能簡介:在白色地面或皮質上用黑色膠帶粘貼出路線路徑寬度微大于相鄰檢測管間距。
?這樣小車便可在其上循跡運行。
??@補充說明:該程序采取“右優先”的原則:
?????????????????????????????????????????即右邊有黑線向右轉,
?????????????????????????????????????????若無,前方有黑線,向前走,
?若無,左邊有黑線,向左轉,
?若全無,從右方向后轉。
?????????????
?????????????程序開頭定義的變量的取值是根據我的小車所調試選擇好的,
?????????????如果采用本程序,請自行調試適合自己小車的合適參數值。
?
編者:陳堯,黃永剛(江蘇大學電氣學院二年級,三年級)
?
?
1.假定:IN1=1,IN3=1時電機正向轉動,必須保證本條件
2.假定:遇到白線輸出0,遇到黑線輸出1;
???????如果實際電路是:遇到白線輸出1,遇到黑線輸出0,
???這種情況下只需要將第四,第五句改成:
????????????????#define m0 1
????????????????#define m1 0
?即可。
3.說明1:直行---------------速度full_speed_left,full_speed_right.
?????????轉彎,調頭速度------correct_speed_left,correct_speed_right.
?微小校正時---------高速輪full_speed_left,full_speed_right;
????????????????????低速輪correct_speed. ?
????????可以通過調節第六,七,八,九,十條程序,改變各個狀態
????????下的占空比(Duty cycle ),以求達到合適的轉彎,直行速度
?
?
?
4.lenth----------length檢測到黑線到啟動轉動的時間間隔
5.width----------mid3在黑線上到脫離黑線的時間差
6.mid3-----------作為判斷中心位置是否進入黑線的標志,由于運行的粗糙性和慣性,
?????????????????常取其他對管的輸出信號作為判斷條件
7.check_right----若先檢測到左邊黑線,并且左邊已出黑線,判斷右端是否壓黑線時間拖延
--------------------------------------------------------
--------------------------------------------------------*/
?
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
?
#define m0 1//黑線m1,白線m0
#define m1 0
???????????
#define full_speed_left 40 //方便調節各個狀態的占空比 ,可用參數組:(30,35,6,25,30,68000,27000,500);
#define full_speed_right 45 // ????????? (40,45,6,25,30,68000,27000,500);
#define correct_speed 6 //校正時的低速輪的占空比
#define turn_speed_left 25
#define turn_speed_right 30
#define lenth 68000 //測試數據:10000--》100--》500--》2000--80000--76000--68000
#define width 27000 //500--》10-->2000--》60000--30000---》27000
#define check_right 500 //2000--》20--》200--》500
#define midl left1
#define midr right5
?
uchar Duty_left,Duty_right,i=0,j=0; //左右占空比標志,取1--100
????????????????
sbit IN1=P2^0; ?
sbit IN2=P2^1; ?
sbit IN3=P2^2;
sbit IN4=P2^3;
sbit ENA=P1^0; ???
sbit ENB=P1^1; ?
?
//循跡口 五組紅外對管,依次對應從左往右第1,2,3,4,5五組
sbit left1 =P1^6;
sbit left2 =P1^5;
sbit mid3 ?=P1^4;
sbit right4=P1^3;
sbit right5=P1^2;
?
void line_left();
void line_right();
void line_straight()reentrant;
//----------------------------------------
void delay(long int Delay_time)//延時函數
?{
?uint t=Delay_time;
?while(t--);
?}
//-----------------------------------------
void init() ?//定時器初始化
?{
???left1=m0; //初始化
???left2=m0; ?//白線位置
???mid3 =m1; ??//黑線位置
???right4=m0;
???right5=m0;
???TMOD|=0x01;
???TH0=(65536-66)/256;
???TL0=(65536-66)%256;
???EA=1;
???ET0=1;
???TR0=1;
???ENA=1; //使能端口,初始化
???ENB=1;
??}
//--------------------------------------------
void time0(void)interrupt 1 ?//中斷程序
{
??i++; //調速在中斷中執行
??j++;
??if(i<=Duty_left)
?????ENA=1;
??else ENA=0; ?
??if(i>100)
?????{ENA=1;i=0;}
??if(j<=Duty_right)
?????ENB=1;
??else ENB=0;
??if(j>100)
?????{ENB=1;j=0;}
TH0=(65536-66)/256; ???//取約150HZ,12M晶振,每次定時66us,分100次,這樣開頭定義的變量正好直接表示占空比的數值
TL0=(65536-66)%256;
}
//-----------------------------------------------
void correct_left()//向左校正,賦值
?{
???Duty_left =correct_speed;
???Duty_right=full_speed_right;
???IN1=1;
???IN2=0;
???IN3=1;
???IN4=0;
?}
//------------------------------------------------
?void correct_right()//向右校正,賦值
?{
???Duty_left =full_speed_left;
???Duty_right=correct_speed;
???IN1=1;
???IN2=0;
???IN3=1;
???IN4=0;
?}
//--------------------------------------------------
void turn_left()//左轉,賦值
{
??Duty_left =turn_speed_left;
??Duty_right=turn_speed_right;
??IN1=0; ?//轉彎時一個正轉,一個反轉,
??IN2=1;
??IN3=1;
??IN4=0;
}
//---------------------------------------------------
void turn_right()//右轉,賦值
{
??Duty_left =turn_speed_left;
??Duty_right=turn_speed_right;
??IN1=1; ??//轉彎時一個正轉,一個反轉,
??IN2=0;
??IN3=0;
??IN4=1;
}
//-----------------------------------------------------
void straight() //直走,賦值
{
??Duty_left =full_speed_left; //左右電機占空比初始化,調節直線運動速度
??Duty_right=full_speed_right; //鑒于左右輪電機內部阻力不同,故占空比取不同值,這組值需要單獨寫程序取值
??IN1=1;
??IN2=0;
??IN3=1;
??IN4=0;
}
//-----------------------------------------------------
void line_straight()reentrant //函數名后加reentrant可以遞歸調用,//一直走黑直線時
{
??straight();
??if(right5==m1){line_right();}
??else
??if(left1==m1){line_left();}
??else
??if(left2==m1) ??//防止校正時,小車沖出過大,導致2,4號檢測管屏蔽了兩端檢測管的檢測,避免其走直線時出軌
????while(left2==m1)
?????{correct_left();
???????if(right5==m1)
??????????{
???line_right();
???goto label3;
???}
???else if(left1==m1)
?{line_left();
?????goto label3;}
?????}
??else
??if(right4==m1) ???//防止校正時,小車沖出過大,導致2,4號檢測管屏蔽了兩端檢測管的檢測,避免其走直線時出軌
???while(right4==m1)
????{correct_right();
?????if(right5==m1)
???????{ line_right(); ?goto label3;}
?????else if(left1==m1)
{line_left();goto label3;}
}
??else
??if((left1==m0)&&(left2==m0)&&(mid3==m0)&&(right4==m0)&&(right5==m0))
????{
??straight();
??//delay(lenth);
??while(right4==m0) //本來應該是用mid3,但是為了提高靈敏度,選擇right4;向左時,可取left2對管
????{turn_right();}
??if(mid3==m1)
????{line_straight();}
}
?
label3: ; //什么都不做
}
//-------------------------------------------------------------------------
void line_right() //右邊有黑線時
{
straight();//這里的直走是在不管紅外檢測結果的直行
delay(lenth);
if(mid3==m1)
{
??turn_right();//執行向右轉的賦值
label:delay(width); //由width值決定轉彎時mid3經過黑線寬度時所需要的時間
??if(mid3==m0)
????while(right4==m0)
?????{}
??else
?? ??goto label;
?}
?
else
if(mid3==m0)
???{
?????turn_right();
?????while(right4==m0)
???????{}
?????if(midr==m1)
???????{line_straight();}
???????} ?
}
//-----------------------------------------------------------------
void line_left() //左邊出現黑線時
{
??while(left1==m1)
??{
if(right5==m1)
{
line_right();
goto label2;
}
???}
?
???delay(check_right);//左邊遇到黑線時,左邊出了黑線之后,繼續延時一段時間,判斷右邊是否遇到黑線,
???//若遇到黑線,執行line_right()函數
if(right5==m1)
{
line_right();
goto label2;
}
?
???if((mid3==m1)||(left2==m1)||(right4==m1)){line_straight();}
??else
??{
?????while(left2==m0)
????{turn_left();}
?????if(midl==m1)
????????line_straight(); ???
??}
label2: ;
}
//--------------------------------------------------------------------
void detect_infrared() //循跡,紅外檢測
?{
???if(right5==m1){line_right();}
???else
???if(left1==m1){line_left();}
???else
???if(left2==m1){correct_left();}
???else
???if(right4==m1){correct_right();}
???else
???line_straight();
?}
//--------------------------------------
void main(void)//主程序部分
{
??init();
??while(1) //循環檢測紅外對管采集的電平信號
???{detect_infrared();}
}
???????
總結
- 上一篇: tensorflow 版本列表_Tens
- 下一篇: duilib入门简明教程(1)