STM32F103:三.(3)MPU6050
STM32F103:三.(3)MPU6050
先只上传代码
接线 VCC GND PB9 PB8
main.c
#include "io.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "oled.h"
#include "Infrared.h"
#include "TIME.h"
#include "mpu6050.h"
float Pitch,Roll,Yaw;
int MPU_temp;
int main(void)
{ u8 string[10] = {0}; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);Usart1_Init(115200);delay_init(); //延时初始化LED_Init();printf("1");OLED_Init();OLED_ShowString(40,0,"MPU6050",16);OLED_Refresh();printf("2");IIC_Init();MPU6050_initialize(); //=====MPU6050初始化 DMP_Init();printf("3");TIM2_Getsample_Int(1999,719); //50ms任务定时中断
printf("4");while(1){ delay_ms(999);sprintf((char *)string,"Pitch:%.2f",Pitch);//0300OLED_ShowString(16,16,string,16);sprintf((char *)string,"Roll :%.2f",Roll);//0300OLED_ShowString(16,32,string,16);sprintf((char *)string,"Yaw :%.2f",Yaw);//0300OLED_ShowString(16,48,string,16);OLED_Refresh();}
}
mpu6050.c
#include "MPU6050.h"#define PRINT_ACCEL (0x01)
#define PRINT_GYRO (0x02)
#define PRINT_QUAT (0x04)
#define ACCEL_ON (0x01)
#define GYRO_ON (0x02)
#define MOTION (0)
#define NO_MOTION (1)
#define DEFAULT_MPU_HZ (200)
#define FLASH_SIZE (512)
#define FLASH_MEM_START ((void*)0x1800)
#define q30 1073741824.0f
short gyro[3], accel[3], sensors;
//float Pitch,Roll;
float q0=1.0f,q1=0.0f,q2=0.0f,q3=0.0f;
static signed char gyro_orientation[9] = {-1, 0, 0,0,-1, 0,0, 0, 1};static unsigned short inv_row_2_scale(const signed char *row)
{unsigned short b;if (row[0] > 0)b = 0;else if (row[0] < 0)b = 4;else if (row[1] > 0)b = 1;else if (row[1] < 0)b = 5;else if (row[2] > 0)b = 2;else if (row[2] < 0)b = 6;elseb = 7; // errorreturn b;
}static unsigned short inv_orientation_matrix_to_scalar(const signed char *mtx)
{unsigned short scalar;scalar = inv_row_2_scale(mtx);scalar |= inv_row_2_scale(mtx + 3) << 3;scalar |= inv_row_2_scale(mtx + 6) << 6;return scalar;
}static void run_self_test(void)
{int result;long gyro[3], accel[3];result = mpu_run_self_test(gyro, accel);if (result == 0x7) {/* Test passed. We can trust the gyro data here, so let's push it down* to the DMP.*/float sens;unsigned short accel_sens;mpu_get_gyro_sens(&sens);gyro[0] = (long)(gyro[0] * sens);gyro[1] = (long)(gyro[1] * sens);gyro[2] = (long)(gyro[2] * sens);dmp_set_gyro_bias(gyro);mpu_get_accel_sens(&accel_sens);accel[0] *= accel_sens;accel[1] *= accel_sens;accel[2] *= accel_sens;dmp_set_accel_bias(accel);printf("setting bias succesfully ......\r\n");}
}uint8_t buffer[14];int16_t MPU6050_FIFO[6][11];
int16_t Gx_offset=0,Gy_offset=0,Gz_offset=0;/**************************实现函数********************************************
*函数原型: void MPU6050_newValues(int16_t ax,int16_t ay,int16_t az,int16_t gx,int16_t gy,int16_t gz)
*功 能: 将新的ADC数据更新到 FIFO数组,进行滤波处理
*******************************************************************************/void MPU6050_newValues(int16_t ax,int16_t ay,int16_t az,int16_t gx,int16_t gy,int16_t gz)
{unsigned char i ;
int32_t sum=0;
for(i=1;i<10;i++){ //FIFO 操作
MPU6050_FIFO[0][i-1]=MPU6050_FIFO[0][i];
MPU6050_FIFO[1][i-1]=MPU6050_FIFO[1][i];
MPU6050_FIFO[2][i-1]=MPU6050_FIFO[2][i];
MPU6050_FIFO[3][i-1]=MPU6050_FIFO[3][i];
MPU6050_FIFO[4][i-1]=MPU6050_FIFO[4][i];
MPU6050_FIFO[5][i-1]=MPU6050_FIFO[5][i];
}
MPU6050_FIFO[0][9]=ax;//将新的数据放置到 数据的最后面
MPU6050_FIFO[1][9]=ay;
MPU6050_FIFO[2][9]=az;
MPU6050_FIFO[3][9]=gx;
MPU6050_FIFO[4][9]=gy;
MPU6050_FIFO[5][9]=gz;sum=0;
for(i=0;i<10;i++){ //求当前数组的合,再取平均值sum+=MPU6050_FIFO[0][i];
}
MPU6050_FIFO[0][10]=sum/10;sum=0;
for(i=0;i<10;i++){sum+=MPU6050_FIFO[1][i];
}
MPU6050_FIFO[1][10]=sum/10;sum=0;
for(i=0;i<10;i++){sum+=MPU6050_FIFO[2][i];
}
MPU6050_FIFO[2][10]=sum/10;sum=0;
for(i=0;i<10;i++){sum+=MPU6050_FIFO[3][i];
}
MPU6050_FIFO[3][10]=sum/10;sum=0;
for(i=0;i<10;i++){sum+=MPU6050_FIFO[4][i];
}
MPU6050_FIFO[4][10]=sum/10;sum=0;
for(i=0;i<10;i++){sum+=MPU6050_FIFO[5][i];
}
MPU6050_FIFO[5][10]=sum/10;
}/**************************实现函数********************************************
*函数原型: void MPU6050_setClockSource(uint8_t source)
*功 能: 设置 MPU6050 的时钟源* CLK_SEL | Clock Source* --------+--------------------------------------* 0 | Internal oscillator* 1 | PLL with X Gyro reference* 2 | PLL with Y Gyro reference* 3 | PLL with Z Gyro reference* 4 | PLL with external 32.768kHz reference* 5 | PLL with external 19.2MHz reference* 6 | Reserved* 7 | Stops the clock and keeps the timing generator in reset
*******************************************************************************/
void MPU6050_setClockSource(uint8_t source){IICwriteBits(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_CLKSEL_BIT, MPU6050_PWR1_CLKSEL_LENGTH, source);}/** Set full-scale gyroscope range.* @param range New full-scale gyroscope range value* @see getFullScaleRange()* @see MPU6050_GYRO_FS_250* @see MPU6050_RA_GYRO_CONFIG* @see MPU6050_GCONFIG_FS_SEL_BIT* @see MPU6050_GCONFIG_FS_SEL_LENGTH*/
void MPU6050_setFullScaleGyroRange(uint8_t range) {IICwriteBits(devAddr, MPU6050_RA_GYRO_CONFIG, MPU6050_GCONFIG_FS_SEL_BIT, MPU6050_GCONFIG_FS_SEL_LENGTH, range);
}/**************************实现函数********************************************
*函数原型: void MPU6050_setFullScaleAccelRange(uint8_t range)
*功 能: 设置 MPU6050 加速度计的最大量程
*******************************************************************************/
void MPU6050_setFullScaleAccelRange(uint8_t range) {IICwriteBits(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_AFS_SEL_BIT, MPU6050_ACONFIG_AFS_SEL_LENGTH, range);
}/**************************实现函数********************************************
*函数原型: void MPU6050_setSleepEnabled(uint8_t enabled)
*功 能: 设置 MPU6050 是否进入睡眠模式enabled =1 睡觉enabled =0 工作
*******************************************************************************/
void MPU6050_setSleepEnabled(uint8_t enabled) {IICwriteBit(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_SLEEP_BIT, enabled);
}/**************************实现函数********************************************
*函数原型: uint8_t MPU6050_getDeviceID(void)
*功 能: 读取 MPU6050 WHO_AM_I 标识 将返回 0x68
*******************************************************************************/
uint8_t MPU6050_getDeviceID(void) {IICreadBytes(devAddr, MPU6050_RA_WHO_AM_I, 1, buffer);return buffer[0];
}/**************************实现函数********************************************
*函数原型: uint8_t MPU6050_testConnection(void)
*功 能: 检测MPU6050 是否已经连接
*******************************************************************************/
uint8_t MPU6050_testConnection(void) {if(MPU6050_getDeviceID() == 0x68) //0b01101000;return 1;else return 0;
}/**************************实现函数********************************************
*函数原型: void MPU6050_setI2CMasterModeEnabled(uint8_t enabled)
*功 能: 设置 MPU6050 是否为AUX I2C线的主机
*******************************************************************************/
void MPU6050_setI2CMasterModeEnabled(uint8_t enabled) {IICwriteBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_I2C_MST_EN_BIT, enabled);
}/**************************实现函数********************************************
*函数原型: void MPU6050_setI2CBypassEnabled(uint8_t enabled)
*功 能: 设置 MPU6050 是否为AUX I2C线的主机
*******************************************************************************/
void MPU6050_setI2CBypassEnabled(uint8_t enabled) {IICwriteBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_I2C_BYPASS_EN_BIT, enabled);
}/**************************实现函数********************************************
*函数原型: void MPU6050_initialize(void)
*功 能: 初始化 MPU6050 以进入可用状态。
*******************************************************************************/
void MPU6050_initialize(void) {MPU6050_setClockSource(MPU6050_CLOCK_PLL_YGYRO); //设置时钟MPU6050_setFullScaleGyroRange(MPU6050_GYRO_FS_2000);//陀螺仪最大量程 +-1000度每秒MPU6050_setFullScaleAccelRange(MPU6050_ACCEL_FS_2); //加速度度最大量程 +-2GMPU6050_setSleepEnabled(0); //进入工作状态MPU6050_setI2CMasterModeEnabled(0); //不让MPU6050 控制AUXI2CMPU6050_setI2CBypassEnabled(0); //主控制器的I2C与 MPU6050的AUXI2C 直通。控制器可以直接访问HMC5883L
}/**************************************************************************
函数功能:MPU6050内置DMP的初始化
入口参数:无
返回 值:无
作 者:平衡小车之家
**************************************************************************/
void DMP_Init(void)
{ u8 temp[1]={0};i2cRead(0x68,0x75,1,temp);printf("mpu_set_sensor complete ......\r\n");if(temp[0]!=0x68)NVIC_SystemReset();if(!mpu_init()){if(!mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL))printf("mpu_set_sensor complete ......\r\n");if(!mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL))printf("mpu_configure_fifo complete ......\r\n");if(!mpu_set_sample_rate(DEFAULT_MPU_HZ))printf("mpu_set_sample_rate complete ......\r\n");if(!dmp_load_motion_driver_firmware())printf("dmp_load_motion_driver_firmware complete ......\r\n");if(!dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation)))printf("dmp_set_orientation complete ......\r\n");if(!dmp_enable_feature(DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP |DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO |DMP_FEATURE_GYRO_CAL))printf("dmp_enable_feature complete ......\r\n");if(!dmp_set_fifo_rate(DEFAULT_MPU_HZ))printf("dmp_set_fifo_rate complete ......\r\n");run_self_test();if(!mpu_set_dmp_state(1))printf("mpu_set_dmp_state complete ......\r\n");}
}
/**************************************************************************
函数功能:读取MPU6050内置DMP的姿态信息
入口参数:无
返回 值:无
作 者:平衡小车之家
**************************************************************************/
void Read_DMP(float *Pitch,float *Roll,float *Yaw)
{ unsigned long sensor_timestamp;unsigned char more;long quat[4];dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors, &more); if (sensors & INV_WXYZ_QUAT ){ q0=quat[0] / q30;q1=quat[1] / q30;q2=quat[2] / q30;q3=quat[3] / q30;*Pitch = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; *Roll = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // roll*Yaw = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3; //yaw}}/**************************************************************************
函数功能:读取MPU6050内置温度传感器数据
入口参数:无
返回 值:摄氏温度
作 者:平衡小车之家
**************************************************************************/
int Read_Temperature(void)
{ float Temp;Temp=(I2C_ReadOneByte(devAddr,MPU6050_RA_TEMP_OUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_TEMP_OUT_L);if(Temp>32768) Temp-=65536;Temp=(36.53+Temp/340)*10;return (int)Temp;
}
/**************************************************************************
函数功能:外部中断初始化
入口参数:无
返回 值:无
**************************************************************************/
void MPU6050_INT_Ini(void)
{ GPIO_InitTypeDef GPIO_InitStructure;EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断,需要使能AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource5);EXTI_InitStructure.EXTI_Line=EXTI_Line5;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能按键所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2, NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //子优先级1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure);
}
//------------------End of File----------------------------
mpu6050.h
#ifndef __MPU6050_H
#define __MPU6050_H#include "io.h"
#include "IIC.h"
#include <math.h>
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
#include "usart.h"
#define devAddr 0xD0#define MPU6050_ADDRESS_AD0_LOW 0x68 // address pin low (GND), default for InvenSense evaluation board
#define MPU6050_ADDRESS_AD0_HIGH 0x69 // address pin high (VCC)
#define MPU6050_DEFAULT_ADDRESS MPU6050_ADDRESS_AD0_LOW#define MPU6050_RA_XG_OFFS_TC 0x00 //[7] PWR_MODE, [6:1] XG_OFFS_TC, [0] OTP_BNK_VLD
#define MPU6050_RA_YG_OFFS_TC 0x01 //[7] PWR_MODE, [6:1] YG_OFFS_TC, [0] OTP_BNK_VLD
#define MPU6050_RA_ZG_OFFS_TC 0x02 //[7] PWR_MODE, [6:1] ZG_OFFS_TC, [0] OTP_BNK_VLD
#define MPU6050_RA_X_FINE_GAIN 0x03 //[7:0] X_FINE_GAIN
#define MPU6050_RA_Y_FINE_GAIN 0x04 //[7:0] Y_FINE_GAIN
#define MPU6050_RA_Z_FINE_GAIN 0x05 //[7:0] Z_FINE_GAIN
#define MPU6050_RA_XA_OFFS_H 0x06 //[15:0] XA_OFFS
#define MPU6050_RA_XA_OFFS_L_TC 0x07
#define MPU6050_RA_YA_OFFS_H 0x08 //[15:0] YA_OFFS
#define MPU6050_RA_YA_OFFS_L_TC 0x09
#define MPU6050_RA_ZA_OFFS_H 0x0A //[15:0] ZA_OFFS
#define MPU6050_RA_ZA_OFFS_L_TC 0x0B
#define MPU6050_RA_XG_OFFS_USRH 0x13 //[15:0] XG_OFFS_USR
#define MPU6050_RA_XG_OFFS_USRL 0x14
#define MPU6050_RA_YG_OFFS_USRH 0x15 //[15:0] YG_OFFS_USR
#define MPU6050_RA_YG_OFFS_USRL 0x16
#define MPU6050_RA_ZG_OFFS_USRH 0x17 //[15:0] ZG_OFFS_USR
#define MPU6050_RA_ZG_OFFS_USRL 0x18
#define MPU6050_RA_SMPLRT_DIV 0x19
#define MPU6050_RA_CONFIG 0x1A
#define MPU6050_RA_GYRO_CONFIG 0x1B
#define MPU6050_RA_ACCEL_CONFIG 0x1C
#define MPU6050_RA_FF_THR 0x1D
#define MPU6050_RA_FF_DUR 0x1E
#define MPU6050_RA_MOT_THR 0x1F
#define MPU6050_RA_MOT_DUR 0x20
#define MPU6050_RA_ZRMOT_THR 0x21
#define MPU6050_RA_ZRMOT_DUR 0x22
#define MPU6050_RA_FIFO_EN 0x23
#define MPU6050_RA_I2C_MST_CTRL 0x24
#define MPU6050_RA_I2C_SLV0_ADDR 0x25
#define MPU6050_RA_I2C_SLV0_REG 0x26
# define MPU6050_RA_I2C_SLV0_CTRL 0x27
#define MPU6050_RA_I2C_SLV1_ADDR 0x28
#define MPU6050_RA_I2C_SLV1_REG 0x29
#define MPU6050_RA_I2C_SLV1_CTRL 0x2A
#define MPU6050_RA_I2C_SLV2_ADDR 0x2B
#define MPU6050_RA_I2C_SLV2_REG 0x2C
#define MPU6050_RA_I2C_SLV2_CTRL 0x2D
#define MPU6050_RA_I2C_SLV3_ADDR 0x2E
#define MPU6050_RA_I2C_SLV3_REG 0x2F
#define MPU6050_RA_I2C_SLV3_CTRL 0x30
#define MPU6050_RA_I2C_SLV4_ADDR 0x31
#define MPU6050_RA_I2C_SLV4_REG 0x32
#define MPU6050_RA_I2C_SLV4_DO 0x33
#define MPU6050_RA_I2C_SLV4_CTRL 0x34
#define MPU6050_RA_I2C_SLV4_DI 0x35
#define MPU6050_RA_I2C_MST_STATUS 0x36
#define MPU6050_RA_INT_PIN_CFG 0x37
#define MPU6050_RA_INT_ENABLE 0x38
#define MPU6050_RA_DMP_INT_STATUS 0x39
#define MPU6050_RA_INT_STATUS 0x3A
#define MPU6050_RA_ACCEL_XOUT_H 0x3B
#define MPU6050_RA_ACCEL_XOUT_L 0x3C
#define MPU6050_RA_ACCEL_YOUT_H 0x3D
#define MPU6050_RA_ACCEL_YOUT_L 0x3E
#define MPU6050_RA_ACCEL_ZOUT_H 0x3F
#define MPU6050_RA_ACCEL_ZOUT_L 0x40
#define MPU6050_RA_TEMP_OUT_H 0x41
#define MPU6050_RA_TEMP_OUT_L 0x42
#define MPU6050_RA_GYRO_XOUT_H 0x43
#define MPU6050_RA_GYRO_XOUT_L 0x44
#define MPU6050_RA_GYRO_YOUT_H 0x45
#define MPU6050_RA_GYRO_YOUT_L 0x46
#define MPU6050_RA_GYRO_ZOUT_H 0x47
#define MPU6050_RA_GYRO_ZOUT_L 0x48
#define MPU6050_RA_EXT_SENS_DATA_00 0x49
#define MPU6050_RA_EXT_SENS_DATA_01 0x4A
#define MPU6050_RA_EXT_SENS_DATA_02 0x4B
#define MPU6050_RA_EXT_SENS_DATA_03 0x4C
#define MPU6050_RA_EXT_SENS_DATA_04 0x4D
#define MPU6050_RA_EXT_SENS_DATA_05 0x4E
#define MPU6050_RA_EXT_SENS_DATA_06 0x4F
#define MPU6050_RA_EXT_SENS_DATA_07 0x50
#define MPU6050_RA_EXT_SENS_DATA_08 0x51
#define MPU6050_RA_EXT_SENS_DATA_09 0x52
#define MPU6050_RA_EXT_SENS_DATA_10 0x53
#define MPU6050_RA_EXT_SENS_DATA_11 0x54
#define MPU6050_RA_EXT_SENS_DATA_12 0x55
#define MPU6050_RA_EXT_SENS_DATA_13 0x56
#define MPU6050_RA_EXT_SENS_DATA_14 0x57
#define MPU6050_RA_EXT_SENS_DATA_15 0x58
#define MPU6050_RA_EXT_SENS_DATA_16 0x59
#define MPU6050_RA_EXT_SENS_DATA_17 0x5A
#define MPU6050_RA_EXT_SENS_DATA_18 0x5B
#define MPU6050_RA_EXT_SENS_DATA_19 0x5C
#define MPU6050_RA_EXT_SENS_DATA_20 0x5D
#define MPU6050_RA_EXT_SENS_DATA_21 0x5E
#define MPU6050_RA_EXT_SENS_DATA_22 0x5F
#define MPU6050_RA_EXT_SENS_DATA_23 0x60
#define MPU6050_RA_MOT_DETECT_STATUS 0x61
#define MPU6050_RA_I2C_SLV0_DO 0x63
#define MPU6050_RA_I2C_SLV1_DO 0x64
#define MPU6050_RA_I2C_SLV2_DO 0x65
#define MPU6050_RA_I2C_SLV3_DO 0x66
#define MPU6050_RA_I2C_MST_DELAY_CTRL 0x67
#define MPU6050_RA_SIGNAL_PATH_RESET 0x68
#define MPU6050_RA_MOT_DETECT_CTRL 0x69
#define MPU6050_RA_USER_CTRL 0x6A
#define MPU6050_RA_PWR_MGMT_1 0x6B
#define MPU6050_RA_PWR_MGMT_2 0x6C
#define MPU6050_RA_BANK_SEL 0x6D
#define MPU6050_RA_MEM_START_ADDR 0x6E
#define MPU6050_RA_MEM_R_W 0x6F
#define MPU6050_RA_DMP_CFG_1 0x70
#define MPU6050_RA_DMP_CFG_2 0x71
#define MPU6050_RA_FIFO_COUNTH 0x72
#define MPU6050_RA_FIFO_COUNTL 0x73
#define MPU6050_RA_FIFO_R_W 0x74
#define MPU6050_RA_WHO_AM_I 0x75#define MPU6050_TC_PWR_MODE_BIT 7
#define MPU6050_TC_OFFSET_BIT 6
#define MPU6050_TC_OFFSET_LENGTH 6
#define MPU6050_TC_OTP_BNK_VLD_BIT 0#define MPU6050_VDDIO_LEVEL_VLOGIC 0
#define MPU6050_VDDIO_LEVEL_VDD 1#define MPU6050_CFG_EXT_SYNC_SET_BIT 5
#define MPU6050_CFG_EXT_SYNC_SET_LENGTH 3
#define MPU6050_CFG_DLPF_CFG_BIT 2
#define MPU6050_CFG_DLPF_CFG_LENGTH 3#define MPU6050_EXT_SYNC_DISABLED 0x0
#define MPU6050_EXT_SYNC_TEMP_OUT_L 0x1
#define MPU6050_EXT_SYNC_GYRO_XOUT_L 0x2
#define MPU6050_EXT_SYNC_GYRO_YOUT_L 0x3
#define MPU6050_EXT_SYNC_GYRO_ZOUT_L 0x4
#define MPU6050_EXT_SYNC_ACCEL_XOUT_L 0x5
#define MPU6050_EXT_SYNC_ACCEL_YOUT_L 0x6
#define MPU6050_EXT_SYNC_ACCEL_ZOUT_L 0x7#define MPU6050_DLPF_BW_256 0x00
#define MPU6050_DLPF_BW_188 0x01
#define MPU6050_DLPF_BW_98 0x02
#define MPU6050_DLPF_BW_42 0x03
#define MPU6050_DLPF_BW_20 0x04
#define MPU6050_DLPF_BW_10 0x05
#define MPU6050_DLPF_BW_5 0x06#define MPU6050_GCONFIG_FS_SEL_BIT 4
#define MPU6050_GCONFIG_FS_SEL_LENGTH 2#define MPU6050_GYRO_FS_250 0x00
#define MPU6050_GYRO_FS_500 0x01
#define MPU6050_GYRO_FS_1000 0x02
#define MPU6050_GYRO_FS_2000 0x03#define MPU6050_ACONFIG_XA_ST_BIT 7
#define MPU6050_ACONFIG_YA_ST_BIT 6
#define MPU6050_ACONFIG_ZA_ST_BIT 5
#define MPU6050_ACONFIG_AFS_SEL_BIT 4
#define MPU6050_ACONFIG_AFS_SEL_LENGTH 2
#define MPU6050_ACONFIG_ACCEL_HPF_BIT 2
#define MPU6050_ACONFIG_ACCEL_HPF_LENGTH 3#define MPU6050_ACCEL_FS_2 0x00
#define MPU6050_ACCEL_FS_4 0x01
#define MPU6050_ACCEL_FS_8 0x02
#define MPU6050_ACCEL_FS_16 0x03#define MPU6050_DHPF_RESET 0x00
#define MPU6050_DHPF_5 0x01
#define MPU6050_DHPF_2P5 0x02
#define MPU6050_DHPF_1P25 0x03
#define MPU6050_DHPF_0P63 0x04
#define MPU6050_DHPF_HOLD 0x07#define MPU6050_TEMP_FIFO_EN_BIT 7
#define MPU6050_XG_FIFO_EN_BIT 6
#define MPU6050_YG_FIFO_EN_BIT 5
#define MPU6050_ZG_FIFO_EN_BIT 4
#define MPU6050_ACCEL_FIFO_EN_BIT 3
#define MPU6050_SLV2_FIFO_EN_BIT 2
#define MPU6050_SLV1_FIFO_EN_BIT 1
#define MPU6050_SLV0_FIFO_EN_BIT 0#define MPU6050_MULT_MST_EN_BIT 7
#define MPU6050_WAIT_FOR_ES_BIT 6
#define MPU6050_SLV_3_FIFO_EN_BIT 5
#define MPU6050_I2C_MST_P_NSR_BIT 4
#define MPU6050_I2C_MST_CLK_BIT 3
#define MPU6050_I2C_MST_CLK_LENGTH 4#define MPU6050_CLOCK_DIV_348 0x0
#define MPU6050_CLOCK_DIV_333 0x1
#define MPU6050_CLOCK_DIV_320 0x2
#define MPU6050_CLOCK_DIV_308 0x3
#define MPU6050_CLOCK_DIV_296 0x4
#define MPU6050_CLOCK_DIV_286 0x5
#define MPU6050_CLOCK_DIV_276 0x6
#define MPU6050_CLOCK_DIV_267 0x7
#define MPU6050_CLOCK_DIV_258 0x8
#define MPU6050_CLOCK_DIV_500 0x9
#define MPU6050_CLOCK_DIV_471 0xA
#define MPU6050_CLOCK_DIV_444 0xB
#define MPU6050_CLOCK_DIV_421 0xC
#define MPU6050_CLOCK_DIV_400 0xD
#define MPU6050_CLOCK_DIV_381 0xE
#define MPU6050_CLOCK_DIV_364 0xF#define MPU6050_I2C_SLV_RW_BIT 7
#define MPU6050_I2C_SLV_ADDR_BIT 6
#define MPU6050_I2C_SLV_ADDR_LENGTH 7
#define MPU6050_I2C_SLV_EN_BIT 7
#define MPU6050_I2C_SLV_BYTE_SW_BIT 6
#define MPU6050_I2C_SLV_REG_DIS_BIT 5
#define MPU6050_I2C_SLV_GRP_BIT 4
#define MPU6050_I2C_SLV_LEN_BIT 3
#define MPU6050_I2C_SLV_LEN_LENGTH 4#define MPU6050_I2C_SLV4_RW_BIT 7
#define MPU6050_I2C_SLV4_ADDR_BIT 6
#define MPU6050_I2C_SLV4_ADDR_LENGTH 7
#define MPU6050_I2C_SLV4_EN_BIT 7
#define MPU6050_I2C_SLV4_INT_EN_BIT 6
#define MPU6050_I2C_SLV4_REG_DIS_BIT 5
#define MPU6050_I2C_SLV4_MST_DLY_BIT 4
#define MPU6050_I2C_SLV4_MST_DLY_LENGTH 5#define MPU6050_MST_PASS_THROUGH_BIT 7
#define MPU6050_MST_I2C_SLV4_DONE_BIT 6
#define MPU6050_MST_I2C_LOST_ARB_BIT 5
#define MPU6050_MST_I2C_SLV4_NACK_BIT 4
#define MPU6050_MST_I2C_SLV3_NACK_BIT 3
#define MPU6050_MST_I2C_SLV2_NACK_BIT 2
#define MPU6050_MST_I2C_SLV1_NACK_BIT 1
#define MPU6050_MST_I2C_SLV0_NACK_BIT 0#define MPU6050_INTCFG_INT_LEVEL_BIT 7
#define MPU6050_INTCFG_INT_OPEN_BIT 6
#define MPU6050_INTCFG_LATCH_INT_EN_BIT 5
#define MPU6050_INTCFG_INT_RD_CLEAR_BIT 4
#define MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT 3
#define MPU6050_INTCFG_FSYNC_INT_EN_BIT 2
#define MPU6050_INTCFG_I2C_BYPASS_EN_BIT 1
#define MPU6050_INTCFG_CLKOUT_EN_BIT 0#define MPU6050_INTMODE_ACTIVEHIGH 0x00
#define MPU6050_INTMODE_ACTIVELOW 0x01#define MPU6050_INTDRV_PUSHPULL 0x00
#define MPU6050_INTDRV_OPENDRAIN 0x01#define MPU6050_INTLATCH_50USPULSE 0x00
#define MPU6050_INTLATCH_WAITCLEAR 0x01#define MPU6050_INTCLEAR_STATUSREAD 0x00
#define MPU6050_INTCLEAR_ANYREAD 0x01#define MPU6050_INTERRUPT_FF_BIT 7
#define MPU6050_INTERRUPT_MOT_BIT 6
#define MPU6050_INTERRUPT_ZMOT_BIT 5
#define MPU6050_INTERRUPT_FIFO_OFLOW_BIT 4
#define MPU6050_INTERRUPT_I2C_MST_INT_BIT 3
#define MPU6050_INTERRUPT_PLL_RDY_INT_BIT 2
#define MPU6050_INTERRUPT_DMP_INT_BIT 1
#define MPU6050_INTERRUPT_DATA_RDY_BIT 0// TODO: figure out what these actually do
// UMPL source code is not very obivous
#define MPU6050_DMPINT_5_BIT 5
#define MPU6050_DMPINT_4_BIT 4
#define MPU6050_DMPINT_3_BIT 3
#define MPU6050_DMPINT_2_BIT 2
#define MPU6050_DMPINT_1_BIT 1
#define MPU6050_DMPINT_0_BIT 0#define MPU6050_MOTION_MOT_XNEG_BIT 7
#define MPU6050_MOTION_MOT_XPOS_BIT 6
#define MPU6050_MOTION_MOT_YNEG_BIT 5
#define MPU6050_MOTION_MOT_YPOS_BIT 4
#define MPU6050_MOTION_MOT_ZNEG_BIT 3
#define MPU6050_MOTION_MOT_ZPOS_BIT 2
#define MPU6050_MOTION_MOT_ZRMOT_BIT 0#define MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT 7
#define MPU6050_DELAYCTRL_I2C_SLV4_DLY_EN_BIT 4
#define MPU6050_DELAYCTRL_I2C_SLV3_DLY_EN_BIT 3
#define MPU6050_DELAYCTRL_I2C_SLV2_DLY_EN_BIT 2
#define MPU6050_DELAYCTRL_I2C_SLV1_DLY_EN_BIT 1
#define MPU6050_DELAYCTRL_I2C_SLV0_DLY_EN_BIT 0#define MPU6050_PATHRESET_GYRO_RESET_BIT 2
#define MPU6050_PATHRESET_ACCEL_RESET_BIT 1
#define MPU6050_PATHRESET_TEMP_RESET_BIT 0#define MPU6050_DETECT_ACCEL_ON_DELAY_BIT 5
#define MPU6050_DETECT_ACCEL_ON_DELAY_LENGTH 2
#define MPU6050_DETECT_FF_COUNT_BIT 3
#define MPU6050_DETECT_FF_COUNT_LENGTH 2
#define MPU6050_DETECT_MOT_COUNT_BIT 1
#define MPU6050_DETECT_MOT_COUNT_LENGTH 2#define MPU6050_DETECT_DECREMENT_RESET 0x0
#define MPU6050_DETECT_DECREMENT_1 0x1
#define MPU6050_DETECT_DECREMENT_2 0x2
#define MPU6050_DETECT_DECREMENT_4 0x3#define MPU6050_USERCTRL_DMP_EN_BIT 7
#define MPU6050_USERCTRL_FIFO_EN_BIT 6
#define MPU6050_USERCTRL_I2C_MST_EN_BIT 5
#define MPU6050_USERCTRL_I2C_IF_DIS_BIT 4
#define MPU6050_USERCTRL_DMP_RESET_BIT 3
#define MPU6050_USERCTRL_FIFO_RESET_BIT 2
#define MPU6050_USERCTRL_I2C_MST_RESET_BIT 1
#define MPU6050_USERCTRL_SIG_COND_RESET_BIT 0#define MPU6050_PWR1_DEVICE_RESET_BIT 7
#define MPU6050_PWR1_SLEEP_BIT 6
#define MPU6050_PWR1_CYCLE_BIT 5
#define MPU6050_PWR1_TEMP_DIS_BIT 3
#define MPU6050_PWR1_CLKSEL_BIT 2
#define MPU6050_PWR1_CLKSEL_LENGTH 3#define MPU6050_CLOCK_INTERNAL 0x00
#define MPU6050_CLOCK_PLL_XGYRO 0x01
#define MPU6050_CLOCK_PLL_YGYRO 0x02
#define MPU6050_CLOCK_PLL_ZGYRO 0x03
#define MPU6050_CLOCK_PLL_EXT32K 0x04
#define MPU6050_CLOCK_PLL_EXT19M 0x05
#define MPU6050_CLOCK_KEEP_RESET 0x07#define MPU6050_PWR2_LP_WAKE_CTRL_BIT 7
#define MPU6050_PWR2_LP_WAKE_CTRL_LENGTH 2
#define MPU6050_PWR2_STBY_XA_BIT 5
#define MPU6050_PWR2_STBY_YA_BIT 4
#define MPU6050_PWR2_STBY_ZA_BIT 3
#define MPU6050_PWR2_STBY_XG_BIT 2
#define MPU6050_PWR2_STBY_YG_BIT 1
#define MPU6050_PWR2_STBY_ZG_BIT 0#define MPU6050_WAKE_FREQ_1P25 0x0
#define MPU6050_WAKE_FREQ_2P5 0x1
#define MPU6050_WAKE_FREQ_5 0x2
#define MPU6050_WAKE_FREQ_10 0x3#define MPU6050_BANKSEL_PRFTCH_EN_BIT 6
#define MPU6050_BANKSEL_CFG_USER_BANK_BIT 5
#define MPU6050_BANKSEL_MEM_SEL_BIT 4
#define MPU6050_BANKSEL_MEM_SEL_LENGTH 5#define MPU6050_WHO_AM_I_BIT 6
#define MPU6050_WHO_AM_I_LENGTH 6#define INT PBin(5) //PB5连接到MPU6050的中断引脚extern short gyro[3], accel[3];
extern int16_t Gx_offset,Gy_offset,Gz_offset;
extern float Acc1G_Values;
//extern float Pitch;
//供外部调用的API
void MPU6050_initialize(void); //初始化
uint8_t MPU6050_testConnection(void); //检测MPU6050是否存在
//读取ADC值
//void MPU6050_getMotion6(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz);
//void MPU6050_getlastMotion6(int16_t* ax, int16_t* ay,
//int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz);
//void MPU6050_InitGyro_Offset(void);//初始化陀螺仪偏置
uint8_t MPU6050_getDeviceID(void); //读取MPU6050的ID
void DMP_Init(void);
void Read_DMP(float *Pitch,float *Roll,float *Yaw);
int Read_Temperature(void);
void MPU6050_INT_Ini(void);
#endif
IIC.c
#include "IIC.h"
#include "delay.h"
//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK战舰STM32开发板
//IIC驱动 代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2012/9/9
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//
void IIC_Delay(void)
{delay_us(2);
}//初始化IIC
void IIC_Init(void)
{ GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //使能GPIOB时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB,GPIO_Pin_8|GPIO_Pin_9); //PB6,PB7 输出高
}
//产生IIC起始信号
u8 IIC_Start(void)
{SDA_OUT(); //sda线输出IIC_SDA=1;if(!READ_SDA)return 0; IIC_SCL=1;IIC_Delay();IIC_SDA=0;//START:when CLK is high,DATA change form high to low if(READ_SDA)return 0;IIC_Delay();IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 return 1;
// SDA_OUT(); //sda线输出
// IIC_SDA=1;
// IIC_SCL=1;
// IIC_Delay();
// IIC_SDA=0;//START:when CLK is high,DATA change form high to low
// IIC_Delay();
// 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 highIIC_Delay();IIC_SCL=1; IIC_SDA=1;//发送I2C总线结束信号IIC_Delay();
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)
{u8 ucErrTime=0;SDA_IN(); //SDA设置为输入 IIC_SDA=1;IIC_Delay(); IIC_SCL=1;IIC_Delay(); while(READ_SDA){ucErrTime++;if(ucErrTime>100){IIC_Stop(); //return 0;}IIC_Delay();}IIC_SCL=0;//时钟输出0 return 1;
}
//产生ACK应答
void IIC_Ack(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=0;IIC_Delay();IIC_SCL=1;IIC_Delay();IIC_SCL=0;
}
//不产生ACK应答
void IIC_NAck(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=1;IIC_Delay();IIC_SCL=1;IIC_Delay();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;if((txd&0x80)>>7)IIC_SDA=1;elseIIC_SDA=0;txd<<=1; IIC_Delay(); //对TEA5767这三个延时都是必须的IIC_SCL=1;IIC_Delay(); IIC_SCL=0; IIC_Delay();}
}
//读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; IIC_Delay();IIC_SCL=1;receive<<=1;if(READ_SDA)receive++; IIC_Delay(); } if (!ack)IIC_NAck();//发送nACKelseIIC_Ack(); //发送ACK return receive;
}
//****************************
//
//********添加代码************
//
/**************************实现函数********************************************
*函数原型: bool i2cWrite(uint8_t addr, uint8_t reg, uint8_t data)
*功 能:
*******************************************************************************/
int i2cWrite(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *data)
{int i;if (!IIC_Start())return 1;IIC_Send_Byte(addr << 1 );if (!IIC_Wait_Ack()) {IIC_Stop();return 1;}IIC_Send_Byte(reg);IIC_Wait_Ack();for (i = 0; i < len; i++) {IIC_Send_Byte(data[i]);if (!IIC_Wait_Ack()) {IIC_Stop();return 0;}}IIC_Stop();return 0;
}
/**************************实现函数********************************************
*函数原型: bool i2cWrite(uint8_t addr, uint8_t reg, uint8_t data)
*功 能:
*******************************************************************************/
int i2cRead(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf)
{if (!IIC_Start())return 1;IIC_Send_Byte(addr << 1);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);else*buf = IIC_Read_Byte(1);buf++;len--;}IIC_Stop();return 0;
}
/**************************实现函数********************************************
*函数原型: unsigned char I2C_ReadOneByte(unsigned char I2C_Addr,unsigned char addr)
*功 能: 读取指定设备 指定寄存器的一个值
输入 I2C_Addr 目标设备地址addr 寄存器地址
返回 读出来的值
*******************************************************************************/
unsigned char I2C_ReadOneByte(unsigned char I2C_Addr,unsigned char addr)
{unsigned char res=0;IIC_Start(); IIC_Send_Byte(I2C_Addr); //发送写命令res++;IIC_Wait_Ack();IIC_Send_Byte(addr); res++; //发送地址IIC_Wait_Ack(); //IIC_Stop();//产生一个停止条件 IIC_Start();IIC_Send_Byte(I2C_Addr+1); res++; //进入接收模式 IIC_Wait_Ack();res=IIC_Read_Byte(0); IIC_Stop();//产生一个停止条件return res;
}/**************************实现函数********************************************
*函数原型: u8 IICreadBytes(u8 dev, u8 reg, u8 length, u8 *data)
*功 能: 读取指定设备 指定寄存器的 length个值
输入 dev 目标设备地址reg 寄存器地址length 要读的字节数*data 读出的数据将要存放的指针
返回 读出来的字节数量
*******************************************************************************/
u8 IICreadBytes(u8 dev, u8 reg, u8 length, u8 *data){u8 count = 0;IIC_Start();IIC_Send_Byte(dev); //发送写命令IIC_Wait_Ack();IIC_Send_Byte(reg); //发送地址IIC_Wait_Ack(); IIC_Start();IIC_Send_Byte(dev+1); //进入接收模式 IIC_Wait_Ack();for(count=0;count<length;count++){if(count!=length-1)data[count]=IIC_Read_Byte(1); //带ACK的读数据else data[count]=IIC_Read_Byte(0); //最后一个字节NACK}IIC_Stop();//产生一个停止条件return count;
}/**************************实现函数********************************************
*函数原型: u8 IICwriteBytes(u8 dev, u8 reg, u8 length, u8* data)
*功 能: 将多个字节写入指定设备 指定寄存器
输入 dev 目标设备地址reg 寄存器地址length 要写的字节数*data 将要写的数据的首地址
返回 返回是否成功
*******************************************************************************/
u8 IICwriteBytes(u8 dev, u8 reg, u8 length, u8* data){u8 count = 0;IIC_Start();IIC_Send_Byte(dev); //发送写命令IIC_Wait_Ack();IIC_Send_Byte(reg); //发送地址IIC_Wait_Ack(); for(count=0;count<length;count++){IIC_Send_Byte(data[count]); IIC_Wait_Ack(); }IIC_Stop();//产生一个停止条件return 1; //status == 0;
}/**************************实现函数********************************************
*函数原型: u8 IICreadByte(u8 dev, u8 reg, u8 *data)
*功 能: 读取指定设备 指定寄存器的一个值
输入 dev 目标设备地址reg 寄存器地址*data 读出的数据将要存放的地址
返回 1
*******************************************************************************/
u8 IICreadByte(u8 dev, u8 reg, u8 *data){*data=I2C_ReadOneByte(dev, reg);return 1;
}/**************************实现函数********************************************
*函数原型: unsigned char IICwriteByte(unsigned char dev, unsigned char reg, unsigned char data)
*功 能: 写入指定设备 指定寄存器一个字节
输入 dev 目标设备地址reg 寄存器地址data 将要写入的字节
返回 1
*******************************************************************************/
unsigned char IICwriteByte(unsigned char dev, unsigned char reg, unsigned char data){return IICwriteBytes(dev, reg, 1, &data);
}/**************************实现函数********************************************
*函数原型: u8 IICwriteBits(u8 dev,u8 reg,u8 bitStart,u8 length,u8 data)
*功 能: 读 修改 写 指定设备 指定寄存器一个字节 中的多个位
输入 dev 目标设备地址reg 寄存器地址bitStart 目标字节的起始位length 位长度data 存放改变目标字节位的值
返回 成功 为1 失败为0
*******************************************************************************/
u8 IICwriteBits(u8 dev,u8 reg,u8 bitStart,u8 length,u8 data)
{u8 b;if (IICreadByte(dev, reg, &b) != 0) {u8 mask = (0xFF << (bitStart + 1)) | 0xFF >> ((8 - bitStart) + length - 1);data <<= (8 - length);data >>= (7 - bitStart);b &= mask;b |= data;return IICwriteByte(dev, reg, b);} else {return 0;}
}/**************************实现函数********************************************
*函数原型: u8 IICwriteBit(u8 dev, u8 reg, u8 bitNum, u8 data)
*功 能: 读 修改 写 指定设备 指定寄存器一个字节 中的1个位
输入 dev 目标设备地址reg 寄存器地址bitNum 要修改目标字节的bitNum位data 为0 时,目标位将被清0 否则将被置位
返回 成功 为1 失败为0
*******************************************************************************/
u8 IICwriteBit(u8 dev, u8 reg, u8 bitNum, u8 data){u8 b;IICreadByte(dev, reg, &b);b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum));return IICwriteByte(dev, reg, b);
}//------------------End of File----------------------------
iic.h
#ifndef __MYIIC_H
#define __MYIIC_H
#include "io.h"
//IO方向设置#define SDA_IN() {GPIOB->CRH&=0XFFFFFFF0;GPIOB->CRH|=(u32)8<<0;}
#define SDA_OUT() {GPIOB->CRH&=0XFFFFFFF0;GPIOB->CRH|=(u32)3<<0;}//IO操作函数
#define IIC_SCL PBout(9) //SCL
#define IIC_SDA PBout(8) //SDA
#define READ_SDA PBin(8) //输入SDA IO方向设置
//
//#define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
//#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}IO操作函数
//#define IIC_SCL PBout(6) //SCL
//#define IIC_SDA PBout(7) //SDA
//#define READ_SDA PBin(7) //输入SDA //IIC所有操作函数
void IIC_Init(void); //初始化IIC的IO口
u8 IIC_Start(void); //发送IIC开始信号
void IIC_Stop(void); //发送IIC停止信号
void IIC_Send_Byte(u8 txd); //IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void); //IIC等待ACK信号
void IIC_Ack(void); //IIC发送ACK信号
void IIC_NAck(void); //IIC不发送ACK信号void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);
//添加平衡小车代码//
/
unsigned char I2C_ReadOneByte(unsigned char I2C_Addr,unsigned char addr);
unsigned char IICwriteByte(unsigned char dev, unsigned char reg, unsigned char data);
u8 IICwriteBytes(u8 dev, u8 reg, u8 length, u8* data);
u8 IICwriteBits(u8 dev,u8 reg,u8 bitStart,u8 length,u8 data);
u8 IICwriteBit(u8 dev,u8 reg,u8 bitNum,u8 data);
u8 IICreadBytes(u8 dev, u8 reg, u8 length, u8 *data);
int i2cWrite(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *data);
int i2cRead(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf);
#endif
STM32F103:三.(3)MPU6050相关推荐
- 对于STM32F103三轴机械臂控制器进行基本功能测试-关节角度读取
➤01 机械臂调试 1.简介 对 基于STM32对于三轴机械臂控制器设计 中对应的控制电路读取肩部和肘部两个 角度编码器 ST-3806-15-RS 数据进行调试. 2.接口电路1 ▲ 角度读取的相关 ...
- STM32F103:三.(2)红外接收
STM32F103:三.(2)红外接收 代码参考正点原子,STM32F103C8T6正常运行. NEC 协议的高低电平辨别方式 整体思路是将PB9设置上拉输入,并开启定时器4的输入捕获功能,溢出值设置 ...
- 对于STM32F103三轴机械臂控制器进行基本功能测试-上下运动功能
简 介: 本文针对基于在基于STM32对于三轴机械臂控制器设计 中设计了控制电路板.本文记录对其在机械臂实际部件进行调试的过程. 关键词: STM32F103,机械臂,三轴,上下运动 ➤01 机械臂控 ...
- STM32F103:三.(1)步进电机
八相驱动 引用洋桃代码 注意步进电机使用delay函数卡死正常步骤 进行项目开发时可在定时器中处理. 比如调用步进电机函数时 开启定时中断 达到设定的时间时void STEP_MOTOR_8A (u8 ...
- 对于STM32F103控制的三轴机械臂基本功能测试-关节转动控制
➤01 机械臂调试 1.简介 对于 基于STM32对于三轴机械臂控制器设计 的设计已经进行了如下的调试: 对于STM32F103三轴机械臂控制器进行基本功能测试-关节角度读取 对于STM32F103三 ...
- 【51单片机快速入门指南】4.3: I2C读取MPU6050陀螺仪的原始数据
目录 硬知识 特性参数 MPU6050 简介 模块重要寄存器简介 电源管理寄存器 1 陀螺仪配置寄存器 加速度传感器配置寄存器 FIFO 使能寄存器 陀螺仪采样率分频寄存器 配置寄存器 电源管理寄存器 ...
- STM32入门笔记(02):MPU6050、MPU9250、ICM20948及姿态解算(SPL库函数版)
目录 MPU6050 什么是MPU6050? MPU6050的特点 MPU6050框图 MPU6050初始化 MPU6050寄存器 电源管理寄存器1(0X6B) 陀螺仪配置寄存器(0X1B) 加速度传 ...
- 三关节机械臂控制命令修改
▌01 机械控制臂 1.简介 在 调试机械臂一体化控制电路:STM32F103控制器初步调试 对于 三轴机械臂的 的控制,最初版本采用了 简易调试命令组合. 这个命令是为了付方便最初的调试与测试机械臂 ...
- 调试机械臂一体化控制电路:STM32F103控制器初步调试
▌01 机械臂控制器 在 基于STM32F103双轴机械臂完整电路板设计1 给出了 双轴机械臂 的控制电路设计. ▲ 已经基本焊接完毕的设计电路板 Mon 06Mon 13设计 调试控制器 软件 调试 ...
最新文章
- 软件隐喻的本质与模式
- Fidder 抓取Android模拟器数据包
- 使用java.util.LinkedList模拟实现内存页面置换算法--LRU算法
- 最大搜索二叉子树大小(树形dp)
- Boost:双图bimap与mi_hashed indices索引的测试程序
- python dict sorted 排序
- webpack(1)-简介和基础知识
- 量子计算机怎么编程,量子计算机编程(一)——QPU编程
- centos java mvn_Linux(centos7)安装JDK1.8与maven
- 【百度地图API】如何激发手机的高分辨率
- 自学网html视频教程,ps教程自学网html视频教程
- 汉字笔顺动画技术剖析,android应用开发实战
- 数字通信第六章——信道模型和信道容量
- Android 进阶之路《丢掉初学者的诟病》
- 骨感传导蓝牙耳机怎么样、骨感传导蓝牙耳机有什么特点
- 小孩子初次办身份证需携带什么资料?年龄有要求吗?
- 心率脉搏测试c语言算法,基于51单片机语音播报心率计脉搏测量仪设计(仿真源码+电路图+当时PaperPass16%查重论文)...
- linux使用usb刻录光驱,linux光驱刻录
- 爱尔威火星车 AirWheel 电动独轮车
- CKA考试习题:安全管理--Network Policy、serviceaccount、clusterrole
热门文章
- flask创建mysql表_Flask-SQLAlchemy 无法创建数据库???
- MDP马尔可夫决策过程(二)
- oracle 数字格式取整,Oracle SQL语句操作数字:取整、四舍五入及格式化
- java里上下文对象,java-在百里香模板中的Web上下文对象上发出...
- python根据相关系数绘制热力图
- java 多线程共享变量两类问题_Java并发基础09. 多个线程间共享数据问题
- python填充_python 实现矩阵填充0的例子
- docker 日志_解决docker容器日志导致主机磁盘空间满了的情况
- python docker自动化_「docker实战篇」python的docker爬虫技术-移动自动化控制工具安卓ADB的使用(15)...
- 04-Bootstrap的插件