单片机学习小组
直播中

地方

12年用户 651经验值
私信 关注

如何利用51单片机实现红外遥控小车的设计?

如何利用51单片机实现遥控小车的设计?

回帖(1)

徐夕武

2022-1-18 11:34:25
模块:
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
typedef unsigned char u8;
typedef unsigned int u16;
***it ena=P1^0;
***it in1=P1^1;
***it in2=P1^2;
***it in3=P1^3;
***it in4=P1^4;
***it enb=P1^5;
***it 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     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>>=1;//细细体会
            if(time>=8)//8X100us=0.8ms认定它为位1
              irdata|=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);//防止程序跑飞
}
举报

更多回帖

×
20
完善资料,
赚取积分