一、对iic类模块分析与使用

bmp280驱动代码

说明:

1、该模块用于获取气压,温度,海拔等数据。

vcc,gnd接电源

sda ,scl 接iic通信引脚

2、该模块使用iic通信,通过iic发送请求相关类的寄存器值,芯片获取对应寄存器返回的数据。

所以使用的时调用HAL_I2C_Mem_Write函数

3、调用:

c 复制代码
	uint8_t ret = BMP280_Init();		
	if(ret != 0x58)
	{
		printf("BMP280传感器初始化错误\n");
		while(1);
	}
	float P,T,ALT;
	BMP280GetData(&P, &T, &ALT);
	 printf("BMP280传感器测试数据:\n");
     printf("气压: %0.4f hPa\n",P);
     printf("温度: %0.2f ℃\n",T);
     printf("海拔: %0.2f m\n",ALT);
 		 printf("\n\n");

.h文件

c 复制代码
#define bmp280 hi2c2


#define	INIT		    0xBE	//初始化
#define	SoftReset		0xBA	//软复位
#define	StartTest		0xAC	//开始测试

#define BMP280_SLAVE_ADDRESS    0xec		/* I2C从机地址 0xee或0xec */

/*calibration parameters */
#define BMP280_DIG_T1_LSB_REG                0x88
#define BMP280_DIG_T1_MSB_REG                0x89
#define BMP280_DIG_T2_LSB_REG                0x8A
#define BMP280_DIG_T2_MSB_REG                0x8B
#define BMP280_DIG_T3_LSB_REG                0x8C
#define BMP280_DIG_T3_MSB_REG                0x8D
#define BMP280_DIG_P1_LSB_REG                0x8E
#define BMP280_DIG_P1_MSB_REG                0x8F
#define BMP280_DIG_P2_LSB_REG                0x90
#define BMP280_DIG_P2_MSB_REG                0x91
#define BMP280_DIG_P3_LSB_REG                0x92
#define BMP280_DIG_P3_MSB_REG                0x93
#define BMP280_DIG_P4_LSB_REG                0x94
#define BMP280_DIG_P4_MSB_REG                0x95
#define BMP280_DIG_P5_LSB_REG                0x96
#define BMP280_DIG_P5_MSB_REG                0x97
#define BMP280_DIG_P6_LSB_REG                0x98
#define BMP280_DIG_P6_MSB_REG                0x99
#define BMP280_DIG_P7_LSB_REG                0x9A
#define BMP280_DIG_P7_MSB_REG                0x9B
#define BMP280_DIG_P8_LSB_REG                0x9C
#define BMP280_DIG_P8_MSB_REG                0x9D
#define BMP280_DIG_P9_LSB_REG                0x9E
#define BMP280_DIG_P9_MSB_REG                0x9F

#define BMP280_CHIPID_REG                    0xD0  /*Chip ID Register */
#define BMP280_RESET_REG                     0xE0  /*Softreset Register */
#define BMP280_STATUS_REG                    0xF3  /*Status Register */
#define BMP280_CTRLMEAS_REG                  0xF4  /*Ctrl Measure Register */
#define BMP280_CONFIG_REG                    0xF5  /*Configuration Register */
#define BMP280_PRESSURE_MSB_REG              0xF7  /*Pressure MSB Register */
#define BMP280_PRESSURE_LSB_REG              0xF8  /*Pressure LSB Register */
#define BMP280_PRESSURE_XLSB_REG             0xF9  /*Pressure XLSB Register */
#define BMP280_TEMPERATURE_MSB_REG           0xFA  /*Temperature MSB Reg */
#define BMP280_TEMPERATURE_LSB_REG           0xFB  /*Temperature LSB Reg */
#define BMP280_TEMPERATURE_XLSB_REG          0xFC  /*Temperature XLSB Reg */


#define BMP280_SLEEP_MODE				(0x00)
#define BMP280_FORCED_MODE				(0x01)
#define BMP280_NORMAL_MODE				(0x03)

#define BMP280_TEMPERATURE_CALIB_DIG_T1_LSB_REG             (0x88)
#define BMP280_PRESSURE_TEMPERATURE_CALIB_DATA_LENGTH       (24)
#define BMP280_DATA_FRAME_SIZE			(6)

#define BMP280_OVERSAMP_SKIPPED			(0x00)
#define BMP280_OVERSAMP_1X				(0x01)
#define BMP280_OVERSAMP_2X				(0x02)
#define BMP280_OVERSAMP_4X				(0x03)
#define BMP280_OVERSAMP_8X				(0x04)
#define BMP280_OVERSAMP_16X				(0x05)

typedef struct
{
    uint16_t dig_T1;/* calibration T1 data */
    int16_t dig_T2; /* calibration T2 data */
    int16_t dig_T3; /* calibration T3 data */
    uint16_t dig_P1;/* calibration P1 data */
    int16_t dig_P2; /* calibration P2 data */
    int16_t dig_P3; /* calibration P3 data */
    int16_t dig_P4; /* calibration P4 data */
    int16_t dig_P5; /* calibration P5 data */
    int16_t dig_P6; /* calibration P6 data */
    int16_t dig_P7; /* calibration P7 data */
    int16_t dig_P8; /* calibration P8 data */
    int16_t dig_P9; /* calibration P9 data */
    int32_t t_fine; /* calibration t_fine data */
} bmp280Calib;
uint8_t BMP280_Init(void);
void BMP280GetData(float* pressure, float* temperature, float* asl);

.c文件

c 复制代码
#include "bmp280.h"


static int32_t bmp280RawPressure = 0;
static int32_t bmp280RawTemperature = 0;

