咨询,代码问题

请问有人能帮忙看一下我的问题在哪里吗?
想测试用51单片机超声波避障功能,

用LED显示效果:
P1口对应的单片机LED如下:
P10-LED1
P11-LED2
P12-LED3
P13-LED4
P14-LED5
P15-LED6
P16-LED7
P17-LED8
写入单片机后,希望可以控制小车实现避障
一、目标如下
(一)距离大于20时:
#前进:
#P1^0=1,
#P1^1=0,
#P1^2=1,
#P1^3=0,
#P1^4=PWM,
#P1^5=PWM,
#即在单片机上
#共阳LED1~8:0101,1100,(1为亮,0为不亮)
#其中LED5和LED6闪烁或者亮度较低

(二)距离小于20时:
#左旋转:
#P1^0=0,
#P1^1=1,
#P1^2=1,
#P1^3=0,
#P1^4=PWM,
#P1^5=PWM
#即单片机上:
#LED1~8亮1001,1100,
#其中LED5和LED6闪烁或者亮度较低

二、实际实验结果:程序下载并启动启动后,未按照要求的输出:显示的是LED2和LED4亮,无论如何改变超声波模块与障碍物距离,都无法达到目标。

寻迹代码来源:https://mp.weixin.qq.com/s/vFqbx-vwkY-K6JfZHAflQw
超声波代码来源:https://blog.csdn.net/ca1m0921/article/details/80549746?utm_source=app

#include <reg52.h>
#include <math.h>
#include <intrins.h>
#define uchar unsigned char
#define uint  unsigned   int  
//#define led P2	   //流水灯宏定义P2口

sbit L=P0^0;	   //循迹模块L路:左
sbit M=P0^1;		//循迹模块M路:中
sbit R=P0^2;		//循迹模块R路:右

sbit TX  = P0^3; //超声波产生脉冲引脚
sbit RX  = P0^4; //回波引脚
				   

sbit IN1=P1^0;	   //电机1	ZUO
sbit IN2=P1^1;

sbit IN3=P1^2;	   //电机2
sbit IN4=P1^3;

sbit ENA=P1^4;	   //左使能A	
sbit ENB=P1^5;	   //右使能B




uchar m1=0,m2=0;   //电机预定速度值  
uchar tmp1,tmp2;   //电机当前速度值
uchar moto_t=0,n,g,g1,tt=0;//参数:moto__t->pwm计数,n->保留,g-->循迹模式下当前状态,g1-->保留,tt-->
//unsigned int m,t;  	   //流水灯变量
unsigned int  time=0;//超声波计数时间
float         Distance=0;//距离:用时间计算
bit           flag =0;   //超声波:T1中断溢出标志
//bit	csb_s=0;

void delayms(unsigned int ms);//申明延时函数
void init_Timer();//申明定时器
void motor(int num, int speed);//申明电机控制函数
void zhidong();//申明制动函数
void zhizou();//申明直走函数
void daotui();//申明倒退函数
void youzhuan1();//申明右转函数1
void youzhuan2();//申明右转函数2
void zuozhuan1();//申明左转函数1
void zuozhuan2();//申明左转函数2
void StartModule();//申明超声波发送函数
void Conut();//申明超声波计算与控制电机的函数
void xunji();//申明循迹函数
void csb();//申明超声波作用函数

void main()
{
	init_Timer();//定时器初始化
	while(1)
	{
		csb();//调用超声波函数
	}
	
}

void delayms(unsigned int ms)//延时函数
{
	unsigned char i=100,j;
	for(;ms;ms--) 
	{
		while(--i)
		{
			j=10;
			while(--j);
		}
		
	}
	
}

/*******T0定时器初始化*******/
void init_Timer()
{
  TMOD=0x22; //T0/T1采用工作方式2

//	TF0=1;
	TR0=0;      //开启定时器T0	:pwm用
	ET0=1;      //T0中断允许
	TH0=0x9b;  //定时器T0装入定时器的初值定时100us 
	TL0=0x9b;
	
//	TF1=1;
	TR1=0; //开启定时器T1-->超声波计时
	ET1=1;  	  //允许T1中断
	TH1=0;  //T1初始化,用于判断测距溢出,最大65.536 ms
	TL1=0; 



	
	EA=1;	  //开总中断
//  IT1=1;     //下降沿触发
//  EX1=1;     //外部中断
}



