找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 13603|回复: 21
打印 上一主题 下一主题
收起左侧

51单片机读取BMP085气压值1602显示程序

  [复制链接]
跳转到指定楼层
楼主
读取BMP085的气压值 以及温度值(气压值带温度补偿)
采用模拟i2c通讯
LCD1602液晶显示


单片机源程序如下:
  1. //***************************************
  2. // BMP085 IIC测试程序
  3. // 使用单片机STC89C51
  4. // 晶振:11.0592M
  5. // 显示:LCD1602
  6. // 编译环境 Keil uVision2
  7. // 参考宏晶网站24c04通信程序
  8. // 时间:2011年7月1日
  9. // QQ:531389319
  10. //****************************************
  11. #include  <REG51.H>         
  12. #include  <math.h>    //Keil library  
  13. #include  <stdlib.h>  //Keil library  
  14. #include  <stdio.h>   //Keil library        
  15. #include  <INTRINS.H> //Keil library  
  16. #define   uchar unsigned char
  17. #define   uint unsigned int        
  18. #define   DataPort P0    //LCD1602数据端口
  19. sbit          SCL=P1^0;      //IIC时钟引脚定义
  20. sbit           SDA=P1^1;      //IIC数据引脚定义
  21. sbit      LCM_RS=P2^4;   //LCD1602命令端口               
  22. sbit      LCM_RW=P2^5;   //LCD1602命令端口               
  23. sbit      LCM_EN=P2^6;   //LCD1602命令端口

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

  25. #define OSS 0        // Oversampling Setting (note: code is not set up to use other OSS values)
  26.                                                            
  27. typedef unsigned char  BYTE;
  28. typedef unsigned short WORD;
  29.            
  30. uchar ge,shi,bai,qian,wan,shiwan;           //显示变量
  31. int  dis_data;                              //变量

  32. short ac1;
  33. short ac2;
  34. short ac3;
  35. unsigned short ac4;
  36. unsigned short ac5;
  37. unsigned short ac6;
  38. short b1;
  39. short b2;
  40. short mb;
  41. short mc;
  42. short md;

  43. void delay(unsigned int k);
  44. void InitLcd();                            //初始化lcd1602

  45. void WriteDataLCM(uchar dataW);
  46. void WriteCommandLCM(uchar CMD,uchar Attribc);
  47. void DisplayOneChar(uchar X,uchar Y,uchar DData);
  48. void conversion(long temp_data);

  49. void  Single_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data);   //单个写入数据
  50. uchar Single_Read(uchar REG_Address);                                      //单个读取内部寄存器数据
  51. void  Multiple_Read(uchar,uchar);                                          //连续的读取内部寄存器数据
  52. //------------------------------------
  53. void Delay5us();
  54. void Delay5ms();
  55. void BMP085_Start();
  56. void BMP085_Stop();
  57. void BMP085_SendACK(bit ack);
  58. bit  BMP085_RecvACK();
  59. void BMP085_SendByte(BYTE dat);
  60. BYTE BMP085_RecvByte();
  61. void BMP085_ReadPage();
  62. void BMP085_WritePage();
  63. //-----------------------------------

  64. //*********************************************************
  65. void conversion(long temp_data)  
  66. {  
  67.    
  68.     shiwan=temp_data/100000+0x30 ;
  69.     temp_data=temp_data%100000;   //取余运算
  70.     wan=temp_data/10000+0x30 ;
  71.     temp_data=temp_data%10000;   //取余运算
  72.         qian=temp_data/1000+0x30 ;
  73.     temp_data=temp_data%1000;    //取余运算
  74.     bai=temp_data/100+0x30   ;
  75.     temp_data=temp_data%100;     //取余运算
  76.     shi=temp_data/10+0x30    ;
  77.     temp_data=temp_data%10;      //取余运算
  78.     ge=temp_data+0x30;         
  79. }

  80. /*******************************/
  81. void delay(unsigned int k)        
  82. {                                                
  83. unsigned int i,j;                                
  84. for(i=0;i<k;i++)
  85. {                        
  86. for(j=0;j<121;j++)                        
  87. {;}}                                                
  88. }
  89. /*******************************/
  90. void WaitForEnable(void)        
  91. {                                       
  92. DataPort=0xff;               
  93. LCM_RS=0;LCM_RW=1;_nop_();
  94. LCM_EN=1;_nop_();_nop_();
  95. while(DataPort&0x80);        
  96. LCM_EN=0;                                
  97. }                                       
  98. /*******************************/
  99. void WriteCommandLCM(uchar CMD,uchar Attribc)
  100. {                                       
  101. if(Attribc)WaitForEnable();        
  102. LCM_RS=0;LCM_RW=0;_nop_();
  103. DataPort=CMD;_nop_();        
  104. LCM_EN=1;_nop_();_nop_();LCM_EN=0;
  105. }                                       
  106. /*******************************/
  107. void WriteDataLCM(uchar dataW)
  108. {                                       
  109. WaitForEnable();               
  110. LCM_RS=1;LCM_RW=0;_nop_();
  111. DataPort=dataW;_nop_();        
  112. LCM_EN=1;_nop_();_nop_();LCM_EN=0;
  113. }               
  114. /***********************************/
  115. void InitLcd()                                
  116. {                        
  117. WriteCommandLCM(0x38,1);        
  118. WriteCommandLCM(0x08,1);        
  119. WriteCommandLCM(0x01,1);        
  120. WriteCommandLCM(0x06,1);        
  121. WriteCommandLCM(0x0c,1);
  122. }                        
  123. /***********************************/
  124. void DisplayOneChar(uchar X,uchar Y,uchar DData)
  125. {                                                
  126. Y&=1;                                                
  127. X&=15;                                                
  128. if(Y)X|=0x40;                                       
  129. X|=0x80;                        
  130. WriteCommandLCM(X,0);               
  131. WriteDataLCM(DData);               
  132. }                                                

  133. /**************************************
  134. 延时5微秒(STC90C52RC@12M)
  135. 不同的工作环境,需要调整此函数,注意时钟过快时需要修改
  136. 当改用1T的MCU时,请调整此延时函数
  137. **************************************/
  138. void Delay5us()
  139. {
  140.     _nop_();_nop_();_nop_();_nop_();
  141.     _nop_();_nop_();_nop_();_nop_();
  142.         _nop_();_nop_();_nop_();_nop_();
  143.         _nop_();_nop_();_nop_();_nop_();
  144. }

  145. /**************************************
  146. 延时5毫秒(STC90C52RC@12M)
  147. 不同的工作环境,需要调整此函数
  148. 当改用1T的MCU时,请调整此延时函数
  149. **************************************/
  150. void Delay5ms()
  151. {
  152.     WORD n = 560;

  153.     while (n--);
  154. }

  155. /**************************************
  156. 起始信号
  157. **************************************/
  158. void BMP085_Start()
  159. {
  160.     SDA = 1;                    //拉高数据线
  161.     SCL = 1;                    //拉高时钟线
  162.     Delay5us();                 //延时
  163.     SDA = 0;                    //产生下降沿
  164.     Delay5us();                 //延时
  165.     SCL = 0;                    //拉低时钟线
  166. }

  167. /**************************************
  168. 停止信号
  169. **************************************/
  170. void BMP085_Stop()
  171. {
  172.     SDA = 0;                    //拉低数据线
  173.     SCL = 1;                    //拉高时钟线
  174.     Delay5us();                 //延时
  175.     SDA = 1;                    //产生上升沿
  176.     Delay5us();                 //延时
  177. }

  178. /**************************************
  179. 发送应答信号
  180. 入口参数:ack (0:ACK 1:NAK)
  181. **************************************/
  182. void BMP085_SendACK(bit ack)
  183. {
  184.     SDA = ack;                  //写应答信号
  185.     SCL = 1;                    //拉高时钟线
  186.     Delay5us();                 //延时
  187.     SCL = 0;                    //拉低时钟线
  188.     Delay5us();                 //延时
  189. }

  190. /**************************************
  191. 接收应答信号
  192. **************************************/
  193. bit BMP085_RecvACK()
  194. {
  195.     SCL = 1;                    //拉高时钟线
  196.     Delay5us();                 //延时
  197.     CY = SDA;                   //读应答信号
  198.     SCL = 0;                    //拉低时钟线
  199.     Delay5us();                 //延时

  200.     return CY;
  201. }

  202. /**************************************
  203. 向IIC总线发送一个字节数据
  204. **************************************/
  205. void BMP085_SendByte(BYTE dat)
  206. {
  207.     BYTE i;

  208.     for (i=0; i<8; i++)         //8位计数器
  209.     {
  210.         dat <<= 1;              //移出数据的最高位
  211.         SDA = CY;               //送数据口
  212.         SCL = 1;                //拉高时钟线
  213.         Delay5us();             //延时
  214.         SCL = 0;                //拉低时钟线
  215.         Delay5us();             //延时
  216.     }
  217.     BMP085_RecvACK();
  218. }

  219. /**************************************
  220. 从IIC总线接收一个字节数据
  221. **************************************/
  222. BYTE BMP085_RecvByte()
  223. {
  224.     BYTE i;
  225.     BYTE dat = 0;

  226.     SDA = 1;                    //使能内部上拉,准备读取数据,
  227.     for (i=0; i<8; i++)         //8位计数器
  228.     {
  229.         dat <<= 1;
  230.         SCL = 1;                //拉高时钟线
  231.         Delay5us();             //延时
  232.         dat |= SDA;             //读数据               
  233.         SCL = 0;                //拉低时钟线
  234.         Delay5us();             //延时
  235.     }
  236.     return dat;
  237. }
  238. /*
  239. //单字节写入BMP085内部数据*******************************

  240. void Single_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data)
  241. {
  242.     BMP085_Start();                  //起始信号
  243.     BMP085_SendByte(SlaveAddress);   //发送设备地址+写信号
  244.     BMP085_SendByte(REG_Address);    //内部寄存器地址
  245.     BMP085_SendByte(REG_data);       //内部寄存器数据
  246.     BMP085_Stop();                   //发送停止信号
  247. }
  248. */
  249. /*
  250. //单字节读取BMP085内部数据********************************
  251. uchar Single_Read(uchar REG_Address)
  252. {  uchar REG_data;
  253.     BMP085_Start();                          //起始信号
  254.     BMP085_SendByte(BMP085_SlaveAddress);           //发送设备地址+写信号
  255.     BMP085_SendByte(REG_Address);            //发送存储单元地址        
  256.     BMP085_Start();                          //起始信号
  257.     BMP085_SendByte(BMP085_SlaveAddress+1);         //发送设备地址+读信号
  258.     REG_data=BMP085_RecvByte();              //读出寄存器数据
  259.         BMP085_SendACK(1);   
  260.         BMP085_Stop();                           //停止信号
  261.     return REG_data;
  262. }
  263. */
  264. //*********************************************************
  265. //读出BMP085内部数据,连续两个
  266. //*********************************************************
  267. short Multiple_read(uchar ST_Address)
  268. {   
  269.         uchar msb, lsb;
  270.         short _data;
  271.     BMP085_Start();                          //起始信号
  272.     BMP085_SendByte(BMP085_SlaveAddress);    //发送设备地址+写信号
  273.     BMP085_SendByte(ST_Address);             //发送存储单元地址
  274.     BMP085_Start();                          //起始信号
  275.     BMP085_SendByte(BMP085_SlaveAddress+1);         //发送设备地址+读信号

  276.     msb = BMP085_RecvByte();                 //BUF[0]存储
  277.     BMP085_SendACK(0);                       //回应ACK
  278.     lsb = BMP085_RecvByte();     
  279.         BMP085_SendACK(1);                       //最后一个数据需要回NOACK

  280.     BMP085_Stop();                           //停止信号
  281.     Delay5ms();
  282.     _data = msb << 8;
  283.         _data |= lsb;        
  284.         return _data;
  285. }
  286. //********************************************************************
  287. long bmp085ReadTemp(void)
  288. {

  289.     BMP085_Start();                  //起始信号
  290.     BMP085_SendByte(BMP085_SlaveAddress);   //发送设备地址+写信号
  291.     BMP085_SendByte(0xF4);                  // write register address
  292.     BMP085_SendByte(0x22);               // write register data for temp
  293.     BMP085_Stop();                   //发送停止信号
  294.         delay(10);        // max time is 4.5ms
  295.         
  296.         return (long) Multiple_read(0xFa);
  297. }
  298. //*************************************************************
  299. long bmp085ReadPressure(void)
  300. {
  301.         long pressure = 0;

  302.     BMP085_Start();                   //起始信号
  303.     BMP085_SendByte(BMP085_SlaveAddress);   //发送设备地址+写信号
  304.     BMP085_SendByte(0xF4);                  // write register address
  305.     BMP085_SendByte(0x34);                 // write register data for pressure
  306.     BMP085_Stop();                    //发送停止信号
  307.         delay(10);                              // max time is 4.5ms
  308.         
  309.         pressure = Multiple_read(0xF9);
  310.         pressure &= 0x0000FFFF;
  311.         
  312.         return pressure;        
  313.         //return (long) bmp085ReadShort(0xF6);
  314. }

  315. //**************************************************************

  316. //初始化BMP085,根据需要请参考pdf进行修改**************
  317. void Init_BMP085()
  318. {
  319.         ac1 = Multiple_read(0xAA);
  320.         ac2 = Multiple_read(0xAC);
  321.         ac3 = Multiple_read(0xAE);
  322.         ac4 = Multiple_read(0xB0);
  323.         ac5 = Multiple_read(0xB2);
  324.         ac6 = Multiple_read(0xB4);
  325.         b1 =  Multiple_read(0xB6);
  326.         b2 =  Multiple_read(0xB8);
  327.         mb =  Multiple_read(0xBA);
  328.         mc =  Multiple_read(0xBC);
  329.         md =  Multiple_read(0xBE);
  330. }
  331. //***********************************************************************
  332. void bmp085Convert()
  333. {
  334.         long ut;
  335.         long up;
  336.         long x1, x2, b5, b6, x3, b3, p;
  337.         unsigned long b4, b7;
  338.         long  temperature;
  339.         long  pressure;
  340.         
  341.         ut = bmp085ReadTemp();
  342.         ut = bmp085ReadTemp();           // 读取温度
  343.         up = bmp085ReadPressure();
  344.         up = bmp085ReadPressure();  // 读取压强
  345.         
  346.         x1 = ((long)ut - ac6) * ac5 >> 15;
  347.         x2 = ((long) mc << 11) / (x1 + md);
  348.         b5 = x1 + x2;
  349.          temperature = (b5 + 8) >> 4;

  350.          //*************

  351.          conversion(temperature);
  352.          DisplayOneChar(4,0,'T');       //温度显示
  353.      DisplayOneChar(5,0,':');
  354.      DisplayOneChar(7,0,bai);      
  355.      DisplayOneChar(8,0,shi);
  356.      DisplayOneChar(9,0,'.');
  357.          DisplayOneChar(10,0,ge);
  358.          DisplayOneChar(11,0,0XDF);     //温度单位
  359.          DisplayOneChar(12,0,'C');

  360.          
  361.      //*************
  362.         
  363.         b6 = b5 - 4000;
  364. ……………………

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

所有资料51hei提供下载:
51读气压计.rar (44.5 KB, 下载次数: 256)




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶1 踩
回复

使用道具 举报

来自 2#
ID:164050 发表于 2018-1-29 23:24 | 只看该作者
BMP280不知为何读不出读数
回复

使用道具 举报

板凳
ID:152434 发表于 2017-6-23 21:27 | 只看该作者
280的怎么修改参数啊
回复

使用道具 举报

地板
ID:68356 发表于 2017-6-24 10:29 | 只看该作者
读取BMP085 180 280是通用的吗?貌似寄存器地址和最后的补偿计算不一样吧
回复

使用道具 举报

5#
ID:217797 发表于 2017-9-29 14:23 | 只看该作者
280的这程序不能用吧?
回复

使用道具 举报

6#
ID:68356 发表于 2017-9-30 16:04 | 只看该作者
有中文的pdf资料就好了
回复

使用道具 举报

7#
ID:246441 发表于 2017-11-6 10:20 | 只看该作者
很好,不错.
回复

使用道具 举报

8#
ID:105146 发表于 2017-12-28 16:14 | 只看该作者
很好啊,参考一下
回复

使用道具 举报

9#
ID:263693 发表于 2018-1-2 10:01 | 只看该作者
看上去很强大,下载下来试下
回复

使用道具 举报

10#
ID:263693 发表于 2018-1-2 10:14 | 只看该作者
感谢楼主无私分享
回复

使用道具 举报

11#
ID:263693 发表于 2018-1-2 10:22 | 只看该作者

280的这个程序用不了吧
回复

使用道具 举报

12#
ID:165424 发表于 2018-1-12 11:53 | 只看该作者
网上这个280的资源很少,楼楼在吗,最近也在用280,楼主的程序好像是085的,移植过来不能直接用,需要改寄存器,如果我调好了也发到论坛里
回复

使用道具 举报

13#
ID:282606 发表于 2018-2-6 15:07 | 只看该作者
有没有这个芯片的中文PDF啊
回复

使用道具 举报

14#
ID:343102 发表于 2018-6-1 23:22 | 只看该作者
谢谢分享,下来学习一下。
回复

使用道具 举报

15#
ID:8222 发表于 2019-2-20 11:20 | 只看该作者
谢谢分享。这个可以用于MPD280吗?
回复

使用道具 举报

16#
ID:510315 发表于 2019-4-22 13:27 | 只看该作者
大神,有没有接口电路啊,280跟51的
回复

使用道具 举报

17#
ID:93375 发表于 2019-9-9 17:23 | 只看该作者
thank you share!
回复

使用道具 举报

18#
ID:472300 发表于 2020-1-8 17:05 | 只看该作者
kats 发表于 2018-1-29 23:24
BMP280不知为何读不出读数

085不是280
回复

使用道具 举报

19#
ID:675863 发表于 2020-1-12 17:52 | 只看该作者
很好,不错.
回复

使用道具 举报

20#
ID:704106 发表于 2020-3-28 14:36 | 只看该作者
是的,大家不要下了,根本用不了
回复

使用道具 举报

21#
ID:718594 发表于 2020-3-30 19:37 来自手机 | 只看该作者
kbq1950361006 发表于 2018-1-12 11:53
网上这个280的资源很少,楼楼在吗,最近也在用280,楼主的程序好像是085的,移植过来不能直接用,需要改寄 ...

有程序了吗
回复

使用道具 举报

22#
ID:346648 发表于 2021-8-11 16:59 | 只看该作者
无情啊,单纯的085.
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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