#define BMP280_PRESSURE_OSR			(BMP280_OVERSAMP_8X)
#define BMP280_TEMPERATURE_OSR		(BMP280_OVERSAMP_16X)
#define BMP280_MODE					(BMP280_PRESSURE_OSR << 2 | BMP280_TEMPERATURE_OSR << 5 | BMP280_NORMAL_MODE)

bmp280Calib  bmp280Cal;

uint8_t BMP280_Init(void)
{
    uint8_t bmp280_id;
    uint8_t tmp[10];
 
	  HAL_I2C_Mem_Read(&bmp280,BMP280_SLAVE_ADDRESS, BMP280_CHIPID_REG, 1, (uint8_t *)&bmp280_id,1,0xff);
	
		HAL_I2C_Mem_Read(&bmp280,BMP280_SLAVE_ADDRESS, BMP280_DIG_T1_LSB_REG, 1, (uint8_t *)&bmp280Cal,24,0xff);
	
    tmp[0] = BMP280_MODE;
	
    HAL_I2C_Mem_Write(&bmp280,BMP280_SLAVE_ADDRESS,BMP280_CTRLMEAS_REG, 1,tmp ,1,0xff);

    tmp[0] = (5<<2);
    HAL_I2C_Mem_Write(&bmp280,BMP280_SLAVE_ADDRESS,BMP280_CONFIG_REG, 1,tmp ,1,0xff);		/*配置IIR滤波*/

    return bmp280_id;
}


static void BMP280GetPressure2(void)
{
    uint8_t data[6];

    // read data from sensor
    HAL_I2C_Mem_Read(&bmp280,BMP280_SLAVE_ADDRESS, BMP280_PRESSURE_MSB_REG, 6, (uint8_t *)&data,6,0xff);
    bmp280RawPressure = (int32_t)((((uint32_t)(data[0])) << 12) | (((uint32_t)(data[1])) << 4) | ((uint32_t)data[2] >> 4));
    bmp280RawTemperature = (int32_t)((((uint32_t)(data[3])) << 12) | (((uint32_t)(data[4])) << 4) | ((uint32_t)data[5] >> 4));
}

static int32_t BMP280CompensateT(int32_t adcT)
{
    int32_t var1, var2, T;

    var1 = ((((adcT >> 3) - ((int32_t)bmp280Cal.dig_T1 << 1))) * ((int32_t)bmp280Cal.dig_T2)) >> 11;
    var2  = (((((adcT >> 4) - ((int32_t)bmp280Cal.dig_T1)) * ((adcT >> 4) - ((int32_t)bmp280Cal.dig_T1))) >> 12) * ((int32_t)bmp280Cal.dig_T3)) >> 14;
    bmp280Cal.t_fine = var1 + var2;

    T = (bmp280Cal.t_fine * 5 + 128) >> 8;

    return T;
}

// Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits).
// Output value of "24674867" represents 24674867/256 = 96386.2 Pa = 963.862 hPa
static uint32_t BMP280CompensateP(int32_t adcP)
{
    int64_t var1, var2, p;
    var1 = ((int64_t)bmp280Cal.t_fine) - 128000;
    var2 = var1 * var1 * (int64_t)bmp280Cal.dig_P6;
    var2 = var2 + ((var1*(int64_t)bmp280Cal.dig_P5) << 17);
    var2 = var2 + (((int64_t)bmp280Cal.dig_P4) << 35);
    var1 = ((var1 * var1 * (int64_t)bmp280Cal.dig_P3) >> 8) + ((var1 * (int64_t)bmp280Cal.dig_P2) << 12);
    var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)bmp280Cal.dig_P1) >> 33;
    if (var1 == 0)
        return 0;
    p = 1048576 - adcP;
    p = (((p << 31) - var2) * 3125) / var1;
    var1 = (((int64_t)bmp280Cal.dig_P9) * (p >> 13) * (p >> 13)) >> 25;
    var2 = (((int64_t)bmp280Cal.dig_P8) * p) >> 19;
    p = ((p + var1 + var2) >> 8) + (((int64_t)bmp280Cal.dig_P7) << 4);
    return (uint32_t)p;
}


#define CONST_PF 0.1902630958	//(1/5.25588f) Pressure factor
#define FIX_TEMP 25				// Fixed Temperature. ASL is a function of pressure and temperature, but as the temperature changes so much (blow a little towards the flie and watch it drop 5 degrees) it corrupts the ASL estimates.
								// TLDR: Adjusting for temp changes does more harm than good.
/**
 * Converts pressure to altitude above sea level (ASL) in meters
 */
static float BMP280PressureToAltitude(float* pressure/*, float* groundPressure, float* groundTemp*/)
{
    if (*pressure > 0)
    {
        return ((pow((1015.7f / *pressure), CONST_PF) - 1.0f) * (FIX_TEMP + 273.15f)) / 0.0065f;
    }
    else
    {
        return 0;
    }
}

#define FILTER_NUM	5
#define FILTER_A	0.1f

/*限幅平均滤波法*/
static void presssureFilter(float* in, float* out)
{
	static uint8_t i = 0;
	static float filter_buf[FILTER_NUM] = {0.0};
	double filter_sum = 0.0;
	uint8_t cnt = 0;
	float deta;

	if(filter_buf[i] == 0.0f)
	{
		filter_buf[i] = *in;
		*out = *in;
		if(++i >= FILTER_NUM)
            i=0;
	}
    else
	{
		if(i)
            deta = *in-filter_buf[i - 1];
		else
            deta = *in-filter_buf[FILTER_NUM - 1];

		if(fabs(deta) < FILTER_A)
		{
			filter_buf[i] = *in;
			if(++i >= FILTER_NUM)
                i = 0;
		}
		for(cnt = 0; cnt < FILTER_NUM; cnt++)
		{
			filter_sum += filter_buf[cnt];
		}
		*out = filter_sum / FILTER_NUM;
	}
}

