【MEMS传感器】基于MPU6500/ICM206xx系列的移动监测

最近要做一个物体移动报警的项目,刚好六轴传感器里面就有,选定型号为ICM20602,但是手边只有MPU6500,对比了下寄存器,这两个寄存器地址基本相同。

在MPU6500的手册里面有专门的移动操作指南如下图:

代码贴出来分享下:


#ifndef MPU6500_H_
#define MPU6500_H_

#include "include.h"
#define MPU6500 1

#if MPU6500

#define  MPU6500_WHO_AM_I  0x70
/* Hardware registers needed by driver. */
struct pmu6500_sensor_reg {
	unsigned char who_am_i;
	unsigned char rate_div;
	unsigned char lpf;
	//    unsigned char prod_id;
	unsigned char xg_offs_usr;
	unsigned char yg_offs_usr;
	unsigned char zg_offs_usr;
	unsigned char user_ctrl;
	unsigned char fifo_en;
	unsigned char gyro_cfg;
	unsigned char accel_cfg;
	unsigned char accel_cfg2;
	unsigned char lp_mode_cfg;
	unsigned char motion_thr;
	//    unsigned char motion_dur;
	unsigned char fifo_count_h;
	unsigned char fifo_r_w;
	unsigned char raw_gyro;
	unsigned char raw_accel;
	unsigned char temp;
	unsigned char int_enable;
	//    unsigned char dmp_int_status;
	unsigned char int_status;
	unsigned char accel_intel;
	unsigned char pwr_mgmt_1;
	unsigned char pwr_mgmt_2;
	unsigned char int_pin_cfg;
	//    unsigned char mem_r_w;
	unsigned char xa_offset;
	unsigned char ya_offset;
	unsigned char za_offset;
	//    unsigned char i2c_mst;
	//    unsigned char bank_sel;
	//    unsigned char mem_start_addr;
	unsigned char prgm_start_h;
	//    unsigned char fifo_wm_th;
	unsigned char signal_reset;
	//    unsigned char st_gyro;
	unsigned char st_accel;
};
#endif





void MPU6500_Init(void);
void MPU6500_read_ID(void);
void MPU6500_Restart(void);
void MPU6500_CHIP_startup(void);
void MPU6500_CHIP_POWERON(void);
void MPU6500_CHIP_POWEROFF(void);
void MPU6500_ACC_POWERON(void);
void MPU6500_ACC_POWEROFF(void);
void MPU6500_GYRO_POWERON(void);
void MPU6500_GYRO_POWEROFF(void);
void MPU6500_ACC_ENABLE(void);
void MPU6500_GYRO_ENABLE(void);



//                 FIFO Setting                                     





//                Lowpower Motion Detect                            


void PPU_6500_WAKEON_motion(void);

//               GET	   DATA                                     

void MPU6500_GetACC(void);



#endif /* MPU6500_H_ */

#include "MPU6500.h"
//
#if MPU6500
uint8_t read_MPU6500_ID=0xff;
const struct pmu6500_sensor_reg mpu6500_reg = {
	.who_am_i       = 0x75,
	.rate_div       = 0x19,
	.lpf            = 0x1A,
	//    .prod_id        = 0x0C,
	.xg_offs_usr    = 0x13,
	.yg_offs_usr    = 0x15,
	.zg_offs_usr    = 0x17,
	.user_ctrl      = 0x6A,
	.fifo_en        = 0x23,
	.gyro_cfg       = 0x1B,
	.accel_cfg      = 0x1C,
	.accel_cfg2     = 0x1D,
	.lp_mode_cfg    = 0x1E,
	.motion_thr     = 0x1F,
	//    .motion_dur     = 0x20,
	.fifo_count_h   = 0x72,
	.fifo_r_w       = 0x74,
	.raw_gyro       = 0x43,
	.raw_accel      = 0x3B,
	.temp           = 0x41,
	.int_enable     = 0x38,
	//    .dmp_int_status = 0x39,
	.int_status     = 0x3A,
	.accel_intel    = 0x69,
	.pwr_mgmt_1     = 0x6B,
	.pwr_mgmt_2     = 0x6C,
	.int_pin_cfg    = 0x37,
	//    .mem_r_w        = 0x6F,
	.xa_offset      = 0x77,
	.ya_offset      = 0x7A,
	.za_offset      = 0x7D,
	//    .i2c_mst        = 0x24,
	//    .bank_sel       = 0x6D,
	//    .mem_start_addr = 0x6E,
	.prgm_start_h   = 0x70,
	//    .fifo_wm_th     = 0x61,
	.signal_reset   = 0x68,
	//    .st_gyro        = 0x00,
	.st_accel       = 0x0D
};
#endif
//

