智能双小车C程序主机.docx
- 文档编号:12881082
- 上传时间:2023-04-22
- 格式:DOCX
- 页数:27
- 大小:19.57KB
智能双小车C程序主机.docx
《智能双小车C程序主机.docx》由会员分享,可在线阅读,更多相关《智能双小车C程序主机.docx(27页珍藏版)》请在冰豆网上搜索。
智能双小车C程序主机
#include
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitPW0=P2^0;//左前轮
sbitPW1=P2^1;//控制电机的两个输入
sbitPW4=P2^2;//右前轮
sbitPW5=P2^3;//控制电机的两个输入
sbitENA_L=P2^4;//左前轮控制
sbitENA_R=P2^5;//右前轮控制
sbitPW2=P0^0;//左后轮
sbitPW3=P0^1;//控制电机的两个输入
sbitPW6=P0^2;//右后轮
sbitPW7=P0^3;//控制电机的两个输入
sbitENB_L=P0^4;//左后轮控制
sbitENB_R=P0^5;//右后轮控制
//寻线电路引脚
sbitFollow_L2=P1^2;
sbitFollow_L1=P1^3;
sbitFollow_R1=P1^4;
sbitFollow_R2=P1^5;
sbitbell=P1^7;
//红外蔽障
sbitInfra_redL=P2^6;
sbitInfra_redR=P2^7;
//********超声波****************
sbitTrig=P3^6;//产生脉冲引脚
sbitEcho=P3^2;//回波引脚
uchardis=0,flag=0,high_time,low_time,m=0;
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;
TH0=0xFF;//定时0.25Ms
TL0=0x06;
if(t ENA_L=1; else ENA_L=0; if(t ENA_R=1; else ENA_R=0; if(t ENB_L=1; else ENB_L=0; if(t ENB_R=1; else ENB_R=0; ET0=1; 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; PWM1=1; } voidright_turn1()//一级右转15 { PWM1=30; PWM2=20; PWM4=3; PWM3=1; } voidright_turn2()//二级右转30 { PWM1=40; PWM2=30; PWM4=2; PWM3=1; } voidstraight1()//直线低速1(25------80之间有速度) { PWM1=20; PWM2=20; PWM3=20; PWM4=20; } voidstraight2()//直线中速 { PWM1=30; PWM2=30;//补偿5 PWM3=30; PWM4=30; } voidstraight3()//直线高速 { PWM1=40; PWM2=40;//补偿5 PWM3=40; PWM4=40; } voidswift_stop()//快速停止注意调用swift_stop()后若要开机ET0=1;////////////////// { ET0=0;//开始ET0=1; TR0=0; ENA_L=0; ENB_L=0; ENA_R=0; ENB_R=0; ET0=0;//开始ET0=1; TR0=0; PW0=1;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>0;a--); } voiddelay1ms()//误差0us { unsignedchara,b,c; for(c=1;c>0;c--) for(b=142;b>0;b--) for(a=2;a>0;a--); } voiddelay100us()//误差0us { unsignedchara,b; for(b=1;b>0;b--) for(a=47;a>0;a--); }*/ voiddelay10ms()//误差0us { unsignedchara,b,c; for(c=1;c>0;c--) for(b=38;b>0;b--) for(a=130;a>0;a--); } voiddelay5ms()//误差0us { unsignedchara,b; for(b=19;b>0;b--) for(a=130;a>0;a--); } //寻线函数: Follow() voiddelay_nms(uintn)//超声波 { uchari; while(n--) { for(i=123;i>0;i--); } } voidFollow() { uchartemp=0; //Metal_init();//金属传感器初始化 while (1) { temp=(temp<<1)|Follow_R2; temp=(temp<<1)|Follow_R1; temp=(temp<<1)|Follow_L1; temp=(temp<<1)|Follow_L2; /*while((temp&0x0F)==0x00||(temp&0x0F)==0x0F)//00000000 { temp=(temp<<1)|Follow_R2; temp=(temp<<1)|Follow_R1; temp=(temp<<1)|Follow_L1; temp=(temp<<1)|Follow_L2; straight1(); } while((temp&0x0F)==0x02)//一级左转00000010 { temp=(temp<<1)|Follow_R2; temp=(temp<<1)|Follow_R1; temp=(temp<<1)|Follow_L1; temp=(temp<<1)|Follow_L2; left_turn1(); } while((temp&0x0F)==0x01||(temp&0x0F)==0x03)//二级左转00000001 { temp=(temp<<1)|Follow_R2; temp=(temp<<1)|Follow_R1; temp=(temp<<1)|Follow_L1; temp=(temp<<1)|Follow_L2; left_turn2(); } while((temp&0x0F)==0x04)//一级右转00000100 { temp=(temp<<1)|Follow_R2; temp=(temp<<1)|Follow_R1; temp=(temp<<1)|Follow_L1; temp=(temp<<1)|Follow_L2; right_turn1(); } while((temp&0x0F)==0x08||(temp&0x0F)==0x0C)//二级右转00001000 { temp=(temp<<1)|Follow_R2; temp=(temp<<1)|Follow_R1; temp=(temp<<1)|Follow_L1; temp=(temp<<1)|Follow_L2; right_turn2(); }*/ switch(temp&0x0F) { case0x00: case0x0F: straight1();break;//00000000 case0x02: left_turn1();delay5ms();break;//一级左转00000010 case0x01: case0x03: left_turn2();delay10ms();break;//二级左转00000001 case0x04: right_turn1();delay5ms();break;//一级右转00000100 case0x08: case0x0C: right_turn2(); delay10ms();break;//二级右转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(); } while(Infra_redL&&Infra_redR) { //flag_red=1; straight1(); } if(flag_red) break; } } /******************************************************************************** 函数名称: 超声波测量函数 入口参数: 无 返回值: 无 *********************************************************************************/ voidultrasonic_init()//超声波初始化 { TMOD=0x11;//定时器方式用于计时与电机初始化加在一起 TH1=0; TL1=0;/*设定T0的工作模式为*/ PT1=1;//T1为高优先级中断 //EA=1;//电机初始化已开 IT0=0;//下降沿有效,左传感器 PX0=1;//外部中断零为高优先级中断 } voidultrasonic()//超声波函数 { uchari; floattemp; TH1=0; TL1=0;//清定时 TR1=1;//开定时 for(i=8;i>0;i--) { Trig=! Trig; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _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;//关定时器 ET0=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 { unsignedchara,b,c; for(c=167;c>0;c--) for(b=171;b>0;b--) for(a=16;a>0;a--); _nop_();//ifKeil,requireuseintrins.h } INT1_()interrupt2//外部中断1 { bell=1; MetalNum++; delay1s(); if(MetalNum==4) { swift_stop(); flag_Metal=0; } bell=0; } voiddelay5s()//5秒暂停////////////////////////////// { unsignedchara,b,c; for(c=165;c>0;c--) for(b=100;b>0;b--) for(a=150;a>0;a--); _nop_();//ifKeil,requireuseintrins.h _nop_();//ifKeil,requireuseintrins.h } /********************************************************************** *******************I2C总线通信协议******寻光开始************** *********************************************************************** *******************/ voidstart_i2c()//启动i2c总线 { SDA=1;//发送起始条件的数据信号 _nop_(); SCL=1; _nop_();//起始条件建立时间大于4.7us,延时 _nop_(); _nop_(); _nop_(); _nop_(); SDA=0;//发送起始信号 _nop_();//起始条件锁定时间大于4μ _nop_(); _nop_(); _nop_(); _nop_(); SCL=0;//钳住I2C总线,准备发送或接收数据 _nop_(); _nop_(); } voidstop_i2c()//结束总线 { SDA=0;//发送结束条件的数据信号 _nop_();//发送结束条件的时钟信号 SCL=1;//结束条件建立时间大于4μ _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); SDA=1;//发送I2C总线结束信号 _nop_(); _nop_(); _nop_(); _nop_(); } voidsendbyte(ucharc)//发送数据传递函数,注意这里发送的是一个字节的数据8bit { unsignedcharBitCnt; for(BitCnt=0;BitCnt<8;BitCnt++)//要传送的数据长度为8位 { if((c< SDA=1;//判断发送位 else SDA=0; _nop_(); SCL=1;//置时钟线为高,通知被控器开始接收数据位 _nop_(); _nop_();//保证时钟高电平周期大于4μ _nop_(); _nop_(); _nop_(); SCL=0; } _nop_(); _nop_(); SDA=1;//8位发送完后释放数据线,准备接收应答位 _nop_(); _nop_(); SCL=1; _nop_(); _nop_(); _nop_(); if(SDA==1) ack=0; else ack=1;//判断是否接收到应答信号 SCL=0; _nop_(); _nop_(); } ucharrcvbyte()//接受数据传递函数,注意这里发送的是一个字节的数据8bit { ucharretc; ucharBitCnt; retc=0; SDA=1;//置数据线为输入方式 for(BitCnt=0;BitCnt<8;BitCnt++) { _nop_(); SCL=0;//置时钟线为低,准备接收数据位 _nop_(); _nop_();//时钟低电平周期大于4.7us _nop_(); _nop_(); _nop_(); SCL=1;//置时钟线为高使数据线上数据有效 _nop_(); _nop_(); retc=retc<<1; if(SDA==1)retc=retc+1;//读数据位,接收的数据位放入retc中 _nop_(); _nop_(); } SCL=0; _nop_(); _nop_(); return(retc); } voidnoack_i2c(void)//非应答子函数 { SDA=1; _nop_(); _nop_(); _nop_(); SCL=1; _nop_(); _nop_();//
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 智能双小车C程序 主机 智能 小车 程序