void BMP280GetData(float* pressure, float* temperature, float* asl)
{
    static float t;
    static float p;

	BMP280GetPressure2();
	t = BMP280CompensateT(bmp280RawTemperature) / 100.0;
	p = BMP280CompensateP(bmp280RawPressure) / 25600.0;
	presssureFilter(&p, pressure);
	*temperature = (float)t;/*单位度*/

	*asl = BMP280PressureToAltitude(pressure);	/*转换成海拔*/
}

mpu6050驱动代码

说明:

1、模块主要对外输出加速度,陀螺仪,温度等数据

vcc,gnd 接电源

scl,sda iic通信引脚

xda,xcl,iic主机通信引脚,(作为主机通信使用)

ad0,iic地址配置引脚

int,中断信号输出引脚

明确一点:scl,sda在通信时的目的是配置模块中的寄存器。

2、调用

c 复制代码
	MPU6050_Init();
	if (MPU6050ReadID() == 0)
	{	   
    printf("检测不到MPU6050,停机");
	  while(1);
  }
	short Accel[3];
	short Gyro [3];
	short Temp;

 	  MPU6050ReadAcc(Accel);			
      printf("加速度: %d__%d__%d ",Accel[0],Accel[1],Accel[2]);
	  MPU6050ReadGyro(Gyro);
      printf("陀螺仪:%8d %8d %8d",Gyro[0],Gyro[1],Gyro[2]);
	  MPU6050_ReturnTemp(&Temp);
      printf("温度:%d",Temp);

.h文件

c 复制代码
#define MPU6050_ADDRESS            0x68
#define MPU6050_WHO_AM_I           0x75
#define MPU6050_SMPLRT_DIV            0  //8000Hz
#define MPU6050_DLPF_CFG              0
#define MPU6050_GYRO_OUT           0x43  //MPU6050陀螺仪数据寄存器地址
#define MPU6050_ACC_OUT            0x3B  //MPU6050加速度数据寄存器地址

#define MPU6050_SLAVE_ADDRESS      0xd0  //MPU6050器件读地址

#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

#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 MPU6050_DMP_MEMORY_BANKS        8
#define MPU6050_DMP_MEMORY_BANK_SIZE    256
#define MPU6050_DMP_MEMORY_CHUNK_SIZE   16

#define mpu_6050 hi2c4
void               I2C_MPU6050_WriteData(uint16_t Addr, uint8_t Reg, uint8_t Value);
HAL_StatusTypeDef  I2C_MPU6050_WriteBuffer(uint16_t Addr, uint8_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length);
uint8_t            I2C_MPU6050_ReadData(uint16_t Addr, uint8_t Reg);
HAL_StatusTypeDef  I2C_MPU6050_ReadBuffer(uint16_t Addr, uint8_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length);
HAL_StatusTypeDef  I2C_MPU6050_IsDeviceReady(uint16_t DevAddress, uint32_t Trials);

void  WriteData(uint8_t Byte);
void WriteCommand(uint8_t Command);

void MPU6050ReadTemp(short *tempData);
void MPU6050ReadGyro(short *gyroData);
void MPU6050ReadAcc(short *accData);
void MPU6050_ReturnTemp(short*Temperature);
void MPU6050_Init(void);
uint8_t MPU6050ReadID(void);
void PMU6050_ReadData(uint8_t reg_add,unsigned char*Read,uint8_t num);
void PMU6050_WriteReg(uint8_t reg_add,uint8_t reg_dat);

void MPU6050_PWR_MGMT_1_INIT(void);

.c文件

c 复制代码
//用于向设备发送指令。
void WriteCommand(uint8_t Command)
{
	uint8_t date=0;
	HAL_I2C_Mem_Write(&mpu_6050, 0x69,0x00, I2C_MEMADD_SIZE_8BIT,(uint8_t *)&Command, 1, 0xff);
	if(HAL_I2C_IsDeviceReady(&mpu_6050,0x69,100,0xffff)==HAL_OK)
	 {
    	
	 }

}
//用于向从设备发送数据
void  WriteData(uint8_t Byte)
{
		HAL_I2C_Master_Transmit(&mpu_6050, 0x69,(uint8_t *)&Byte, 1, 0xff);
		if(HAL_I2C_IsDeviceReady(&mpu_6050,0x69,100,0xffff)==HAL_OK)
	 {
	
	 }

}

/**
  * 函数功能: I2C通信错误处理函数
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 一般在I2C通信超时时调用该函数
  */
static void I2C_MPU6050_Error (void)
{
  /* 反初始化I2C通信总线 */
  HAL_I2C_DeInit(&mpu_6050);
  
  /* 重新初始化I2C通信总线*/
  MX_I2C2_Init();
  printf("MPU6050 I2C通信超时!!! 重新启动I2C...\n");
}

/**
  * 函数功能: 通过I2C写入一个值到指定寄存器内
  * 输入参数: Addr:I2C设备地址
  *           Reg:目标寄存器
  *           Value:值
  * 返 回 值: 无
  * 说    明: 无
  */
void I2C_MPU6050_WriteData(uint16_t Addr, uint8_t Reg, uint8_t Value)
{
  HAL_StatusTypeDef status = HAL_OK;
  
  status = HAL_I2C_Mem_Write(&mpu_6050, Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, &Value, 1, 1000);
  
  /* 检测I2C通信状态 */
  if(status != HAL_OK)
  {
    /* 调用I2C通信错误处理函数 */
    I2C_MPU6050_Error();
  }
}

