- 1.65 MB
- 64页
- 1、本文档共5页,可阅读全部内容。
- 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
- 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
- 文档侵权举报电话:19940600175。
'2012中国教育机器人大赛教育机器人创意设计项目报告书项目名称:无线协作搬运机器人学校:院系:专业:学生姓名:指导教师:时间:2012年11月20日60
目录1.设计任务与要求..........................................12.方案设计与论证..........................................13.硬件单元电路设计........................................23.1主控制电路......................................23.2循迹电路........................................33.3电源模块........................................43.4最小系统原理图..................................43.5物块颜色识别传感器..............................43.6无线通信传感器..................................44.安装与调试..............................................54.1电路的安装......................................54.2电路的调试......................................54.3软件的调试......................................55.性能测试与分析..........................................55.1循迹模块........................................55.2TCS3200颜色传感器...............................55.3NRF905通信模块无线通信..........................56.结论与心得..............................................67.致谢....................................................68.参考文献................................................69.程序清单................................................69.1无线通信部分....................................69.2颜色传感器部分..................................159.3主程序部分......................................199.3.1机器人A主程序...............................199.3.2机器人B主程序...............................3960
摘要:目前,随着现代传感器技术、自动控制技术以及网络通信技术的不断提高和完善,机器人技术的发展更加趋于自动化和智能化。机器人爱好者藉此趋势设计了各种各具风格的机器人。本设计以两个机器人为主体,这两个机器人通过相互协作,以推的方式进行物体的搬运并将不同颜色的物体加以分类。通过无线通信控制搬运过程。该设计是以AT89S52为系统核心,结合TRC5000寻迹模块、nRF905无线通信模块和TCS3200颜色传感器模块,综合了运用机器人技术、现代传感器技术,自动控制技术。关键词:无线搬运、机器人、TCS3200颜色传感器、nRF905无线通信模块60
1设计任务与要求设计两个智能搬运机器人,由两个搬运机器人在一类似蜘蛛网的循迹图里交替搜寻物块,让机器人识别出物块的颜色,并将物块搬运至对应的物体存放区,如果正在搬运物块的那个机器人发现有另一个搬运机器人占用了它的行走路线,它就会马上通知另一个搬运机器人为它让路,当该机器人把物体搬运到目的地后,它就会通知另一个机器人搜寻物体,如此循环,直到把所有物体搬运完。实物图如下图所示:图1-1搬运路线图图1-2机器人实物图2方案设计与论证方案一:通过51单片机外接NRF905无线模块实现,这种51单片机非常普遍,主要运用于小的系统,但是如果要处理比较复杂的任务就会非常吃力,51单片机是我们学习编程入门很好的工具,操作简单方便。60
方案二:采用CC2510无线单片机来实现任务,CC2510是一种低成本的无线SoC,也是为低功耗无线应用而设计。其工作在2.4Ghz频段,此芯片包含标准的增强型8051MCU和一个收发芯片。其通信更是其最大优点但本设计中没有很复杂的功能要实现,CC2510操作起来比较难,并且CC2510外接的可控IO端口数量较少,不能满足我们的设计需求。方案论证:通过以上比较,对于通过用51单片机外接NRF905无线模块实现明显足以满足我们的设计要求。综合以上论述,我们选择方案一。3硬件单元设计3.1主控制电路以采用PLCC封装AT89S52单片机作为主控制器,AT89S52单片机是靠程序运行的,并且可以修改。8051CPU与MCS-51兼容,全静态工作:0Hz-24KHz,4K字节可编程FLASH存储器(寿命:1000写/擦循环),三级程序存储器保密锁定,128*8位内部RAM,32条可编程I/O线,两个16位定时器6个中断源,可编程串行通道,低功耗的闲置和掉电模式,片内振荡器和时钟电路。此控制芯片资源丰富,但价格比较贵,尽管它可以实现各种复杂的逻辑功能,功耗小,在此非常适合,外围接无线模块进行控制机器人的搬运。3.2循迹电路循迹电路如图所示:图3-2-1寻迹电路60
图3-2-2循迹电路PCB图我们用的循迹模块是用贴片元件来制作,类似工业制板,制作设备由学校提供。该制作过程大大提高了我们的制板技能和焊接技术。我们用到的红外传感器是TCR5000红外对管,传感器的红外发射三极管不断发射红外线,当发射出的红外线没有被反射回来或者被反射回来但强度不够大时,光敏三极管一直处于关断状态,此时模块的输出端为低电平,指示二极管一直处于熄灭状态;被监测物体出现在监测范围内时,红外线被反射回来且强度足够大,光敏三极管饱和,此时模块的输出端为高电平,指示二极管被点亮。TCRT5000光电传感器模块是基于TCRT5000红外关电传感器设计的一款红外反射式光电开关,传感器采用高发射功率红外光电二极管和高灵敏度光晶体管组成,输出信号经施密特电路整形,稳定可靠。3.3电源模块电源电路图如图3-4-1所示:图3-3电源部分电路图该稳压电路主要实现5V(供给控制芯片及其它模块)、6V(供给舵机)和3.3V(NRF905无线模块需要3.3V的电压)稳压,采用LM7805、LM7806和LM1117芯片作为稳压芯片。这些稳压用的集成电路,只有三条引脚输出,分别是输入端、接地端和输出端。它的样子象是普通的三极管,TO-220的标准封装,也有lm9013样子的TO-92封。用7805、7806和1117来组成稳压电源所需的外围元件极少,电路内部还有过流、过热及调整管的保护电路,使用起来可靠方便,而且价格便。3.4AT89S52最小系统原理图60
图3-4单片机最小系统3.5物块颜色识别传感器根据德国物理学家赫姆霍兹的三原色理论可知,各种颜色是由不同比例的三原色(红、绿、蓝)混合而成的。通过颜色传感器测出构成各种颜色的三原色的值,就能知道物体的颜色。以前的颜色传感器通常是在独立的光电二极管上覆盖经过修正的红、绿、蓝滤波片,然后对输出信号进行相应的处理,才能将颜色信号识别出来;有的将两者集合起来,但是输出模拟信号,需要一个A/D电路进行采集,对该信号进一步处理,才能进行识别,增加了电路的复杂性,并且存在较大的识别误差,影响了识别的效果。这里我们选择TAOS公司推出的可编程彩色光到频率的转换器TCS3200颜色传感器来识别物块颜色。它的输出信号时数字量,因此它能直接与微处理器或逻辑电路相连接,这使得组成电路变得简单。它与测试物体的最佳位置大约为1厘米。TCS3200的引脚图如下:图3-5TCS3200引脚图3.5无线通信模块方案一:60
选择NRF2401无线模块。nRF2401内置地址解码器、先进先出堆栈区、调解处理器、时钟处理器、GFSK滤波器、低噪声放大器、频率合成器、功能放大器等功能模块,它具有收发模式、配置模式、空闲模式和关机模式,需要很少的外围元件,且工作时能耗低(工作电流仅几十毫安,待机模式下电流为十几微安),内部有内置天线,使用方便。但市场价格比较贵。方案二:选择NRF905无线模块。nRF905单片无线收发器是挪威NORDIC公司推出的单片射频发射芯片,工作于433/868/915MHz个ISM频道,芯片内置频率合成器、功率放大器、晶体振荡器和调制调解器等功能模块,它具有多个通讯频道,满足多点通讯、分组跳频等应用需求,通道切换时间短(小于6us),能进入关机模式和空闲模式,使用起来节能方便,且价格便宜。综上所述,根据本设计的需求,nRF905无线模块已能满足我们的设计需求。4安装与调试4.1电路的安装与调试做好循迹模块,并调好循迹传感器的灵敏度。在制作模块的过程中,焊接贴片元件时不要出现虚焊、漏焊等,因为一旦出现电路出问题,虚焊是比较难查找的。还要注意元件的位置要对应,极性不要接反。电路板做好后,就可以把循迹模块安装在机器人上了,安装过程中要注意传感器与水平地面的距离(距离一般在1CM左右),连接时要注意每个红外对管对应输出接口的位置,以免机器人运行出错。接下来把其他模块安装好。安装颜色传感器时,要把它牢牢的固定在它所能检测到物体颜色的特定位置(注意:它与检测物体的最佳距离大约为1厘米)。4.3软件的调试5性能测试与分析5.1循迹模块让机器人在行走轨迹上运行,机器人反应灵敏,能稳定的按照特定轨迹行走,这说明循迹模块性能稳定。如果出现机器人跑出轨道的现象,这可能是因为循迹模块灵敏度未调到最佳状态,也可能是因为传感器距离水平地面过低或过高,还可能是因为提供的电压过低等因素造成。5.2颜色传感器在调试程序的过程中,当机器人接触到物块时,机器人很快就能识别出物块颜色,并立即将物块运至物体所属区域。5.3NRF905无线通信模块60
正确将NRF905无线模块安装在机器人上,下载程序,让两个机器人进行交替搬运,当一个机器人搬运一个物块到达目的地后,就通知另一个机器人去搜寻要搬运的物块,调试过程中,机器人之间通信正常。如果出现通信问题,这可能是因为收发频率或收发地址不一致造成的。在应用过程中需求注意的问题:一定要把接收天线接上,以免通信不稳定;提供的电压不能超过3.6伏,否则会烧坏该模块。6结论与心得通过我们小组三人的共同努力,制作完成了搬运群机器人,特色鲜明,较好的完成了预期的目标。。而且通过沟通交流讨论尽可能的增加了作品设计的创新功能,在整个过程中,我们在机器人设计和程序编写方面获得了很多经验,同时也了解到团队精神的重要性。通过备战这次中国教育机器人大赛创意设计和制作比赛,极大的锻炼了我们的动手能力,通过将软件开发,电路设计,网络通信,自动化控制,电子技术等多个学科融合在一起,做出令自己满意的作品,很有成就感,通过这次活动,让我明白不管做什么,只要努力了就会有收获。作为一名大学在校本科生,除了学习理论知识要,还要勤于动手实践,培养自己的创新能力,动手能力,从而提升自己的综合实力,为投入社会,为社会创造价值做好准备。7致谢衷心感谢河池学院的领导和同学们,本次参赛是河池学院派遣学生参加全国机器人大赛,受到了全院领导和同学们的大力支持,在此一并表示感谢,在今后的日子里,我们会再接再厉,拿出更好的作品出来与大家一起分享。衷心感谢我的指导老师,在项目期间,他给予了众多宝贵的经验,给我们的研制工作提供了很多硬件设备和指导,在此表示感谢。同时也感谢辛勤培育我们的老师!提供创新实验室让我们学习,营造了温馨的第二课堂的氛围。让我们学到了知识能够飞翔于广阔的天际。8参考文献[1]康华光,邹寿彬.电子技术基础(数字部分)[M].高等教育出版社,2002[2]童诗白,华成英.模拟电子技术基础[M].清华大学出版社,2006[3]吴线.实战微功耗SimpliciTI无线网络.出版地:电子产品世界,出版年2009.09[2011.10.29].http://www.eepw.com.cn/article/97727.htm9程序清单9.1无线通信部分60
////----------------------------------------------------------------------------------------------------------------#defineuintunsignedint#defineucharunsignedcharucharwuxian=0;//无线发送、接收标志位//----------------------------------------LED显示端口---------------------------------------------------sbitLED=P2^7;ucharwx_jieshou=0;ucharwx_fasong=0;/**********************************************************************************************函数声明**************************************************************************************************/voidTxPacket(uchar*TxRxBuf,ucharn);voidSpiWrite(unsignedcharsend);voidnrf905_Delay(intn);unsignedcharSpiRead(void);voidnRF905Init(void);voidConfig905(void);voidSetTxMode(void);voidTxPacket(uchar*TxRxBuf,ucharn);voidRxPacket(void);voidRX(void);voidclear(void);//清空接收数组unsignedcharCheckDR(void);//检查是否有新数据传入Data//----------------------------------------------------------------------------------------------------------------#defineBYTE_BIT00x01#defineBYTE_BIT10x02#defineBYTE_BIT20x04#defineBYTE_BIT30x08#defineBYTE_BIT40x10#defineBYTE_BIT50x20#defineBYTE_BIT60x40#defineBYTE_BIT70x80//---------------------------------------------------------------------------------------------------------------bdataunsignedcharDATA_BUF;//可位寻址的片内RAN#defineDATA7((DATA_BUF&BYTE_BIT7)!=0)#defineDATA0((DATA_BUF&BYTE_BIT0)!=0)60
sbitflag=DATA_BUF^7;sbitflag1=DATA_BUF^0;//------------------------------------发送数据缓冲区-------------------------------------------------#defineTxRxBuf_Len4unsignedcharTxRxBuf[TxRxBuf_Len]={0x29,0x30,0x31,0x32};codeTxAddress[4]={0xcc,0xcc,0xcc,0xcc};unsignedchartf=0;//----------------------------------------NRF905工作模式控制端口------------------------------------------------------sbitTXEN=P3^3;//发射使能233sbitTRX_CE=P3^4;//发射接收使能434sbitPWR=P3^2;//132//----------------------------------------NRF905数据交换端口(SPI)---------------------------------------------------sbitMISO=P2^3;//输出sbitMOSI=P2^2;//输入sbitSCK=P2^1;//时钟sbitCSN=P2^0;//使能//----------------------------------------nrf905状态端口---------------------------------------------------------sbitAM=P2^5;sbitDR=P2^4;sbitCD=P2^6;//---------------------nrf905控制指令-------------------------------------------#defineWC0x00//写配置寄存?#defineRC0x10//读配置寄存?#defineWTP0x20//向TX-Payload寄存器写入发送有效数据#defineRTP0x21//向TX-Payload寄存器读取发送有效数据#defineWTA0x22//向TX-Addtess寄存器写入发送地址#defineRTA0x23//向TX-Addtess寄存器读取发送地址#defineRRP0x24//从RX-Payload寄存器读取接收到的有效数据//------------------------------------------NRF905寄存器配置------------------------------------------------unsignedcharidataRFConf[11]={0x00,//配置命令//0x4c,//CH_NO,配置频段在430MHZ字节0,配置频段0x0c,//输出功率为10db,不重发,节电为正常模式字节1,00011000x44,//地址宽度设置,为4字节字节2,6:4是TX地址宽度,2:0是RX地址宽度60
0x04,0x04,//接收发送有效数据长度为4字节字节3(RX),字节(TX):可设置为1,2,4,8,16,32字节,其中6,7两位为空,写00,则4字节为:00000100:0x04依次类推0xCC,0xCC,0xCC,0xCC,//接收地址字节5到字节80x58,//CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振字节9,};//================================================延时===========================================================voidnrf905_Delay(intn){uchari;while(n--)for(i=0;i<80;i++);}//=================================================SPI读函数=======================================================//步骤一:MISO线准备好需要发送的数据位//步骤二:SCK置高,主机读取MISO线上的数据//步骤三:SCK置低,准备接收数据的下一位//以上步骤循环执行8次,通过SPI从器件上读取数据完成//数据传送时候。高位在前,低位在后。unsignedcharSpiRead(void){unsignedcharj;for(j=0;j<8;j++){DATA_BUF=DATA_BUF<<1;SCK=1;if(MISO)//读取最高位,保存至最末尾,通过左移位完成整个字节 {DATA_BUF|=BYTE_BIT0;}else{DATA_BUF&=~BYTE_BIT0;}SCK=0;}returnDATA_BUF;}60
//===========================================SPI写函数===============================================================//步骤一:MOSI线准备好需要发送的数据位//步骤二:SCK置高,器件读取MOSI线上的数据//步骤三:SCK置低,准备发送数据的下一位//以上步骤循环执行8次,通过SPI从器件上发送数据完成//数据传送时候。低位在前,高位在后。voidSpiWrite(unsignedcharsend){unsignedchari;DATA_BUF=send;for(i=0;i<8;i++){if(DATA7)//总是发送最高位{MOSI=1;//SPI输入,主机写操作}else{MOSI=0;}SCK=1;DATA_BUF=DATA_BUF<<1;SCK=0;}}//--------------------------------------初始化nRF905---------------------------------------------voidnRF905Init(void){CSN=1;//SpidisableSCK=0;//SpiclocklineinitlowDR=1;//InitDRforinputAM=1;//InitAMforinputCD=1;//InitCDforinputPWR=1;//nRF905poweronTRX_CE=0;//SetnRF905instandbymodeTXEN=0;//setradioinRxmode}//-----------------------------------------------------初始化寄存器-----------------------------------------------//步骤一:CSN置低电平,SPI接口开始等待第一条命令//步骤二:调用SpiWrite函数,向nrf905发送WC指令,准备写入配置信息60
//步骤三:反复调用SpiWrite函数,向器件配置寄存器写入配置信息//步骤四:CSN置高电平,结束SPI通讯。即nrf905配置完成!voidConfig905(void){uchari;CSN=0;//CSN片选信号,SPI使能//SpiWrite(WC);//向905芯片写配置命令for(i=0;i<11;i++)//循环写入配置信息{SpiWrite(RFConf[i]);//RxTxConf保存预先设置好的配置信息}CSN=1;//结束SPI数据传输}//----------------------------------------------设置发送初始状态---------------------------------------------voidSetTxMode(void){TRX_CE=0;TXEN=1;nrf905_Delay(1);//nrf905_Delayformodechange(>=650us)}//步骤一:TRX_ce=0;必须将次引脚置低,使905进入standby模式//步骤二:发送RRP指令//步骤三:循环调用SpiWrite函数,读取接收到的数据//步骤四:等待DR和AM引脚复位为低电平//AM地址匹配,接收到有效地址,被置高//DR接收到有效数据包,并解码后,被置高,当所有有效数据被读取后,//nrf905降AM和DR置低,最后需要注意的是,必须首先设置器件的//发送/接收模式才能保证有效的数据发生接收//-----------------------------------------------设置nrf905进入接收模式---------------------------------------------------voidSetRxMode(void){TXEN=0;TRX_CE=1;nrf905_Delay(1);//nrf905_Delayformodechange(>=650us)}//-------------------------------发送数据打包---------------------------------------------------60
//步骤一:通过SpiWrite函数发送WTP命令,准备写入TX有效数据//步骤二:循环调用SpiWrite向TX-Payload寄存器写入有效数据(中间必须夹有CSN电平变化//步骤三:延时//步骤四:通过SpiWrite函数发送WTA命令,准备写入TX地址//步骤五:循环调用SpiWrite向TX-Address寄存器写入TX地址//步骤六:TRC_CE=1;开始发送数据,延时,nrf905数据发送完成//当nrf905接收到一条完成的信息时,会将DR引脚置高。voidTxPacket(uchar*TxRxBuf,ucharn){uchari;TxRxBuf[0]=n;nRF905Init();//初始化Config905();SetTxMode();//Config905();CSN=0;SpiWrite(WTP);//Writepayloadcommandfor(i=0;i<4;i++){SpiWrite(TxRxBuf[i]);//写入32直接发送数据}CSN=1;nrf905_Delay(1);//关闭SPI,保存写入的数据CSN=0;//SPI使能,保存写入的数据SpiWrite(WTA);//写数据至地址寄存器for(i=0;i<4;i++)//写入四字节地址写入与对方地址一样的地址{SpiWrite(TxAddress[i]);}CSN=1;//关闭SPI TRX_CE=1;//进入发送模式,启动射频发送nrf905_Delay(1);//进入ShockBurst发送模式后,芯片保存数据TRX_CE=0;//发送完成后返回ATANDBY模式while(DR!=1);nrf905_Delay(10);LED=0;nrf905_Delay(300);LED=1;nrf905_Delay(300);//发送后LED闪烁}60
//-------------------------------------判断数据接收状态-----------------------------------------------------unsignedcharCheckDR(void)//检查是否有新数据传入Data{DR=1;//通过对端口写1,可以使端口为输入状态,这51的特性。不熟悉者可以参阅51相关书籍作证(将DR端口设置为输入状态。)if(DR==1){DR=0;return1;}else{return0;}}//----------------------------NRF905接收到数据后读取保存----------------------------------------------------------voidRxPacket(void){uchari;nrf905_Delay(1);//TRX_CE=0;//设置905进入待机模式nrf905_Delay(100);TRX_CE=0;CSN=0;//使能SPInrf905_Delay(1);SpiWrite(RRP);//准备读取接收到的数据for(i=0;i<4;i++){TxRxBuf[i]=SpiRead();//通过SPI接口从905芯片读取数据}CSN=1;//禁用SPInrf905_Delay(10);TRX_CE=1;}//------------------------------------------voidclear(void)//清空接收数组{uchari;for(i=0;i<4;i++)TxRxBuf[i]=0;}60
//--------------------------------------------------------数据接收------------------------------------------------voidRX(void){clear();//清空接收数组nRF905Init();//初始化Config905();tf=0;SetRxMode();//设置为接收模式while(tf==0){if(DR){nrf905_Delay(10);RxPacket();if(TxRxBuf[1]==0x30){switch(TxRxBuf[0]){case1:wx_jieshou=1;break;case2:wx_jieshou=2;break;case3:wx_jieshou=3;break;}LED=0;nrf905_Delay(300);LED=1;nrf905_Delay(300);//接收到数据后闪烁tf=1;DR=0;}}}}9.2颜色传感器部分#include#defineucharunsignedchar#defineuintunsignedintsbittcs230_s2=P1^6;//TCS230S2接单片机P1.0sbittcs230_s3=P1^7;//TCS230S3接单片机P1.1sbittcs230_en=P3^0;//TCS230EN(E0)接GNDucharflat2=0;//颜色传感器函数声明60
/*===================================================================*/voidbaipingheng();voidceliang();voidjudge_colour(uintrb1,uintgb1,uintbb1);voidDelayMs(uintMs);//1MS基准延时程序voidbaipingheng();//白平衡子程序voidceliang();//实际颜色程序voidDelayMs(uintMs);uintryz,gyz,byz;//分别定义红色因子绿色因子蓝色因子uintrb,gb,bb;//RGB值/*====================================================================*//*====================================================================白平衡子程序====================================================================*/voidceliang(){//*********求R值************************************TH0=(65536-10000)/256;TL0=(65536-10000)%256;TH1=0;TL1=0;tcs230_s2=0;tcs230_s3=0;//选择红色滤光器tcs230_en=0;TR0=1;//10毫秒开始计时TR1=1;//开始计数while(TF0==0);//等待定时器溢出TF0=0;//清楚定时器0溢出标志TR0=0;//关闭定时0TR1=0;rb=(unsignedlong)(TH1*256+TL1)*255/ryz;if(rb>255)rb=255;//判断RGB值是否合法//***********求B值**************************************TH0=(65536-10000)/256;TL0=(65536-10000)%256;TH1=0;TL1=0;tcs230_s2=0;tcs230_s3=1;//选择蓝色滤光器60
TR0=1;//10毫秒开始计时TR1=1;//开始计数while(TF0==0);//等待定时器溢出TF0=0;//清楚定时器0溢出标志TR0=0;//关闭定时0TR1=0;bb=(unsignedlong)(TH1*256+TL1)*255/byz;if(bb>255)bb=255;//判断RGB值是否合法//***********求G值**************************************TH0=(65536-10000)/256;TL0=(65536-10000)%256;TH1=0;TL1=0;tcs230_s2=1;tcs230_s3=1;//选择绿色滤光器TR0=1;//10毫秒开始计时TR1=1;//开始计数while(TF0==0);//等待定时器溢出TF0=0;//清楚定时器0溢出标志TR0=0;//关闭定时0TR1=0;tcs230_en=1;gb=(unsignedlong)(TH1*256+TL1)*255/gyz;if(gb>255)gb=255;//判断RGB值是否合法}/*====================================================================白平衡子程序====================================================================*/voidbaipingheng(){//**************求取红色因子***********************TH0=(65536-10000)/256;TL0=(65536-10000)%256;TH1=0;TL1=0;tcs230_s2=0;tcs230_s3=0;//选择红色滤光器tcs230_en=0;TR0=1;//10毫秒开始计时TR1=1;//开始计数60
while(TF0==0);//等待定时器溢出TF0=0;//清处定时器0溢出标志TR0=0;//关闭定时0TR1=0;ryz=TH1*256+TL1;//其实这里的比例因子应该为255/(TH1*256+TL1)//**************求取蓝色因子***********************TH0=(65536-10000)/256;TL0=(65536-10000)%256;TH1=0;TL1=0;tcs230_s2=0;tcs230_s3=1;//选择蓝色滤光器TR0=1;//10毫秒开始计时TR1=1;//开始计数while(TF0==0);//等待定时器溢出TF0=0;//清楚定时器0溢出标志TR0=0;//关闭定时0TR1=0;byz=TH1*256+TL1;//其实这里的比例因子应该为255/(TH1*256+TL1)//**************求绿红色因子***********************TH0=(65536-10000)/256;TL0=(65536-10000)%256;TH1=0;TL1=0;tcs230_s2=1;tcs230_s3=1;//选择绿色滤光器TR0=1;//10毫秒开始计时TR1=1;//开始计数while(TF0==0);//等待定时器溢出TF0=0;//清楚定时器0溢出标志TR0=0;//关闭定时0TR1=0;tcs230_en=1;gyz=TH1*256+TL1;//其实这里的比例因子应该为255/(TH1*256+TL1)}/*====================================================================设定延时时间:x*1ms====================================================================*/60
voidDelayMs(uintMs){uinti,TempCyc;for(i=0;i25&&R<55)&&(G>25&&G<55)&&(B>32&&B<55)))黑白线判断黑272727红1694146蓝283772黄22718382================================================================*/voidjudge_colour(uintrb1,uintgb1,uintbb1){if(rb1>120&&gb1<80&&bb1<80)//判定是否为红色{flat2=1;}if(rb1<40&&gb1>20&&bb1>50)//判定是否为蓝色{flat2=2;60
}}9.3主程序部分9.3.1机器人A/*P1_0输出高电平-延时1.5ms1_1输出高电平-延时1.5ms静止P1_0输出高电平-延时1.7msP1_1输出高电平-延时1.3ms前进P1_0输出高电平-延时1.3msP1_1输出高电平-延时1.7ms后退P1_0输出高电平-延时1.5msP1_1输出高电平-延时1.7ms向后向左P1_0输出高电平-延时1.7msP1_1输出高电平-延时1.5ms向前向右P1_0输出高电平-延时1.3msP1_1输出高电平-延时1.3ms逆时针旋转P1_0输出高电平-延时1.7msP1_1输出高电平-延时1.7ms顺时针旋转*/#include#include"nrf905shoufa.h"#include"yanse.h"sbitkey1=P1^5;sbitj1=P1^0;//左轮sbitj2=P1^1;//右轮sbitleft2=P1^3;//左2(寻迹)13sbitleft1=P1^2;//左112sbitzhong=P1^4;//中14sbitright1=P3^7;//右137sbitright2=P3^6;//右2(寻迹)36//sbityou=P2^5;//右边的终点检测//sbitzuo=P2^7;//左边的终点检测//如果照到黑色物体红外对管引脚为低电平,白色——-高电平ucharnum=0;60
voiddelay_nus(unsignedinti);voiddelay_nms(unsignedintn);voidbackward(void);voidforward(void);voidleftward(void);voidrightward(void);voidbackward2(uintn);voidforward2(uintn);voidleftward2(uintn);voidrightward2(uintn);voidxunji(void);voidxunji_ht(void);voidforward3(uintn);voidting(uintn);voidjiansu();voidxunji_2(void);voidxunji_3(void);voidqidian_A(void);voiddelay(uint);voidjudge(uintrb1,uintgb1,uintbb1);voidfan_hui(charn,uchara,ucharm,ucharc,ucharh);voidchufa(uchark,ucharc);voidchufa_lan();voidanjian();voidhuan_xiang();//延时nmsvoiddelay(uintxms){uinta,b;for(a=xms;a>0;a--)for(b=xms;b>0;b--);}voiddelay_nus(unsignedinti)//延时nus{i=i/10;while(--i);60
}voiddelay_nms(unsignedintn){n=n+1;while(--n)delay_nus(900);//延时1ms,同时进行补偿}voidting(uintn){uinti;for(i=1;i<=n;i++){j1=1;//设置PC3输出高电平delay_nus(1500);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1500);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}}voidbackward2(uintn)//声明一个后退子函数{uinti;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/for(i=1;i<=n;i++){j1=1;//设置PC3输出高电平delay_nus(1700);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1300);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}}voidleftward2(uintn)//声明一个左转可调角度的函数60
{//45°(14)90°(27)135(41)180°(54)uchari;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/for(i=1;i<=n;i++){j1=1;//设置PC3输出高电平delay_nus(1300);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1300);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}}voidrightward2(uintn)//声明一个右转可调角度的函数{//45°(14)90°(27)135(41)180°(54)uchari;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/for(i=1;i<=n;i++){j1=1;//设置PC3输出高电平delay_nus(1700);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1700);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}}voidforward2(uintn)//声明一个前进子函数{uchari;60
/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/for(i=1;i<=n;i++){j1=1;//设置PC3输出高电平delay_nus(1300);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1700);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}}voidforward3(uintn)//声明一个前进子函数{uchari;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/for(i=1;i<=n;i++){j1=1;//设置PC3输出高电平delay_nus(1300);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1700);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}}voidbackward(void)//声明一个后退子函数{//uinti;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/j1=1;//设置PC3输出高电平delay_nus(1700);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1300);//延时0.0013s60
j2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}voidleftward(void)//声明一个左转函数{//uinti;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/j1=1;//设置PC3输出高电平delay_nus(1300);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1300);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}voidrightward(void)//声明一个右转函数{//uinti;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/j1=1;//设置PC3输出高电平delay_nus(1700);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1700);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}voidforward(void)//声明一个前进进子函数{//uinti;60
/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/j1=1;//设置PC3输出高电平delay_nus(1300);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1700);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}voidxunji(void)//循迹程序{forward();if((left1==0||left2==0)){rightward();}if((right1==0||right2==0)){leftward();}}voidxunji_2(void)//循迹程序{forward();if((left1==0||left2==0)){rightward();forward2(2);}if((right1==0||right2==0)){leftward();forward2(2);}}voidxunji_ht(void)//循迹后退程序60
{backward();if(left1==0||left2==0)rightward();if(right1==0||right2==0)leftward();}/*********************************************************************************功能:从一个待存区移动到另一个待存区************************************************************************************/voidhuan_xiang(){uchari=0;while(1){xunji();if((zhong==0&&left2==0)||(zhong==0&&right2==0)||(left2==0&&right2==0)){i++;if(i==2){backward2(13);ting(3);rightward2(39);ting(3);for(i=0;i<3;i++){TxPacket(TxRxBuf,1);//无线发送信号1}while(1){RX();//等待接收if(wx_jieshou==3)break;}if(wx_jieshou==3){60
break;}}forward2(32);}}}/*********************************************************************************功能:从等待区出发k=1从红色区域出发k=2从蓝色区域出发c=1第一大环调用,c=2第二个大环调用**********************************************************************************/voidchufa(uchark,ucharc){ucharn=0,m=0,h,b=0;uchari=0,flat1=0,a=1,d=20;h=k;while(a){switch(m){case0:xunji();break;//循迹case1:xunji_2();break;//循迹2}if(b==1){celiang();//颜色测试judge_colour(rb,gb,bb);//判断颜色if(flat2==1||flat2==2){m=0;ting(3);forward2(5);switch(c){case1:fan_hui(n,1,1,1,h);break;//调用返回程序case2:fan_hui(n,1,1,2,h);60
break;}a=0;}}if(flat1==0){if((zhong==0&&left2==0&&right2==0)||(zhong==0&&right2==0&&right1==0)||(left2==0&&right2==0&&left1==0)||(left2==0&&right2==0&&right1==0)){i++;if(c==1)//第一层{ting(5);forward2(28);ting(5);if(i==1){switch(k)//第一个十字路口{case1:rightward2(20);break;//右转从红色区域出发case2:leftward2(20);break;//左转从蓝色区域出发}}if(i==2){leftward2(21);}ting(5);forward2(17);if(i==2){flat1=1;i=0;m=1;}}60
if(c==2)//第二层{if(i==1){ting(5);forward2(28);ting(5);switch(k)//第一个路口{case1:rightward2(20);break;//右转从红色区域出发case2:leftward2(20);break;//左转从蓝色区域出发}ting(5);forward2(17);}if(i==2){ting(5);forward2(6);ting(5);while(d--){xunji();if((zhong==0&&left2==0&&right2==0)||(zhong==0&&right2==0&&right1==0)||(left2==0&&right2==0&&left1==0)||(left2==0&&right2==0&&right1==0))break;}ting(5);forward2(30);ting(5);leftward2(19);ting(5);forward2(13);flat1=1;i=0;m=1;}}60
}}if(flat1==1){if((zhong==0)){ting(1);rightward2(1);forward2(8);ting(5);rightward2(11);if(n>1){rightward2(2);}ting(5);b=1;n++;if(n==6)flat1=2;}}}}/*******************************************************************************************按键程序*********************************************************************************************/voidanjian(){while(1){if(key1==0)//按键按下{delay(7);//延时过抖动其if(key1==0){break;}}}60
}/***************************************************************************功能:检测到色块后,返回n走过小梯形的个数a=1返回时遇到小梯形的黑线时左转a=2返回遇到小梯形黑线时右转m=1从左边返回时右转走向单通道m=2从右边返回时左转走向单通道c=1从第一层返回c=2从第二层返回h=1从红色区域出发h=2从蓝色区域出发a=1,m=1c=1第一层左边返回a=2,m=2c=2第二层右边返回***************************************************************************/voidfan_hui(charn,uchara,ucharm,ucharc,ucharh){uchark=1,j=0,i=0,t=1,b=0,e=20;//b用于在第二层返回到单通道,第三根黑线时跳出循环使用ting(5);leftward2(41);ting(5);while(t){switch(k){case1:xunji_2();break;case2:xunji();break;}if(n==0&&((zhong==0&&left2==0&&right2==0)||(zhong==0&&left2==0&&left1==0)||(left2==0&&right2==0&&right1==0))){//回到单通道前ting(5);if(c==1){if(flat2==1)//如果flat=1(红色)无线发送数据,使另一辆车移位;{for(i=0;i<5;i++){TxPacket(TxRxBuf,1);//60
无线发送信号1}i=0;while(1){RX();//等待接收数据if(wx_jieshou==1)break;}}}if(c==2){if((flat2==2)&&(h==1))//从红色区域出发,检测到蓝色物体时发送信号{for(i=0;i<5;i++){TxPacket(TxRxBuf,1);//无线发送信号1}i=0;while(1){RX();//等待接收数据if(wx_jieshou==1)break;}}if((flat2==1)&&(h==2))//从蓝色区域出发,检测到红色物体时发送信号{for(i=0;i<5;i++){TxPacket(TxRxBuf,1);//无线发送信号1}i=0;while(1){RX();//等待接收数据60
if(wx_jieshou==1)break;}}}forward2(30);leftward2(4);ting(5);switch(m){case1:rightward2(20);break;case2:leftward2(20);break;}ting(5);forward2(12);ting(2);if(c==2){while(t){xunji();if((zhong==0&&left2==0&&right2==0)||(zhong==0&&right2==0&&right1==0)||(left2==0&&right2==0&&left1==0)||(left2==0&&right2==0&&right1==0)){ting(5);forward2(12);ting(5);break;}}}while(t){xunji();if(j==0){if((zhong==0&&left2==0&&right2==0)||(zhong==0&&right2==0&&right1==0)||(left2==0&&right2==0&&left1==0)||(left2==0&&right2==0&&right1==0)){ting(3);60
forward2(15);while(1){xunji();if((zhong==0&&left2==0&&right2==0)||(zhong==0&&right2==0&&right1==0)||(left2==0&&right2==0&&left1==0)||(left2==0&&right2==0&&right1==0)){ting(5);break;}}//ting(5);switch(flat2)//flat2=1红色flat=2蓝色{case1:leftward2(21);ting(5);break;case2:rightward2(21);ting(5);break;}forward2(10);j=1;}}if(j==1){if((zhong==0&&left2==0&&right2==0)||(zhong==0&&right2==0&&right1==0)||(left2==0&&right2==0&&left1==0)||(left2==0&&right2==0&&right1==0)){//ting(5);forward2(17);ting(5);backward2(30);ting(5);for(i=0;i<10;i++){TxPacket(TxRxBuf,3);}i=0;wx_jieshou=0;60
while(1){RX();//等待接收下一个信号RX();if(wx_jieshou==1||wx_jieshou==3)break;}ting(5);rightward2(39);ting(5);t=0;//跳出另一个循环标志n=-1;j=2;}}}}if(n>0&&zhong==0){n--;ting(3);switch(a){case1:leftward2(1);break;case2:rightward2(1);break;}forward2(8);ting(5);switch(a){case1:leftward2(15);break;case2:rightward2(15);break;}ting(5);if(n==0)k=2;}}}/*--------------------主程序-------------------------------------------------------*/60
voidmain()//A车先放在蓝色区域{nRF905Init();//初始化Config905();TMOD=0x51;//设定T0以工作方式1定时10毫秒baipingheng();//上电时先白平衡一次anjian();//按下按键小车开始运动//chufa(1,2);chufa(2,1);//从蓝色区域出发往第一层走if(wx_jieshou==1){switch(flat2)//flat=1从第一层回到红色区域flat=2从第一层回到蓝色区域{//chufa(1,2)1:从红色区域出发2:从第二层出发case1:flat2=0;huan_xiang();chufa(2,2);while(1);//换向后从蓝色区域出发往第二层走case2:flat2=0;huan_xiang();chufa(1,2);while(1);//换向后从红色区域出发往第二层走}}if(wx_jieshou==3){switch(flat2){case1:flat2=0;chufa(1,2);while(1);//从红色区域出发往第二层走case2:flat2=0;chufa(2,2);while(1);//从蓝色区域出发往第二层走}}}/***********************************************************************if(flat1==3)60
{if((zhong==0&&left2==0)||(zhong==0&&right2==0)||(left2==0&&right2==0)){ting(3);i++;if(i==3){while(1);}forward2(25);ting(3);leftward2(19);ting(3);forward2(18);}}if(k==1){while(j--){celiang();//颜色测试judge_colour(rb,gb,bb);//判断颜色if(flat2==1||flat2==2);{ting(20);break;}}}*//*while(a){switch(m){case0:xunji();break;case1:xunji_2();break;}celiang();60
//颜色测试judge_colour(rb,gb,bb);//判断颜色if(flat2==1||flat2==2){//ting(5);forward2(5);fan_hui(n);//调用返回程序}if(flat1==0){if((zhong==0&&left2==0&&right2==0)||(zhong==0&&right2==0&&right1==0)||(left2==0&&left1==0)&&left2==0){ting(3);forward2(27);ting(3);leftward2(20);ting(3);forward2(25);i++;if(i==2){flat1=1;i=0;m=1;}}}if(flat1==1){if((zhong==0)){ting(3);forward2(8);ting(3);rightward2(12);ting(3);n++;if(n==6)flat1=2;}60
}}*/9.3.2机器人B主程序/*P1_0输出高电平-延时1.5ms1_1输出高电平-延时1.5ms静止P1_0输出高电平-延时1.7msP1_1输出高电平-延时1.3ms前进P1_0输出高电平-延时1.3msP1_1输出高电平-延时1.7ms后退P1_0输出高电平-延时1.5msP1_1输出高电平-延时1.7ms向后向左P1_0输出高电平-延时1.7msP1_1输出高电平-延时1.5ms向前向右P1_0输出高电平-延时1.3msP1_1输出高电平-延时1.3ms逆时针旋转P1_0输出高电平-延时1.7msP1_1输出高电平-延时1.7ms顺时针旋转*/#include#include"nrf905shoufa.h"#include“YANSE.H”#defineucharunsignedchar#defineuintunsignedintsbitkey1=P1^5;sbittcs230_s2=P1^6;//TCS230S2接单片机P1.0sbittcs230_s3=P1^7;//TCS230S3接单片机P1.1sbittcs230_en=P3^0;//TCS230EN(E0)接GNDsbitj1=P1^0;//左轮sbitj2=P1^1;//右轮sbitleft2=P1^3;//左2(寻迹)13sbitleft1=P1^2;//左112sbitzhong=P1^4;//中14sbitright1=P3^7;//右137sbitright2=P3^6;//右2(寻迹)36//sbityou=P2^5;//右边的终点检测//sbitzuo=P2^7;//左边的终点检测//如果照到黑色物体红外对管引脚为低电平,白色——-高电平60
ucharnum=0;ucharflat2=0;voiddelay_nus(unsignedinti);voiddelay_nms(unsignedintn);voidbackward(void);voidforward(void);voidleftward(void);voidrightward(void);voidbackward2(uintn);voidforward2(uintn);voidleftward2(uintn);voidrightward2(uintn);voidxunji(void);voidxunji_ht(void);voidforward3(uintn);voidting(uintn);voidjiansu();voidxunji_2(void);voidqidian_A(void);voiddelay(uint);intjudge(uintrb1,uintgb1,uintbb1);voidfan_hui(charn,uchara,ucharm,ucharc,ucharh);voidhuan_xiang();voidchufa(uchark,ucharc);//延时nmsvoiddelay(uintxms){uinta,b;for(a=xms;a>0;a--)for(b=xms;b>0;b--);}voiddelay_nus(unsignedinti)//延时nus{i=i/10;while(--i);60
}voiddelay_nms(unsignedintn){n=n+1;while(--n)delay_nus(900);//延时1ms,同时进行补偿}voidting(uintn){uinti;for(i=1;i<=n;i++){j1=1;//设置PC3输出高电平delay_nus(1500);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1500);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}}voidbackward2(uintn)//声明一个后退子函数{uinti;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/for(i=1;i<=n;i++){j1=1;//设置PC3输出高电平delay_nus(1700);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1300);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}}voidleftward2(uintn)//声明一个左转可调角度的函数{//45°(14)90°(27)60
135(41)180°(54)uinti;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/for(i=1;i<=n;i++){j1=1;//设置PC3输出高电平delay_nus(1300);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1300);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}}voidrightward2(uintn)//声明一个右转可调角度的函数{//45°(14)90°(27)135(41)180°(54)uinti;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/for(i=1;i<=n;i++){j1=1;//设置PC3输出高电平delay_nus(1700);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1700);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}}voidforward2(uintn)//声明一个前进子函数{uinti;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/for(i=1;i<=n;i++){j1=1;//设置PC3输出高电平delay_nus(1300);//延时0.0017s60
j1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1700);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}}voidforward3(uintn)//声明一个前进子函数{uinti;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/for(i=1;i<=n;i++){j1=1;//设置PC3输出高电平delay_nus(1300);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1700);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}}voidbackward(void)//声明一个后退子函数{//uinti;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/j1=1;//设置PC3输出高电平delay_nus(1700);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1300);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}voidleftward(void)//声明一个左转函数60
{//uinti;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/j1=1;//设置PC3输出高电平delay_nus(1300);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1300);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}voidrightward(void)//声明一个右转函数{//uinti;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/j1=1;//设置PC3输出高电平delay_nus(1700);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1700);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms}voidforward(void)//声明一个前进进子函数{//uinti;/*声明定义16位无符号整型变量i,在开始时i被设为1,并在每次重复的最后被增加1。在循环重复前,如果i大于65,则循环结束。*/j1=1;//设置PC3输出高电平delay_nus(1300);//延时0.0017sj1=0;//设置PC3输出低电平j2=1;//设置PC2输出高电平delay_nus(1700);//延时0.0013sj2=0;//设置PC2输出低电平delay_nms(20);//延时20ms60
}voidxunji(void)//循迹程序{forward();if(left1==0||left2==0)rightward();if(right1==0||right2==0)leftward();}voidxunji_2(void)//循迹程序{forward();if(left1==0||left2==0){rightward();forward2(2);}if(right1==0||right2==0){leftward();forward2(2);}}voidxunji_ht(void)//循迹程序{backward();if(left2==0)leftward();if(right2==0)rightward();if(left2==1&&zhong==1&&right2==1){backward();if(left1==0)leftward();if(right1==0)rightward();}}/***************************************************************************功能:检测到色块后,返回n走过小梯形的个数60
a=1返回时遇到小梯形的黑线时左转a=2返回遇到小梯形黑线时右转m=1从左边返回时右转走向单通道m=2从右边返回时左转走向单通道c=1从第一层返回c=2从第二层返回h=1从红色区域出发h=2从蓝色区域出发a=1,m=1c=1第一层左边返回a=2,m=2c=2第二层右边返回***************************************************************************/voidfan_hui(charn,uchara,ucharm,ucharc,ucharh){uchark=1,j=0,i=0,t=1,b=0;//b用于在第二层返回到单通道,第三根黑线时跳出循环使用ting(5);leftward2(41);ting(5);while(t){switch(k){case1:xunji_2();break;case2:xunji();break;}if(n==0&&((zhong==0&&left2==0&&right2==0)||(zhong==0&&left2==0&&left1==0)||(left2==0&&right2==0&&right1==0))){//回到单通道前ting(5);if(c==1){if((flat2==2)&&(h==1))//从红色区域出发,检测到蓝色物体时发送信号{for(i=0;i<5;i++){TxPacket(TxRxBuf,1);//无线发送信号1}i=0;while(1){60
RX();//等待接收数据if(wx_jieshou==1)break;}wx_jieshou=0;}if((flat2==1)&&(h==2))//从蓝色区域出发,检测到红色物体时发送信号{for(i=0;i<5;i++){TxPacket(TxRxBuf,1);//无线发送信号1}i=0;while(1){RX();//等待接收数据if(wx_jieshou==1)break;}wx_jieshou=0;}}if(c==2){if((flat2==2)&&(h==1))//从红色区域出发,检测到蓝色物体时发送信号{for(i=0;i<5;i++){TxPacket(TxRxBuf,1);//无线发送信号1}i=0;while(1){RX();//等待接收数据if(wx_jieshou==1)break;}wx_jieshou=0;}if((flat2==1)&&(h==2))//60
从蓝色区域出发,检测到红色物体时发送信号{for(i=0;i<5;i++){TxPacket(TxRxBuf,1);//无线发送信号1}i=0;while(1){RX();//等待接收数据if(wx_jieshou==1)break;}wx_jieshou=0;}}forward2(28);leftward2(4);ting(5);switch(m){case1:rightward2(20);break;case2:leftward2(20);break;}ting(5);forward2(10);ting(2);if(c==2){while(t){xunji();if((zhong==0&&left2==0&&right2==0)||(zhong==0&&right2==0&&right1==0)||(left2==0&&right2==0&&left1==0)||(left2==0&&right2==0&&right1==0)){ting(5);forward2(12);ting(5);break;}}60
}while(t){xunji();if(j==0){if((zhong==0&&left2==0&&right2==0)||(zhong==0&&right2==0&&right1==0)||(left2==0&&right2==0&&left1==0)||(left2==0&&right2==0&&right1==0)){ting(3);forward2(15);while(1){xunji();if((zhong==0&&left2==0&&right2==0)||(zhong==0&&right2==0&&right1==0)||(left2==0&&right2==0&&left1==0)||(left2==0&&right2==0&&right1==0)){ting(5);//forward2(5);break;}}ting(5);switch(flat2)//flat2=1红色flat=2蓝色{case1:leftward2(20);ting(3);break;case2:rightward2(20);ting(3);break;}forward2(10);j=1;}}if(j==1){if((zhong==0&&left2==0)||(zhong==0&&right2==0)||(left2==0&&right2==0))//回到终点{60
forward2(17);ting(5);backward2(30);ting(5);for(i=0;i<10;i++){TxPacket(TxRxBuf,3);//发送信号让另一辆车运动}i=0;wx_jieshou=0;while(1){RX();//等待接收下一个信号if(wx_jieshou==1||wx_jieshou==3)break;}ting(5);rightward2(39);ting(5);t=0;//跳出另一个循环标志n=-1;j=2;}}}}if(n>0&&zhong==0){n--;ting(3);switch(a){case1:leftward2(1);break;case2:rightward2(1);break;}forward2(8);ting(5);switch(a){case1:leftward2(14);break;case2:rightward2(14);break;60
}ting(5);if(n==0)k=2;}}}/*********************************************************************************功能:从一个待存区移动到另一个待存区************************************************************************************/voidhuan_xiang(){ucharm=0,i=0;while(1){xunji();if((zhong==0&&left2==0)||(zhong==0&&right2==0)||(left2==0&&right2==0)){i++;if(i==2){ting(5);backward2(13);ting(5);rightward2(39);ting(5);for(i=0;i<3;i++){TxPacket(TxRxBuf,1);//无线发送信号1}while(1){RX();//等待接收if(wx_jieshou==3)break;}if(wx_jieshou==3){break;60
}}forward2(40);}}}/*********************************************************************************功能:从等待区出发k=1从红色区域出发k=2从蓝色区域出发c=1第一大环调用,c=2第二个大环调用**********************************************************************************/voidchufa(uchark,ucharc){ucharn=0,m=0,h,b=0;uchari=0,flat1=0,a=1,d=20;h=k;while(a){switch(m){case0:xunji();break;//循迹case1:xunji_2();break;//循迹2}if(b==1){celiang();//颜色测试judge_colour(rb,gb,bb);//判断颜色if(flat2==1||flat2==2){m=0;ting(3);forward2(5);switch(c){case1:fan_hui(n,2,2,1,h);break;//第一层右边返回60
case2:fan_hui(n,2,2,2,h);break;//第二层右边返回}//调用返回程序a=0;}}if(flat1==0){if((zhong==0&&left2==0&&right2==0)||(zhong==0&&right2==0&&right1==0)||(left2==0&&right2==0&&left1==0)||(left2==0&&right2==0&&right1==0)){i++;if(c==1)//第一层{ting(5);forward2(28);ting(5);if(i==1){switch(k)//第一个十字路口{case1:rightward2(20);break;//右转从红色区域出发case2:leftward2(20);break;//左转从蓝色区域出发}}if(i==2){rightward2(21);}ting(5);forward2(17);if(i==2){flat1=1;i=0;m=1;}60
}if(c==2)//第二层{if(i==1){ting(5);forward2(28);ting(5);switch(k)//第一个路口{case1:rightward2(20);break;//右转从红色区域出发case2:leftward2(20);break;//左转从蓝色区域出发}ting(5);forward2(17);}if(i==2){ting(5);forward2(6);ting(5);while(d--){xunji();if((zhong==0&&left2==0&&right2==0)||(zhong==0&&right2==0&&right1==0)||(left2==0&&right2==0&&left1==0)||(left2==0&&right2==0&&right1==0))break;}ting(5);forward2(30);ting(5);rightward2(19);ting(5);forward2(10);flat1=1;i=0;m=1;}}60
}}if(flat1==1){if((zhong==0)){ting(1);leftward2(1);forward2(8);ting(5);leftward2(11);if(n>1){leftward2(2);}ting(5);b=1;n++;if(n==6)flat1=2;}}}}/*---------------------------------------------------------------------------主程序B车开始时停放在红色区域------------------------------------------------------------------------------------*/voidmain(){uchara=1;nRF905Init();//初始化Config905();TMOD=0x51;//设定T0以工作方式1定时10毫秒baipingheng();//上电时先白平衡一次while(1){if(a==1)//第一层{RX();60
if(wx_jieshou==1)//无线接收到1从原点出发,接收到3先走到另一个暂存区域{huan_xiang();//从一个待存区移动到另一个待存区flat2=0;chufa(2,1);//2:从蓝色区域出发1:往第一层a=2;}if(wx_jieshou==3){flat2=0;chufa(1,1);//从红色区域出发往第一层a=2;}}if(a==2)//进入第二层{if(flat2==1)//从第一层回到红色区域{if(wx_jieshou==1){huan_xiang();//从一个待存区移动到另一个待存区flat2=0;chufa(2,2);//从蓝色区域出发a=3;}if(wx_jieshou==3){flat2=0;chufa(1,2);//从蓝色区域出发a=3;}}if(flat2==2)//从第二层回到蓝色区域{if(wx_jieshou==1)60
{huan_xiang();//从一个待存区移动到另一个待存区flat2=0;chufa(1,2);//从红色区域出发a=3;}if(wx_jieshou==3){flat2=0;chufa(2,2);//从蓝色区域出发a=3;}}while(1);}}}/*while(1){switch(m){case0:xunji();break;case1:xunji_2();break;}celiang();//颜色测试judge_colour(rb,gb,bb);//判断颜色if(flat2==1||flat2==2){m=0;//ting(3);forward2(5);fan_hui(n);//调用返回程序}if(flat1==0){60
if((zhong==0&&left2==0)||(zhong==0&&right2==0)||(left2==0&&right2==0)){//ting(3);forward2(27);ting(3);rightward2(20);ting(3);forward2(25);i++;}if(i==2){flat1=1;i=0;m=1;}}if(flat1==1){if((zhong==0)){ting(3);forward2(8);ting(3);leftward2(12);ting(3);n++;if(n==6)flat1=2;}}}}/***************************************************************************功能:检测到色块后,返回n走过小梯形的个数a=1返回时遇到小梯形的黑线时左转a=2返回遇到小梯形黑线时右转60
m=1从左边返回时右转走向单通道m=2从右边返回时左转走向单通道a=1,m=1左边返回a=2,m=2右边返回***************************************************************************voidfan_hui(ucharn,uchara,ucharm){uchark=1,j=0,t=0,i;ting(3);leftward2(41);ting(3);while(1){switch(k){case1:xunji_2();break;case2:xunji();break;}if(n==0&&((zhong==0&&left2==0&&right2==0)||(zhong==0&&left2==0&&left1==0)||(left2==0&&right2==0&&right1==0))){//回到单通道前ting(3);forward2(26);ting(3);switch(m){case1:rightward2(20);break;case2:leftward2(20);break;}ting(3);forward2(8);while(1){xunji();if(j==0){if((zhong==0&&left2==0)||(zhong==0&&right2==0)||(left2==0&&right2==0)){//ting(2);60
forward2(26);ting(5);switch(flat2)//flat2=1红色flat=2蓝色{case1:leftward2(22);ting(3);break;case2:rightward2(20);ting(3);break;}forward2(20);j=1;}}if(j==1){if((zhong==0&&left2==0)||(zhong==0&&right2==0)||(left2==0&&right2==0))//回到终点{forward2(20);ting(1);backward2(30);ting(3);for(i=0;i<20;i++){TxPacket(TxRxBuf,2);//发送信号让另一辆车运动}//TxPacket(TxRxBuf,2);//wx_jieshou=0;while(1){RX();//等待接收下一个信号if(wx_jieshou==3)break;}rightward2(39);t=1;break;}}}if(t==1)60
break;}if(n>0&&zhong==0){n--;ting(1);switch(a){case1:leftward2(1);break;case2:rightward2(1);break;}forward2(8);ting(3);switch(a){case1:leftward2(13);break;case2:rightward2(13);break;}ting(3);if(n==0)k=2;}}}}*/60'