51单片机循迹小车 三红外

 在学习51单机后进行的小小总结和记录,欢迎指正

工作器件:电动马达;红外模块;最小系统板;红外模块;电机驱动模块等

工作原理:

使用定时器来进行pwm调速

红外模块接收信号

使用io口控制L298N驱动模板

装小车时候注意的地方:

注意:l298n电机驱动模块别接短路了,额接短路了直接烧了,

还有最小开发板的接线端子正确对接电机驱动模块的正负极;

对于电机驱动模块L298N: 

我是当时使用的是7.5v左右的电源供电

两个使能模块接口    ENA      ENB

IN1 IN2 IN3 IN4控制 电机反转和正转的

高低分别为置1,0  杜邦线对着自己定义的io口进行对接

 

 

对于红外模块:红外模块默认发送的是1,当接收信号之后是发送0;

就 一个信号线   和一个VCC,一个GND

虽然本代码是三个红外,自己加以修改,两个红外也是可以的

对于代码可以多加调试,对于每个人电机插线的不同,需要修改0  1的数值,还有供电的电压,可能也需要修改 本人使用12v电源也是可以正常使用。想把循迹小车做好,还得多加修改

本代码对于复杂赛道,比如锐角暂时不能做到,本代码提供了个人的一点思路

总的代码:(供参考)

#include<reg52.h>																		   

typedef unsigned int uint;   
typedef unsigned char uchar;

uchar Duty_left,Duty_right; //左右占空比标志,取1-100
uchar i=0,j=0;
uchar flag;	 //用于循迹方向的判断
uchar g=0;
//驱动L298N----> 
//ENA,ENB为使能端; ENA,1,2和ENB,3,4分别控制一个电机;
//设置啥io口自行设置
sbit IN1 = P1^0;
sbit IN2 = P1^1;
sbit IN3 = P1^2;
sbit IN4 = P1^3;
sbit ENA = P1^4;
sbit ENB = P1^5;

sbit left=P0^0;	//左边的传感器
sbit right=P0^2;  //右边的传感器
sbit mid=P0^1;  //中间的传感器


void delay_ms(unsigned int n)
{
    unsigned int i=0,j=0;
    for(i=0;i<n;i++)
        for(j=0;j<123;j++);
}


//小车直行速度赋值
void forward_move()
{
    Duty_left=100;   //我8v电源速度拉满啥事没有
    Duty_right=100;    
    IN1=1;   	//两个电机均正转    具体0 1还是1 0看自己电机接线设置   我8v电源速度拉满啥事没用
    IN2=0; 
    IN3=1;
    IN4=0;
}

//小车停止
void stop()
{   Duty_left=50;
	Duty_right=50;    //停车代码
    IN1=0;
    IN2=0;
    IN3=0;
    IN4=0;
}

void Left_turning()//左拐
{
    Duty_left=70;
    Duty_right=60;
    IN1=1;       //两个电机一个正转一个反转
    IN2=0;
    IN3=0;		  
    IN4=1;
}

void Right_turning()
{
    Duty_left=60;
    Duty_right=60;   //两个电机一个正转一个反转
    IN1=0;	  
    IN2=1;
    IN3=1;	  
    IN4=0 ;
}


void timer0init()
{
    TMOD|=0x01;//定时器T0, 工作方式1, 16位
    TH0=0xff;//定时 ff9c  0.1ms
    TL0=0x9c;
    EA=1;  //开启总中断
    ET0=1;//开启中断允许
    TR0=1;//开启定时器中断  
}


void timer0() interrupt 1
{
    TH0=0xff;
    TL0=0x9c;
    i++;
    j++;
    
    if(i<=Duty_left)
        ENA=1;
    else
        ENA=0;
    
    if(j<=Duty_right)
        ENB=1;
    else
        ENB=0;
    
    if(i==100)  //设置pwm周期=0.1ms*100=10ms,这样开头定义的变量正好表示占空比数值
    {
        i=0;//加到100后变为0,重新计数
    }
    if(j==100)
    {
        j=0;
    }  



//由于我使用while来写,这边使用中断来给红外循迹的判断 
	    if((left==1)&&(right==0))
    {
	     flag=0;//右边检测到线	   //右拐
    }
    else if((left==0)&&(right==1))
    {
		 flag=1;//左边检测到线   左拐
	}
    else if((left==0)&&(right==0)&&(right==0))
	{
		 flag=3; //三个红外都检测到的时候直行
	}
	else if((mid==0)&&(right==1)&&(right==1))
	   {
	     flag=5;    //中间检测到,两边没用检测到直行
	   }
	}

//循迹模块
void xunji()
{   
//使用while来写发现可以效果更好。原本我使用的是switch来写
while(flag==1)
{	
  Right_turning();	
  if((flag==3)||(flag==5)||(flag==0))break;//跳出循环
}


while(flag==0)
{
   Left_turning();
   if((flag==3)||(flag==5)||(flag==1))break;//跳出循环
}


if((flag==3)||(flag==5))//直行
{
	 forward_move();
	
}
 if((flag==3))//检测三红外
{
	 forward_move();
	 delay_ms(100);//延时判断  如果还是三个红外都亮,说明抵达终点
	 {
	 if(flag==3)
	 {
	  stop();   //终点停车代码,很粗糙可以自己修改
	  delay_ms(1500);
	  if(g<1)
	  {
	  Left_turning();  //摆尾掉头代码,不要可以自己修改
	  delay_ms(800);
	  if(flag==3)
	  forward_move();
	  g++;
	  }
	 }
	 }

}


}
void main()
{
    timer0init();
    while(1)
    {
    	xunji();
    }
}

  • 3
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式学不会不改名

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值