/**
  * 函数功能: 通过I2C写入一段数据到指定寄存器内
  * 输入参数: Addr:I2C设备地址
  *           Reg:目标寄存器
  *           RegSize:寄存器尺寸(8位或者16位)
  *           pBuffer:缓冲区指针
  *           Length:缓冲区长度
  * 返 回 值: HAL_StatusTypeDef:操作结果
  * 说    明: 在循环调用是需加一定延时时间
  */
HAL_StatusTypeDef I2C_MPU6050_WriteBuffer(uint16_t Addr, uint8_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length)
{
  HAL_StatusTypeDef status = HAL_OK;
  
  status = HAL_I2C_Mem_Write(&mpu_6050, Addr, (uint16_t)Reg, RegSize, pBuffer, Length, 1000); 

  /* 检测I2C通信状态 */
  if(status != HAL_OK)
  {
    /* 调用I2C通信错误处理函数 */
    I2C_MPU6050_Error();
  }        
  return status;
}


/**
  * 函数功能: 通过I2C读取一个指定寄存器内容
  * 输入参数: Addr:I2C设备地址
  *           Reg:目标寄存器
  * 返 回 值: uint8_t:寄存器内容
  * 说    明: 无
  */
uint8_t I2C_MPU6050_ReadData(uint16_t Addr, uint8_t Reg)
{
  HAL_StatusTypeDef status = HAL_OK;
  uint8_t value = 0;
  
  status = HAL_I2C_Mem_Read(&mpu_6050, Addr, Reg, I2C_MEMADD_SIZE_8BIT, &value, 1, 1000);
 
  /* 检测I2C通信状态 */
  if(status != HAL_OK)
  {
    /* 调用I2C通信错误处理函数 */
    I2C_MPU6050_Error();
  
  }
  return value;
}

/**
  * 函数功能: 通过I2C读取一段寄存器内容存放到指定的缓冲区内
  * 输入参数: Addr:I2C设备地址
  *           Reg:目标寄存器
  *           RegSize:寄存器尺寸(8位或者16位)
  *           pBuffer:缓冲区指针
  *           Length:缓冲区长度
  * 返 回 值: HAL_StatusTypeDef:操作结果
  * 说    明: 无
  */
HAL_StatusTypeDef I2C_MPU6050_ReadBuffer(uint16_t Addr, uint8_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length)
{
  HAL_StatusTypeDef status = HAL_OK;

  status = HAL_I2C_Mem_Read(&mpu_6050, Addr, (uint16_t)Reg, RegSize, pBuffer, Length, 1000);
  
  /* 检测I2C通信状态 */
  if(status != HAL_OK)
  {
    /* 调用I2C通信错误处理函数 */
    I2C_MPU6050_Error();
  }        
  return status;
}

/**
  * 函数功能: 检测I2C设备是否处于准备好可以通信状态
  * 输入参数: DevAddress:I2C设备地址
  *           Trials:尝试测试次数
  * 返 回 值: HAL_StatusTypeDef:操作结果
  * 说    明: 无
  */
HAL_StatusTypeDef I2C_MPU6050_IsDeviceReady(uint16_t DevAddress, uint32_t Trials)
{ 
  return (HAL_I2C_IsDeviceReady(&mpu_6050, DevAddress, Trials, 1000));
}




/**
  * 函数功能: 写数据到MPU6050寄存器
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */ 
void MPU6050_WriteReg(uint8_t reg_add,uint8_t reg_dat)
{
  I2C_MPU6050_WriteData(MPU6050_SLAVE_ADDRESS,reg_add,reg_dat);
}

/**
  * 函数功能: 从MPU6050寄存器读取数据
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */ 
void MPU6050_ReadData(uint8_t reg_add,unsigned char *Read,uint8_t num)
{
  I2C_MPU6050_ReadBuffer(MPU6050_SLAVE_ADDRESS,reg_add,I2C_MEMADD_SIZE_8BIT,Read,num);
}

/**
  * 函数功能: 初始化MPU6050芯片
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */ 
void MPU6050_Init(void)
{
  int i=0,j=0;
  //在初始化之前要延时一段时间,若没有延时,则断电后再上电数据可能会出错
  for(i=0;i<1000;i++)
  {
    for(j=0;j<1000;j++)
    {
      ;
    }
  }
  // HAL_Delay(50);
	MPU6050_WriteReg(MPU6050_RA_PWR_MGMT_1, 0x00);	    //解除休眠状态
	MPU6050_WriteReg(MPU6050_RA_SMPLRT_DIV , 0x07);	    //陀螺仪采样率,1KHz
	MPU6050_WriteReg(MPU6050_RA_CONFIG , 0x06);	        //低通滤波器的设置,截止频率是1K,带宽是5K
	MPU6050_WriteReg(MPU6050_RA_ACCEL_CONFIG , 0x00);	  //配置加速度传感器工作在2G模式,不自检
	MPU6050_WriteReg(MPU6050_RA_GYRO_CONFIG, 0x18);     //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
}

/**
  * 函数功能: 读取MPU6050的ID
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */ 
uint8_t MPU6050ReadID(void)
{
	unsigned char Re = 0;
    MPU6050_ReadData(MPU6050_RA_WHO_AM_I,&Re,1);    //读器件地址
	if(Re != 0x68)
	{
		printf("MPU6050 dectected error!\r\n检测不到MPU6050模块,请检查模块与开发板的接线");
		return 0;
	}
	else
	{
		printf("MPU6050 ID = %d\r\n",Re);
		return 1;
	}
		
}

/**
  * 函数功能: 读取MPU6050的加速度数据
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */ 
void MPU6050ReadAcc(short *accData)
{
    uint8_t buf[6];
    MPU6050_ReadData(MPU6050_ACC_OUT, buf, 6);
    accData[0] = (buf[0] << 8) | buf[1];
    accData[1] = (buf[2] << 8) | buf[3];
    accData[2] = (buf[4] << 8) | buf[5];
}

