STM32通过I2C与BMP280通信

发布者:rnm888最新更新时间:2018-04-22 来源: eefocus关键字:STM32  I2C  BMP280  通信 手机看文章 扫描二维码
随时随地手机看文章

BMP280气压传感器(Digital Pressure sensor)


测试流程图:




项目中使用的是I2C通信,BMP280的作为slave的地址要确认好,它的地址根据硬件电路SDO接什么脚来决定:


1.BMP280的测试启动流程(注意它的datasheet中的status寄存器):
(1)读取BMP280的id,其值等于0x58。
(2)把补偿寄存器的值都读出来。
(3)对BMP280进行reset。
(4)对BMP280的数据采集精度,模式。。。等进行配置。
(5)给点延时,等待数据采集完毕放入寄存器中。
(6)读取寄存器中的采集数据。
注意:BMP280对温度和气压的测量是通过一堆补偿数据然后根据自己的算法算出来的,要注意这些数据是什么类型的,刚开始我就因为粗心没看清楚,算出来的数据总是不正确。


下面把代码贴出来:
1.bmp280的驱动文件:


  1. #include   

  2. #include "stm32f4xx_hal.h"  

  3. #include "stm32f4xx_hal_i2c.h"  

  4. #include   

  5.   

  6. #define dig_T1 bmp280->T1  

  7. #define dig_T2 bmp280->T2  

  8. #define dig_T3 bmp280->T3  

  9. #define dig_P1 bmp280->P1  

  10. #define dig_P2 bmp280->P2  

  11. #define dig_P3 bmp280->P3  

  12. #define dig_P4 bmp280->P4  

  13. #define dig_P5 bmp280->P5  

  14. #define dig_P6 bmp280->P6  

  15. #define dig_P7 bmp280->P7  

  16. #define dig_P8 bmp280->P8  

  17. #define dig_P9 bmp280->P9  

  18.   

  19. static uint8_t bmp280_read_register(I2C_HandleTypeDef Bmp280_I2cHandle, uint8_t reg_addr)  

  20. {  

  21.     uint8_t reg_data;  

  22.   

  23.     while(HAL_I2C_Master_Transmit(&Bmp280_I2cHandle, BMP280_ADDRESS, ®_addr, 1, 10000) != HAL_OK) {  

  24.         if(HAL_I2C_GetError(&Bmp280_I2cHandle) != HAL_I2C_ERROR_AF) {  

  25.             printf("Transmit slave address error!!!\r\n");  

  26.             return -1;  

  27.         }  

  28.     }  

  29.   

  30.     while(HAL_I2C_Master_Receive(&Bmp280_I2cHandle, BMP280_ADDRESS, ®_data, 1, 10000) != HAL_OK) {  

  31.         if(HAL_I2C_GetError(&Bmp280_I2cHandle) != HAL_I2C_ERROR_AF) {  

  32.             printf("Receive slave data error!!!\r\n");  

  33.             return -1;  

  34.         }  

  35.     }  

  36.   

  37.     return reg_data;  

  38. }  

  39.   

  40. static void bmp280_write_register(I2C_HandleTypeDef Bmp280_I2cHandle, uint8_t reg_addr, uint8_t reg_data)  

  41. {  

  42.     uint8_t tx_data[2] = {reg_addr, reg_data};  

  43.   

  44.     while(HAL_I2C_Master_Transmit(&Bmp280_I2cHandle, BMP280_ADDRESS, tx_data, 2, 10000) != HAL_OK) {  

  45.         if(HAL_I2C_GetError(&Bmp280_I2cHandle) != HAL_I2C_ERROR_AF) {  

  46.             printf("Transmit slave address error!!!\r\n");  

  47.         }  

  48.     }  

  49. }  

  50.   

  51. /** 

  52.  * 在bmp280_init()函数里默认初始化t_standby为0.5ms, 

  53.  * 温度和气压的采样精度设为最低, 

  54.  * 滤波器系数设为最低, 

  55.  * 并且进入sleep mode。 

  56.  */  

  57. struct bmp280 *bmp280_init(I2C_HandleTypeDef I2cHandle)  

  58. {  

  59.     uint8_t bmp280_id;  

  60.     uint8_t lsb, msb;  

  61.     uint8_t ctrlmeas_reg, config_reg;  

  62.     struct bmp280 *bmp280;  

  63.   

  64.     bmp280_id = bmp280_read_register(I2cHandle, BMP280_CHIPID_REG);  

  65.     if(bmp280_id == 0x58) {  

  66.         bmp280 = malloc(sizeof(struct bmp280));  

  67.   

  68.         bmp280->I2cHandle = I2cHandle;  

  69.         bmp280->mode = BMP280_SLEEP_MODE;  

  70.         bmp280->t_sb = BMP280_T_SB1;  

  71.         bmp280->p_oversampling = BMP280_P_MODE_1;  

  72.         bmp280->t_oversampling = BMP280_T_MODE_1;  

  73.         bmp280->filter_coefficient = BMP280_FILTER_MODE_1;  

  74.     } else {  

  75.         printf("Read BMP280 id error!\r\n");  

  76.         return NULL;  

  77.     }  

  78.   

  79.     /* read the temperature calibration parameters */  

  80.     lsb = bmp280_read_register(I2cHandle, BMP280_DIG_T1_LSB_REG);  

  81.     msb = bmp280_read_register(I2cHandle, BMP280_DIG_T1_MSB_REG);  

  82.     dig_T1 = msb << 8 | lsb;  

  83.     lsb = bmp280_read_register(I2cHandle, BMP280_DIG_T2_LSB_REG);  

  84.     msb = bmp280_read_register(I2cHandle, BMP280_DIG_T2_MSB_REG);  

  85.     dig_T2 = msb << 8 | lsb;  

  86.     lsb = bmp280_read_register(I2cHandle, BMP280_DIG_T3_LSB_REG);  

  87.     msb = bmp280_read_register(I2cHandle, BMP280_DIG_T3_MSB_REG);  

  88.     dig_T3 = msb << 8 | lsb;  

  89.   

  90.     /* read the pressure calibration parameters */  

  91.     lsb = bmp280_read_register(I2cHandle, BMP280_DIG_P1_LSB_REG);  

  92.     msb = bmp280_read_register(I2cHandle, BMP280_DIG_P1_MSB_REG);  

  93.     dig_P1 = msb << 8 | lsb;  

  94.     lsb = bmp280_read_register(I2cHandle, BMP280_DIG_P2_LSB_REG);  

  95.     msb = bmp280_read_register(I2cHandle, BMP280_DIG_P2_MSB_REG);  

  96.     dig_P2 = msb << 8 | lsb;  

  97.     lsb = bmp280_read_register(I2cHandle, BMP280_DIG_P3_LSB_REG);  

  98.     msb = bmp280_read_register(I2cHandle, BMP280_DIG_P3_MSB_REG);  

  99.     dig_P3 = msb << 8 | lsb;  

  100.     lsb = bmp280_read_register(I2cHandle, BMP280_DIG_P4_LSB_REG);  

  101.     msb = bmp280_read_register(I2cHandle, BMP280_DIG_P4_MSB_REG);  

  102.     dig_P4 = msb << 8 | lsb;  

  103.     lsb = bmp280_read_register(I2cHandle, BMP280_DIG_P5_LSB_REG);  

  104.     msb = bmp280_read_register(I2cHandle, BMP280_DIG_P5_MSB_REG);  

  105.     dig_P5 = msb << 8 | lsb;  

  106.     lsb = bmp280_read_register(I2cHandle, BMP280_DIG_P6_LSB_REG);  

  107.     msb = bmp280_read_register(I2cHandle, BMP280_DIG_P6_MSB_REG);  

  108.     dig_P6 = msb << 8 | lsb;  

  109.     lsb = bmp280_read_register(I2cHandle, BMP280_DIG_P7_LSB_REG);  

  110.     msb = bmp280_read_register(I2cHandle, BMP280_DIG_P7_MSB_REG);  

  111.     dig_P7 = msb << 8 | lsb;  

  112.     lsb = bmp280_read_register(I2cHandle, BMP280_DIG_P8_LSB_REG);  

  113.     msb = bmp280_read_register(I2cHandle, BMP280_DIG_P8_MSB_REG);  

  114.     dig_P8 = msb << 8 | lsb;  

  115.     lsb = bmp280_read_register(I2cHandle, BMP280_DIG_P9_LSB_REG);  

  116.     msb = bmp280_read_register(I2cHandle, BMP280_DIG_P9_MSB_REG);  

  117.     dig_P9 = msb << 8 | lsb;  

  118.   

  119.     bmp280_reset(bmp280);  

  120.   

  121.     ctrlmeas_reg = bmp280->t_oversampling << 5 | bmp280->p_oversampling << 2 | bmp280->mode;  

  122.     config_reg = bmp280->t_sb << 5 | bmp280->filter_coefficient << 2;  

  123.   

  124.     bmp280_write_register(I2cHandle, BMP280_CTRLMEAS_REG, ctrlmeas_reg);  

  125.     bmp280_write_register(I2cHandle, BMP280_CONFIG_REG, config_reg);  

  126.   

  127.     HAL_Delay(100);  

  128.   

  129.     return bmp280;  

  130. }  

  131.   

  132. void bmp280_reset(struct bmp280 *bmp280)  

  133. {  

  134.     bmp280_write_register(bmp280->I2cHandle, BMP280_RESET_REG, BMP280_RESET_VALUE);  

  135. }  

  136.   

  137. void bmp280_set_standby_time(struct bmp280 *bmp280, BMP280_T_SB t_standby)  

  138. {  

  139.     uint8_t config_reg;  

  140.   

  141.     bmp280->t_sb = t_standby;  

  142.     config_reg = bmp280->t_sb << 5 | bmp280->filter_coefficient << 2;  

  143.   

  144.     bmp280_write_register(bmp280->I2cHandle, BMP280_CONFIG_REG, config_reg);  

  145. }  

  146.   

  147. void bmp280_set_work_mode(struct bmp280 *bmp280, BMP280_WORK_MODE mode)  

  148. {  

  149.     uint8_t ctrlmeas_reg;  

  150.   

  151.     bmp280->mode = mode;  

  152.     ctrlmeas_reg = bmp280->t_oversampling << 5 | bmp280->p_oversampling << 2 | bmp280->mode;  

  153.   

  154.     bmp280_write_register(bmp280->I2cHandle, BMP280_CTRLMEAS_REG, ctrlmeas_reg);  

  155. }  

  156.   

  157. void bmp280_set_temperature_oversampling_mode(struct bmp280 *bmp280, BMP280_T_OVERSAMPLING t_osl)  

  158. {  

  159.     uint8_t ctrlmeas_reg;  

  160.   

  161.     bmp280->t_oversampling = t_osl;  

  162.     ctrlmeas_reg = bmp280->t_oversampling << 5 | bmp280->p_oversampling << 2 | bmp280->mode;  

  163.   

  164.     bmp280_write_register(bmp280->I2cHandle, BMP280_CTRLMEAS_REG, ctrlmeas_reg);  

  165. }  

  166.   

  167. void bmp280_set_pressure_oversampling_mode(struct bmp280 *bmp280, BMP280_P_OVERSAMPLING p_osl)  

  168. {  

  169.     uint8_t ctrlmeas_reg;  

  170.   

  171.     bmp280->t_oversampling = p_osl;  

  172.     ctrlmeas_reg = bmp280->t_oversampling << 5 | bmp280->p_oversampling << 2 | bmp280->mode;  

  173.   

  174.     bmp280_write_register(bmp280->I2cHandle, BMP280_CTRLMEAS_REG, ctrlmeas_reg);  

  175. }  

  176.   

  177. void bmp280_set_filter_mode(struct bmp280 *bmp280, BMP280_FILTER_COEFFICIENT f_coefficient)  

  178. {  

  179.     uint8_t config_reg;  

  180.   

  181.     bmp280->filter_coefficient = f_coefficient;  

  182.     config_reg = bmp280->t_sb << 5 | bmp280->filter_coefficient << 2;  

  183.   

  184.     bmp280_write_register(bmp280->I2cHandle, BMP280_CONFIG_REG, config_reg);  

  185. }  

  186.   

  187. /* Returns temperature in DegC, double precision. Output value of “51.23” equals 51.23 DegC. */  

  188. static double bmp280_compensate_temperature_double(struct bmp280 *bmp280, int32_t adc_T)  

  189. {  

  190.     double var1, var2, temperature;  

  191.   

  192.     var1 = (((double) adc_T) / 16384.0 - ((double) dig_T1) / 1024.0)  

  193.             * ((double) dig_T2);  

  194.     var2 = ((((double) adc_T) / 131072.0 - ((double) dig_T1) / 8192.0)  

  195.             * (((double) adc_T) / 131072.0 - ((double) dig_T1) / 8192.0))  

  196.             * ((double) dig_T3);  

  197.     bmp280->t_fine = (int32_t) (var1 + var2);  

  198.     temperature = (var1 + var2) / 5120.0;  

  199.   

  200.     return temperature;  

  201. }  

  202.   

  203.   

  204. /* Returns pressure in Pa as double. Output value of “96386.2” equals 96386.2 Pa = 963.862 hPa */  

  205. static double bmp280_compensate_pressure_double(struct bmp280 *bmp280, int32_t adc_P)  

  206. {  

  207.     double var1, var2, pressure;  

  208.   

  209.     var1 = ((double) bmp280->t_fine / 2.0) - 64000.0;  

  210.     var2 = var1 * var1 * ((double) dig_P6) / 32768.0;  

  211.     var2 = var2 + var1 * ((double) dig_P5) * 2.0;  

  212.     var2 = (var2 / 4.0) + (((double) dig_P4) * 65536.0);  

  213.     var1 = (((double) dig_P3) * var1 * var1 / 524288.0  

  214.             + ((double) dig_P2) * var1) / 524288.0;  

  215.     var1 = (1.0 + var1 / 32768.0) * ((double) dig_P1);  

  216.   

  217.     if (var1 == 0.0) {  

  218.         return 0; // avoid exception caused by division by zero  

  219.     }  

  220.   

  221.     pressure = 1048576.0 - (double) adc_P;  

  222.     pressure = (pressure - (var2 / 4096.0)) * 6250.0 / var1;  

  223.     var1 = ((double) dig_P9) * pressure * pressure / 2147483648.0;  

  224.     var2 = pressure * ((double) dig_P8) / 32768.0;  

  225.     pressure = pressure + (var1 + var2 + ((double) dig_P7)) / 16.0;  

  226.   

  227.     return pressure;  

  228. }  

  229.   

  230. #if 0  

  231. static int32_t bmp280_compensate_temperature_int32(struct bmp280 *bmp280, int32_t adc_T)  

  232. {  

  233.     int32_t var1, var2, temperature;  

  234.   

  235.     var1 = ((((adc_T>>3) - ((int32_t)dig_T1<<1))) * ((int32_t)dig_T2)) >> 11;  

  236.     var2 = (((((adc_T>>4) - ((int32_t)dig_T1)) * ((adc_T>>4) - ((int32_t)dig_T1))) >> 12) * ((int32_t)dig_T3)) >> 14;  

  237.     bmp280->t_fine = var1 + var2;  

  238.     temperature = (bmp280->t_fine * 5 + 128) >> 8;  

  239.   

  240.     return temperature;  

  241. }  

  242.   

  243. static uint32_t bmp280_compensate_pressure_int64(struct bmp280 *bmp280, int32_t adc_P)  

  244. {  

  245.     int64_t var1, var2, pressure;  

  246.   

  247.     var1 = ((int64_t)bmp280->t_fine) - 128000;  

  248.     var2 = var1 * var1 * (int64_t)dig_P6;  

  249.     var2 = var2 + ((var1*(int64_t)dig_P5)<<17);  

  250.     var2 = var2 + (((int64_t)dig_P4)<<35);  

  251.     var1 = ((var1 * var1 * (int64_t)dig_P3)>>8) + ((var1 * (int64_t)dig_P2)<<12);  

  252.     var1 = (((((int64_t)1)<<47)+var1))*((int64_t)dig_P1)>>33;  

  253.     if (var1 == 0)  

  254.     {  

  255.         return 0; // avoid exception caused by division by zero  

  256.     }  

  257.   

  258.     pressure = 1048576-adc_P;  

  259.     pressure = (((pressure<<31)-var2)*3125)/var1;  

  260.     var1 = (((int64_t)dig_P9) * (pressure>>13) * (pressure>>13)) >> 25;  

  261.     var2 = (((int64_t)dig_P8) * pressure) >> 19;  

  262.     pressure = ((pressure + var1 + var2) >> 8) + (((int64_t)dig_P7)<<4);  

  263.   

  264.     return (uint32_t)pressure;  

  265. }  

  266. #endif  

  267.   

  268. /* Returns temperature in DegC, double precision. Output value of “51.23” equals 51.23 DegC. */  

  269. double bmp280_get_temperature(struct bmp280 *bmp280)  

  270. {  

  271.     uint8_t lsb, msb, xlsb;  

  272.     int32_t adc_T;  

  273.     double temperature;  

  274.   

  275.     xlsb = bmp280_read_register(bmp280->I2cHandle, BMP280_TEMPERATURE_XLSB_REG);  

  276.     lsb = bmp280_read_register(bmp280->I2cHandle, BMP280_TEMPERATURE_LSB_REG);  

  277.     msb = bmp280_read_register(bmp280->I2cHandle, BMP280_TEMPERATURE_MSB_REG);  

  278.   

  279.     adc_T = (msb << 12) | (lsb << 4) | (xlsb >> 4);  

  280.     temperature = bmp280_compensate_temperature_double(bmp280, adc_T);  

  281.   

  282.     return temperature;  

  283. }  

  284.   

  285. /* Returns pressure in Pa as double. Output value of “96386.2” equals 96386.2 Pa = 963.862 hPa */  

  286. double bmp280_get_pressure(struct bmp280 *bmp280)  

  287. {  

  288.     uint8_t lsb, msb, xlsb;  

  289.     int32_t adc_P;  

  290.     double pressure;  

  291.   

  292.   

  293.     xlsb = bmp280_read_register(bmp280->I2cHandle, BMP280_PRESSURE_XLSB_REG);  

  294.     lsb = bmp280_read_register(bmp280->I2cHandle, BMP280_PRESSURE_LSB_REG);  

  295.     msb = bmp280_read_register(bmp280->I2cHandle, BMP280_PRESSURE_MSB_REG);  

  296.   

  297.     adc_P = (msb << 12) | (lsb << 4) | (xlsb >> 4);  

  298.     pressure = bmp280_compensate_pressure_double(bmp280, adc_P);  

  299.   

  300.     return pressure;  

  301. }  

  302.   

  303. /** 

  304.  * 仅在BMP280被设置为normal mode后, 

  305.  * 可使用该接口直接读取温度和气压。 

  306.  */  

  307. void bmp280_get_temperature_and_pressure(struct bmp280 *bmp280, doubledouble *temperature, doubledouble *pressure)  

  308. {  

  309.     *temperature = bmp280_get_temperature(bmp280);  

  310.     *pressure = bmp280_get_pressure(bmp280);  

  311. }  

  312.   

  313. /** 

  314.  * 当BMP280被设置为forced mode后, 

  315.  * 可使用该接口直接读取温度和气压。 

  316.  */  

  317. void bmp280_forced_mode_get_temperature_and_pressure(struct bmp280 *bmp280, doubledouble *temperature, doubledouble *pressure)  

  318. {  

  319.     bmp280_set_work_mode(bmp280, BMP280_FORCED_MODE);  

  320.   

  321.     HAL_Delay(100);  

  322.   

  323.     bmp280_get_temperature_and_pressure(bmp280, temperature, pressure);  

  324. }  

  325.   

  326. /** 

  327.  * 此demo使用forced mode以1s为周期, 

  328.  * 对温度和气压进行数据采集并打印。 

  329.  */  

  330. void bmp280_demo(I2C_HandleTypeDef I2cHandle, doubledouble *temperature, doubledouble *pressure)  

  331. {  

  332.     struct bmp280 *bmp280;  

  333.     bmp280 = bmp280_init(I2cHandle);  

  334.   

  335.     if(bmp280 != NULL) {  

  336.         while(1) {  

  337.             bmp280_forced_mode_get_temperature_and_pressure(bmp280, temperature, pressure);  

  338.             printf("temperature=%ld   pressure=%ld\r\n", (int32_t)*temperature, (uint32_t)*pressure);  

  339.   

  340.             HAL_Delay(1000);  

  341.         }  

  342.     } else  

  343.         printf("create bmp280 error!\r\n");  

  344. }  


