标题: 基于手势的智能遥控车配件与程序 [打印本页]
作者: xpf2009403 时间: 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; //启动定时器T1,INT0触发方式为脉冲负边沿触发
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(不自检,2G,5Hz)
#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');
}
}
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |