之前做过的红外小车避障可以做个参考,是固定的障碍,要过障碍还是要通过算法,要自己算一下,
控制小车的运动一直是实验室中的重点项目之一,这次我们进行的项目就是运用红外检测模块对小车进行运动控制,从而让小车达到自动前进避开障碍物的目的。此次实验我们要用到AT89C51 单片机来控制,实现的目标为让小车自动走出迷宫以及记录障碍物遇到的个数。
基本内容
在一个有障碍物的区域内,小车可以自由前进,不碰撞到任何障碍物。
在行进的过程中,记录下遇到障碍物的个数
2.扩展内容
小车在光源的引导下,进入停车区到达车库并停止
小车的行走电机由两个H桥驱动,Q1到Q6是左边电机的驱动电路,Q3,Q4,Q7,Q8,Q11,Q12是右边电机的驱动电路,电路如图所示,图中的逻辑门电路U6A,U6B,U6C.U6D构成了一个逻辑互锁电路,避免H桥驱动电路中Q3与Q4同时导通,使得Q7,Q8,Q11,Q12全部导通,造成短路。其执行时Q3的基极为高电平时,Q3导通Q8,Q11也导通,右电机反转。当Q4的基极为高电平时,Q4导通Q7,Q12也导通,右电机正转。
第二节 红外模块介绍要保证小车在前进运动中正确地避开障碍物,至少需要三组红外传感器来探测障碍物是在左面还是右面或者是在前方,并且三组传感器还要能探测到小车正前方的障碍物。为达到此要求,传感器的使用方案如下: 在小车的正中向前的方向安装红外接收模块,在小车前面朝左右方向各安装-一 个发射模块。安装时要注意调整安装位置,要确保反射回来的红外线能被接收到,所以要调整好方位。如果三个发射模块同时发射,接受模块将无法区分所接收到的信号来自何方。如果我们采用时分复用的方法就可以解决这个问题,让他们交替工作,只要交替的速度快就可以保证检测的正确性。 L为“1”表示接收模块接收到左面的反射信号,为“0”表示没有 接收到反射信号R为“1”表示接收模块接收到右面的反射信号,为“0”表示没有接收到反射信号。程序中除了要对判断是否有障碍外,还要对障碍物的方位做出准确的判断才能使小车做出正确的避让。先选择三个标志位,用于表示前,左,右 
是否有障碍。有障碍置1,无障碍置0,最好是选择相邻的位,便于逻辑判断。 左边为红外发射模块电路图,右为红外接受电路图。
第三章 软件程序
第一节 流程图编写本系统采用汇编语言编程。软件程序由主程序,PWM调速程序,红外模块控制程序,判断障碍物方位程序,障碍物个数显示程序和延时子程序组成。小车开机,检测先进行PWM调速,在对障碍物的方位进行检测从而对小车的运动状态进行调整,最后在对障碍物个数进行计数并且顺利走出搭建迷宫以完成实验。实验流程图如下:
第二节 程序编写PWM调速: 调用调速模块,设置各项初值以及PWM调速的频率,最后改变其占空比来实现对小车速度的控制。 控制障碍物方位; 设置一个寄存器20H,使其高五位清零,再把三个传感器分别检测到障碍物个数时的情况列举出来,设置有障碍物为1没有障碍物为0,并和20H相与,最后得到检测障碍物方向的结论。 障碍物数目显示: 在转向时说明是检测到了前方有障碍物,让R7置1,转向变为直行说明前方已经没有了障碍物,就检测R7是否为1,如果为1,就说明有障碍物,那显示就加一 红外检测: 先关闭所有发射端口,设定发送脉冲数目,然后接受寄存器清零,然后启动第一个发射模块,然后给延时,判断是否接受到反射信号,接收到就脉冲数目加1,没有就停止发射,延时,然后判断是否发射10次,没有就继续启动发射模块重复直到10次发射完毕,然后判断接受脉冲数目是否等于或者大于2(等于或者大于2是为了检测更加灵敏),小于2就是没有障碍物,等于或者大于2就是有障碍物,另外两个模块也是这样。 附录1 传感器接口与其引脚功能
单片机源程序如下: - CCON DATA 0D8H
- CMOD DATA 0D9H
- CCAPM0 DATA 0DAH
- CCAPM1 DATA 0DBH
- CCAPM2 DATA 0DCH
- CCAPM3 DATA 0DDH
- CCAPM4 DATA 0DEH
- CL DATA 0E9H
- CCAP0L DATA 0EAH
- CCAP1L DATA 0EBH
- CCAP2L DATA 0ECH
- CCAP3L DATA 0EDH
- CCAP4L DATA 0EEH
- CH DATA 0F9H
- CCAP0H DATA 0FAH
- CCAP1H DATA 0FBH
- CCAP2H DATA 0FCH
- CCAP3H DATA 0FDH
- CCAP4H DATA 0FEH
-
- ORG 0000H
- LJMP MAIN
- ORG 0030H
-
- MAIN:
-
- MOV 20H,#00H
- LCALL PWM // PWM初始化
- N1:
-
- CLR P3.2 //关闭红外发射端口P3.2
- CLR P3.4 //关闭红外发射端口P3.4
- CLR P3.7 //关闭红外发射端口P3.7
- MOV R0,#10 //设定脉冲发射数目
- MOV R1,#00 //接收寄存器清零
- LOOP0:
- SETB P3.7 //打开红外发射端口P3.7
- LCALL DE600U //延时
- JB P2.3,LOOP1//判断接收端口P2.3是否为1,不是则跳转到LOOP1
- INC R1 //接收端口为1,R1加一
- LOOP1:
- CLR P3.7 //关闭红外发射端口P3.7
- LCALL DE600U //延时
- DJNZ R0,LOOP0 //判断R0减一是否为0不为零则跳转到LOOP0
- CJNE R1,#2,LOOP2 //判断R1是否等于2,不等则跳转
- LOOP2:
-
- JC N2 //有进位、即CF=1,则跳转N2
- SETB 02H //02H置1
- N2:
-
- CLR P3.2 //关闭红外发射端口P3.2
- CLR P3.4 //关闭红外发射端口P3.4
- CLR P3.7 //关闭红外发射端口P3.7
- MOV R2,#10 //设定脉冲发射数目
- MOV R3,#00 //接收寄存器清零
- LOOP3:
- SETB P3.4 //打开红外发射端口P3.4
- LCALL DE600U //延时
- JB P3.5,LOOP4//判断接收端口P3.5是否为1,不是则跳转到LOOP4
- INC R3 //接收端口为1,R3加一
- LOOP4:
- CLR P3.4 //关闭红外发射端口P3.4
- LCALL DE600U //延时
- DJNZ R2,LOOP3 //判断R2减一是否为0不为零则跳转到LOOP3
- CJNE R3,#2,LOOP5 //判断R3是否等于2,不等则跳转到LOOP5
- LOOP5:
-
- JC MAIN1 //有进位、即CF=1,则跳转MAIN1
- SETB 01H //01H置1
- MAIN1:
-
- CLR P3.2 //关闭红外发射端口P3.2
- CLR P3.4 //关闭红外发射端口P3.4
- CLR P3.7 //关闭红外发射端口P3.7
- MOV R4,#10 //设定脉冲发射数目
- MOV R5,#00 //接收寄存器清零
- LOOP6:
- SETB P3.2 //打开红外发射端口P3.2
- LCALL DE600U //延时
- JB P3.3,LOOP7//判断接收端口P3.3是否为1,不是则跳转到LOOP7
- INC R5 //接收端口为1,R5加一
- LOOP7:
- CLR P3.2 //关闭红外发射端口P3.2
- LCALL DE600U //延时
- DJNZ R4,LOOP6 //判断R4减一是否为0不为零则跳转到LOOP6
- CJNE R5,#2,LOOP8 //判断R5是否等于2,不等则跳转到LOOP8
- LOOP8:
-
- JC PD//有进位、即CF=1,则跳转PD
- SETB 00H //00H置1
-
- PD:
-
- ANL 20H,#07H //把20H里的值和07H相与
- MOV A,20H //把20H里的值给A
- CJNE A,#00H, PD0 //判断A是否等于00H,不等则跳转到PD0
- LCALL mansu //进入直行慢速子程序
- CJNE R7,#01H,SL //判断R7是否等于01H,不等则跳转到SL
- LCALL JSXS //进入计数显示子程序
- LJMP MAIN //跳转到MAIN
- PD0:
- CJNE A,#01H,PD1 //判断A是否等于01H,不等则跳转到PD1
- LCALL mansu1 //进入直行慢速1子程序
- CJNE R7,#01H,SL //判断R7是否等于01H,不等则跳转到SL
- LCALL JSXS //进入计数显示子程序
- LJMP MAIN //跳转到MAIN
- PD1:
- CJNE A,#02H,PD2 //判断A是否等于02H,不等则跳转到PD2
- LCALL mansu2 //进入直行慢速2子程序
- CJNE R7,#01H,SL //判断R7是否等于01H,不等则跳转到SL
- LCALL JSXS //进入计数显示子程序
- LJMP MAIN //跳转到MAIN
- PD2:
- CJNE A,#03H,PD3 //判断A是否等于03H,不等则跳转到PD3
- LCALL mansu //进入直行慢速子程序
- CJNE R7,#01H,SL //判断R7是否等于01H,不等则跳转到SL
- LCALL JSXS //进入计数显示子程序
- LJMP MAIN //跳转到MAIN
- PD3:
- CJNE A,#04H,PD4 //判断A是否等于04H,不等则跳转到PD4
- LCALL YZ //进入右转子程序
- MOV R7,#01H //给R7赋值01H
- LJMP MAIN //跳转到MAIN
- PD4:
- CJNE A,#05H,PD5 //判断A是否等于05H,不等则跳转到PD5
- LCALL ZZ //进入左转子程序
- MOV R7,#01H //给R7赋值01H
- LJMP MAIN //跳转到MAIN
- PD5:
- CJNE A,#06H,PD6 //判断A是否等于06H,不等则跳转到PD6
- LCALL YZ //进入右转子程序
- MOV R7,#01H //给R7赋值01H
- LJMP MAIN //跳转到MAIN
- PD6:
- CJNE A,#07H,SL //判断A是否等于07H,不等则跳转到SL
- LCALL YZ //进入右转子程序
- MOV R7,#01H //给R7赋值01H
- SL:
- LJMP MAIN //跳转到MAIN
- DE600U: //延时子程序
- MOV 30H,#200
- K1: NOP
- DJNZ 30H,K1
- RET
- DE: //延时子程序
- MOV 33H,#10
- K4: MOV 31H,#123
- K2: MOV 32H,#200
- K3: DJNZ 32H,K3
- DJNZ 31H,K2
- DJNZ 33H,K4
- RET
- DEL3S: MOV 48H,#60
- DEL0: MOV 49H,#123
- DEL1: MOV 50H,#200
- DEL2: DJNZ 50H,DEL2
- DJNZ 49H,DEL1
- DJNZ 48H,DEL0
- RET
- ST: SETB P1.4 //小车停止程序
- SETB P1.5
- SETB P1.6
- SETB P1.7
- RET
- mansu: //前进慢速子程序
- MOV CCON,#00H
- LCALL ST
- MOV CCAPM1,#00H
- MOV CCAPM3,#00H
- MOV CCAP2H,#48
- MOV CCAPM2,#42H
- MOV CCAP4H,#30
- MOV CCAPM4,#42H
- MOV CCON,#40H
- RET
- mansu1:
- MOV CCON,#00H
- LCALL ST
- MOV CCAPM1,#00H
- MOV CCAPM3,#00H
- MOV CCAP2H,#35
- MOV CCAPM2,#42H
- MOV CCAP4H,#20
- MOV CCAPM4,#42H
- MOV CCON,#40H
- RET
- mansu2:
- MOV CCON,#00H
- LCALL ST
- MOV CCAPM1,#00H
- MOV CCAPM3,#00H
- MOV CCAP2H,#40
- MOV CCAPM2,#42H
- MOV CCAP4H,#30
- MOV CCAPM4,#42H
- MOV CCON,#40H
- RET
- YZ: //右转子程序
- MOV CCON,#00H
- LCALL ST
- MOV CCAPM2,#00H
- MOV CCAPM3,#00H
- MOV CCAPM1,#42H
- MOV CCAP1H,#12
- MOV CCAPM4,#42H
- MOV CCAP4H,#30
- MOV CCON,#40H
- RET
- ZZ: //左转子程序
- MOV CCON,#00H
- LCALL ST
- MOV CCAPM1,#00H
- MOV CCAPM4,#00H
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
以上资料51hei提供下载:
|