/**
  * 函数功能: 读取MPU6050的角速度数据
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */ 
void MPU6050ReadGyro(short *gyroData)
{
    uint8_t buf[6];
    MPU6050_ReadData(MPU6050_GYRO_OUT,buf,6);
    gyroData[0] = (buf[0] << 8) | buf[1];
    gyroData[1] = (buf[2] << 8) | buf[3];
    gyroData[2] = (buf[4] << 8) | buf[5];
}

/**
  * 函数功能: 读取MPU6050的原始温度数据
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */ 
void MPU6050ReadTemp(short *tempData)
{
	uint8_t buf[2];
    MPU6050_ReadData(MPU6050_RA_TEMP_OUT_H,buf,2);     //读取温度值
    *tempData = (buf[0] << 8) | buf[1];
}

/**
  * 函数功能: 读取MPU6050的温度数据,转化成摄氏度
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */ 
void MPU6050_ReturnTemp(short*Temperature)
{
	short temp3;
	uint8_t buf[2];
	
	MPU6050_ReadData(MPU6050_RA_TEMP_OUT_H,buf,2);     //读取温度值
  temp3= (buf[0] << 8) | buf[1];
	*Temperature=(((double) (temp3 + 13200)) / 280)-13;
}

ATH20驱动文件

说明:

vcc,gnd供电相关

scl,sda iic通信相关引脚

该模块用于获取温湿度,使用iic通信,通过配置模块中芯片的寄存器来获取数据。

调用

c 复制代码
	ATH20_Init();
	float temperaut,humtidiy;
	ATH20_Read_CTdata(&temperaut,&humtidiy);
			printf("温度: %.3lf ℃\n",temperaut);
			printf("湿度: %.3lf %%\n",humtidiy);

.h文件

c 复制代码
#define ATH20_SLAVE_ADDRESS    0x70	/* I2C从机地址 */

#define	INIT		    0xBE	//初始化
#define	SoftReset		0xBA	//软复位
#define	StartTest		0xAC	//开始测试

uint8_t ATH20_Init(void);
void ATH20_Read_CTdata(float *temperature,float *Humidity);

.c文件

c 复制代码
void ATH20_Read_CTdata(float *temperature,float *Humidity) //读取AHT10的温度和湿度数据
{
    uint32_t RetuData = 0;
    uint8_t Data[6]={0};
		static uint8_t tmp[3]={0xac,0x33,0x00};
		HAL_I2C_Master_Transmit(&hi2cx,ATH20_SLAVE_ADDRESS,tmp,3,0xffff);
		HAL_Delay(75);//等待75ms
		HAL_I2C_Master_Receive(&hi2cx,ATH20_SLAVE_ADDRESS,Data,6,0xffff);
		if((Data[0]&0x80)==0x00)
		{
			RetuData = 0;
			RetuData = ((uint32_t)Data[3]>>4)+((uint32_t)Data[2]<<4)+((uint32_t)Data[1]<<12);
			*Humidity = RetuData*100.0f/(1<<20);
			RetuData =  (((uint32_t)Data[3]&0x0f)<<16)+((uint32_t)Data[4]<<8)+((uint32_t)Data[5]);
			*temperature = RetuData*200.0f/(1<<20)-50;
		}
}


uint8_t ATH20_Init(void)
{
		static uint8_t tmp[3]={0xbe,0x08,0x00};
		uint8_t read_buf={0};
    HAL_Delay(40);
		HAL_I2C_Master_Receive(&hi2cx,ATH20_SLAVE_ADDRESS,&read_buf,1,0xffff);
		if((read_buf&0x80)==0x00)
		{
			HAL_I2C_Master_Transmit(&hi2cx,ATH20_SLAVE_ADDRESS,tmp,3,0xffff);
		}
}




uint8_t ATH20_Read_Status(void)//读取AHT10的状态寄存器
{
    uint8_t Byte_first;
	
    HAL_I2C_Mem_Read(&hi2cx,ATH20_SLAVE_ADDRESS,0x00,1,&Byte_first,1,0xff);

	return Byte_first;
}

uint8_t ATH20_Read_Cal_Enable(void)
{
    uint8_t val = 0;//ret = 0,

    val = ATH20_Read_Status();
    if((val & 0x68) == 0x08)  //判断NOR模式和校准输出是否有效
        return 1;
    else
        return 0;
}

void ATH20_Read_CTdata1(uint32_t *ct) //读取AHT10的温度和湿度数据
{
    uint32_t RetuData = 0;
	  uint16_t cnt = 0;
    uint8_t Data[10];
    uint8_t tmp[10];

    tmp[0] = 0x33;
    tmp[1] = 0x00;
	  HAL_I2C_Mem_Write(&hi2cx,ATH20_SLAVE_ADDRESS,StartTest,1,tmp,2,0xff);
		HAL_Delay(75);//等待75ms

    cnt = 0;
	while(((ATH20_Read_Status()&0x80) == 0x80))//等待忙状态结束
	{
        HAL_Delay(1);
        if(cnt++ >= 100)
        {
            break;
        }
	}

  HAL_I2C_Mem_Read(&hi2cx,ATH20_SLAVE_ADDRESS,0,1,Data,7,0xff);
	RetuData = 0;
    RetuData = (RetuData|Data[1]) << 8;
	RetuData = (RetuData|Data[2]) << 8;
	RetuData = (RetuData|Data[3]);
	RetuData = RetuData >> 4;
	ct[0] = RetuData;

    RetuData = 0;
	RetuData = (RetuData|Data[3]) << 8;
	RetuData = (RetuData|Data[4]) << 8;
	RetuData = (RetuData|Data[5]);
	RetuData = RetuData&0xfffff;
	ct[1] = RetuData;
}