#if  MPU6500

void MPU6500_read_ID(void)		// read_ID
{
		uint8_t temp_who_am_i,num;
		for (num=0;num<4;num++)
		{
			SPI_master_read_register(mpu6500_reg.who_am_i,1,&temp_who_am_i);	//  MPU6500 who_am_i address is 0x75,the only read defult value is 0x70;
			if(temp_who_am_i == MPU6500_WHO_AM_I)
			{
				printf("Register = 0x%x,who-am-i  =0x%02x\r\n",mpu6500_reg.who_am_i,temp_who_am_i);break;
			}
			else if(num==3 && temp_who_am_i != 0x12)
			{
				read_MPU6500_ID = false;
				printf("NO MPU6500\r\n");
			}
		}
}

void MPU6500_Init(void)
{
	uint8_t temp;
	MPU6500_Restart();
	delay_ms(100);
	temp=0x3F;
	SPI_master_write_register(mpu6500_reg.pwr_mgmt_2, 1, &temp);	    //disable ACC and GYRO by default.
	delay_ms(10);
	MPU6500_read_ID();
	if (read_MPU6500_ID != 0)
	{
		MPU6500_CHIP_startup();
	}
		
}

void MPU6500_Restart(void)
{
	uint8_t temp;
	temp=0x80;
	SPI_master_write_register(mpu6500_reg.pwr_mgmt_1, 1, &temp);		//reset
}

void MPU6500_CHIP_startup(void)
{
	uint8_t temp,ch;
	MPU6500_CHIP_POWERON();
	MPU6500_ACC_POWERON();
	MPU6500_GYRO_POWERON();
	temp=0x27;				//SMPLRT_DIV=9	SAMPLE_RATE = INTERNAL_SAMPLE_RATE / (1 + SMPLRT_DIV)	Where INTERNAL_SAMPLE_RATE = 1kHz
	SPI_master_write_register(0x19, 1, &temp);		//ODR设置为25HZ
	temp=0x05;				//Gro  3db BW,截止频率10HZ
	SPI_master_write_register(0x1a, 1, &temp);		//Gro滤波器设置
	SPI_master_read_register(0x1b,1,&ch);			//读取gro配置
	ch &= 0xE4;				//250dps
	SPI_master_write_register(0x1b, 1,&ch);			//陀螺量程设置
	temp=0x18;				//[4:3]		±2g (00), ±4g (01), ±8g (10), ±16g (11)
	SPI_master_write_register(0x1c, 1, &temp);		//加表量程设置
	temp=0x05;				//Acc  BW=10HZ
	SPI_master_write_register(0x1d, 1, &temp);		//Acc滤波器设置
	temp=0x00;
	SPI_master_write_register(0x1e, 1, &temp);		//关闭低功耗模式,
	temp=0x00;
	SPI_master_write_register(0x69, 1, &temp);		//Acc Wake-on-Motion设置 ---disable
	delay_ms(10);
}

void MPU6500_CHIP_POWERON(void)
{
	uint8_t temp;
	temp=0x01;	//achieve full gyroscope performance
	SPI_master_write_register(mpu6500_reg.pwr_mgmt_1, 1, &temp);      //00000001 PWR_MGMT_1 [6]SLEEP	When set to 1, the chip is set to sleep mode.
	//[2:0]	CLKSEL[2:0] 1	Auto selects the best available clock source  PLL if ready, else use the Internal oscillator
	delay_ms(10);              //for entering sleep take effect
}

void MPU6500_CHIP_POWEROFF(void)
{
	uint8_t temp;
	temp=0x41;
	SPI_master_write_register(mpu6500_reg.pwr_mgmt_1, 1, &temp);      //00000001 PWR_MGMT_1       [6]	SLEEP	When set to 1, the chip is set to sleep mode.
	//                          [2:0]	CLKSEL[2:0] 1	Auto selects the best available clock source  PLL if ready, else use the Internal oscillator
	delay_ms(10);                  //for exiting sleep take effect
}

void MPU6500_ACC_POWERON(void)
{
	uint8_t ch;
	SPI_master_read_register(mpu6500_reg.pwr_mgmt_2,1,&ch);
	ch &= 0xC7;
	SPI_master_write_register(mpu6500_reg.pwr_mgmt_2, 1,&ch);        //set [5:3] as 0; 1  XYZ accelerometer is disabled. 0  XYZ accelerometer is on.
}
void MPU6500_ACC_POWEROFF(void)
{
	uint8_t ch;
	SPI_master_read_register(mpu6500_reg.pwr_mgmt_2,1,&ch);
	ch |= 0x38;
	SPI_master_write_register(mpu6500_reg.pwr_mgmt_2, 1,&ch);        //set [5:3] as 0; 1  XYZ accelerometer is disabled. 0  XYZ accelerometer is on.
}