/********电机处理********/
void motor(int num, int speed)  //num:电机号,speed:速度	//motor(电机号,pwm速度值)
{ 
//	ET0=1;  这里原本打算用来初始化T0,但是发现行不通
//	ET1=0;
	if(speed>=-100 && speed<=100) 
	{  
		if(num==1)       //电机1的处理 
		{ 
			m1=abs(speed); //取速度的绝对值 
			if(speed<0)   //判断正反转 //速度值为负则反转 
			{
				IN1=0; 
				IN2=1;
			} 
			
			else           //不为负数则正转 
			{
				IN1=1;
				IN2=0;
			} 
			
		} 
		
		if(num==2)   
		{ 
			m2=abs(speed); 
			if(speed<0)    
			{
				IN3=0;
				IN4=1;
			} 
			
			else 
			{
				IN3=1;
				IN4=0;
			} 
			
		}

	} 
	
}

/****T0中断服务程序****/
void timer0() interrupt 1  
{ 

	/*****电机pwm输出*****/
	if(moto_t==0)  // 1个PWM周期完成后才会接受新数值 
	{
		tmp1=m1;
		tmp2=m2; 
	} 
	if(moto_t<tmp1)//产生电机1的PWM信号
	{
		ENA=1; 
	} 
	else
	{
		ENA=0;  
	} 
	if(moto_t<tmp2)//产生电机2的PWM信号
	{
		ENB=1; 
	} 
	else
	{
		ENB=0;  
	} 

	moto_t++; 
	if(moto_t>=100)//1个PWM信号由100次中断产生
	{
		moto_t=0;
//		TH0=0x9b;
//		TL0=0x9b;
	}
//	t++;

}	
 

/******电机方向控制*******/
void zhizou()		 //直走
{
	motor(1,60);  
	motor(2,55);

}
void youzhuan1()	 //右转1
{
	motor(1,0);  
	motor(2,40);
}
void youzhuan2()	 //右转2
{
	motor(1,70);  
	motor(2,-70);
}

void zuozhuan1()	 //左转1
{
	motor(1,30);  
	motor(2,0);
}
void zuozhuan2()	 //左转2
{
	motor(1,-80);  
	motor(2,80);
}
void zhidong()	 //制动
{
	ENA=0;
	ENB=0;
}
void daotui()
{
	motor(1,-60);  
	motor(2,-60);
}


void xunji()
{
	if (R==0 && M==1 && L==0)
	{
		zhizou();
		g=0;//用于走出黑线判断返回方式
	}
	/*****右转处理******/
	if ((R==0 && M==1 && L==1) || (R==0 && M==0 && L==1)) 
	{
		youzhuan1();
		g=1;//用于走出黑线判断返回方式
	}
	/******左转处理******/
	if ((R==1 && M==1 && L==0) || (R==1 && M==0 && L==0))
	{
		zuozhuan1();	
		g=2;//用于走出黑线判断返回方式
	}
	 /*****全黑****/
	if (IN3==1 && IN2==1 && IN1==1)
	{
		zhizou();
		g=3;//用于走出黑线判断返回方式
	}
	/*****跑出轨道记忆回到跑道上****/
		if (IN3==0 && IN2==0 && IN1==0)
	{

		switch (g)
		{
			case 0:
				youzhuan2();//从线的终点出去,右旋转回到线上
			break;				
			case 1:
				zuozhuan1();//右转出线,左转回到线上
			break;
			case 2:
				youzhuan1();//左转出线,右转回到线上
			break;
			case 3:
				daotui();//跨越黑线,倒退回到线上
			break;
			case 4:
				youzhuan2();
			break;
		}
		g=4;//如果最后走出线,右旋转回到线上		
	}	
}

void csb()
{
//	ET1=1;
//	ET0=0;
	StartModule();//发送超声波信号
	while(!RX);		//当超声波模块接收口输出低电平则等待
	TR1=1;	        //开启计数
  while(RX);			//当RX为1计数并等待
	TR1=0;				  //关闭计数
  Conut();	//计算距离,做出相应措施		  //读取定时器的值,计算
	delayms(60);	
//	if(csb_s == 0)//一开始想把距离判断用变量存储起来,然后再控制小车做出动作,但最后发现行不通
//	{
//		zhizou();
//	}
//	if(csb_s == 1)
//	{
//		zuozhuan1();
//	}
}

void  StartModule() //超声波模块Trig控制端给大于10us的高电平触发模块测距	
{
	  TX=1;     
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  TX=0;
}
 
void Conut()
{
	 time=TH1*256+TL1;//计算时间
	 TH1=0;
	 TL1=0;
	 Distance = (time*1.87)/100;  //CM  (见代码最后注释)
	 if(flag==1)		    //超出测量
	 {
	  flag=0;
	 	zhizou();
	 }
	 if(Distance<20){
	 	zuozhuan1();//距离小于20,左旋转找到距离大于20的方向继续前进
	 }else{
	 	zhizou();
//	  printf("Distance = %f CM\n",Distance); 
		}
}

void Timer0IRQ() interrupt 3 //T0中断用来计数器溢出,超过测距范围
{
    flag=1;	
}
 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值