uint8_t count;
uint8_t ATH20_Init1(void)
{
    uint8_t tmp[10];

    HAL_Delay(40);

    tmp[0] = 0x08;
    tmp[1] = 0x00;

		HAL_I2C_Mem_Write(&hi2cx,ATH20_SLAVE_ADDRESS,INIT,1,tmp,2,0xff);
    HAL_Delay(500);
    count = 0;
    while(ATH20_Read_Cal_Enable() == 0)//需要等待状态字status的Bit[3]=1时才去读数据。如果Bit[3]不等于1 ,发软件复位0xBA给AHT10,再重新初始化AHT10,直至Bit[3]=1
    {

				HAL_I2C_Mem_Write(&hi2cx,ATH20_SLAVE_ADDRESS,SoftReset,1,tmp,2,0xff);
        HAL_Delay(200);

				HAL_I2C_Mem_Write(&hi2cx,ATH20_SLAVE_ADDRESS,INIT,1,tmp,2,0xff);
        count++;
        if(count >= 10)
            return 0;
        HAL_Delay(500);
    }
    return 1;
}

ads1115驱动文件

说明:

该模块是adc采集模块精度为16bit,使用iic进行数据通信

vcc,gnd供电

scl,sda iic通信

addr,配置模块iic地址

alrt,比较器输出/转换状态就绪引脚

a0~a3,adc采集通道

调用:

c 复制代码
	float A0_Voltage;
	char buffer[]="";//显示存储数组

	A0_Voltage=ADS1115_Read_average_ADC(0);	//读取A0通道输入的电压,选择6.144V最大量程	
	sprintf(buffer,"%5.3f",A0_Voltage);//浮点型数据转为指定格式的字符串,5位,3位小数点
	printf("a0:%s\n",buffer);
	HAL_Delay(100);//等待100ms

.h文件

c 复制代码
#define ADS1115_DEV_ADDR_GND            0x90//ADDR接GND,ADS1115地址
#define ADS1115_DEV_ADDR_VDD            0x92//ADDR接VDD,ADS1115地址
#define ADS1115_DEV_ADDR_SDA            0x94//ADDR接SDA,ADS1115地址
#define ADS1115_DEV_ADDR_SCL            0x96//ADDR接SCL,ADS1115地址

#define ADS1115_DEV_ADDR            	0x90//ADDR接GND决定ADS1115的7位地址,如果是写命令就是0x90,读命令就是0x91     

#define ADS1115_Conversion        	 	 0x00  //转换寄存器地址
#define ADS1115_Config              	 0x01  //配置寄存器地址

#define REG_L_thresh 	 0x02// Low threshold value
#define REG_H_thresh 	 0x03	// High threshold value

extern uint8_t BYTE_BUF[2];//读取转换寄存器的数组值
float ADS1115_Read_ADC(uint8_t channel);
float ADS1115_Read_average_ADC(uint8_t channel);

.c文件

