我平时的习惯是使用寄存器进行GPIO操作:
- #define I2C_SCL_P100_HIGH R_PFS->PORT[1].PIN[0].PmnPFS_b.PODR = 1
- #define I2C_SCL_P100_LOW R_PFS->PORT[1].PIN[0].PmnPFS_b.PODR = 0
- #define I2C_SDA_P101_HIGH R_PFS->PORT[1].PIN[1].PmnPFS_b.PODR = 1
- #define I2C_SDA_P101_LOW R_PFS->PORT[1].PIN[1].PmnPFS_b.PODR = 0
I2C驱动代码直接移植原子的代码即可:
- void I2C_IDLE_P100_P101()
- {
- I2C_SDA_P101_OUT();
- I2C_SDA_P101_HIGH;
- I2C_SCL_P100_HIGH;
- R_BSP_SoftwareDelay(4 , BSP_DELAY_UNITS_MICROSECONDS);
- }
- void I2C_Start_P100_P101(void)
- {
- I2C_SDA_P101_OUT();
- I2C_SDA_P101_HIGH;
- I2C_SCL_P100_HIGH;
- R_BSP_SoftwareDelay(4 , BSP_DELAY_UNITS_MICROSECONDS);
- I2C_SDA_P101_LOW;
- R_BSP_SoftwareDelay(4 , BSP_DELAY_UNITS_MICROSECONDS);
- I2C_SCL_P100_LOW;
- R_BSP_SoftwareDelay(4 , BSP_DELAY_UNITS_MICROSECONDS);
- }
- void I2C_Stop_P100_P101(void)
- {
- I2C_SDA_P101_OUT();
- I2C_SDA_P101_LOW;
- I2C_SCL_P100_HIGH;
- R_BSP_SoftwareDelay(4 , BSP_DELAY_UNITS_MICROSECONDS);
- I2C_SDA_P101_HIGH;
- }
- uint8_t I2C_Wait_Ack_P100_P101(void)
- {
- uint8_t rvalue;
- I2C_SDA_P101_OUT();
- I2C_SDA_P101_HIGH;
- R_BSP_SoftwareDelay(4 , BSP_DELAY_UNITS_MICROSECONDS);
- I2C_SCL_P100_HIGH;
- R_BSP_SoftwareDelay(4 , BSP_DELAY_UNITS_MICROSECONDS);
- I2C_SDA_P101_IN();
- if(I2C_SDA_P101_READ)
- {
- rvalue = 1;
- }
- else
- {
- rvalue = 0;
- }
- I2C_SCL_P100_LOW;
- R_BSP_SoftwareDelay(4 , BSP_DELAY_UNITS_MICROSECONDS);
- return rvalue;
- }
- void I2C_Ack_P100_P101(void)
- {
- I2C_SDA_P101_OUT();
- I2C_SDA_P101_LOW;
- R_BSP_SoftwareDelay(4 , BSP_DELAY_UNITS_MICROSECONDS);
- I2C_SCL_P100_HIGH;
- R_BSP_SoftwareDelay(4 , BSP_DELAY_UNITS_MICROSECONDS);
- I2C_SCL_P100_LOW;
- R_BSP_SoftwareDelay(4 , BSP_DELAY_UNITS_MICROSECONDS);
- I2C_SDA_P101_HIGH;
- }
- void I2C_NAck_P100_P101(void)
- {
- I2C_SDA_P101_OUT();
- I2C_SDA_P101_HIGH;
- R_BSP_SoftwareDelay(4 , BSP_DELAY_UNITS_MICROSECONDS);
- I2C_SCL_P100_HIGH;
- R_BSP_SoftwareDelay(4 , BSP_DELAY_UNITS_MICROSECONDS);
- I2C_SCL_P100_LOW;
- R_BSP_SoftwareDelay(4 , BSP_DELAY_UNITS_MICROSECONDS);
- }
- void I2C_Send_Byte_P100_P101(uint8_t txd)
- {
- uint8_t i;
- I2C_SDA_P101_OUT();
- I2C_SCL_P100_LOW;
- for(i = 0 ; i < 8 ; i ++)
- {
- if((txd&0x80)>>7)
- I2C_SDA_P101_HIGH;
- else
- I2C_SDA_P101_LOW;
- txd <<= 1;
- R_BSP_SoftwareDelay(20 , BSP_DELAY_UNITS_MICROSECONDS);
- I2C_SCL_P100_HIGH;
- R_BSP_SoftwareDelay(20 , BSP_DELAY_UNITS_MICROSECONDS);
- I2C_SCL_P100_LOW;
- R_BSP_SoftwareDelay(20 , BSP_DELAY_UNITS_MICROSECONDS);
- }
- R_BSP_SoftwareDelay(20 , BSP_DELAY_UNITS_MICROSECONDS);
- }
- uint16_t I2C_Read_Byte_P100_P101(uint8_t ack)
- {
- uint8_t i;
- uint16_t dat = 0;
- I2C_SDA_P101_IN();
- for(i = 0 ; i < 8 ; i++)
- {
- I2C_SCL_P100_LOW;
- R_BSP_SoftwareDelay(20 , BSP_DELAY_UNITS_MICROSECONDS);
- I2C_SCL_P100_HIGH;
- dat <<= 1;
- if(I2C_SDA_P101_READ)
- dat++;
- R_BSP_SoftwareDelay(20 , BSP_DELAY_UNITS_MICROSECONDS);
- }
- if (!ack)
- I2C_NAck_P100_P101();
- else
- I2C_Ack_P100_P101();
- return dat;
- }
- uint8_t I2C_Read_Addr_P100_P101(uint8_t dev_addr , uint8_t reg)
- {
- uint8_t res;
- I2C_Start_P100_P101();
- I2C_Send_Byte_P100_P101((dev_addr << 1) | 0);
- I2C_Wait_Ack_P100_P101();
- I2C_Send_Byte_P100_P101(reg);
- I2C_Wait_Ack_P100_P101();
- I2C_Start_P100_P101();
- I2C_Send_Byte_P100_P101((dev_addr << 1) | 1);
- I2C_Wait_Ack_P100_P101();
- res = I2C_Read_Byte_P100_P101(0);
- I2C_Stop_P100_P101();
- return res;
- }
- void I2C_Read_Datas_P100_P101(uint8_t dev_addr , uint8_t reg , uint8_t data_len , uint8_t data[])
- {
- while(data_len)
- {
- *data = I2C_Read_Addr_P100_P101(dev_addr , reg++);
- data ++;
- data_len --;
- }
- }
- void I2C_Write_Reg_Data_P100_P101(uint8_t dev_addr , uint8_t reg , uint8_t data)
- {
- I2C_Start_P100_P101();
- I2C_Send_Byte_P100_P101((dev_addr << 1) | 0);
- I2C_Wait_Ack_P100_P101();
- I2C_Send_Byte_P100_P101(reg);
- I2C_Wait_Ack_P100_P101();
- I2C_Send_Byte_P100_P101(data);
- I2C_Wait_Ack_P100_P101();
- I2C_Stop_P100_P101();
- }
- void I2C_Write_Reg_Datas_P100_P101(uint8_t dev_addr , uint8_t reg , uint8_t data_len , uint8_t data[])
- {
- int i;
- I2C_Start_P100_P101();
- I2C_Send_Byte_P100_P101((dev_addr << 1) | 0);
- I2C_Wait_Ack_P100_P101();
- I2C_Send_Byte_P100_P101(reg);
- I2C_Wait_Ack_P100_P101();
- for(i = 0 ; i < data_len ; i++)
- {
- I2C_Send_Byte_P100_P101(data[i]);
- I2C_Wait_Ack_P100_P101();
- }
- I2C_Stop_P100_P101();
- R_BSP_SoftwareDelay(10 , BSP_DELAY_UNITS_MILLISECONDS);
- }
- #define ATH20_SLAVE_ADDRESS 0x38
- #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)
- #define BMP280_SLAVE_ADDRESS_0x76 0x76
- #define BMP280_SLAVE_ADDRESS_0x77 0x77
- /*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)
- #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.
- 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 */
- int t_fine; /* calibration t_fine data */
- } bmp280Calib;
- uint8_t msb , lsb , xlsb;
- float var1 , var2;
- bmp280Calib bmp280Cal;
- uint8_t BMP280_Init(void)
- {
- uint8_t bmp280_id;
- uint8_t tmp[1];
- I2C_Read_Datas_P100_P101(BMP280_SLAVE_ADDRESS_0x77 , BMP280_CHIPID_REG, 1, &bmp280_id);
- printf("bmp280_id = 0x%x\n" , bmp280_id);
- I2C_Read_Datas_P100_P101(BMP280_SLAVE_ADDRESS_0x77, BMP280_DIG_T1_LSB_REG , 24 , (uint8_t *)&bmp280Cal);
- //printf("%d %d %d %d %d %d %d %d %d %d %d %d\n" ,
- // bmp280Cal.dig_T1 , bmp280Cal.dig_T2 , bmp280Cal.dig_T3 ,
- // bmp280Cal.dig_P1 , bmp280Cal.dig_P2 , bmp280Cal.dig_P3 ,
- // bmp280Cal.dig_P4 , bmp280Cal.dig_P5 , bmp280Cal.dig_P6 ,
- // bmp280Cal.dig_P7 , bmp280Cal.dig_P8 , bmp280Cal.dig_P9);
- tmp[0] = BMP280_MODE;
- I2C_Write_Reg_Datas_P100_P101(BMP280_SLAVE_ADDRESS_0x77 , BMP280_CTRLMEAS_REG , 1 , tmp);
- tmp[0] = 5 << 2;
- I2C_Write_Reg_Datas_P100_P101(BMP280_SLAVE_ADDRESS_0x77 , BMP280_CONFIG_REG , 1 , tmp);
- return bmp280_id;
- }
- float BMP280PressureToAltitude(float* pressure)
- {
- if (*pressure > 0)
- {
- return ((pow((1015.7f / (*pressure)), CONST_PF) - 1.0f) * (FIX_TEMP + 273.15f)) / 0.0065f;
- }
- else
- {
- return 0;
- }
- }
- void BMP280_Read_Pressure_Tempature(float * pres , float * temp)
- {
- msb = I2C_Read_Addr_P100_P101(BMP280_SLAVE_ADDRESS_0x77 , BMP280_PRESSURE_MSB_REG);
- lsb = I2C_Read_Addr_P100_P101(BMP280_SLAVE_ADDRESS_0x77 , BMP280_PRESSURE_LSB_REG);
- xlsb = I2C_Read_Addr_P100_P101(BMP280_SLAVE_ADDRESS_0x77 , BMP280_PRESSURE_XLSB_REG);
- *pres = (msb * 65536 | lsb * 256 | xlsb) >> 4;
- msb = I2C_Read_Addr_P100_P101(BMP280_SLAVE_ADDRESS_0x77 , BMP280_TEMPERATURE_MSB_REG);
- lsb = I2C_Read_Addr_P100_P101(BMP280_SLAVE_ADDRESS_0x77 , BMP280_TEMPERATURE_LSB_REG);
- xlsb = I2C_Read_Addr_P100_P101(BMP280_SLAVE_ADDRESS_0x77 , BMP280_TEMPERATURE_XLSB_REG);
- *temp = (msb * 65536 | lsb * 256 | xlsb) >> 4;
- var1 = ((*temp) / 16384.0 - bmp280Cal.dig_T1 / 1024.0)*(bmp280Cal.dig_T2);
- var2 = (((*temp) / 131072.0 - bmp280Cal.dig_T1 / 8192.0) *
- ((*temp) / 131072.0 - bmp280Cal.dig_T1 / 8192.0)) * bmp280Cal.dig_T3;
- *temp = var1 + var2;
- *temp /= 5120.0;
- var1 = ((*temp) / 2.0) - 64000.0;
- var2 = var1 * var1*(bmp280Cal.dig_P6) / 32768.0;
- var2 = var2 + var1 * (bmp280Cal.dig_P5)*2.0;
- var2 = (var2 / 4.0) + ((bmp280Cal.dig_P4)*65536.0);
- var1 = (bmp280Cal.dig_P3)*var1*var1 / 524288.0 + (bmp280Cal.dig_P2)*var1 / 524288.0;
- var1 = (1.0 + var1 / 32768.0)*(bmp280Cal.dig_P1);
- *pres = 1048576.0 - (*pres);
- *pres = ((*pres) - (var2 / 4096.0))*6250.0 / var1;
- var1 = (bmp280Cal.dig_P9) * (*pres) * (*pres) / 2147483648.0;
- var2 = (*pres) * (bmp280Cal.dig_P8) / 32768.0;
- *pres = (*pres) + (var1 + var2 + (bmp280Cal.dig_P7)) / 16.0;
- }
运行效果: