找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2078|回复: 0
打印 上一主题 下一主题
收起左侧

基于手势的智能遥控车配件与程序

[复制链接]
跳转到指定楼层
楼主
ID:302480 发表于 2018-4-26 11:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我的设计是纯模块,比较贵,但是方便安装
小车:L298N驱动模块,小车,STC89C52RC单片机,HC06蓝牙    12V电源
遥控器:STC12C5A60S2单片机,MPU6050重力传感器,HC 05蓝牙  5V电源
小车程序
#include<reg52.h>
sbit ENA=P2^2;
sbit IN1=P2^3;
sbit IN2=P2^4;
sbit ENB=P2^5;
sbit IN3=P2^6;
sbit IN4=P2^7;
unsigned char u;
void delay(unsigned int n)                     //延时子程序
{
       unsignedchar i,j,k;
       for(i=n;i>0;i--)
       for(j=100;j>0;j--)
       for(k=200;k>0;k--);
}
/********************中断初始化********************/
void interrupt_Init(void)
{
   TH1|=0xFA;               //波特率9600     晶振11.0592   
       TL1|=0xFA;
       IE|=0x91;        //允许总中断,串口中断,使能 INT0 外部中断
       TCON|=0x41;      //启动定时器T1INT0触发方式为脉冲负边沿触发
       SCON|=0x50;      //REN=1允许串行接受状态,串口工作模式1                          
       TMOD|=0x20;      //定时器工作方式2                    
       PCON|=0x80;      //波特率倍频           
}
/*************串口中断程序**************/
void ser_int(void) interrupt 4 using 1
{
       if(RI==1)           
       {
              RI=0;     
              u=SBUF;
       }
}
  