void MPU6500_GYRO_POWERON(void)
{
	uint8_t ch;
	SPI_master_read_register(mpu6500_reg.pwr_mgmt_1,1,&ch);	//set gyro clk
	ch |=0x01;
	SPI_master_write_register(mpu6500_reg.pwr_mgmt_1, 1,&ch);
	delay_ms(1);

	SPI_master_read_register(mpu6500_reg.pwr_mgmt_2,1,&ch);
	ch &= 0xF8;
	SPI_master_write_register(mpu6500_reg.pwr_mgmt_2, 1,&ch);        //set [2:0] as 0; 1  XYZ gyroscope is disabled. 0  XYZ gyroscope is on.
	delay_ms(80);                 //for Start up of the gyro
}
void MPU6500_GYRO_POWEROFF(void)
{
	uint8_t ch;
	SPI_master_read_register(mpu6500_reg.pwr_mgmt_1,1,&ch);	//set gyro clk
	ch &= 0xFE;
	SPI_master_write_register(mpu6500_reg.pwr_mgmt_1, 1,&ch);
	delay_ms(1);

	//??? need to double check here whether UI or OIS is still using GYRO , don't do following untill no one use gyro anymore
	SPI_master_read_register(mpu6500_reg.pwr_mgmt_2, 1, &ch);
	ch = 0x80 | 0x07;
	SPI_master_write_register(mpu6500_reg.pwr_mgmt_2, 1, &ch);        //set [2:0] as 0; 1  XYZ gyroscope is disabled. 0  XYZ gyroscope is on.
	delay_ms(200);                 //for discharge
}

void MPU6500_ACC_ENABLE(void)
{
	uint8_t temp;
	temp=0x01;
	//量程,8g
	SPI_master_write_register(mpu6500_reg.accel_cfg, 1, &temp);//00010000 ACCEL_CONFIG [4:3]	AFS_SEL[1:0]	UI Path Accel Full Scale Select:10 = ∮8g
	//量程,16g
	//  write_1B(reg.accel_cfg,0x18);
	//速度,200Hz
	temp=0x04;
	SPI_master_write_register(mpu6500_reg.rate_div, 1, &temp);//00000100 SMPLRT_DIV SMPLRT_DIV[7:0]   200Hz = Divides the internal sample rate (see register CONFIG) to generate the sample rate that controls sensor data output rate, FIFO sample rate.  NOTE: This register is only effective when FCHOICE_B register bits are 2ˇb00, and (0 < DLPF_CFG < 7). This is the update rate of the sensor register: SAMPLE_RATE = INTERNAL_SAMPLE_RATE / (1 + SMPLRT_DIV) Where INTERNAL_SAMPLE_RATE = 1kHz
	//滤波器截止频率和噪声带宽
	temp=0x02;
	SPI_master_write_register(mpu6500_reg.accel_cfg2, 1,  &temp);//00100000 ACCEL_CONFIG2       [5:4]  DEC2_CFG[1:0] 0
	//                          [3]    ACCEL_FCHOICE_B    Used to bypass DLPF as shown in the table below
	//                          [2:0]    A_DLPF_CFG    100Hz Bend Pass UI path accelerometer low pass filter setting as shown in the table below  0 ODR 1/(1+SMPLRT_DIV)  : Filter BW 218(Hz)    Filter Delay 1.88(ms)
}
void MPU6500_GYRO_ENABLE(void)
{
	uint8_t  temp;
	//量程,2000dps
	temp=0x0c;
	SPI_master_write_register(mpu6500_reg.gyro_cfg, 1, &temp);//00001100 GYROSCOPE CONFIGURATION [4:2] UI Path Gyro Full Scale Select 011 = ∮2000dps
	//滤波器截止频率和噪声带宽
	temp=0x01;
	SPI_master_write_register(mpu6500_reg.lpf, 1, &temp);//00000001 CONFIGURATION [2:0]	DLPF_CFG[2:0] Filter BW 184(Hz) Filter Delay 2.9 (ms)
	//速度
	temp=0x04;
	SPI_master_write_register(mpu6500_reg.rate_div, 1, &temp);//00000100 SMPLRT_DIV SMPLRT_DIV[7:0]   200Hz = Divides the internal sample rate (see register CONFIG) to generate the sample rate that controls sensor data output rate, FIFO sample rate.  NOTE: This register is only effective when FCHOICE_B register bits are 2ˇb00, and (0 < DLPF_CFG < 7). This is the update rate of the sensor register: SAMPLE_RATE = INTERNAL_SAMPLE_RATE / (1 + SMPLRT_DIV) Where INTERNAL_SAMPLE_RATE = 1kHz
	//是否配置Gyro低功耗模式
	temp=0x00;
	SPI_master_write_register(mpu6500_reg.lp_mode_cfg, 1, &temp);//00000000 LP_MODE_CONFIG [7]	GYRO_CYCLE	When set to ˉ1ˇ low-power gyroscope mode is enabled.  Default setting is ˉ0ˇ
}

