您现在的位置是:主页 > news > 法律咨询东莞网站建设/网站关键词排名怎么优化
法律咨询东莞网站建设/网站关键词排名怎么优化
admin2025/5/31 23:11:54【news】
简介法律咨询东莞网站建设,网站关键词排名怎么优化,开发app的公司挣钱吗,政府平台公司是什么意思预备知识(基于STM32开发板(正点原子)) 1、MPU6050简介 1.1、MPU6050简介-什么是MPU6050? MPU6050是InvenSense公司推出的全球首款整合性6轴运动处理组件,内带3轴陀螺仪和3轴加速度传感器,并且含有一个第…
预备知识(基于STM32开发板(正点原子))
-
1、MPU6050简介
-
1.1、MPU6050简介-什么是MPU6050?
MPU6050是InvenSense公司推出的全球首款整合性6轴运动处理组件,内带3轴陀螺仪和3轴加速度传感器,并且含有一个第二IIC接口,可用于连接外部磁力传感器,利用自带数字运动处理器(DMP: Digital Motion Processor)硬件加速引擎,通过主IIC接口,可以向应用端输出完整的9轴姿态融合演算数据。
有了DMP,我们可以使用InvenSense公司提供的运动处理资料库,非常方便的实现姿态解算,降低了运动处理运算对操作系统的负荷,同时大大降低了开发难度 。
-
1.2、MPU6050简介-MPU6050的特点
①自带数字运动处理( DMP: Digital Motion Processing ),可以输出6轴或9轴(需外接磁传感器)姿态解算数据。
②集成可程序控制,测量范围为±250、±500、±1000与±2000°/sec 的3轴角速度感测器(陀螺仪)
③集成可程序控制,范围为±2g、±4g、±8g和±16g的3轴加速度传感器
④自带数字温度传感器
⑤可输出中断(interrupt),支持姿势识别、摇摄、画面放大缩小、滚动、快速下降中断、high-G中断、零动作感应、触击感应、摇动感应功能
⑥自带1024字节FIFO,有助于降低系统功耗
⑦高达400Khz的IIC通信接口
⑧超小封装尺寸:4x4x0.9mm(QFN)
-
1.3、MPU6050简介-MPU6050框图
AD0=0->地址=0X68
AD0=1->地址=0X69(F4板子上已经设置到AD0=0)
-
1.4、MPU6050简介-MPU6050初始化(后面再继续粘贴程序)
①初始化IIC接口。
②复位MPU6050。由电源管理寄存器1(0X6B)控制。
③设置角速度传感器和加速度传感器的满量程范围。由陀螺仪配置寄存器(0X1B)和加速度传感器配置寄存器(0X1C)设置 。
④设置其他参数。配置中断,由中断使能寄存器(0X38)控制;设置AUX IIC接口,由户控制寄存器(0X6A)控制;设置FIFO,由FIFO使能寄存器(0X23)控制;陀螺仪采样率 ,由采样率分频寄存器(0X19)控制;设置数字低通滤波器,由配置寄存器(0X1A)控制。
⑤设置系统时钟。由电源管理寄存器1(0X6B)控制。一般选择x轴陀螺PLL作为时钟源,以获得更高精度的时钟。
⑥使能角速度传感器(陀螺仪)和加速度传感器。由电源管理寄存器2(0X6C)控制
-
1.5、MPU6050简介-寄存器介绍
-
电源管理寄存器1(0X6B)
DEVICE_RESE=1,复位MPU6050,复位完成后,自动清零。
SLEEP=1,进入睡眠模式;SLEEP=0,正常工作模式。
TEMP_DIS,用于设置是否使能温度传感器,设置为0,则使能
CLKSEL[2:0],用于选择系统时钟源,如右表所示:
CLKSEL[2:0] | 时钟源 |
000 | 内部8M RC晶振 |
001 | PLL,使用X轴陀螺作为参考 |
010 | PLL,使用Y轴陀螺作为参考 |
011 | PLL,使用Z轴陀螺作为参考 |
100 | PLL,使用外部32.768Khz作为参考 |
101 | PLL,使用外部19.2Mhz作为参考 |
110 | 保留 |
111 | 关闭时钟,保持时序产生电路复位状态 |
-
陀螺仪配置寄存器(0X1B)
该寄存器我们只关心FS_SEL[1:0]这两个位,用于设置陀螺仪的满量程范围:0,±250°/S;1,±500°/S;2,±1000°/S;3,±2000°/S;我们一般设置为3,即±2000°/S,因为陀螺仪的ADC为16位分辨率,所以得到灵敏度为:65536/4000=16.4LSB/(°/S)。
-
加速度传感器配置寄存器(0X1C)
该寄存器我们只关心AFS_SEL[1:0]这两个位,用于设置加速度传感器的满量程范围:0,±2g;1,±4g;2,±8g;3,±16g;我们一般设置为0,即±2g,因为加速度传感器的ADC也是16位,所以得到灵敏度为:65536/4=16384LSB/g。
-
FIFO使能寄存器(0X23)
该寄存器用于控制FIFO使能,在简单读取传感器数据的时候,可以不用FIFO,设置对应位为:0,即可禁止FIFO,设置为1,则使能FIFO。
注意:加速度传感器的3个轴,全由1个位(ACCEL_FIFO_EN)控制,只要该位置1,则加速度传感器的三个通道都开启FIFO了
-
陀螺仪采样率分频寄存器(0X19)
该寄存器用于设置MPU6050的陀螺仪采样频率,计算公式为:
采样频率 = 陀螺仪输出频率 / (1+SMPLRT_DIV)
这里陀螺仪的输出频率,是1Khz或者8Khz,与数字低通滤波器(DLPF)的设置有关,当DLPF_CFG=0/7的时候,频率为8Khz,其他情况是1Khz。而且DLPF滤波频率一般设置为采样率的一半。采样率,我们假定设置为50Hz,那么:SMPLRT_DIV=1000/50-1=19。
-
配置寄存器(0X1A)
重点看数字低通滤波器(DLPF)的设置位,即:DLPF_CFG[2:0],加速度计和陀螺仪,都是根据这三个位的配置进行过滤的,如下表:
DLPF_CFG[2:0] | 加速度传感器 | 角速度传感器 | |||
带宽(Hz) | 延迟(ms) | 带宽(Hz) | 延迟(ms) | Fs(Khz) | |
000 | 260 | 0 | 256 | 0.98 | 8 |
001 | 184 | 2.0 | 188 | 1.9 | 1 |
010 | 94 | 3.0 | 98 | 2.8 | 1 |
011 | 44 | 4.9 | 42 | 4.8 | 1 |
100 | 21 | 8.5 | 20 | 8.3 | 1 |
101 | 10 | 13.8 | 10 | 13.4 | 1 |
110 | 5 | 19.0 | 5 | 18.6 | 1 |
111 | 保留 | 保留 | 8 |
-
电源管理寄存器2(0X6C)
该寄存器的LP_WAKE_CTRL用于控制低功耗时的唤醒频率,本例程用不到。剩下的6位,分别控制加速度和陀螺仪的x/y/z轴是否进入待机模式,这里我们全部都不进入待机模式,所以全部设置为:0 ,即可。
-
加速度传感器数据输出寄存器(0X3B~0X40)
加速度传感器数据输出寄存器总共由6个寄存器组成,输出X/Y/Z三个轴的加速度传感器值,高字节在前,低字节在后。
-
陀螺仪数据输出寄存器(0X43~0X48)
陀螺仪数据输出寄存器总共由6个寄存器组成,输出X/Y/Z三个轴的陀螺仪传感器数据,高字节在前,低字节在后。
-
温度传感器数据输出寄存器(0X41~0X42)
通过读取0X41(高8位)和0X42(低8位)寄存器得到,温度换算公式为:
Temperature = 36.53 + regval/340
其中,Temperature为计算得到的温度值,单位为℃,regval为从0X41和0X42读到的温度传感器值。
相关程序
硬件连接STM32F4
- 初始化MPU6050
//初始化MPU6050
//返回值:0,成功
// 其他,错误代码
u8 MPU_Init(void)
{ u8 res;IIC_Init();//初始化IIC总线MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X80); //复位MPU6050delay_ms(100);MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X00); //唤醒MPU6050 MPU_Set_Gyro_Fsr(3); //陀螺仪传感器,±2000dpsMPU_Set_Accel_Fsr(0); //加速度传感器,±2gMPU_Set_Rate(50); //设置采样率50HzMPU_Write_Byte(MPU_INT_EN_REG,0X00); //关闭所有中断MPU_Write_Byte(MPU_USER_CTRL_REG,0X00); //I2C主模式关闭MPU_Write_Byte(MPU_FIFO_EN_REG,0X00); //关闭FIFOMPU_Write_Byte(MPU_INTBP_CFG_REG,0X80); //INT引脚低电平有效res=MPU_Read_Byte(MPU_DEVICE_ID_REG);if(res==MPU_ADDR)//器件ID正确{MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01); //设置CLKSEL,PLL X轴为参考MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00); //加速度与陀螺仪都工作MPU_Set_Rate(50); //设置采样率为50Hz}else return 1;return 0;
}
2.设置MPU6050陀螺仪传感器满量程范围
//设置MPU6050陀螺仪传感器满量程范围
//fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
//返回值:0,设置成功
// 其他,设置失败
u8 MPU_Set_Gyro_Fsr(u8 fsr)
{return MPU_Write_Byte(MPU_GYRO_CFG_REG,fsr<<3);//设置陀螺仪满量程范围
}
3.设置MPU6050加速度传感器满量程范围
//设置MPU6050加速度传感器满量程范围
//fsr:0,±2g;1,±4g;2,±8g;3,±16g
//返回值:0,设置成功
// 其他,设置失败
u8 MPU_Set_Accel_Fsr(u8 fsr)
{return MPU_Write_Byte(MPU_ACCEL_CFG_REG,fsr<<3);//设置加速度传感器满量程范围
}
4.设置MPU6050的数字低通滤波器
//设置MPU6050的数字低通滤波器
//lpf:数字低通滤波频率(Hz)
//返回值:0,设置成功
// 其他,设置失败
u8 MPU_Set_LPF(u16 lpf)
{u8 data=0;if(lpf>=188)data=1;else if(lpf>=98)data=2;else if(lpf>=42)data=3;else if(lpf>=20)data=4;else if(lpf>=10)data=5;else data=6; return MPU_Write_Byte(MPU_CFG_REG,data);//设置数字低通滤波器
}
5.设置MPU6050的采样率(假定Fs=1KHz)
//设置MPU6050的采样率(假定Fs=1KHz)
//rate:4~1000(Hz)
//返回值:0,设置成功
// 其他,设置失败
u8 MPU_Set_Rate(u16 rate)
{u8 data;if(rate>1000)rate=1000;if(rate<4)rate=4;data=1000/rate-1;data=MPU_Write_Byte(MPU_SAMPLE_RATE_REG,data); //设置数字低通滤波器return MPU_Set_LPF(rate/2); //自动设置LPF为采样率的一半
}
6.得到温度值
//得到温度值
//返回值:温度值(扩大了100倍)
short MPU_Get_Temperature(void)
{u8 buf[2]; short raw;float temp;MPU_Read_Len(MPU_ADDR,MPU_TEMP_OUTH_REG,2,buf); raw=((u16)buf[0]<<8)|buf[1]; temp=36.53+((double)raw)/340; return temp*100;;
}
7.得到陀螺仪值(原始值)
//得到陀螺仪值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
// 其他,错误代码
u8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
{u8 buf[6],res; res=MPU_Read_Len(MPU_ADDR,MPU_GYRO_XOUTH_REG,6,buf);if(res==0){*gx=((u16)buf[0]<<8)|buf[1]; *gy=((u16)buf[2]<<8)|buf[3]; *gz=((u16)buf[4]<<8)|buf[5];} return res;;
}
8.得到加速度值(原始值)
//得到加速度值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
// 其他,错误代码
u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az)
{u8 buf[6],res; res=MPU_Read_Len(MPU_ADDR,MPU_ACCEL_XOUTH_REG,6,buf);if(res==0){*ax=((u16)buf[0]<<8)|buf[1]; *ay=((u16)buf[2]<<8)|buf[3]; *az=((u16)buf[4]<<8)|buf[5];} return res;;
}
9.IIC连续写
//IIC连续写
//addr:器件地址
//reg:寄存器地址
//len:写入长度
//buf:数据区
//返回值:0,正常
// 其他,错误代码
u8 MPU_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf)
{u8 i; IIC_Start(); IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令 if(IIC_Wait_Ack()) //等待应答{IIC_Stop(); return 1; }IIC_Send_Byte(reg); //写寄存器地址IIC_Wait_Ack(); //等待应答for(i=0;i<len;i++){IIC_Send_Byte(buf[i]); //发送数据if(IIC_Wait_Ack()) //等待ACK{IIC_Stop(); return 1; } } IIC_Stop(); return 0;
}
10.IIC连续读
//IIC连续读
//addr:器件地址
//reg:要读取的寄存器地址
//len:要读取的长度
//buf:读取到的数据存储区
//返回值:0,正常
// 其他,错误代码
u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf)
{ IIC_Start(); IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令 if(IIC_Wait_Ack()) //等待应答{IIC_Stop(); return 1; }IIC_Send_Byte(reg); //写寄存器地址IIC_Wait_Ack(); //等待应答IIC_Start();IIC_Send_Byte((addr<<1)|1);//发送器件地址+读命令 IIC_Wait_Ack(); //等待应答 while(len){if(len==1)*buf=IIC_Read_Byte(0);//读数据,发送nACK else *buf=IIC_Read_Byte(1); //读数据,发送ACK len--;buf++; } IIC_Stop(); //产生一个停止条件 return 0;
}
11.IIC写一个字节
//IIC写一个字节
//reg:寄存器地址
//data:数据
//返回值:0,正常
// 其他,错误代码
u8 MPU_Write_Byte(u8 reg,u8 data)
{ IIC_Start(); IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令 if(IIC_Wait_Ack()) //等待应答{IIC_Stop(); return 1; }IIC_Send_Byte(reg); //写寄存器地址IIC_Wait_Ack(); //等待应答 IIC_Send_Byte(data);//发送数据if(IIC_Wait_Ack()) //等待ACK{IIC_Stop(); return 1; } IIC_Stop(); return 0;
}
12.IIC读一个字节
//IIC读一个字节
//reg:寄存器地址
//返回值:读到的数据
u8 MPU_Read_Byte(u8 reg)
{u8 res;IIC_Start(); IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令 IIC_Wait_Ack(); //等待应答 IIC_Send_Byte(reg); //写寄存器地址IIC_Wait_Ack(); //等待应答IIC_Start();IIC_Send_Byte((MPU_ADDR<<1)|1);//发送器件地址+读命令 IIC_Wait_Ack(); //等待应答 res=IIC_Read_Byte(0);//读取数据,发送nACK IIC_Stop(); //产生一个停止条件 return res;
}
13.其他IIC程序汇总
//初始化IIC
void IIC_Init(void)
{ GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟//GPIOB8,B9初始化设置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化IIC_SCL=1;IIC_SDA=1;
}
//产生IIC起始信号
void IIC_Start(void)
{SDA_OUT(); //sda线输出IIC_SDA=1; IIC_SCL=1;delay_us(4);IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4);IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void IIC_Stop(void)
{SDA_OUT();//sda线输出IIC_SCL=0;IIC_SDA=0;//STOP:when CLK is high DATA change form low to highdelay_us(4);IIC_SCL=1; IIC_SDA=1;//发送I2C总线结束信号delay_us(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)
{u8 ucErrTime=0;SDA_IN(); //SDA设置为输入 IIC_SDA=1;delay_us(1); IIC_SCL=1;delay_us(1); while(READ_SDA){ucErrTime++;if(ucErrTime>250){IIC_Stop();return 1;}}IIC_SCL=0;//时钟输出0 return 0;
}
//产生ACK应答
void IIC_Ack(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=0;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;
}
//不产生ACK应答
void IIC_NAck(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=1;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(u8 txd)
{ u8 t; SDA_OUT(); IIC_SCL=0;//拉低时钟开始数据传输for(t=0;t<8;t++){ IIC_SDA=(txd&0x80)>>7;txd<<=1; delay_us(2); //对TEA5767这三个延时都是必须的IIC_SCL=1;delay_us(2); IIC_SCL=0; delay_us(2);}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 IIC_Read_Byte(unsigned char ack)
{unsigned char i,receive=0;SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){IIC_SCL=0; delay_us(2);IIC_SCL=1;receive<<=1;if(READ_SDA)receive++; delay_us(1); } if (!ack)IIC_NAck();//发送nACKelseIIC_Ack(); //发送ACK return receive;
}