2.头文件:


  1. #ifndef __BMP280_H__  

  2. #define __BMP280_H__  

  3.   

  4. #define BMP280_ADDRESS 0xEC  

  5.   

  6. #define BMP280_RESET_VALUE 0xB6  

  7.   

  8. /*calibration parameters */  

  9. #define BMP280_DIG_T1_LSB_REG                0x88  

  10. #define BMP280_DIG_T1_MSB_REG                0x89  

  11. #define BMP280_DIG_T2_LSB_REG                0x8A  

  12. #define BMP280_DIG_T2_MSB_REG                0x8B  

  13. #define BMP280_DIG_T3_LSB_REG                0x8C  

  14. #define BMP280_DIG_T3_MSB_REG                0x8D  

  15. #define BMP280_DIG_P1_LSB_REG                0x8E  

  16. #define BMP280_DIG_P1_MSB_REG                0x8F  

  17. #define BMP280_DIG_P2_LSB_REG                0x90  

  18. #define BMP280_DIG_P2_MSB_REG                0x91  

  19. #define BMP280_DIG_P3_LSB_REG                0x92  

  20. #define BMP280_DIG_P3_MSB_REG                0x93  

  21. #define BMP280_DIG_P4_LSB_REG                0x94  

  22. #define BMP280_DIG_P4_MSB_REG                0x95  

  23. #define BMP280_DIG_P5_LSB_REG                0x96  

  24. #define BMP280_DIG_P5_MSB_REG                0x97  

  25. #define BMP280_DIG_P6_LSB_REG                0x98  

  26. #define BMP280_DIG_P6_MSB_REG                0x99  

  27. #define BMP280_DIG_P7_LSB_REG                0x9A  

  28. #define BMP280_DIG_P7_MSB_REG                0x9B  

  29. #define BMP280_DIG_P8_LSB_REG                0x9C  

  30. #define BMP280_DIG_P8_MSB_REG                0x9D  

  31. #define BMP280_DIG_P9_LSB_REG                0x9E  

  32. #define BMP280_DIG_P9_MSB_REG                0x9F  

  33.   

  34. #define BMP280_CHIPID_REG                    0xD0  /*Chip ID Register */  

  35. #define BMP280_RESET_REG                     0xE0  /*Softreset Register */  

  36. #define BMP280_STATUS_REG                    0xF3  /*Status Register */  

  37. #define BMP280_CTRLMEAS_REG                  0xF4  /*Ctrl Measure Register */  

  38. #define BMP280_CONFIG_REG                    0xF5  /*Configuration Register */  

  39. #define BMP280_PRESSURE_MSB_REG              0xF7  /*Pressure MSB Register */  

  40. #define BMP280_PRESSURE_LSB_REG              0xF8  /*Pressure LSB Register */  

  41. #define BMP280_PRESSURE_XLSB_REG             0xF9  /*Pressure XLSB Register */  

  42. #define BMP280_TEMPERATURE_MSB_REG           0xFA  /*Temperature MSB Reg */  

  43. #define BMP280_TEMPERATURE_LSB_REG           0xFB  /*Temperature LSB Reg */  

  44. #define BMP280_TEMPERATURE_XLSB_REG          0xFC  /*Temperature XLSB Reg */  

  45.   

  46. /* 在foreced mode下,1s的采样周期,温度和气压使用最低的精度采集并且使用最小的滤波器系数, 

  47.  * 数据的采集时间大概在6ms,平均功率为3.27uA。 

  48.  * */  

  49.   

  50. /* 在foreced mode下,1s的采样周期, 温度和气压使用最高的精度采集并且使用最大的滤波器系数, 

  51.  * 数据的采集时间大概在70ms,平均功率为30uA。 

  52.  * */  

  53.   

  54. typedef enum {  

  55.     BMP280_T_MODE_SKIP = 0x0,   /*skipped*/  

  56.     BMP280_T_MODE_1,            /*x1*/  

  57.     BMP280_T_MODE_2,            /*x2*/  

  58.     BMP280_T_MODE_3,            /*x4*/  

  59.     BMP280_T_MODE_4,            /*x8*/  

  60.     BMP280_T_MODE_5             /*x16*/  

  61. } BMP280_T_OVERSAMPLING;  

  62.   

  63. typedef enum {  

  64.     BMP280_SLEEP_MODE = 0x0,  

  65.     BMP280_FORCED_MODE,  

  66.     BMP280_NORMAL_MODE  

  67. } BMP280_WORK_MODE;  

  68.   

  69. typedef enum {  

  70.     BMP280_P_MODE_SKIP = 0x0,   /*skipped*/  

  71.     BMP280_P_MODE_1,            /*x1*/  

  72.     BMP280_P_MODE_2,            /*x2*/  

  73.     BMP280_P_MODE_3,            /*x4*/  

  74.     BMP280_P_MODE_4,            /*x8*/  

  75.     BMP280_P_MODE_5             /*x16*/  

  76. } BMP280_P_OVERSAMPLING;  

  77.   

  78. typedef enum {  

  79.     BMP280_FILTER_OFF = 0x0,    /*filter off*/  

  80.     BMP280_FILTER_MODE_1,       /*0.223*ODR*/  

  81.     BMP280_FILTER_MODE_2,       /*0.092*ODR*/  

  82.     BMP280_FILTER_MODE_3,       /*0.042*ODR*/  

  83.     BMP280_FILTER_MODE_4        /*0.021*ODR*/  

  84. } BMP280_FILTER_COEFFICIENT;  

  85.   

  86. typedef enum {  

  87.     BMP280_T_SB1 = 0x0,     /*0.5ms*/  

  88.     BMP280_T_SB2,           /*62.5ms*/  

  89.     BMP280_T_SB3,           /*125ms*/  

  90.     BMP280_T_SB4,           /*250ms*/  

  91.     BMP280_T_SB5,           /*500ms*/  

  92.     BMP280_T_SB6,           /*1000ms*/  

  93.     BMP280_T_SB7,           /*2000ms*/  

  94.     BMP280_T_SB8,           /*4000ms*/  

  95. } BMP280_T_SB;  

  96.   

  97. struct bmp280 {  

  98.     I2C_HandleTypeDef I2cHandle;  

  99.     /* T1~P9 为补偿系数 */  

  100.     uint16_t T1;  

  101.     int16_t T2;  

  102.     int16_t T3;  

  103.     uint16_t P1;  

  104.     int16_t P2;  

  105.     int16_t P3;  

  106.     int16_t P4;  

  107.     int16_t P5;  

  108.     int16_t P6;  

  109.     int16_t P7;  

  110.     int16_t P8;  

  111.     int16_t P9;  

  112.     int32_t t_fine;  

  113.     uint8_t t_sb;  

  114.     uint8_t mode;  

  115.     uint8_t t_oversampling;  

  116.     uint8_t p_oversampling;  

  117.     uint8_t filter_coefficient;  

  118. };  

  119.   

  120. extern struct bmp280 *bmp280_init(I2C_HandleTypeDef I2cHandle);  

  121.   

  122. extern void bmp280_reset(struct bmp280 *bmp280);  

  123.   

  124. extern void bmp280_set_standby_time(struct bmp280 *bmp280, BMP280_T_SB t_standby);  

  125.   

  126. extern void bmp280_set_work_mode(struct bmp280 *bmp280, BMP280_WORK_MODE mode);  

  127.   

  128. extern void bmp280_set_temperature_oversampling_mode(struct bmp280 *bmp280, BMP280_T_OVERSAMPLING t_osl);  

  129.   

  130. extern void bmp280_set_pressure_oversampling_mode(struct bmp280 *bmp280, BMP280_P_OVERSAMPLING p_osl);  

  131.   

  132. extern void bmp280_set_filter_mode(struct bmp280 *bmp280, BMP280_FILTER_COEFFICIENT f_coefficient);  

  133.   

  134. extern double bmp280_get_temperature(struct bmp280 *bmp280);  

  135.   

  136. extern double bmp280_get_pressure(struct bmp280 *bmp280);  

  137.   

  138. extern void bmp280_get_temperature_and_pressure(struct bmp280 *bmp280, doubledouble *temperature, doubledouble *pressure);  

  139.   

  140. extern void bmp280_forced_mode_get_temperature_and_pressure(struct bmp280 *bmp280, doubledouble *temperature, doubledouble *pressure);  

  141.   

  142. extern void bmp280_demo(I2C_HandleTypeDef I2cHandle, doubledouble *temperature, doubledouble *pressure);  

  143.   

  144. #endif  




