51蓝牙+红外遥控小车

	51蓝牙+红外遥控小车

模块:
51最小系统
l289n驱动模块
杜邦线
车模
18650锂电池
蓝牙模块HC-06
红外接收器(用开发板上面的就!可!)
红外遥控器(用开发板上的就!可!)
手机一部(安装好蓝牙串口APP)
工具:
剪刀,万用表,螺丝刀,胶布,什么杂七杂八的。

			l298n
ENA:控制IN1 IN2 
ENB:控制 IN3 IN4
IN1 IN2 IN3 IN4:分别控制OUT1 OUT2 OUT3 OUT4
12V输入口:接3节3.7V串联锂电池正极
GND口:接3节3.7V串联锂电池负极+接单片机GND
5V输出口:接单片机VCC
功能:单片机IO口接好ENA ENB IN1 IN2 IN3 IN4 
	  OUT1 OUT2 控制车模左电机(左电机)依据个人喜好
	  OUT2 OUT4 控制车模右电机(右电机)
	  
	前进:
	IN1高电平——OUT1相当于正极
	IN2低电平——OUT2相当于负极
	此时连接在OUT1 和OUT2 的这个电机正转
	(IN3 IN4同理) 后退同理
	左转:
	左轮后退,右轮前进实现后退(很神奇)
	右转同理
	
	pwm调速:
	通过软件编写的程序使单片机IO口控制ENA ENB高电平和低电平在	
	一个周期内占的比例实现调速。(用到定时器中断)
	譬如:1秒内ENA和ENB的高电平时间是0.5秒,低电平时间也是	
	           0.5秒。小车就中等速度开车。
	       	    1秒内ENA和ENB的高电平时间是0.1秒,低电平时间就死
	 	     0.9秒。小车就龟速开车。
	
	注意:买来的模块有3个短接片接好的
	分别是ENA ENB 板载5V使能
	用pwm调速的时候去掉ENA ENB短接片
	板载5V使能 我还没用过不用管它

		18650锂电池
之前用5号电池,没两下就没电了。18650锂电池容量大,可	
重复利用。
3节3.7V的就 !可!

			HC-06
用到VCC(5V) GND接上
注意:蓝牙RX接单片机TX,蓝牙TX接单片机RX。
通过!串口中断!用手机发送信号给蓝牙,蓝牙接收数据传		
送给单片机,单片机接收不同的信号控制IO口输出的高低电	
平控制l298n,l298n控制电机。
		红外接收器,红外遥控器
正常的低配的51开发板都会配有
红外遥控器各个按键对应不同的按键码,
红外接收器(注意:VOUT接P32口)
通过!外部中断0!用红外遥控器发送信号(按键码)给红外接	
收器,红外接收器接收数据传送给单片机,
单片机接收不同的信号控制IO口输出的高低电平控制l298n
l298n控制电机。(Ctrl+c然后Ctrl+v)

			车模
安装时候注意先把马达的杜邦线接好再安装轮胎

//一些必要定义

#include<reg52.h>
typedef unsigned char u8;
typedef unsigned int u16;
sbit ena=P1^0;
sbit in1=P1^1;
sbit in2=P1^2;
sbit in3=P1^3; 
sbit in4=P1^4;
sbit enb=P1^5;
sbit ir=P3^2;//P32有外部中断0的功能
u8 m;//
u8 speed=3;//

//一些必要函数

void Delay(u16 i)//延时10us
{
 while(i--);
}
void Slow()
{
 speed-=1;
 if(speed<=5)//参数要自己调
  speed=5;
}
void Quick()
{
 speed+=1;
 if(speed>=10)//参数要自己调
  speed=10;
}
void Forward()
{
  in1=1;
  in2=0;
  in3=1;
  in4=0;
}
void Back()
{
  in1=0;
  in2=1;
  in3=0;
  in4=1;
}
void Left()
{
  in1=1;
  in2=0;
  in3=0;
  in4=1;
}
void Right()
{
  in1=0;
  in2=1;
  in3=1;
  in4=0;
}
void Stop()
{
  in1=0;
  in2=0;
  in3=0;
  in4=0;
}

//初始化(蓝牙的串口中断4配置,红外遥控的外部中断0配置,
pwm的定时器T0中断1配置)
//说明:
串口中断一般用定时器T1,T1用工作方式2,TH1=TL1=0xfd;
PCON=0x00;此时单片机(11.0592hz)串口通信的波特率为9600。
串口工作方式用方式1;

