找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 12673|回复: 25
收起左侧

单片机驱动bmp280气压传感器实现应用源码

  [复制链接]
ID:165424 发表于 2018-1-24 10:45 | 显示全部楼层 |阅读模式
之前用bmp280,网上的资源很少,尤其是51单片机用这个模块的,所以现在任务做好了,模块调通,附上成果,供大家参考免去弯路。废话不多说,附件是bmp280的c和h文件,没带程序,程序有很多乱七八糟的什么4463,opt101,dht11,pcf8563.。。。。就不带了,欢迎坛友一起讨论

0.png

单片机源程序如下:
  1. #include <string.h>
  2. #include "bmp280111.h"
  3. #include  <math.h>    //Keil library  
  4. #include  <stdlib.h>  //Keil library  
  5. #include  <stdio.h>   //Keil library       
  6. #include  <INTRINS.H> //Keil library  
  7. #include "sensor_am21xx.h"
  8. #define   uchar unsigned char
  9. #define   uint unsigned int       

  10. #define        BMP280_SlaveAddress   0xec          //定义器件在IIC总线中的从地址                              

  11. #define OSS 0        // Oversampling Setting (note: code is not set up to use other OSS values)

  12. unsigned short dig_T1;
  13. short dig_T2;
  14. short dig_T3;
  15. unsigned short dig_P1;
  16. short dig_P2;
  17. short dig_P3;
  18. short dig_P4;
  19. short dig_P5;
  20. short dig_P6;
  21. short dig_P7;
  22. short dig_P8;
  23. short dig_P9;


  24. void delay()    //略微延时  6us约>4.7us
  25. {
  26. _nop_();
  27.   _nop_();
  28.    _nop_();
  29.     _nop_();
  30.          _nop_();
  31.           _nop_();
  32. }
  33. void iic_start()   //启动信号
  34. {
  35.   SDA=1;
  36.   SCL=1;
  37.   delay();
  38.   SDA=0;
  39.   delay();
  40.   SCL=0;
  41. }
  42. void iic_stop()  //停止信号
  43. {
  44.         SDA=0;
  45.         SCL=1;
  46.         delay();
  47.         SDA=1;
  48.         delay();
  49.         SCL=0;
  50. }

  51. void iic_ack()   //应答信号
  52. {
  53.         uchar i=0;
  54.         SCL=1;
  55.         delay();
  56.         while((SDA==1)&&(i<255))
  57.         i++;
  58.         SCL=0;
  59.         delay();
  60. }

  61. void iic_send_byte(uchar bat)  //发送数据
  62. {
  63.         uchar i,temp;
  64.         temp=bat;
  65.         for(i=0;i<=7;i++)
  66.         {
  67.           temp=temp<<1;
  68.           SCL=0;
  69.           SDA=CY;
  70.           delay();
  71.           SCL=1;
  72.           delay();
  73.         }
  74.         SCL=0;
  75.         delay();
  76.         SDA=1;
  77.         delay();
  78. }

  79. unsigned char iic_rev()  //接受数据
  80. {
  81.   uchar temp,i;
  82.   SCL=0;
  83.   delay();
  84.   SDA=1;
  85.   for(i=0;i<=7;i++)
  86.   {
  87.    SCL=1;
  88.    delay();
  89.    temp=(temp<<1)|SDA;
  90.    SCL=0;
  91.    delay();
  92.   }
  93.   delay();
  94.   return temp;
  95. }


  96. uchar Single_Read(uchar ST_Address)
  97. {
  98.         uchar REG_data;
  99.         //uchar bit;
  100.        
  101.         iic_start();         //起始信号
  102.         iic_send_byte(BMP280_SlaveAddress);           //发送设备地址+写信号
  103.         iic_ack();
  104.         iic_send_byte(ST_Address);             //发送存储单元地址
  105.         iic_ack();
  106.         iic_start();                          //起始信号
  107.         iic_send_byte(BMP280_SlaveAddress+1);         //发送设备地址+读信号
  108.         iic_ack();
  109.         REG_data = iic_rev();     
  110.         iic_ack();    //最后一个数据需要回NOACK
  111.         return REG_data;
  112. }

  113. void Single_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data)
  114. {
  115.     iic_start();                       //起始信号
  116.     iic_send_byte(SlaveAddress);   //发送设备地址+写信号
  117.         iic_ack();
  118.         iic_send_byte(REG_Address);    //内部寄存器地址
  119.         iic_ack();
  120.         iic_send_byte(REG_data);       //内部寄存器数据
  121.         iic_ack();
  122.         iic_stop();                   //发送停止信号
  123. }

  124. //*********************************************************
  125. //读出BMP085内部数据,连续两个
  126. //*********************************************************
  127. short Multiple_read(uchar ST_Address)
  128. {   
  129.         uchar msb, lsb;
  130.         short _data;
  131.        
  132.         lsb = Single_Read(ST_Address);
  133.         msb = Single_Read(ST_Address+1);
  134.        
  135.         _data = msb << 8;
  136.         _data |= lsb;       
  137.         //rt_kprintf("data is %x %x\n",msb,lsb);
  138.         return _data;
  139. }
  140. //*********************************************************
  141. //读出BMP085内部数据,连续三个
  142. //*********************************************************
  143. long Multiple_three_read(uchar ST_Address)
  144. {   
  145.         uchar msb, lsb,xlsb;
  146.         long _data = 0;
  147.        
  148.         msb = Single_Read(ST_Address);
  149.         lsb = Single_Read(ST_Address+1);
  150.         xlsb = Single_Read(ST_Address+2);
  151.        
  152.         //rt_kprintf("data is %x %x %x\n",msb,lsb,xlsb);
  153.        
  154. //         _data = msb << 16;                ////stm32可以这么用,51有的单片机不可以,重要!!!
  155. //         _data |= lsb << 8;       
  156. //         _data |= xlsb;
  157. //         _data = _data >> 4;
  158.         _data=(long)(((uint32_t)msb<<12)|((uint32_t)lsb<<4)|((uint32_t)xlsb>>4));
  159.         return _data;
  160. }

  161. //**************************************************************

  162. //初始化BMP280,根据需要请参考pdf进行修改**************
  163. void Init_BMP280(void)
  164. {
  165.         unsigned short temp = 0;
  166.         unsigned char write_byte;

  167.         temp = Single_Read(0xd0);//读取id、判断iic是否正常模块是否正常,读取出来的地址是0x58就是对的
  168. //         if(temp==0x58)printf("BMP280 ID IS: 0x%X\n",temp);
  169. //         else printf("BMP280 ID IS FAIL: 0x%X\n",temp);

  170.         dig_T1 = Multiple_read(0x88);
  171.         dig_T2 = Multiple_read(0x8A);
  172.         dig_T3 = Multiple_read(0x8C);
  173.         dig_P1 = Multiple_read(0x8E);
  174.         dig_P2 = Multiple_read(0x90);
  175.         dig_P3 = Multiple_read(0x92);
  176.         dig_P4 = Multiple_read(0x94);
  177.         dig_P5 = Multiple_read(0x96);
  178.         dig_P6 = Multiple_read(0x98);
  179.         dig_P7 = Multiple_read(0x9A);
  180.         dig_P8 = Multiple_read(0x9C);
  181.         dig_P9 = Multiple_read(0x9E);



  182.         write_byte = 0x91;//write_byte
  183.         Single_Write(BMP280_SlaveAddress,0xf4,0xb3);
  184.         write_byte = 0x00;//配置
  185.         Single_Write(BMP280_SlaveAddress,0xf5,5<<2);//5<<2
  186.         //rt_thread_delay(RT_TICK_PER_SECOND);
  187.         Delay_N1ms(200);       
  188. }
  189. //***********************************************************************

  190. long bmp280Convert(void)
  191. {
  192.         long adc_T;
  193.         long adc_P;
  194.         long var1, var2,t_fine,T,p;

  195.          //rt_kprintf("----------------------------\n");
  196.        
  197.         //adc_T = Multiple_three_read(0xFA);
  198.         adc_T = Multiple_three_read(0xFA);    // 读取温度
  199.         //adc_P = Multiple_three_read(0xF7);
  200.         adc_P = Multiple_three_read(0xF7); // 读取压强

  201.         if(adc_P == 0)
  202.         {
  203.                 return 0;
  204.         }
  205.         //Temperature
  206.         var1 = (((double)adc_T)/16384.0-((double)dig_T1)/1024.0)*((double)dig_T2);
  207.         //rt_kprintf("var1 is %d\n",var1);
  208.         var2 = ((((double)adc_T)/131072.0-((double)dig_T1)/8192.0)*(((double)adc_T)/131072.0-((double)dig_T1)/8192.0))*((double)dig_T3);
  209.         //rt_kprintf("var2 is %d\n",var2);
  210.        
  211.         t_fine = (uint32)(var1+var2);
  212.         //rt_kprintf("t_fine is %d\n",t_fine);
  213.        
  214.         T = (var1+var2)/5120.0;
  215.         T = T;
  216.         //rt_kprintf("temperature is %d\n",T);
  217.        
  218.         var1 = ((double)t_fine/2.0)-64000.0;
  219.         //rt_kprintf("var1 is %d\n",var1);
  220.        
  221.         var2 = var1*var1*((double)dig_P6)/32768.0;
  222.         //rt_kprintf("var2 is %d\n",var2);
  223.        
  224.         var2 = var2+var1*((double)dig_P5)*2.0;
  225.         //rt_kprintf("var2 is %d\n",var2);
  226.        
  227.         var2 = (var2/4.0)+(((double)dig_P4)*65536.0);
  228.         //rt_kprintf("var2 is %d\n",var2);
  229.        
  230.         var1 = (((double)dig_P3)*var1*var1/524288.0+((double)dig_P2)*var1)/524288.0;
  231.         //rt_kprintf("var1 is %d\n",var1);
  232.        
  233.         var1 = (1.0+var1/32768.0)*((double)dig_P1);
  234.         //rt_kprintf("var1 is %d\n",var1);
  235.        
  236.         p = 1048576.0-(double)adc_P;
  237.         //rt_kprintf("p is %d\n",p);

  238.         p = (p-(var2/4096.0))*6250.0/var1;
  239.         //rt_kprintf("p is %d\n",p);
  240. ……………………

  241. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
bmp280111.rar (2.85 KB, 下载次数: 441)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:209899 发表于 2018-2-9 17:45 | 显示全部楼层
我之前那个确实不能读取280的。试着跑了一下您的程序,感觉读出来的值好像还是有点不对。有空咱交流一下呗
回复

使用道具 举报

ID:209899 发表于 2018-2-9 17:47 | 显示全部楼层
你好,我之前发的程序后面试了一下确实无法读取280。看您已经做出来了,于是就跑来试了一下,感觉数值好像有点不对,有空咱交流一下
回复

使用道具 举报

ID:165424 发表于 2018-2-24 16:13 | 显示全部楼层
zaza21 发表于 2018-2-9 17:47
你好,我之前发的程序后面试了一下确实无法读取280。看您已经做出来了,于是就跑来试了一下,感觉数值好像 ...

可以留个联系方式
回复

使用道具 举报

ID:165424 发表于 2018-2-24 16:14 | 显示全部楼层
zaza21 发表于 2018-2-9 17:47
你好,我之前发的程序后面试了一下确实无法读取280。看您已经做出来了,于是就跑来试了一下,感觉数值好像 ...

论坛需要审核,上午回复你的下午还没有审核通过,有点慢
回复

使用道具 举报

ID:305849 发表于 2018-4-19 16:11 | 显示全部楼层
我想要积分
回复

使用道具 举报

ID:313227 发表于 2018-4-21 17:06 | 显示全部楼层
感谢楼主分享,用SPI驱动280的太少了
回复

使用道具 举报

ID:252000 发表于 2018-8-12 23:54 | 显示全部楼层
感谢感谢
回复

使用道具 举报

ID:462402 发表于 2019-1-7 21:31 | 显示全部楼层
这能测气压高度吗?
回复

使用道具 举报

ID:472304 发表于 2019-3-9 10:45 | 显示全部楼层
我现在也准备用BMP280芯片。
看了一下程序,有两个问题:
    1.#include "sensor_am21xx.h" 这个是什么意思?指哪个单片机?
    2.#include "MA82G.h"这个呢?
回复

使用道具 举报

ID:165424 发表于 2019-4-13 23:50 | 显示全部楼层
4125027 发表于 2019-3-9 10:45
我现在也准备用BMP280芯片。
看了一下程序,有两个问题:
    1.#include "sensor_am21xx.h" 这个是什么 ...

这两个是头文件调用,单片机用的是ma82g5b32
回复

使用道具 举报

ID:556497 发表于 2019-6-26 16:23 | 显示全部楼层
最近在测试,读取的温度有点高,大气压力不稳定,好头疼啊,尤其大气压,数值偶尔会突变,这样即使标定的话,也不会准确,好头疼,有没有调试成功的看看啊
回复

使用道具 举报

ID:382507 发表于 2019-7-13 19:56 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:604530 发表于 2019-8-28 01:19 | 显示全部楼层
一直在找这个
回复

使用道具 举报

ID:263517 发表于 2019-9-24 18:23 | 显示全部楼层
这个程序用的时候发现一个问题   读取的气压值会逐渐减小   减小的速度非常慢
回复

使用道具 举报

ID:620978 发表于 2019-10-17 17:38 | 显示全部楼层
您好,我用的51单片机烧录后,显示不出数据,是用IIC吗?
这是全部代码吗,还是只是部分文件?
回复

使用道具 举报

ID:647448 发表于 2019-11-22 20:07 | 显示全部楼层
bme280大气压力温湿度传感器程序
回复

使用道具 举报

ID:647448 发表于 2019-11-23 13:21 | 显示全部楼层
不是完整程序
回复

使用道具 举报

ID:55207 发表于 2020-6-17 21:15 | 显示全部楼层
正要用到这个模块,学习一下
回复

使用道具 举报

ID:72088 发表于 2020-10-20 11:28 | 显示全部楼层
BMP280中文资料没找到,网上没有,英文看不懂,哎
回复

使用道具 举报

ID:825140 发表于 2021-7-3 08:44 | 显示全部楼层
楼楼我最近在做一个用bmp280测室内外大气压差的项目,我测试的时候发现两个传感器的差值会随着时间变化,比如说早上+5pa,下午+50帕,或者有的直接从+100pa变成-100多帕,请问楼楼有什么经验分享一下吗
U594`[S73FWFT}F$TM4(VSR.png
回复

使用道具 举报

ID:483991 发表于 2021-7-3 09:17 | 显示全部楼层

一上线就想着要别人给积分!谁让你不给别人点赞,发评论加关注呢?活该你没有分!
回复

使用道具 举报

ID:975054 发表于 2021-12-23 10:02 | 显示全部楼层
triggerfan 发表于 2021-7-3 08:44
楼楼我最近在做一个用bmp280测室内外大气压差的项目,我测试的时候发现两个传感器的差值会随着时间变化,比 ...

近日参考当地天气预报气压数据,发现BMP280气压数据总是偏低约1850Pa(相当于海拔高了150米了);后来读取全部修正因子及公式里的所有变量计算值,发现:
一是dig_P1数值为-30205(手册例子是+34677,无意间看到有个官方API资料里说该值范围是30000到40000),但未影响最终计算结果,用手册数值或任何其他+数代入结果误差极大;
二是实测公式里最后一个var1总是=0,造成后面气压计算值总是低1850Pa左右,我干脆写了条语句if var1=0  retune p跳过去了,实际只获取前面的计算值p,也就是说没有用到dig_7.8.9三个修正参数还准确;不知道为什么,但感觉总比我自己最后直接+1850Pa修订值好一些.

全部实测参数20211214下午/1215:
adc_T = 528832
adc_P = 470864
var1  = 125868.1
var2  = -350.2
t_fine= 125517
T     = 24.5
dig_T1 = 28204  //1129读数28160不同(dig_T1对温度影响极大少0.7℃):原来读之前延时一下就一致,新代码却无影响,但应该加上;
dig_T2 = 26586
dig_T3 = -1000
dig_P1 = -30205            //与手册(要求30000-42000)差距大!但结果可以;直接代入正数倒过来结果影响极大不准;
dig_P2 = -10760
dig_P3 = 3024
dig_P4 = 211
dig_P5 = 437
dig_P6 = -7
dig_P7 = 15500
dig_P8 = -14600
dig_P9 = 6000
var1 = -1241.5
var2 = -329.3
var2 = -1085400.0
var2 = 13556750.0
var1 = 25.5
var1 = 35358.5
p = 577712.0             
p = 101531.9             //这个值比较准!后面-1.86Kpa相当于高了155m挺多的,
//var1 = 0.0             //就这个不对!舍弃后面公式取前面p值就比较准确!;
//var2 = -45238.2             
//p = 99673.2             //这个值误差大!
//Px= -1858▲H =   0m   //要特别留意该值变化,可能比直接自己加修订值准确些:
      -1590▲H = 778m     吸气,+778m内误差268Pa22.3m,22.3/778=2.9%,可接受);
      -1957▲H =-290m     吹气,-290m也误差 99Pa8.25m,8.25/290=2.8%,可接受);
回复

使用道具 举报

ID:237753 发表于 2022-1-26 11:26 | 显示全部楼层
有与单片机的连接方式吗
回复

使用道具 举报

ID:1011179 发表于 2022-3-17 20:49 | 显示全部楼层
为什么头文件只有一个而里面包含的头文件很多?没给全?
回复

使用道具 举报

ID:262 发表于 2022-3-18 06:00 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表