void go()            
{
       IN1=1;
       IN2=0;
       ENA=1;
}
void back()  
{
       IN1=0;
       IN2=1;  
       ENA=1;
}
void stop()   
{
       IN1=0;
       IN2=0;
       ENA=0;
       ENB=0;
}
void left()     
{
       IN3=0;
       IN4=1;
       ENB=1;
}
void right()  
{     
       IN3=1;
       IN4=0;
       ENB=1;
}
void main()
{
      interrupt_Init();
       while(1)
       {
//            0001
//            0010
//            0100
//            1000
              delay(1);
              u=u&0x0F;
              if(u==1)go();
              if(u==2)back();
              if(u==0)stop();
              if(u==4)left();
              if(u==8)right();
              if(u==5){go();left();}
              if(u==9){go();right();}
              if(u==6){back();left();}
              if(u==0x0A){back();right();}
              u=0;
       }
}  
1.1    遥控器程序
#include "STC12C5A60S2.h"
#include "intrins.h"
#include "math.h"
sbit SCL=P1^7;                //IIC时钟引脚定义
sbit SDA=P1^6;                //IIC数据引脚定义
#define u8 unsigned char
#define u16 unsigned int
//****************************************
// 定义MPU6050内部地址
//****************************************
#define  SMPLRT_DIV          0x19      //陀螺仪采样率,典型值:0x07(125Hz)
#define  CONFIG                    0x1A     //低通滤波频率,典型值:0x06(5Hz)
#define  GYRO_CONFIG             0x1B     //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define  ACCEL_CONFIG    0x1C     //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G5Hz)
#define  ACCEL_XOUT_H   0x3B     //MPU6050_BUF[0]
#define  ACCEL_XOUT_L    0x3C     //MPU6050_BUF[1]
#define  ACCEL_YOUT_H   0x3D
#define  ACCEL_YOUT_L    0x3E
#define  ACCEL_ZOUT_H    0x3F
#define  ACCEL_ZOUT_L    0x40
#define  TEMP_OUT_H         0x41      //MPU6050_BUF[6]
#define  TEMP_OUT_L          0x42      //MPU6050_BUF[7]
#define  GYRO_XOUT_H            0x43
#define  GYRO_XOUT_L             0x44      
#define  GYRO_YOUT_H            0x45
#define  GYRO_YOUT_L             0x46
#define  GYRO_ZOUT_H             0x47
#define  GYRO_ZOUT_L             0x48      //MPU6050_BUF[13]
#define  PWR_MGMT_1        0x6B     //电源管理,典型值:0x00(正常启用)
#define  WHO_AM_I             0x75      //IIC地址寄存器(默认数值0x68,只读)
#define  MPU6050_Addr 0xD0     //IIC写入时的地址字节数据,+1为读取
u8 MPU6050_BUF[14];
float angle_x,angle_y;
//unsigned char AB,LR;
static void Delay5us(void)
{
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
}
void I2C_Start(void)
{
   SDA = 1;                    //拉高数据线
   SCL = 1;                    //拉高时钟线
   Delay5us();                 //延时
    SDA= 0;                    //产生下降沿
   Delay5us();                 //延时
   SCL = 0;                    //拉低时钟线
}
void I2C_Stop(void)
{
   SDA = 0;                    //拉低数据线
   SCL = 1;                    //拉高时钟线
   Delay5us();                 //延时
    SDA = 1;                    //产生上升沿
   Delay5us();                 //延时
}
void I2C_SendACK(bit ack)
{
   SDA = ack;                  //写应答信号
   SCL = 1;                    //拉高时钟线
   Delay5us();                 //延时
   SCL = 0;                    //拉低时钟线
   Delay5us();                 //延时
}
bit I2C_RecvACK(void)
{
   SCL = 1;                    //拉高时钟线
   Delay5us();                 //延时
   CY = SDA;                   //读应答信号
   SCL = 0;                    //拉低时钟线
   Delay5us();                 //延时
   return CY;
}
void I2C_SendByte(u8 dat)
{
   u8 i;
   for (i=0; i<8; i++)         //8位计数器
    {
       dat <<= 1;              //移出数据的最高位
       SDA = CY;               //送数据口
       SCL = 1;                //拉高时钟线
       Delay5us();             //延时
       SCL = 0;                //拉低时钟线
       Delay5us();             //延时
    }
   I2C_RecvACK();
}
u8 I2C_RecvByte(void)
{
   u8 i, dat = 0;
   SDA = 1;                    //使能内部上拉,准备读取数据,
   for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;
       SCL = 1;                //拉高时钟线
       Delay5us();             //延时
       dat |= SDA;             //读数据               
       SCL = 0;                //拉低时钟线
       Delay5us();             //延时
    }
   return dat;
}
void Single_Write_MPU6050(u8 REG_Address,u8REG_data)
{
   I2C_Start();                  //起始信号
   I2C_SendByte(MPU6050_Addr);   //发送设备地址+写信号
   I2C_SendByte(REG_Address);    //内部寄存器地址,
   I2C_SendByte(REG_data);       //内部寄存器数据,
   I2C_Stop();                   //发送停止信号
}
u8 Single_Read_MPU6050(u8 REG_Address)
{
       u8REG_data;
       I2C_Start();                   //起始信号
       I2C_SendByte(MPU6050_Addr);    //发送设备地址+写信号
       I2C_SendByte(REG_Address);     //发送存储单元地址,从0开始   
       I2C_Start();                   //起始信号
       I2C_SendByte(MPU6050_Addr+1);  //发送设备地址+读信号
       REG_data= I2C_RecvByte();       //读出寄存器数据
       I2C_SendACK(1);                //接收应答信号
       I2C_Stop();                    //停止信号
       returnREG_data;
}
void MPU6050_Init(void)
{
       Single_Write_MPU6050(PWR_MGMT_1,0x00);    //解除休眠状态
       Single_Write_MPU6050(SMPLRT_DIV,0x07);
       Single_Write_MPU6050(CONFIG,0x06);
       Single_Write_MPU6050(GYRO_CONFIG,0x18);    //2000,16.4
       Single_Write_MPU6050(ACCEL_CONFIG,0x10);          //8g  ,4096
}
void Get_MPU6050_Data(void)
{
       u8i;
       intaccel_x,accel_y,accel_z;
       for(i=0;i<14;i++)
       {
              MPU6050_BUF= Single_Read_MPU6050(0x3B + i);
       }
       accel_x= MPU6050_BUF[0];
       accel_x= (accel_x << 8) | MPU6050_BUF[1];
       accel_y= MPU6050_BUF[2];
       accel_y= (accel_y << 8) | MPU6050_BUF[3];
       accel_z= MPU6050_BUF[4];
       accel_z= (accel_z << 8) | MPU6050_BUF[5];
//     //扩大1000
       angle_x= atan2((float)accel_x,(float)accel_z) * (57.295779) ;
       angle_y= atan2((float)accel_y,(float)accel_z) * (57.295779) ;
}
//串口初始化
void UartInit(void)           //9600bps@12.000MHz
{
       PCON&= 0x7F;        //波特率不倍速
       SCON= 0x50;           //8位数据,可变波特率
       AUXR|= 0x04;         //独立波特率发生器时钟为Fosc,1T
       BRT= 0xD9;             //设定独立波特率发生器重装值
       AUXR|= 0x01;         //串口1选择独立波特率发生器为波特率发生器
       AUXR|= 0x10;         //启动独立波特率发生器
}
/********************发送一个字节********************/
void Sendchar(u8 ch)       //单片机发送一字节数据
{
    SBUF=ch;
       while(!TI);            //等待发送完成
       TI=0;                     //清除标志位
}
void Delay(u16 x)
{
       u8i,j;
       for(i=x;i>0;i--)
       for(j=200;j>0;j--);
}
void cc(long int aa)
{
       u8shiwan,wan,qian,bai,shi,ge;
       if(aa>0)
       {
              Sendchar('+');
       }
       else
       {
              Sendchar('-');
              aa= -aa;
       }     
       shiwan= aa/100000;
       wan    = aa%100000/10000;
       qian   = aa%10000/1000;
       bai    = aa%1000/100;
       shi    = aa%100/10;
       ge     = aa%10;
       Sendchar(shiwan+0x30);
       Sendchar(wan+0x30);
       Sendchar(qian+0x30);
       Sendchar('.');
       Sendchar(bai+0x30);
       Sendchar(shi+0x30);
       Sendchar(ge+0x30);
       Sendchar('');
       Sendchar('');
       Sendchar('');
}
void main(void)
{
       UartInit();
       MPU6050_Init();
       while(1)
       {
         Get_MPU6050_Data();
//            cc((longint)angle_x);
//            cc((longint)angle_y);
//            Sendchar(0x0D);
//            Sendchar(0x0A);
              if((angle_y>-20)&&(angle_y<20)&&(angle_x<-30))Sendchar('1');
              if((angle_y<20)&&(angle_y>-20)&&(angle_x>25))  Sendchar('2');
//            if(angle_y<20)
//            {
//                   if(angle_y>-20)
//                   {
//                          if(angle_x>25)   Sendchar('2');
//                   }
//            }
              if((angle_x<25)&&(angle_x>-30)&&(angle_y>25))Sendchar('8');
              if((angle_x<25)&&(angle_x>-30)&&(angle_y<-25))Sendchar('4');
       if((angle_y<-25)&&(angle_x<-30))Sendchar('5');
       if((angle_y>25)&&(angle_x<-30))Sendchar('9');
              if((angle_y<-25)&&(angle_x>25))Sendchar('6');
              if((angle_y>25)&&(angle_x>25))Sendchar(':');
              if((angle_y>-25)&&(angle_y<25)&&(angle_x<25)&&(angle_x>-30))Sendchar('0');
       }
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表