外部中断0没什么好说的。

定时器中断1用定时器T0,T0用工作方式1。

void Init({
  TMOD=0x21;//TMOD高四位控制T1,低四位控制T0;
  //T1工作方式2,T0工作方式1.
  
  /*串口中断设置部分*/
  PCON=0x00;//波特率不翻倍。
  SCON=0x50;//设置串口工作方式为1
  TH1=TL1=0xfd;//设置串口波特率为9600
  ES=1;//打开串口中断;
  
  /*定时器T0中断1设置*/
  TH0=0xf4;//定时3ms,每3ms进入定时器中断1
  TL0=0x48;
  ET0=1;//打开定时器中断1
  TR0=1//打开定时器;

  /*外部中断0设置*/
  IT0=1;//下降沿触发外部中断0;
  EX0=1;//打开外部中断0;
  
  //PS=1;//串口中断优先。
  PT0=1//定时器0中断优先;

  EA=1;//打开总中断
  }

//串口中断函数

void Uart()interrupt 4
{
  u8 i;
  i=SBUF;
  RI=0;//RI为接收中断标志,SBUF接收到信号,清零RI;
  if(i==0x02)Forward();
  if(i==0x08)Back();
  if(i==0x04)Left();
  if(i==0x06)Right();
  if(i==0x05)Stop();
  if(i==0x01)Slow();
  if(i==0x03)Quick();
}

//定时器T0中断1函数(pwm调速)

void Time0()interrupt 1
{
  TR0=0//先关掉定时器T0,执行中断1内的函数
  TH0=0xf4;//每3ms进入这个中断函数
  TL0=0x48;
  m++;//每次加1,加到一定值清零
  if(m<speed)//speed通过Quick函数和Slow函数改变
    ena=enb=1;
  else
    ena=enb=0;
  if(m==6)//也就是说每3X6=18ms就要清零了
    m=0;
  TR0=1;//执行完中断函数重新打开定时器T0
}

//外部中断0函数

```c
void Ir()interrupt 0
{
  u8 i,j,k,time,irdata[8];//k用来跳出循环
  Delay(700);//7000us
  if(ir==0)//开始接收信号
  {  
    for(k=1000;ir==0&&(k>0);Delay(1),k--);//9ms低电平的起始码,这里最多给它10ms。
    if(ir==1)
    {
      for(k=500;ir==1&&(k>0);Delay(1),k--);//4.5ms高电平的起始码,这里最多给它5ms
      for(i=0;i<4;i++)//读取4组数据
      {
        for(j=0;j<8;j++)//读取每组数据的8位数
        {
          //开始判断每组数据的每一位是位0还是位1
          //位0和位1主要区别看后半部分高电平的时间
          for(k=60;ir==0&&(k>0);Delay(1),k--);//每组数据的每一位前半部分都是0.56ms低电平,这里最多给0.6ms
          for(k=500;ir==1&&(k>0);Delay(10),k--,time++)
            if(time>30)
              return ;//30X100us=3000us=3ms超时退出
            //没有超时继续执行下面的函数
            irdata[i]>>=1;//细细体会
            if(time>=8)//8X100us=0.8ms认定它为位1
              irdata[i]|=0x80;
            time=0;//计数完清零;

        }
      }
    }
  }
  switch(irdata[2])//选择用户码(就是第三组数据)
  {//注每种红外遥控器的按键码不同,case 几自行调节
    case 0x46:ena=~ena;enb=~enb;break;
    case 0x43:Quick();break;
    case 0x40:Slow();break;
    case 0x18:Forward();break;
    case 0x1c:Stop();break;
    case 0x08:Left();break;
    case 0x5a:Right();break;
    case 0x52;Back();break;
  }
}

//主函数

```c
void main()
{
  Stop();
  Init();
  while(1);//防止程序跑飞
}

//说明:课余时间学习51单片机1学期,懂一点皮毛。一些注释比较花里胡哨,大神勿喷
给的程序不一定能编译成功,都是手动敲的,主体问题不大

发布了2 篇原创文章 · 获赞 0 · 访问量 120

猜你喜欢

转载自blog.csdn.net/weixin_45974237/article/details/103957076