STM32F1-使用BMP280

BMP280可以测量大气压力和温度,可以用来实现无人机定高。

这里使用他人的编写的库函数,来快速上手得到数据。

BMP280可用I2C通讯协议,以上是I2C协议所有操作函数。简单移植就可以用到别的器件。

结构体里面的变量用于存储获取的气压、温度数据。

下面的地址取决于硬件,从机地址可以通过SD0接低电平或高电平来改变地址。

下面三个函数分别是 bmp280初始化   bmp280获取原始值  bmp280获取实际大气压高度。

 
  1. #include "BMP280.h"

  2. unsigned short dig_T1;

  3. short dig_T2;

  4. short dig_T3;

  5. unsigned short dig_P1;

  6. short dig_P2;

  7. short dig_P3;

  8. short dig_P4;

  9. short dig_P5;

  10. short dig_P6;

  11. short dig_P7;

  12. short dig_P8;

  13. short dig_P9;

  14. void Bmp280WriteByte(uint8_t addr,uint8_t dat)

  15. {

  16. BMP_IIC_Start();

  17. BMP_IIC_Send_Byte(AddrWrite); // 从机地址+写信号

  18. BMP_IIC_Wait_Ack();

  19. BMP_IIC_Send_Byte(addr);

  20. BMP_IIC_Wait_Ack();

  21. BMP_IIC_Send_Byte(dat);

  22. BMP_IIC_Wait_Ack();

  23. BMP_IIC_Stop();

  24. }

  25. uint8_t Bmp280ReadByte(uint8_t addr)

  26. {

  27. uint8_t dat;

  28. BMP_IIC_Start();

  29. BMP_IIC_Send_Byte(AddrWrite); // 从机地址+写信号

  30. BMP_IIC_Wait_Ack();

  31. BMP_IIC_Send_Byte(addr);

  32. BMP_IIC_Wait_Ack();

  33. BMP_IIC_Start();

  34. BMP_IIC_Send_Byte(AddrRead);// 从机地址+读信号

  35. BMP_IIC_Wait_Ack();

  36. dat = BMP_IIC_Read_Byte(0);// 无需应答

  37. BMP_IIC_Stop();

  38. return dat;

  39. }

  40. long bmp280_MultipleReadThree(unsigned char addr)

  41. {

  42. unsigned char msb, lsb, xlsb;

  43. long temp = 0;

  44. msb = Bmp280ReadByte(addr);

  45. lsb = Bmp280ReadByte(addr + 1);

  46. xlsb = Bmp280ReadByte(addr + 2);

  47. temp = (long)(((unsigned long)msb << 12)|((unsigned long)lsb << 4)|((unsigned long)xlsb >> 4));

  48. return temp;

  49. }

  50. short bmp280_MultipleReadTwo(unsigned char addr)

  51. {

  52. unsigned char msb, lsb;

  53. short temp = 0;

  54. lsb = Bmp280ReadByte(addr);

  55. msb = Bmp280ReadByte(addr + 1);

  56. temp = (short)msb << 8;

  57. temp |= (short)lsb;

  58. return temp;

  59. }

  60. void Bmp280Init()

  61. {

  62. uint8_t id;

  63. BMP_IIC_Init();

  64. Bmp280WriteByte(0xE0,0xB6);// 清除状态

  65. id = Bmp280ReadByte(0xD0); // 读取ID 0x58

  66. // printf("%c",id);

  67. if(id == 0x58)

  68. printf("bmp280 id is right...\r\n");

  69. else

  70. printf("bmp280 id is error...\r\n");

  71. Bmp280WriteByte(0xf4,0xff);

  72. Bmp280WriteByte(0xf5,0x00);

  73. dig_T1 = bmp280_MultipleReadTwo(0x88);

  74. dig_T2 = bmp280_MultipleReadTwo(0x8A);

  75. dig_T3 = bmp280_MultipleReadTwo(0x8C);

  76. dig_P1 = bmp280_MultipleReadTwo(0x8E);

  77. dig_P2 = bmp280_MultipleReadTwo(0x90);

  78. dig_P3 = bmp280_MultipleReadTwo(0x92);

  79. dig_P4 = bmp280_MultipleReadTwo(0x94);

  80. dig_P5 = bmp280_MultipleReadTwo(0x96);

  81. dig_P6 = bmp280_MultipleReadTwo(0x98);

  82. dig_P7 = bmp280_MultipleReadTwo(0x9A);

  83. dig_P8 = bmp280_MultipleReadTwo(0x9C);

  84. dig_P9 = bmp280_MultipleReadTwo(0x9E);

  85. // printf("%d %d %d\r\n",dig_T1,dig_T2,dig_T3);

  86. // printf("%d %d %d %d %d %d %d %d %d\r\n",dig_P1,dig_P2,dig_P3,dig_P4,dig_P5,dig_P6,dig_P7,dig_P8,dig_P9);

  87. delay_ms(200);

  88. }

  89. Bmp280DataTypeDef Bmp280Data;

  90. uint8_t bmp280_GetValue(void)

  91. {

  92. long adc_T;

  93. long adc_P;

  94. long var1, var2, t_fine, T, P;

  95. adc_T = bmp280_MultipleReadThree(0xFA); // 0xFA 0xFB 0xFC

  96. adc_P = bmp280_MultipleReadThree(0xF7); // 0xF7 0xF8 0xF9

  97. if(adc_P == 0 | adc_T == 0)

  98. {

  99. return 0;

  100. }

  101. //Temperature

  102. var1 = (((double)adc_T)/16384.0-((double)dig_T1)/1024.0)*((double)dig_T2);

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

  104. /131072.0-((double)dig_T1)/8192.0))*((double)dig_T3);

  105. t_fine = (unsigned long)(var1+var2);

  106. Bmp280Data.T = (var1+var2)/5120.0;

  107. var1 = ((double)t_fine/2.0)-64000.0;

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

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

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

  111. var1 = (((double)dig_P3)*var1*var1/524288.0+((double)dig_P2)*var1)/524288.0;

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

  113. P = 1048576.0-(double)adc_P;

  114. P = (P-(var2/4096.0))*6250.0/var1;

  115. var1 = ((double)dig_P9)*P*P/2147483648.0;

  116. var2 = P*((double)dig_P8)/32768.0;

  117. Bmp280Data.P = P+(var1+var2+((double)dig_P7))/16.0;

  118. return 1;

  119. }

  120. float bmp280_GetAltitude(void)

  121. {

  122. bmp280_GetValue();

  123. return (1 - pow(Bmp280Data.P / (101325 * pow((1 - 2.25577e-5 * 85),5.25588)), 0.190294)) * 44330.8;

  124. }

初始化,获取值,过滤、转化为高度。

最后的获取大气压高度,这里需要注意,101325是标准海平面大气压,这个数最好根据你所在的城市的海平面大气压来进行更改才能得到尽可能准确的数据。我没有添加温度补偿来让数据更准确,原因是添加后得到的数据出错,研究许久未果,所以暂时放弃。

链接:https://pan.baidu.com/s/1og7lAE_L75O9PpISK_oW7w
提取码:2345

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值