c 复制代码
/*********************************************************************************
描述:配置01H寄存器,实现单次转换,读取00H寄存器,实现电压采样,并转换成电压值
输入:
	   channel:需要采集的通道号,ADS1115是4通道,所以是0~3,分别代表A0~A3通道
返回:
     浮点数,对应通道采集到的电压值,单位V
		 
//配置寄存器说明
 
//config register
/*CRH[15:8](R/W)
   BIT      15      14      13      12      11      10      9       8
   NAME     OS      MUX2    MUX1    MUX0    PGA2    PGA1    PGA0    MODE
CRL[7:0] (R/W)
   BIT      7       6       5       4       3       2       1       0
   NAME    DR0     DR1     DR0   COM_MODE COM_POL COM_LAT COM_QUE1 COM_QUE0
   -----------------------------------------------------------------------------------
 * 15    | OS             |  运行状态会单词转换开始
 *       |                | 写时:
 *       |                | 0   : 无效
 *       |                | 1   : 开始单次转换处于掉电状态时
 *       |                | 读时:
 *       |                | 0   : 正在转换
 *       |                | 1   : 未执行转换
 * -----------------------------------------------------------------------------------
 * 14:12 | MUX [2:0]      | 输入复用多路配置
 *       |                | 000 : AINP = AIN0 and AINN = AIN1 (default)
 *       |                | 001 : AINP = AIN0 and AINN = AIN3
 *       |                | 010 : AINP = AIN1 and AINN = AIN3
 *       |                | 011 : AINP = AIN2 and AINN = AIN3
 *       |                | 100 : AINP = AIN0 and AINN = GND
 *       |                | 101 : AINP = AIN1 and AINN = GND
 *       |                | 110 : AINP = AIN2 and AINN = GND
 *       |                | 111 : AINP = AIN3 and AINN = GND
 * -----------------------------------------------------------------------------------
 * 11:9  | PGA [2:0]      | 可编程增益放大器配置(FSR  full scale range)
 *       |                | 000 : FSR = В±6.144 V
 *       |                | 001 : FSR = В±4.096 V
 *       |                | 010 : FSR = В±2.048 V (默认)
 *       |                | 011 : FSR = В±1.024 V
 *       |                | 100 : FSR = В±0.512 V
 *       |                | 101 : FSR = В±0.256 V
 *       |                | 110 : FSR = В±0.256 V
 *       |                | 111 : FSR = В±0.256 V
 * -----------------------------------------------------------------------------------
 * 8     | MODE           | 工作模式
 *       |                | 0   : 连续转换
 *       |                | 1   : 单词转换
 * -----------------------------------------------------------------------------------
 * 7:5   | DR [2:0]       | 采样频率
 *       |                | 000 : 8 SPS
 *       |                | 001 : 16 SPS
 *       |                | 010 : 32 SPS
 *       |                | 011 : 64 SPS
 *       |                | 100 : 128 SPS (默认)
 *       |                | 101 : 250 SPS
 *       |                | 110 : 475 SPS
 *       |                | 111 : 860 SPS
 * -----------------------------------------------------------------------------------
 * 4     | COMP_MODE      | 比较器模式
 *       |                | 0   : 传统比较器 (default)
 *       |                | 1   : 窗口比较器
 * -----------------------------------------------------------------------------------
 * 3     | COMP_POL       | Comparator polarity
 *       |                | 0   : 低电平有效 (default)
 *       |                | 1   : 高电平有效
 * -----------------------------------------------------------------------------------
 * 2     | COMP_LAT       | Latching comparator
 *       |                | 0   : 非锁存比较器. (default)
 *       |                | 1   : 锁存比较器.
 * -----------------------------------------------------------------------------------
 * 1:0   | COMP_QUE [1:0] | Comparator queue and disable
 *       |                | 00  : Assert after one conversion
 *       |                | 01  : Assert after two conversions
 *       |                | 10  : Assert after four conversions
 *       |                | 11  : 禁用比较器并将ALERT/RDY设置为高阻抗 (default)
 * -----------------------------------------------------------------------------------

**********************************************************************************/
float ADS1115_Read_ADC(uint8_t channel)//选择一个通道的单次转换
{
	uint8_t ConfigBuff[2];
	uint8_t PGA=0;//配置PGA[2:0]为000,采用FSR = ±6.144 V
	int16_t tempData;
	float voltage;//实际电压值

    switch (channel)
    {
        case 0:
            ConfigBuff[0] = (0xC0&0xf1)|(PGA<<1);   
														//bit[15]=OS=1:开始单次转换0xC1[单次]
                            //bit[14:12]=MUX[2:0]=100 : AINP = AIN0 and AINN = GND,采集A0通道
                            //bit[11:9]=PGA[2:0]=000 : FSR = ±6.144 V
                            //bit[8]=MODE=1:单次模式或掉电状态
            break;
 
        case 1:
            ConfigBuff[0] =(0xD1&0xf1)|(PGA<<1) ;   
														//bit[15]=OS=1:开始单次转换0xD1[单次]
                            //bit[14:12]=MUX[2:0]=101 : AINP = AIN1 and AINN = GND,采集A1通道
                            //bit[11:9]=PGA[2:0]=000 : FSR = ±6.144 V
                            //bit[8]=MODE=1:单次模式或掉电状态
            break;
        
        case 2:
            ConfigBuff[0] =(0xE1&0xf1)|(PGA<<1);    
														//bit[15]=OS=1:开始单次转换0xE1[单次]
                            //bit[14:12]=MUX[2:0]=110 : AINP = AIN2 and AINN = GND,采集A2通道
                            //bit[11:9]=PGA[2:0]=000 : FSR = ±6.144 V
                            //bit[8]=MODE=1:单次模式或掉电状态
            break;
 
        case 3:
            ConfigBuff[0] =(0xF1&0xf1)|(PGA<<1);    
														//bit[15]=OS=1:开始单次转换0xF1[单次]
                            //bit[14:12]=MUX[2:0]=111 : AINP = AIN3 and AINN = GND,采集A3通道
                            //bit[11:9]=PGA[2:0]=000 : FSR = ±6.144 V
                            //bit[8]=MODE=1:单次模式或掉电状态
            break;        
    }
    
  ConfigBuff[1] = 0xE3;     
							//bit[7:5]=DR[2:0]=111:860 SPS
							//bit[1:0]=COMP_QUE[1:0]=11:不使能比较器

		
	HAL_I2C_Mem_Write(&hi2c5,ADS1115_DEV_ADDR,ADS1115_Config,1,ConfigBuff,2,1000);//调用HAL库IIC写函数,按上面的参数,配置01H寄存器
	HAL_Delay(2);// 延时一定时间  
	HAL_I2C_Mem_Read(&hi2c5,ADS1115_DEV_ADDR,ADS1115_Conversion,1,BYTE_BUF,2,1000);//调用HAL库IIC读函数读取,00H寄存器的AD转换值,放入BYTE_BUF
    tempData = (int16_t)(BYTE_BUF[0] << 8) + (int16_t)BYTE_BUF[1];
		
		//FSR ±6.144 V,LSB 187.5 μV
		//FSR ±4.096 V,LSB 125 μV
		//FSR ±2.048 V,LSB 62.5 μV
		//FSR ±1.024 V,LSB 31.25 μV
		//FSR ±0.512 V,LSB 15.625 μV
		//FSR ±0.256 V,LSB 7.8125 μV
    switch (PGA)//根据量程,采样值*LSB就是采集到的电压值
    {
			case 5:
					voltage = tempData * 0.0000078125;//单位V
					break;

			case 4:
					voltage = tempData * 0.000015625;//单位V
					break;

			case 3:
					voltage = tempData * 0.00003125;//单位V
					break;

			case 2:
					voltage = tempData * 0.0000625;//单位V
					break;

			case 1:
					voltage = tempData * 0.000125;//单位V
					break;

			case 0:
					voltage = tempData * 0.0001875;//单位V
					break;

			default:
					voltage = 0;
					break;
    }

    return voltage;

}
/*********************************************************************************
描述:计算平均数
输入:
	   channel:需要采集的通道号,ADS1115是4通道,所以是0~3,分别代表A0~A3通道
返回:
     浮点数,求平均后的电压,单位V
**********************************************************************************/
float ADS1115_Read_average_ADC(uint8_t channel)
{
    float sum[10],average;
    for(int i=0;i<10;i++)
    {
        sum[i]=ADS1115_Read_ADC(channel);
    }
    average=(sum[3]+sum[4]+sum[5]+sum[6]+sum[7]+sum[8])/6;
    return average;
}

