📄 car.c
字号:
//#include<AT89x51hyq.h>
#include <reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define DsDat P1_4 //显示数据
#define DsClk P1_5 //送数时钟
#define cd P3_7 /*菜单位*/
#define qw P1_3 /*字千位*/
#define bw P1_2 /*字百位*/
#define sw P1_1 /*字十位*/
#define gw P1_0 /*字个位*/
#define hi0 0xce //定时50us
#define lo0 0xce
#define hi1 0x3c //定时50ms
#define lo1 0xb0
#define m1p P0_0 //电机左的PWM
#define m11 P0_1 //P0_1=1,P0_2=0电机正转;
#define m12 P0_2 //P0_1=0,P0_2=1电机反转;
#define m2p P0_3 //电机右的PWM
#define m21 P0_4 //P0_4=1,P0_5=0电机正转;
#define m22 P0_5 //P0_4=0,P0_5=1电机正转;
#define alarm P0_6 // P06=1报警;
#define key_en P0_7 //高电平时,封锁车轮脉冲,以免影响按键。
#define pian_L P2_0 //为1时偏左;
#define pian_R P2_1 //为1时偏右;
#define have_tie P2_2 //低电平时有铁;
#define have_ai P2_3 //低电平时有障碍物;
#define wheel_Pulse P3_3 //车轮脉冲;
#define light_L P2_5
#define light_ok P2_4
#define light_R P2_6
#define light P2_7
#define ON_TIME 20
//////////////////////定义全局变量
uchar code ledk[27]={0x3F,0x06,0x5B,0x4F,0x66,0x6D, //0,1,2,3,4,5
0x7D,0x07,0x7F,0x6F,0x77,0x7C, //6,7,8,9,A,B
0x39,0x5E,0x79,0x71,0x3d,0x76, //C(12),D,E,F,G(16),H(17),
0x38,0x5c,0x73,0x67,0x78,0x3e, //L(18),o(19),P(20),q(21),t(22),U(23),
0x6e,0x40,0x00}; //Y(24),-(25)," "(26)
uchar disp[5]={9,0,0,0,0};
bit on_off=0,workmode;
long int T1_count=0;
uchar T0_count=0,dis_count=0;
uchar speed1,speed2;
uchar whichset;
uint path_c;
uint s0;
uchar runmode;
uchar sp_c;
uchar spset;
uchar tie_num;
uint *p_array; //用来指向array[6]的指针;
uint array[6]; //保存铁片的中心距离的数组;
bit tie_flag;
uchar led_no;
///////////////////// 定义小车运行模式
#define track_check 1
#define half_circle 2
#define bi_zheng 3
#define light_track 4
#define finish 5
//////////////////////////////////
void stop(uchar r);
void zc(uchar r);
void fc(uchar r);
void start(uchar r,uchar spset,bit zf);
void display();
void send(uchar sdata,uchar wei);
void fon_off(bit b,uchar wei);
void send_one(uchar cdata);
void delay(uchar time);
bit bittest(uchar cdata,uchar nbit);
uchar DecToHex();
uchar key();
void finishcacu();
void FTrack_check();
void Ftie_check();
void FHalf_circle();
void FBi_zheng();
void FLight_track();
void Ffinish();
void HexToDec(uint xx);
main()
{ uchar i;
TMOD=0x12; //T0是定时器0方式2,8位自动装载;T1是定时器1方式1,16位计数;
ET0=1;
ET1=1;
EX0=1;
EA=1;
PT1=1;
s0=0;
stop(0);
stop(1);
key_en=1;
alarm=1;
spset=120;
sp_c=100;
path_c=1000;
while(1)
{
display();
switch(key())
{
case 1: //设置位;
workmode=1;
if(++whichset>4)
whichset=0;
break;
case 2:if(workmode==1) //改数;
if(++disp[whichset]>9)
disp[whichset]=0;
break;
case 3: workmode=0;
switch(disp[0])
{
case 0:spset=DecToHex();break; //速度初置设置;
case 1:sp_c=DecToHex();break; //速度差置设置;
case 2:path_c=DecToHex();break; //第二状态转换设置;
case 9:
for(i=0;i<2;i++) //起动鸣笛;
{
alarm=0;
display();
}
for(i=0;i<2;i++) //关笛;
{
alarm=1;
display();
}
for(i=0;i<200;i++) //起动鸣笛;
{
alarm=0;
display();
}
alarm=1; //关笛;准备开车
for(i=0;i<6;i++) //清参数数组
{
array[i]=0;
}
TR0=1;
TR1=1;
TH0=hi0;
TL0=lo0;
TH1=hi1;
TL1=lo1;
IT1=1; //下降沿触发;
EX1=1; //允许车轮记数
key_en=0; //允许车轮脉冲
p_array=array;
start(0,spset,1);
start(1,spset,1);
runmode=track_check; //预置运行模式为黑线跟踪
while(1) //进入运行的主循环
{
switch(runmode)
{
case 1:FTrack_check();break;//黑线跟踪
case 2:FHalf_circle();break;//半圆跟踪
case 3:FBi_zheng(); break;//避障碍
case 4:FLight_track();break;//光跟踪入库
case 5:Ffinish(); break;//完成,显示参数
default :break;
}
disp[0]=runmode;//显示运行模式
if(T1_count>1800) //时间大于90秒则自动停车
{
stop(0);
stop(1);
key_en=1;
TR0=0;
TR1=0;
EX0=0;
runmode=finish;//运行到完成工序
}
display();
} //while(1)运行的主循环结束
break; //内环case 9
} //switch(disp[0])结束
break; //外环Case 3确定键
default:break;
} //switch(key())
} //while(1)
}
////////////////黑线跟踪函数//////////////////////////////////////////
void FTrack_check()
{
switch(P2&0x03)
{
case 0x01:
start(0,spset+sp_c,1); //偏右;
start(1,spset-sp_c,1);
break;
case 0x02:
start(0,spset-sp_c,1); //偏左;
start(1,spset+sp_c,1);
break;
default:
start(0,spset+sp_c,1); //正位;
start(1,spset+sp_c,1);
break;
}
Ftie_check();//检测铁片
P0_6=!tie_flag; //检测到铁片时,"嘀"一声响
if(s0>path_c) runmode=half_circle; //判断运行距离小车已驶出有铁片的直线段,
//将运行模式转成半圆运行方式
}
////////////检测铁片函数/////////////////////////////////////
void Ftie_check()
{ uchar temp;
if(tie_flag) //有铁片标志1
{ if(have_tie==1) //等到小车运行过铁片的尾端后
{
*p_array++=s0; //把铁片的尾端运行距离数写入数组
tie_flag=0; //有铁片标志复位
temp=(*(p_array-2)+*(p_array-1))/2; //计算铁片中心离起点的距离
HexToDec((temp*33)/100); //转换成十进制
}
return ;
}
else if(have_tie==0&&tie_num<3) //若检测到铁片始端且铁片数量小于3片则
{
tie_num++; //铁片数加1
*p_array++=s0; //且把运行距离数写入数组,并把数级指针加1
tie_flag=1; //铁片标志置1
}
}
//////////半圆跟踪//////////////////////////////////
void FHalf_circle()
{ uint temp;
switch(P2&0x03)
{
case 0x01:
start(0,spset+sp_c,1); //偏右;
start(1,spset-sp_c,1);
break;
case 0x02:
start(0,spset-sp_c,1); //偏左;
start(1,spset+sp_c,1);
break;
default:
start(0,spset+sp_c,1); //正位;
start(1,spset+sp_c,1);
break;
}
if(have_tie==0) //若检测到铁片
{
stop(0); //则停车
stop(1);
temp=T1_count; //把现行时间先记录到Temp,T1_count在运行后每50mS自动加1(中断程序中执行)
while(T1_count-temp<100) //停车5S
{
HexToDec(s0);
switch((T1_count-temp)/10) //每隔1S响一声喇叭
{
case 0:alarm=0;break;
case 1:alarm=1;break;
case 2:alarm=0;break;
case 3:alarm=1;break;
case 4:alarm=0;break;
case 5:alarm=1;break;
case 6:alarm=0;break;
case 7:alarm=1;break;
case 8,9:alarm=0;break;
}
display();
}
alarm=1; //关喇叭
start(0,spset+50,1); //左转运行,修正车方向
start(1,spset-50,1);
temp=T1_count;
while(T1_count-temp<20) ////左转运行1S
{
display();
}
runmode=bi_zheng; //把运行方式转成避障模式
start(0,spset+sp_c,1); //直行
start(1,spset+sp_c,1);
}
}
//////////避障碍函数////////////////////////////////
void FBi_zheng()
{ uchar i;
if(have_ai==0) //若前有障碍物则
{
stop(1); //左转
while(have_ai==0) //左转直到障碍物消失
{
display();
}
for(i=0;i<200;i++) //障碍物消失后再转一会,确保运行方向与障碍物平行
{
display();
}
start(0,spset+sp_c,1); //直行
start(1,spset+sp_c,1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -