主页 > 人工智能  > 

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

一、对iic类模块分析与使用
bmp280驱动代码

说明:

1、该模块用于获取气压,温度,海拔等数据。 vcc,gnd接电源 sda ,scl 接iic通信引脚 2、该模块使用iic通信,通过iic发送请求相关类的寄存器值,芯片获取对应寄存器返回的数据。 所以使用的时调用HAL_I2C_Mem_Write函数 3、调用:

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文件 #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文件 #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、调用

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文件 #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文件 //用于向设备发送指令。 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通信,通过配置模块中芯片的寄存器来获取数据。 调用

ATH20_Init(); float temperaut,humtidiy; ATH20_Read_CTdata(&temperaut,&humtidiy); printf("温度: %.3lf ℃\n",temperaut); printf("湿度: %.3lf %%\n",humtidiy); .h文件 #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文件 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采集通道 调用:

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文件 #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文件 /********************************************************************************* 描述:配置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采集通道) 调用:

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文件 //控制寄存器的模式 #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文件 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]; }
标签:

一、对iic类模块分析与使用由讯客互联人工智能栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“一、对iic类模块分析与使用