pcf8591驱动文件

说明:

该模块集成adc和dac转换功能,使用iic进行通信

vcc,gnd 供电

scl,sda iic通信

aout,输出dac电压

ain0~ain3,adc采集输入(跳线帽可接到对应adc采集通道)

调用:

c 复制代码
	uint8_t Lival[4]={0};

	IICWriteOneByte(PCF8591Add,MODE0|CHNL1);   // Using channel 1
		HAL_Delay(350);
		Lival[0] = IICReadOneByte(PCF8591Add|0x01); //光敏信号The analog value of channel 0 is read and converted to a digital value
		IICWriteOneByte(PCF8591Add,MODE0|CHNL2);   // Using channel 2
		HAL_Delay(350);
		Lival[1] = IICReadOneByte(PCF8591Add|0x01); //热敏信号The analog value of channel 1 is read and converted to a digital value
		IICWriteOneByte(PCF8591Add,MODE0|CHNL3);   // Using channel 3
		HAL_Delay(350);
		Lival[2] = IICReadOneByte(PCF8591Add|0x01); //外部adc采集信号The analog value of channel 2 is read and converted to a digital value
		IICWriteOneByte(PCF8591Add,MODE0|CHNL0);   // Using channel 0
		HAL_Delay(350);
		Lival[3] = IICReadOneByte(PCF8591Add|0x01); //滑动变阻器信号&dac输出信号 The analog value of channel 3 is read and converted to a digital value
		IICWriteTwoByte(PCF8591Add,DAouputEn,Lival[3]);  //Converts the converted digital value to an analog value
		HAL_Delay(100);
		printf("光敏信号channel0:%f \n 热敏信号channel1:%f \n 外部adc采集信号channel2:%d \n 滑动变阻器信号channel3:%f \n dac输出信号channel4:%f v\n",
		100.0-(float)Lival[0]*0.39,100.0-(float)Lival[1]*0.39,Lival[2],(float)Lival[3]*0.39,(float)Lival[3]*0.01294);
		

.h文件

c 复制代码
//控制寄存器的模式
#define MODE0 	0x00	
						//Channel0 = AIN0; 全部开启
						//Channel1 = AIN1;
						//Channel2 = AIN2;
						//Channel3 = AIN3;
#define MODE1 	0x10	
						//Channel0 = AIN3-AIN0;开启0 1 2通道
						//Channel1 = AIN3-AIN1
						//Channel2 = AIN3-AIN2;
#define MODE2 	0x20	
						//Channel0 = AIN0;开启 0 1 3通道
						//Channel1 = AIN1;
						//Channel2 = AIN3-AIN2;//3 2通道合并
#define MODE3 	0x30	
						//Channel0 = AIN1-AIN0;开启 0 1通道
						//Channel1 = AIN3-AIN2;合并1 0 ,3 2为两个通道
						
#define CHNL0 	0		//Using Channel0
#define CHNL1 	1		//Using Channel1
#define CHNL2 	2		//Using Channel2
#define CHNL3 	3		//Using Channel3


/*
当使用dac是控制寄存器需配置为0x40 才不影响其他通道
b{ 0'111'(控制模式) 00'11'(通道)}
*/
#define DAouputEn 0x40//0x50 or 0x60 or 0x70 is also ok!

#define PCF8591Add 0x90 //为默认写时设备地址0x90,当进行读取时设备地址为0x91

uint8_t IICReadOneByte(uint8_t DevAddress);
void IICWriteTwoByte(uint8_t DevAddress,uint8_t control,uint8_t D_value);
void IICWriteOneByte(uint8_t DevAddress,uint8_t control);

.c文件

c 复制代码
void IICWriteOneByte(uint8_t DevAddress,uint8_t control) 
{
	HAL_I2C_Master_Transmit(&hi2c4,DevAddress, &control,1,1000);
}

void IICWriteTwoByte(uint8_t DevAddress,uint8_t control,uint8_t D_value) //WriteTwoByte
{
	uint8_t data[2]={0};
	data[0] = control;
	data[1] = D_value;
	HAL_I2C_Master_Transmit(&hi2c4,DevAddress,data,2,100);
}  
uint8_t IICReadOneByte(uint8_t DevAddress)
{
	uint8_t buf[1]={0};	
	HAL_I2C_Master_Receive(&hi2c4,DevAddress,buf,1,1000);
	return buf[0];
}
相关推荐
离凌寒1 天前
一、超声波模块
stm32·单片机·嵌入式硬件·模块测试
可涵不会debug3 天前
Selenium自动化测试秘籍:解锁常用函数实战指南
python·功能测试·selenium·测试工具·单元测试·模块测试
nx1314445025113 天前
办理蜡烛和烛台的ASTM F2417测试报告流程讲解;
大数据·运维·服务器·数据库·模块测试
王景程13 天前
什么是手机的boot分区
智能手机·模块测试
nx1314445025114 天前
烧烤炉出口亚马逊欧盟站CE认证EN1860安全标准
大数据·数据库·功能测试·安全·模块测试
bjwuzh20 天前
软件的生命周期有哪些阶段?
功能测试·单元测试·测试用例·ab测试·模块测试·测试覆盖率·安全性测试
Ronin-Lotus1 个月前
嵌入式硬件篇---ADC模拟-数字转换
笔记·stm32·单片机·嵌入式硬件·学习·低代码·模块测试
番茄老夫子2 个月前
超声波信号采集传感器模块测试分析总结
人工智能·模块测试
靴子学长2 个月前
基于 Python 自动化接口测试(踩坑与实践)
python·模块测试