標(biāo)題: 基于手勢的智能遙控車配件與程序 [打印本頁]
作者: xpf2009403 時(shí)間: 2018-4-26 11:13
標(biāo)題: 基于手勢的智能遙控車配件與程序
我的設(shè)計(jì)是純模塊,比較貴,但是方便安裝
小車:L298N驅(qū)動(dòng)模塊,小車,STC89C52RC單片機(jī),HC06藍(lán)牙 12V電源
遙控器:STC12C5A60S2單片機(jī),MPU6050重力傳感器,HC 05藍(lán)牙 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) //延時(shí)子程序
{
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; //啟動(dòng)定時(shí)器T1,INT0觸發(fā)方式為脈沖負(fù)邊沿觸發(fā)
SCON|=0x50; //REN=1允許串行接受狀態(tài),串口工作模式1
TMOD|=0x20; //定時(shí)器工作方式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時(shí)鐘引腳定義
sbit SDA=P1^6; //IIC數(shù)據(jù)引腳定義
#define u8 unsigned char
#define u16 unsigned int
//****************************************
// 定義MPU6050內(nèi)部地址
//****************************************
#define SMPLRT_DIV 0x19 //陀螺儀采樣率,典型值:0x07(125Hz)
#define CONFIG 0x1A //低通濾波頻率,典型值:0x06(5Hz)
#define GYRO_CONFIG 0x1B //陀螺儀自檢及測量范圍,典型值:0x18(不自檢,2000deg/s)
#define ACCEL_CONFIG 0x1C //加速計(jì)自檢、測量范圍及高通濾波頻率,典型值: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地址寄存器(默認(rèn)數(shù)值0x68,只讀)
#define MPU6050_Addr 0xD0 //IIC寫入時(shí)的地址字節(jié)數(shù)據(jù),+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; //拉高數(shù)據(jù)線
SCL = 1; //拉高時(shí)鐘線
Delay5us(); //延時(shí)
SDA= 0; //產(chǎn)生下降沿
Delay5us(); //延時(shí)
SCL = 0; //拉低時(shí)鐘線
}
void I2C_Stop(void)
{
SDA = 0; //拉低數(shù)據(jù)線
SCL = 1; //拉高時(shí)鐘線
Delay5us(); //延時(shí)
SDA = 1; //產(chǎn)生上升沿
Delay5us(); //延時(shí)
}
void I2C_SendACK(bit ack)
{
SDA = ack; //寫應(yīng)答信號(hào)
SCL = 1; //拉高時(shí)鐘線
Delay5us(); //延時(shí)
SCL = 0; //拉低時(shí)鐘線
Delay5us(); //延時(shí)
}
bit I2C_RecvACK(void)
{
SCL = 1; //拉高時(shí)鐘線
Delay5us(); //延時(shí)
CY = SDA; //讀應(yīng)答信號(hào)
SCL = 0; //拉低時(shí)鐘線
Delay5us(); //延時(shí)
return CY;
}
void I2C_SendByte(u8 dat)
{
u8 i;
for (i=0; i<8; i++) //8位計(jì)數(shù)器
{
dat <<= 1; //移出數(shù)據(jù)的最高位
SDA = CY; //送數(shù)據(jù)口
SCL = 1; //拉高時(shí)鐘線
Delay5us(); //延時(shí)
SCL = 0; //拉低時(shí)鐘線
Delay5us(); //延時(shí)
}
I2C_RecvACK();
}
u8 I2C_RecvByte(void)
{
u8 i, dat = 0;
SDA = 1; //使能內(nèi)部上拉,準(zhǔn)備讀取數(shù)據(jù),
for (i=0; i<8; i++) //8位計(jì)數(shù)器
{
dat <<= 1;
SCL = 1; //拉高時(shí)鐘線
Delay5us(); //延時(shí)
dat |= SDA; //讀數(shù)據(jù)
SCL = 0; //拉低時(shí)鐘線
Delay5us(); //延時(shí)
}
return dat;
}
void Single_Write_MPU6050(u8 REG_Address,u8REG_data)
{
I2C_Start(); //起始信號(hào)
I2C_SendByte(MPU6050_Addr); //發(fā)送設(shè)備地址+寫信號(hào)
I2C_SendByte(REG_Address); //內(nèi)部寄存器地址,
I2C_SendByte(REG_data); //內(nèi)部寄存器數(shù)據(jù),
I2C_Stop(); //發(fā)送停止信號(hào)
}
u8 Single_Read_MPU6050(u8 REG_Address)
{
u8REG_data;
I2C_Start(); //起始信號(hào)
I2C_SendByte(MPU6050_Addr); //發(fā)送設(shè)備地址+寫信號(hào)
I2C_SendByte(REG_Address); //發(fā)送存儲(chǔ)單元地址,從0開始
I2C_Start(); //起始信號(hào)
I2C_SendByte(MPU6050_Addr+1); //發(fā)送設(shè)備地址+讀信號(hào)
REG_data= I2C_RecvByte(); //讀出寄存器數(shù)據(jù)
I2C_SendACK(1); //接收應(yīng)答信號(hào)
I2C_Stop(); //停止信號(hào)
returnREG_data;
}
void MPU6050_Init(void)
{
Single_Write_MPU6050(PWR_MGMT_1,0x00); //解除休眠狀態(tài)
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];
// //擴(kuò)大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位數(shù)據(jù),可變波特率
AUXR|= 0x04; //獨(dú)立波特率發(fā)生器時(shí)鐘為Fosc,即1T
BRT= 0xD9; //設(shè)定獨(dú)立波特率發(fā)生器重裝值
AUXR|= 0x01; //串口1選擇獨(dú)立波特率發(fā)生器為波特率發(fā)生器
AUXR|= 0x10; //啟動(dòng)獨(dú)立波特率發(fā)生器
}
/********************發(fā)送一個(gè)字節(jié)********************/
void Sendchar(u8 ch) //單片機(jī)發(fā)送一字節(jié)數(shù)據(jù)
{
SBUF=ch;
while(!TI); //等待發(fā)送完成
TI=0; //清除標(biāo)志位
}
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.torrancerestoration.com/bbs/) |
Powered by Discuz! X3.1 |