void MPU6500_GetACC(void)
{
	uint8_t buf[6]={0};
	uint8_t temp,value1,value2;
	int16_t acc[3]={0};
	float value;
	SPI_master_read_register(mpu6500_reg.raw_accel,6,&buf);
	acc[0] = (int16_t)(((int16_t)buf[0]) << 8 | buf[1]);		//x
	acc[1] = (int16_t)(((int16_t)buf[2]) << 8 | buf[3]);		//y
	acc[2] = (int16_t)(((int16_t)buf[4]) << 8 | buf[5]);		//z
	printf("ACC,%d,%d,%d\r\n",acc[0],acc[1],acc[2]);
}
void PPU_6500_WAKEON_motion(void)
{
	uint8_t temp,ch;
	//Make Sure Accel is running:
	temp=0x01;	
	SPI_master_write_register(mpu6500_reg.pwr_mgmt_1, 1, &temp);
	temp=0x07;
	SPI_master_write_register(mpu6500_reg.pwr_mgmt_2, 1, &temp);
	//Set Accel LPF setting to 184 Hz Bandwidth:
	temp=0x01;
	SPI_master_write_register(mpu6500_reg.accel_cfg2, 1, &temp);
	//Enable Motion Interrupt:
	temp=0x40;
	SPI_master_write_register(mpu6500_reg.int_enable, 1, &temp);
	//Enable Accel Hardware Intelligence:
	temp=0xc0;
	SPI_master_write_register(mpu6500_reg.accel_intel, 1, &temp);
	//Set Motion Threshold:
	temp=0x32;			//8bit 0-255   range:0~1020mg  resolution:4LSB/mg
	SPI_master_write_register(0x1f, 1, &temp);
	//Set Frequency of Wake-up:
	temp=0x0b;
	SPI_master_write_register(0x1e, 1, &temp);
	//Enable Cycle Mode (Accel Low Power Mode):
	SPI_master_read_register(mpu6500_reg.pwr_mgmt_1,1,&ch);
	ch &= 0x20;
	SPI_master_write_register(mpu6500_reg.pwr_mgmt_1, 1, &ch);
}


#endif

 

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "timer.h" #include "FreeRTOS.h" #include "task.h" #include "debug_cmdshell.h" #include "stabilizer.h" //任务优先级 #define START_TASK_PRIO 1 //任务堆栈大小 #define START_STK_SIZE 128 //任务句柄 TaskHandle_t StartTask_Handler; //任务函数 void start_task(void *pvParameters); //任务优先级 #define TASK2_TASK_PRIO 3 //任务堆栈大小 #define TASK2_STK_SIZE 512 //任务句柄 TaskHandle_t Task2Task_Handler; //任务函数 void task2_task(void *pvParameters); int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4 delay_init(); //延时函数初始化 uart_init(115200); //初始化串口 LED_Init(); //初始化LED stabilizerInit(); //创建开始任务 xTaskCreate((TaskFunction_t )start_task, //任务函数 (const char* )"start_task", //任务名称 (uint16_t )START_STK_SIZE, //任务堆栈大小 (void* )NULL, //传递给任务函数的参数 (UBaseType_t )START_TASK_PRIO, //任务优先级 (TaskHandle_t* )&StartTask_Handler); //任务句柄 vTaskStartScheduler(); //开启任务调度 } //开始任务任务函数 void start_task(void *pvParameters) { taskENTER_CRITICAL(); //进入临界区 xTaskCreate((TaskFunction_t )task2_task, (const char* )"task2_task", (uint16_t )TASK2_STK_SIZE, (void* )NULL, (UBaseType_t )TASK2_TASK_PRIO, (TaskHandle_t* )&Task2Task_Handler); xTaskCreate(stabilizerTask, "STABILIZER", 450, NULL, 5, NULL); /*创建姿态任务*/ vTaskDelete(StartTask_Handler); //删除开始任务 taskEXIT_CRITICAL(); //退出临界区 } //task2任务函数 void task2_task(void *pvParameters) { //u8 task2_num=0; u16 len; while(1) { //task2_num++; //任务2执行次数加1 注意task1_num2加到255的时候会清零!! //printf("任务2已经执行:%d次\r\n",task2_num); if(USART_RX_STA&0x8000) { len=USART_RX_STA&0x3fff; debugcmd_process(USART_
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值