3.主函数相关代码:

[objc] view plain copy

  1.     uint8_t bmp280_id = 0;  

  2.     uint8_t ctr_reg = 0;  

  3.     uint8_t status_reg = 0;  

  4.   

  5.     int32_t tem = 0;  

  6.     uint32_t pressure = 0;  

  7.   

  8.     bmp280_id = bmp280_init(&I2cHandle);  

  9.     if(bmp280_id == 0x58) {  

  10.         bmp280_reset(&I2cHandle);  

  11.   

  12.         ctr_reg = bmp280_read_register(&I2cHandle, 0xF4);  

  13.   

  14.         printf("ctr_reg1111===0x%x\r\n", ctr_reg);  

  15.   

  16.         bmp280_write_register(&I2cHandle, 0xF4, 0xFF);  

  17.   

  18.         bmp280_write_register(&I2cHandle, 0xF5, 0x14);  

  19.   

  20.         HAL_Delay(100);  

  21.   

  22.         while(1) {  

  23.             ctr_reg = bmp280_read_register(&I2cHandle, 0xF4);  

  24.   

  25.             printf("ctr_reg2222===0x%x\r\n", ctr_reg);  

  26.   

  27.             status_reg = bmp280_read_register(&I2cHandle, 0xF3);  

  28.             printf("status == 0x%x\r\n", status_reg);  

  29.   

  30.   

  31.             tem = bmp280_get_temperature(&I2cHandle);  

  32.             pressure = bmp280_get_pressure(&I2cHandle);  

  33.   

  34.             printf("bmp280_id = 0x%x  tem=%ld    pressure=%ld   \r\n", bmp280_id, tem, pressure/256);  

  35.   

  36.             HAL_Delay(2000);  

  37.         }  

  38.     }  


