xs128控制mpu6050程序.docx
- 文档编号:24797953
- 上传时间:2023-06-01
- 格式:DOCX
- 页数:21
- 大小:18.38KB
xs128控制mpu6050程序.docx
《xs128控制mpu6050程序.docx》由会员分享,可在线阅读,更多相关《xs128控制mpu6050程序.docx(21页珍藏版)》请在冰豆网上搜索。
xs128控制mpu6050程序
#include
#include"derivative.h"/*derivative-specificdefinitions*/
#include
#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;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- xs128 控制 mpu6050 程序
![提示](https://static.bdocx.com/images/bang_tan.gif)