基于51单片机的循迹模块和避障模块同时实现

        一开始我对于循迹和避障两个模块同时实现,想采用的办法是,利用中断的方法,将循迹模块作为主函数进行循环,然后将避障模块放进去中断里面,当判断到前方有障碍时,进行避障,无障碍时依旧进行循迹模块的进行。

        但是在测试中发现,这样尝试,只有避障模块可以正常使用,不知道是我们中断配置的问题还是本身会存在矛盾问题。于是我们采用了另外的一种想法,利用逻辑分析进行判断(如果和我一样是新手可以采用这种方法,会比较简单)。

以下是我的示例代码,如果是和我一样是新手的话,可以尝试一下像这样使用逻辑判断,进行实现两个模块同时实现,但是采用这种方法有缺点,在对于循迹和避障的识别和配合上可能不是运行起来,像使用操作系统那些那么丝滑,小车的行走可能不会像那样那么流畅。

void APP_Loop2(void)
{
	static unsigned char State = 0;//0-直行  1-刹车  2-后退  3-左拐
	static unsigned int Time=0;

	
	
	if(((Left_Flow==1) & (Right_Flow==1)) && ((Left_Flow1==1) | (Right_Flow1==1)))//没有检测到黑线同时没用检测到障碍物
	{
		Motor_Stop();
		Left_LED = 1;
		Right_LED = 1;
		return;
	}
	if((Left_Flow==1)&&((Left_Flow1==1) | (Right_Flow1==1)))//左边循迹检测到黑线,同时没有检测到障碍物
	{
		Motor_Right();
		Left_LED = 0;
		Right_LED = 1;
		return;
	}
	if((Right_Flow==1)&&((Left_Flow1==1) | (Right_Flow1==1)))//右边循迹检测到障碍物,同时没有检测到障碍物
	{
		Motor_Left();
		Left_LED = 1;
		Right_LED = 0;
		return;
	}
	
	if(((Left_Flow1==0) | (Right_Flow1==0)) & (State == 0))//遇到障碍物
	{
		State = 1;
		Time = 0;
	}
	
	Time++;
	
	switch(State)
	{
		case 1 :
			{
				Motor_Stop();
				if(Time > 50)
				{
					Time = 0;
					State = 2;
				}
				break;
			}
		case 2 :
			{
				Motor_Back();
				if(Time > 100)
				{
					Time = 0;
					State = 3;
				}
				break;
			}
		case 3 :
			{
				Motor_Left();
				if(Time > 200)
				{
					Time = 0;
					State = 0;
				}
				break;
			}		
		case 0 :
			{
				Motor_Forward();
				break;
			}		
		default:
			{
				;
			}		
	}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是一个基于51单片机的小车程序,可以实现避障和自动循迹功能。这个程序需要使用一个红外模块和一个超声波模块。 首先,我们需要定义一些常量和变量。这些常量和变量将用于控制小车的运动。 ```c #include <reg51.h> #define LED P2 #define IN1 P1_0 #define IN2 P1_1 #define IN3 P1_2 #define IN4 P1_3 #define ENA P1_4 #define ENB P1_5 sbit IR = P3^2; sbit TRIG = P3^3; sbit ECHO = P3^4; unsigned int distance = 0; ``` 接下来,我们需要初始化各个模块和引脚。这个程序中我们使用 P1_0 到 P1_5 来控制小车的电机, P2 来控制 LED 灯, P3_2 来接收红外模块的信号, P3_3 和 P3_4 分别接超声波模块的 TRIG 和 ECHO 引脚。 ```c void init() { TMOD = 0x01; TH0 = 0xFC; TL0 = 0x67; ET0 = 1; TR0 = 1; IT0 = 1; EX0 = 1; IT1 = 1; EX1 = 1; IR = 1; } ``` 在初始化函数中,我们设置了计时器 T0 的工作模式为模式 1,使其每隔一段时间就会中断,从而实现超声波模块的测距。我们还设置了外部中断 0 和外部中断 1,用于接收红外模块的信号,以实现避障功能。 接下来是计时器 T0 的中断服务函数,用于实现超声波模块的测距。 ```c void timer0() interrupt 1 { TH0 = 0xFC; TL0 = 0x67; distance = 0; TRIG = 1; delay(10); TRIG = 0; while (!ECHO); while (ECHO) { distance++; delay(1); } distance = distance / 58; } ``` 在这个函数中,我们设置了计时器 T0 的中断触发时间为 50us。当 T0 中断时,我们将超声波模块的 TRIG 引脚拉高,延时 10us 后再将其拉低。接着,我们等待超声波模块的 ECHO 引脚变为高电平,开始计时。当 ECHO 引脚变为低电平时,我们计算出测量得到的距离。 下面是外部中断 0 的中断服务函数,用于实现避障功能。 ```c void external0() interrupt 0 { IN1 = 1; IN2 = 0; IN3 = 1; IN4 = 0; delay(300); IN1 = 0; IN2 = 0; IN3 = 0; IN4 = 0; } ``` 在这个函数中,我们将小车的电机设置为向左转,然后延时一段时间后停止电机的运转,从而实现避障功能。 下面是外部中断 1 的中断服务函数,用于实现自动循迹功能。 ```c void external1() interrupt 2 { if (IR) { IN1 = 1; IN2 = 0; IN3 = 0; IN4 = 1; } else { IN1 = 0; IN2 = 1; IN3 = 1; IN4 = 0; } } ``` 在这个函数中,我们根据红外模块的信号判断小车应该向左转还是向右转,然后设置小车的电机运转方向。 最后,我们需要实现一个延时函数,用于控制小车的运动。 ```c void delay(unsigned int t) { unsigned int i, j; for (i = 0; i < t; i++) { for (j = 0; j < 2000; j++); } } ``` 这个函数将延时 t 个单位时间,每个单位时间是一个循环。在这个循环中,我们执行了 2000 次空循环,从而实现了一个大约为 1ms 的延时。 整个程序的主函数如下: ```c void main() { init(); while (1) { if (distance < 20) { IN1 = 1; IN2 = 0; IN3 = 1; IN4 = 0; delay(300); IN1 = 0; IN2 = 0; IN3 = 0; IN4 = 0; } else { IN1 = 1; IN2 = 0; IN3 = 0; IN4 = 1; } } } ``` 在这个主函数中,我们首先调用了初始化函数,然后进入一个无限循环。在这个循环中,我们首先判断超声波模块测量得到的距离,如果距离小于 20cm,就调用避障函数,否则调用自动循迹函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值