智能双小车C程序主机文档格式.docx
《智能双小车C程序主机文档格式.docx》由会员分享,可在线阅读,更多相关《智能双小车C程序主机文档格式.docx(27页珍藏版)》请在冰点文库上搜索。
![智能双小车C程序主机文档格式.docx](https://file1.bingdoc.com/fileroot1/2023-4/30/70366c0f-0e99-439a-959c-af0a305ace07/70366c0f-0e99-439a-959c-af0a305ace071.gif)
ucharflag_tran=1,flag_Metal=1;
//超声波跳出标志//寻线跳出标志
//金属检测引脚
sbitMetal_DTC=P3^3;
ucharMetalNum=0;
//寻光引脚定义I2C总线的数据端口和命令端口
/***********************************************************************
*******************/
sbitSDA=P0^7;
//数据总线
sbitSCL=P0^6;
//控制总线
uintlight_numL=0,light_numM=0,light_numR=0,light_up=0;
//定义san个变量
bitack;
//应答位
//////////////////////红外蔽障/////////////////////////////
ucharflag_red;
unsignedcharPWM1=0;
//**左前电机的占空比**//
unsignedcharPWM2=0;
//**左后电机的占空比**//
unsignedcharPWM3=0;
//**右前电机的占空比**//
unsignedcharPWM4=0;
//**右后电机的占空比**//
unsignedchart=0;
//**定时器中断计数器**//
//**********初始化定时器,中断***********//
voidmotor_init()
{
TMOD=0x01;
//定时器T0工作方式一
TH0=0xFF;
//定时0.25Ms
TL0=0x06;
PT0=0;
//T0为低优先级中断
EA=1;
//总中断
ET0=1;
//允许定时器中断
TR0=1;
//定时器T0开始定时
ENA_L=1;
ENB_L=1;
ENA_R=1;
ENB_R=1;
PWM1=15;
PWM2=15;
PWM3=15;
PWM4=15;
PW0=1;
//******给左前电机加电启动******//向前转
PW1=0;
PW4=1;
//******给右前电机加电启动******//
PW5=0;
PW2=1;
//******给左后电机加电启动******//
PW3=0;
PW6=1;
//******给右后电机加电启动******//
PW7=0;
}
//***********中断函数+脉宽调制***********//
voidtimer0()interrupt1
ET0=0;
if(t<
PWM1)//左前轮
else
ENA_L=0;
PWM3)//右前轮
ENA_R=0;
PWM2)//左后轮
ENB_L=0;
PWM4)//右后轮
ENB_R=0;
t++;
if(t==40)
t=0;
}
voidleft_turn1()//一级左转15
{
PWM3=30;
PWM4=20;
PWM2=3;
PWM1=1;
voidleft_turn2()//二级左转30
PWM3=40;
PWM4=30;
PWM2=2;
voidright_turn1()//一级右转15
PWM1=30;
PWM2=20;
PWM4=3;
PWM3=1;
voidright_turn2()//二级右转30
PWM1=40;
PWM2=30;
PWM4=2;
voidstraight1()//直线低速1(25------80之间有速度)
PWM1=20;
PWM3=20;
voidstraight2()//直线中速
//补偿5
voidstraight3()//直线高速
PWM2=40;
PWM4=40;
voidswift_stop()//快速停止注意调用swift_stop()后若要开机ET0=1;
//////////////////
//开始ET0=1;
TR0=0;
PW1=1;
PW2=1;
PW3=1;
PW4=1;
PW5=1;
PW6=1;
PW7=1;
/*voiddelay500us()//误差0us
unsignedchara,b;
for(b=71;
b>
0;
b--)
for(a=2;
a>
a--);
voiddelay1ms()//误差0us
unsignedchara,b,c;
for(c=1;
c>
c--)
for(b=142;
voiddelay100us()//误差0us
for(b=1;
for(a=47;
}*/
voiddelay10ms()//误差0us
for(b=38;
for(a=130;
voiddelay5ms()//误差0us
for(b=19;
//寻线函数:
Follow()
voiddelay_nms(uintn)//超声波
uchari;
while(n--)
{
for(i=123;
i>
i--);
voidFollow()
uchartemp=0;
//Metal_init();
//金属传感器初始化
while
(1)
temp=(temp<
<
1)|Follow_R2;
temp=(temp<
1)|Follow_R1;
1)|Follow_L1;
1)|Follow_L2;
/*while((temp&
0x0F)==0x00||(temp&
0x0F)==0x0F)//00000000
{
temp=(temp<
temp=(temp<
straight1();
}
while((temp&
0x0F)==0x02)//一级左转00000010
left_turn1();
}
0x0F)==0x01||(temp&
0x0F)==0x03)//二级左转00000001
left_turn2();
0x0F)==0x04)//一级右转00000100
right_turn1();
0x0F)==0x08||(temp&
0x0F)==0x0C)//二级右转00001000
right_turn2();
}*/
switch(temp&
0x0F)
{
case0x00:
case0x0F:
straight1();
break;
//00000000
case0x02:
left_turn1();
delay5ms();
//一级左转00000010
case0x01:
case0x03:
left_turn2();
delay10ms();
//二级左转00000001
case0x04:
right_turn1();
//一级右转00000100
case0x08:
case0x0C:
right_turn2();
delay10ms();
//二级右转00001000
if(!
flag_Metal)
PX1=0;
//低优先级中断
EX1=0;
//关闭外部中断
break;
}
//红外蔽障/*///////////////////////////////////////////////////////////////////
//********************************************************************///////
voidInfra_red()
while
(1)
{
while((!
Infra_redL)&
&
Infra_redR)
right_turn2();
}
while(Infra_redL&
(!
Infra_redR))
left_turn2();
//flag_red=1;
if(flag_red)
break;
/********************************************************************************
函数名称:
超声波测量函数
入口参数:
无
返回值:
无
*********************************************************************************/
voidultrasonic_init()//超声波初始化
TMOD=0x11;
//定时器方式用于计时与电机初始化加在一起
TH1=0;
TL1=0;
/*设定T0的工作模式为*/
PT1=1;
//T1为高优先级中断
//EA=1;
//电机初始化已开
IT0=0;
//下降沿有效,左传感器
PX0=1;
//外部中断零为高优先级中断
voidultrasonic()//超声波函数
floattemp;
//清定时
TR1=1;
//开定时
for(i=8;
i--)
Trig=!
Trig;
_nop_();
_nop_();
Trig=1;
delay_nms
(1);
EX0=1;
//开中断
if(flag==1)//中断标志位置,说明有回波
//以下为路程计算
temp=high_time*256+low_time;
temp=(temp/1000)/2;
temp*=340;
temp=temp/10;
dis=temp;
flag=0;
if(dis<
50)//20为小车到障碍物的距离dis<
30
flag_tran++;
voidUltra_DTC()interrupt0//外部中断零
uinttmp;
TR1=0;
//关定时器
//关外部中断
flag=1;
//置位标志位
tmp=TH1*256+TL1;
//读取定时器的值
if((tmp>
0)&
(tmp<
60000))//判断是否超出范围,此设置的范围为到米,实际不能达到米
high_time=TH1;
//把计时值放入缓冲
low_time=TL1;
else//超出范围则重新测量
high_time=0;
low_time=0;
}
}
//////*************************************************//////////////////
voidMetal_init()
IT1=0;
//外部中断*********触发外部中断*********下降沿触发
EX1=1;
//打开外部中断
//EA=1;
//打开总中断已开
bell=0;
//蜂鸣器初始化
voiddelay1s()//误差0us
for(c=167;
for(b=171;
for(a=16;
//ifKeil,requireuseintrins.h
INT1_()interrupt2//外部中断1
bell=1;
MetalNum++;
delay1s();
if(MetalNum==4)
swift_stop();
flag_Metal=0;
voiddelay5s()//5秒暂停//////////////////////////////
for(c=165;
for(b=100;
for(a=150;
/**********************************************************************
*******************I2C总线通信协议******寻光开始**************
***********************************************************************
voidstart_i2c()//启动i2c总线
SDA=1;
//发送起始条件的数据信号
SCL=1;
//起始条件建立时间大于4.7us,延时
SDA=0;
//发送起始信号
//起始条件锁定时间大于4μ
SCL=0;
//钳住I2C总线,准备发送或接收数据
voidstop_i2c()//结束总线
//发送结束条件的数据信号
//发送结束条件的时钟信号
//结束条件建立时间大于4μ
//发送I2C总线结束信号
voidsendbyte(ucharc)//发送数据传递函数,注意这里发送的是一个字节的数据8bit
unsignedcharBitCnt;
for(BitCnt=0;
BitCnt<
8;
BitCnt++)//要传送的数据长度为8位
if((c<
BitCnt)&
0x80)
SDA=1;
//判断发送位
else
SDA=0;
SCL=1;
//置时钟线为高,通知被控器开始接收数据位
//保证时钟高电平周期大于4μ
SCL=0;
//8位发送完后释放数据线,准备接收应答位
if(SDA==1)
ack=0;
else
ack=1;
//判断是否接收到应答信号
ucharrcvbyte()//接受数据传递函数,注意这里发送的是一个字节的数据8bit
ucharretc;
ucharBitCnt;
retc=0;
//置数据线为输入方式
BitCnt++)
//置时钟线为低,准备接收数据位
//时钟低电平周期大于4.7us
//置时钟线为高使数据线上数据有效
retc=retc<
1;
if(SDA==1)retc=retc+1;
//读数据位,接收的数据位放入retc中
return(retc);
voidnoack_i2c(void)//非应答子函数
//