標題: 智能小車循跡程序 [打印本頁]
作者: 123321gjx 時間: 2019-3-30 17:24
標題: 智能小車循跡程序
#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;
N1=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)
{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;
}
}
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();}
}
作者: 單片小菜雞 時間: 2020-7-30 10:43
建議做好再發出來
歡迎光臨 (http://www.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |