xs128控制mpu6050程序.docx

上传人:b****3 文档编号:24797953 上传时间:2023-06-01 格式:DOCX 页数:21 大小:18.38KB
下载 相关 举报
xs128控制mpu6050程序.docx_第1页
第1页 / 共21页
xs128控制mpu6050程序.docx_第2页
第2页 / 共21页
xs128控制mpu6050程序.docx_第3页
第3页 / 共21页
xs128控制mpu6050程序.docx_第4页
第4页 / 共21页
xs128控制mpu6050程序.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

xs128控制mpu6050程序.docx

《xs128控制mpu6050程序.docx》由会员分享,可在线阅读,更多相关《xs128控制mpu6050程序.docx(21页珍藏版)》请在冰豆网上搜索。

xs128控制mpu6050程序.docx

xs128控制mpu6050程序

#include/*commondefinesandmacros*/

#include"derivative.h"/*derivative-specificdefinitions*/

#include//Keillibrary

#defineucharunsignedchar

#defineuintunsignedint

#defineSMPLRT_DIV0x19//陀螺仪采样率,典型值:

0x07(125Hz)

#defineCONFIG0x1A//低通滤波频率,典型值:

0x06(5Hz)

#defineGYRO_CONFIG0x1B//陀螺仪自检及测量围,典型值:

0x18(不自检,2000deg/s)

#defineACCEL_CONFIG0x1C//加速计自检、测量围及高通滤波频率,典型值:

0x01(不自检,2G,5Hz)

#defineACCEL_XOUT_H0x3B

#defineACCEL_XOUT_L0x3C

#defineACCEL_YOUT_H0x3D

#defineACCEL_YOUT_L0x3E

#defineACCEL_ZOUT_H0x3F

#defineACCEL_ZOUT_L0x40

#defineTEMP_OUT_H0x41

#defineTEMP_OUT_L0x42

#defineGYRO_XOUT_H0x43

#defineGYRO_XOUT_L0x44

#defineGYRO_YOUT_H0x45

#defineGYRO_YOUT_L0x46

#defineGYRO_ZOUT_H0x47

#defineGYRO_ZOUT_L0x48

#definePWR_MGMT_10x6B//电源管理,典型值:

0x00(正常启用)

#defineWHO_AM_I0x75//IIC地址寄存器(默认数值0x68,只读)

#defineSlaveAddress0xD0//IIC写入时的地址字节数据,+1为读取

#defineDataPortPORTA

#defineRSPORTB_PB1//PTS_PTS7

#defineRWPORTB_PB2//PTJ_PTJ7

#defineENPORTB_PB3//PTJ_PTJ6

#definePSBPORTB_PB0

#defineSDAPORTB_PB4

#defineSCLPORTB_PB5

floatx1,y1,z1;

intX,Y,Z,Q,W,E;

charcy;

uchara[]={0,0x2e,0,0};

ucharb[]={0,0,0,0x2e,0};

ucharc[]={0,0,0,0x2e,0};

uchare[]={0,0,0,0x2e,0};

voidPLL_Init(void)//PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1)

{

CLKSEL=0X00;//初始化PLL前先使用外部晶振

PLLCTL_PLLON=1;//开启PLL

SYNR=0x40|0x04;//pllclock=2*osc*(1+SYNR)/(1+REFDV)=80MHz;

REFDV=0x80|0x01;

/*1_0x80|0x01;2_3_0xc0|0x034_0x40|0x04;5_0XC0|0X05;*/

POSTDIV=0x00;

_asm(nop);//BUSCLOCK=40M

_asm(nop);

while(!

(CRGFLG_LOCK==1));//等待PLL稳定

CLKSEL_PLLSEL=1;//fBUS采用根据PLL频率设定

DDRA=0xFF;//SetPORTAInput

DDRB=0xFF;

}

voidPIT_Init(void)//定时中断初始化函数2MS定时中断设置

{

PITCFLMT_PITE=0;//定时中断通道0关

PITCE_PCE0=1;//定时器通道0使能

PITMTLD0=199;//8位定时器初值设定。

200分频,在40MHzBusClock下,为0.2MHz。

即5us

PITLD0=599;//16位定时器初值设定。

PITTIME*0.005MS=2ms

PITMUX_PMUX0=0;//选择时基

PITINTE_PINTE0=1;//定时器中断通道0中断使能

PITCFLMT_PITE=1;//定时器通道0使能

}

voiddelays(intms)