关键字:STM32  I2C  BMP280  通信 引用地址:STM32通过I2C与BMP280通信

上一篇:STM32F407的UDP发送数据
下一篇:STM32F429接MAX6675读取热电偶温度

推荐阅读最新更新时间:2024-03-16 16:00

单片机与PC机电话远程通信系统
1.引言    随着通信技术的不断发展,计算机网络系统通信是当今技术发展的一个重要的方向,然而在网络系统中利用现有电话网作为通信信道则是最经济、最方便和最可靠的方法。当前现代电话通信网已经进入程控交换时代,技术比较先进,速度快,容量大,因此采用电话通信网建立数据通信系统确实具有其独特的优越性。   利用单片机系统采集灌区水位、水流量,实现无人职守和科学的管理水资源具有实际意义,特别对少雨缺水地区更具有应用价值。 2.系统硬件设计    本系统采用了MODEM将前端单片机采集的数据通过电话网远程传输到中心站PC机,并实现一对多点通信(站点数、通信距离均不限),后台PC机通过拨号的方式对各站点进行数据接收并实时存储记录、查询
[应用]
基于兼容主流通信协议NFC收发器的安防产品应用经验
  和传统的近距通讯相比,近场通讯( NFC )有天然的安全性,以及连接建立的快速性。这些优点也使得 NFC 在手机及安防领域里备受欢迎,如智能门锁,门禁等都具有 NFC 功能。下面就随网络通信小编一起来来交易信息国内热播。   目前,我在做的一个安防产品(keypad)也增设了NFC功能。传统的keypad都是通过设置密码,且在按下密码后,keypad方可进行后续的工作。加上NFC功能后,可以使用户直接刷卡,无需再按按键就可以使keypad进行后续工作。所以这个功能无疑是我设计的产品的一大亮点,也是和传统安防产品中的keypad一个重要区别。   在我的安防产品keypad中选用了世强代理的Melexis的 MLX90132