{

intii,jj;

if(ms<1)ms=1;

for(ii=0;ii

for(jj=0;jj<2;jj++);//busclk:

16MHz--1ms(12*1335/16000)=16*8000/48000

}

voiddelay(intms)

{

intii,jj;

if(ms<1)ms=1;

for(ii=0;ii

for(jj=0;jj<2600;jj++);//busclk:

16MHz--1ms(12*1335/16000)=16*8000/48000

}

voiddelay_us(intn)

{

while(n--){

_asm(nop);_asm(nop);_asm(nop);_asm(nop);_asm(nop);

}

}

voiddelayM(unsignedintt)

{unsignedinti,j;

for(i=0;i

for(j=0;j<120;j++);

}

/********检测忙位**********/

voidCheck_Busy(void)

{

DDRA=0x00;//置总线为读入

asm(nop);

asm(nop);

RS=0;

RW=1;

EN=1;

while((DataPort&0x80)==0x80);//忙则等待

EN=0;

DDRA=0xFF;//置总线为输出

}

/********写命令**********/

voidwrite_(unsignedcharCmd)

{

Check_Busy();

RS=0;

RW=0;

DataPort=Cmd;

delay

(1);

EN=1;

delay

(1);

EN=0;

}

/********写数据**********/

voidwrite_date(unsignedcharData)

{

Check_Busy();

delay

(1);

RS=1;

RW=0;

DataPort=Data;

delay

(1);

EN=1;

delay

(1);

EN=0;

}

/******液晶屏初始化******/

voidLCD_init(void)

{

PSB=1;

write_(0x34);//选择基本指令集

delay

(1);//大于40MS的延时程序

write_(0x30);//选择8bit数据流

delay

(1);

write_(0x0c);//开显示(无游标、不反白)

delay

(1);//延时大于100us

write_(0x01);//清除显示,并且设定地址指针为00H

delay

(1);//延时大于10ms

 

}

voidlcd_pos(ucharX,ucharY)

{

ucharpos;

if(X==0)

{X=0x80;}

elseif(X==1)

{X=0x90;}

elseif(X==2)

{X=0x88;}

elseif(X==3)

{X=0x98;}

pos=X+Y;

write_(pos);//显示地址

}

ucharqu_mo(ucharz)

{

switch(z)

{

case0:

return0x30;

case1:

return0x31;

case2:

return0x32;

case3:

return0x33;

case4:

return0x34;

case5:

return0x35;

case6:

return0x36;

case7:

return0x37;

case8:

return0x38;

case9:

return0x39;

default:

return0x2e;

}

}

voidshuzu0(unsignedchary0,unsignedcharx0)//显示高度

{

lcd_pos(y0,x0);

write_date(qu_mo(a[0]));

write_date(qu_mo(a[1]));

write_date(qu_mo(a[2]));

write_date(qu_mo(a[3]));

write_date(0x44);

lcd_pos(y0,x0);

delays

(1);

}

voidshuzu1(unsignedchary1,unsignedcharx1)//显示X

{

lcd_pos(y1,x1);

write_date(b[0]);

write_date(qu_mo(b[1]));

write_date(qu_mo(b[2]));

write_date(qu_mo(b[3]));

write_date(qu_mo(b[4]));

write_date(0x44);

lcd_pos(y1,x1);

delays

(1);

}

voidshuzu2(unsignedchary2,unsignedcharx2)//显示Y

{

lcd_pos(y2,x2);

write_date(c[0]);

write_date(qu_mo(c[1]));

write_date(qu_mo(c[2]));

write_date(qu_mo(c[3]));

write_date(qu_mo(c[4]));

write_date(0x44);

lcd_pos(y2,x2);

delays

(1);

}

voidshuzu3(unsignedchary3,unsignedcharx3)//显示Z

{

lcd_pos(y3,x3);

write_date(e[0]);

write_date(qu_mo(e[1]));

write_date(qu_mo(e[2]));

write_date(qu_mo(e[3]));

write_date(qu_mo(e[4]));

write_date(0x44);

lcd_pos(y3,x3);

delays

(1);

}

/***********************************************

显示字符串

x:

横坐标值,围0~8

y:

纵坐标值,围1~4

************************************************/

voidLCD_PutString(unsignedcharx,unsignedchary,unsignedchar*s)

{

lcd_pos(x,y);

while(*s>0)

{

write_date(*s);

s++;

delays

(1);

}

}

voidsda_high()//SDA高电平的产生

{

DDRB_DDRB4=1;

SDA=1;

_asm(nop);

_asm(nop);

_asm(nop);

_asm(nop);

return;

}

//**************************************

//SDA低电平的产生

//**************************************

voidsda_low()//SDA低电平的产生

{

DDRB_DDRB4=1;

SDA=0;

_asm(nop);

_asm(nop);

_asm(nop);

_asm(nop);

return;

}

//**************************************

//SCL高电平产生

//**************************************

voidscl_high()//SCL高电平产生

{

DDRB_DDRB5=1;;

SCL=1;

_asm(nop);

_asm(nop);

_asm(nop);

_asm(nop);

return;

}

//**************************************

//SCL低电平的产生

//**************************************

voidscl_low()//SCL低电平的产生

{

DDRB_DDRB5=1;;

SCL=0;

_asm(nop);

_asm(nop);

_asm(nop);

_asm(nop);

return;

}

//**************************************

//I2C起始信号

//**************************************

voidI2C_Start()

{

sda_high();//拉高数据线

scl_high();//拉高时钟线

delayM

(1);//延时

sda_low();//产生下降沿

delayM

(1);//延时

scl_low();//拉低时钟线

}

//**************************************

//I2C停止信号

//**************************************

voidI2C_Stop()

{

sda_low();//拉低数据线

scl_high();//拉高时钟线

delayM

(1);//延时

sda_high();//产生上升沿

delayM

(1);//延时

}

//**************************************

//I2C发送应答信号

//入口参数:

ack(0:

ACK1:

NAK)

//**************************************

voidI2C_SendACK(charack)

{

if(ack)

sda_high();

else

sda_low();//写应答信号

scl_high();//拉高时钟线

delayM

(1);//延时

scl_low();//拉低时钟线

delayM

(1);//延时

}

//**************************************

//I2C接收应答信号

//**************************************

ucharI2C_RecvACK()

{

DDRB_DDRB4=0;

scl_high();//拉高时钟线

DDRB_DDRB4=0;

delayM

(1);//延时

if(SDA==1)

{

cy=1;

}

else

{

cy=0;

}

//cy=SDA;//读应答信号

scl_low();//拉低时钟线

delayM

(1);//延时

DDRB_DDRB4=1;

returncy;

}

//**************************************

//向I2C总线发送一个字节数据

//**************************************

voidI2C_SendByte(uchardat)

{

uchari;

for(i=0;i<8;i++)//8位计数器

{

if((dat<

{

sda_high();

}

else

{

sda_low();

}

//SDA=cy;//送数据口

scl_high();//拉高时钟线

delayM

(1);//延时

scl_low();//拉低时钟线

delayM

(1);//延时

}

I2C_RecvACK();

}

//**************************************

//从I2C总线接收一个字节数据

//**************************************

ucharI2C_RecvByte()

{

uchari;

uchardat=0,cy;

sda_high();//使能部上拉,准备读取数据,

DDRB_DDRB4=0;

for(i=0;i<8;i++)//8位计数器

{

dat<<=1;

scl_high();//拉高时钟线

delayM

(1);//延时

if(SDA==1)

{

cy=1;

}

else

{

cy=0;

}

dat|=cy;//读数据

scl_low();//拉低时钟线

delayM

(1);//延时

}

DDRB_DDRB4=1;

returndat;

}

//**************************************

//向I2C设备写入一个字节数据

//**************************************

voidSingle_WriteI2C(ucharREG_Address,ucharREG_data)

{

I2C_Start();//起始信号

I2C_SendByte(SlaveAddress);//发送设备地址+写信号

I2C_SendByte(REG_Address);//部寄存器地址,

I2C_SendByte(REG_data);//部寄存器数据,

I2C_Stop();//发送停止信号

}

//**************************************

//从I2C设备读取一个字节数据

//**************************************

ucharSingle_ReadI2C(ucharREG_Address)

{

ucharREG_data;

I2C_Start();//起始信号

I2C_SendByte(SlaveAddress);//发送设备地址+写信号

I2C_SendByte(REG_Address);//发送存储单元地址,从0开始

I2C_Start();//起始信号

I2C_SendByte(SlaveAddress+1);//发送设备地址+读信号

REG_data=I2C_RecvByte();//读出寄存器数据

I2C_SendACK

(1);//接收应答信号

I2C_Stop();//停止信号

returnREG_data;

}

//**************************************

//初始化MPU6050

//**************************************

voidInitMPU6050()

{

Single_WriteI2C(PWR_MGMT_1,0x00);//解除休眠状态

Single_WriteI2C(SMPLRT_DIV,0x07);

Single_WriteI2C(CONFIG,0x06);

Single_WriteI2C(GYRO_CONFIG,0x18);

Single_WriteI2C(ACCEL_CONFIG,0x01);

}

//**************************************

//合成数据

//**************************************

intGetData(ucharREG_Address)

{

ucharH,L;

H=Single_ReadI2C(REG_Address);

L=Single_ReadI2C(REG_Address+1);

return(H<<8)+L;//合成数据

}

shortMPU6050_Get_Angle(floatx,floaty,floatz,uchardir)

{

floattemp;

floatres=0;

switch(dir)

{

case0:

//与自然Z轴的角度

temp=sqrt((x*x+y*y))/z;

res=atan(temp);

break;

case1:

//与自然X轴的角度

temp=x/sqrt((y*y+z*z));

res=atan(temp);

break;

case2:

//与自然Y轴的角度

temp=y/sqrt((x*x+z*z));

res=atan(temp);

break;

}

returnres*.0/3.1415926;//把弧度转换成角度

}

voidmain(void)

{

DisableInterrupts;

PLL_Init();

//PIT_Init();

delay(300);//上电延时

InitMPU6050();//初始化MPU6050

LCD_init();

EnableInterrupts;

while

(1)

{

x1=GetData(ACCEL_XOUT_H);//X轴输出值,待转化为角度

y1=GetData(ACCEL_YOUT_H);//

z1=GetData(ACCEL_ZOUT_H);//

X=MPU6050_Get_Angle(x1,y1,z1,0)*10.0;//把得到的角度扩大十倍

Y=MPU6050_Get_Angle(x1,y1,z1,1)*10.0;

Z=MPU6050_Get_Angle(x1,y1,z1,2)*10.0;

//显示角度

if(X>=0)

b[0]=0x2b;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 其它课程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1