[网络通信]
医疗信息通信昭示人体局域网时代的到来
  尽管可植入射频收发器芯片技术的进步推动了体内医疗通信技术的发展,但是超低功耗无线人体传感器的快速发展却促进了体外通信技术的形成。进而,构成人体局域网(即BAN)平台,实现体内/体外医用传感器与监测工具的无线连接,实时提供病人的健康数据。   随着宽带移动电子技术与超低功耗消费电子的结合,以及可植入半导体无线收发器芯片和传感器日趋小型化,全球的医疗保健和健康诊疗手段正发生着快速的变化。从而,支持远程实时医疗检测和治疗的新服务与应用不断涌现,进而促进普及式医疗服务发展到一个全新的水平。   2007年,在美国檀香山召开的国际微波大会上,日本横滨国立大学医疗信息通信技术研究所主任Ryuji Kohno教授在他的主题演讲中指
[医疗电子]
医疗信息<font color='red'>通信</font>昭示人体局域网时代的到来
STM32的GPIO输入编程实例之读取按键状态
一、概述 1、按键简介 按键是一种机械器件,按键两端分别对应某电路的两个断点,我们可以通过按键接通和断开控制该电路的电压等参数,我们利用按键做的应用通常有控制继电器、键盘、复位等。随着应用的扩展,按键已成为电路板上不可或缺的一部分。 2、按键类别简介 按键主要有四种类型:常开带复位、常开不带复位、常闭带复位、常闭不带复位。(本次实验使用的是常开带复位按键) 按键主要有以下4种工作模式: 常开带复位:初始默认状态是开路,当受力按下时按键使电路连通,受力结束后其自动返回开路状态。 常开带不复位:初始默认状态是开路,每按下一次按键改变一次开闭状态。 常闭带复位:初始默认状态是连通,当受力按下时按键使电路开路,受力结束后其自动返回
[单片机]
STM32 结构体定义地址对齐
在MDK下定义一个结构体,对一段报文,强制转换为结构体类型,实际运行地址错位。 Heartbeat_Message *tmp_Heartbeat; tmp_Heartbeat=(Heartbeat_Message *) &sen_dma_tmpbuf ; typedef struct { uint16_t Sync; uint16_t Packet_Length; uint8_t ID ; uint8_t Frame_Type; uint8_t Packet_Type; uint32_t time; uint16_t CRC16; }Heartbeat_Message;
[单片机]
STM32 ADC时钟配置
一 STM32 ADC 采样频率的确定 先看一些资料,确定一下STM32 ADC 的时钟: (1),由时钟控制器提供的ADCCLK 时钟和PCLK2(APB2 时钟)同步。CLK 控制器为ADC 时钟提供一个专用的可编程预分频器。 (2)一般情况下在程序 中将 PCLK2 时钟设为 与系统时钟相同 RCC_HCLKConfig(RCC_SYSCLK_Div1); RCC_PCLK2Config(RCC_HCLK_Div1); RCC_PCLK1Config(RCC_HCLK_Div2); (3)在时钟配置寄存器(RCC_CFGR) 中 有 为ADC 时钟提供一个专用的可编程预分器 位15:14 ADCPRE:ADC预分频 由软件设置
[单片机]
STM32f103 —— can通信
#include stm32f10x_can.h CanRxMsg CanPeliRxMsgStructure; CanTxMsg CanPeliTxMsgStructure; static void can_nvic_config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPr
[单片机]
基于STM32实现串口的两个分案解析
首先总结一下串口232,422,485 串口232:可双向传输,全双工,最大速率20Kbps,负逻辑电平,-15V~-3V逻辑“1”,+3V~+15V逻辑“0”。 串口422:可双向传输,4线全双工,2线单工。 串口485:可双向传输,4线全双工,2线单工,最大速率10Mb/s,差分信号,发送端:+2V~+6V逻辑“1”,-2V~-6V逻辑“0”,接收端:+200mV逻辑“1”,-200mV逻辑“0”。 对于串口的实现有以两个方案: 方案一,和原子的《例说STM32》一样,首先接收,然后处理,没有消息验证处理,这样就会出现消息覆盖,消息出错后死机,无法明确区分命令,无法及时应答握手信号。方案二,借鉴uC/OSII的消息队列,进
[单片机]
基于<font color='red'>STM32</font>实现串口的两个分案解析
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved