圣源电子制作

 找回密码
 立即注册
查看: 12251|回复: 4
打印 上一主题 下一主题

BMP085 气压模块-C51-LCD1602显示-程序-原理图

[复制链接]
跳转到指定楼层
楼主
发表于 2011-10-25 23:18:01 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

                                                                                                                            BMP085是一款高精度、超低能耗的压力传感器,可以应用在移动设备中。它的性能卓越,绝对精度最低可以达到0.03hPa,并且耗电极低,只有3µA。BMP085采用强大的8-pin陶瓷无引线芯片承载(LCC)超薄封装,可以通过I²C总线直接与各种微处理器相连。


主要特点:
压力范围:300 ... 1100hPa(海拔9000米...-500米)
电源电压:1.8V  ... 3.6V(VDDA)
                    1.62V ... 3.6V(VDDD)
LCC8封装: 无铅陶瓷载体封装(LCC)
尺  寸:   5.0mmx5.0*1.2mm
低功耗:   5μA 在标准模式
高精度:   低功耗模式下,分辨率为0.06hPa(0.5米)
           高线性模式下,分辨率为0.03hPa(0.25米)
含温度输出
I2C接口
温度补偿
无铅,符合RoHS规范,
MSL 1
反应时间:7.5ms
待机电流:0.1µA
无需外部时钟电路
典型应用:
1.GPS精确导航(航位推算,上下桥检测等)
2.室内室外导航
3.休闲、体育和医疗健康等监测
4.天气预报
5.垂直速度指示(上升/下沉速度)
6.风扇功率控制


C51程序
  1. /*
  2. * BMP085模块
  3. *
  4. * 用途:BMP085模块IIC测试程序
  5. *
  6. * 作者                                        日期                                备注
  7. * Huafeng Lin                        2010/12/10                        新增
  8. * Huafeng Lin                        2010/12/11                        修改
  9. *
  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 P2        //LCD1602数据端口
  19. sbit        SCL=P1^0;      //IIC时钟引脚定义
  20. sbit        SDA=P1^1;      //IIC数据引脚定义
  21. sbit    LCM_RS=P0^2;   //LCD1602命令端口               
  22. sbit    LCM_RW=P0^1;   //LCD1602命令端口               
  23. sbit    LCM_EN=P0^0;   //LCD1602命令端口  

  24. #define        BMP085_SlaveAddress   0xee          //定义器件在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(0x2E);               // write register data for temp
  293.     BMP085_Stop();                   //发送停止信号
  294.         delay(10);        // max time is 4.5ms
  295.        
  296.         return (long) Multiple_read(0xF6);
  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(0xF6);
  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.         x1 = (b2 * (b6 * b6 >> 12)) >> 11;
  365.         x2 = ac2 * b6 >> 11;
  366.         x3 = x1 + x2;
  367.         b3 = (((long)ac1 * 4 + x3) + 2)/4;
  368.         x1 = ac3 * b6 >> 13;
  369.         x2 = (b1 * (b6 * b6 >> 12)) >> 16;
  370.         x3 = ((x1 + x2) + 2) >> 2;
  371.         b4 = (ac4 * (unsigned long) (x3 + 32768)) >> 15;
  372.         b7 = ((unsigned long) up - b3) * (50000 >> OSS);
  373.         if( b7 < 0x80000000)
  374.              p = (b7 * 2) / b4 ;
  375.            else  
  376.                     p = (b7 / b4) * 2;
  377.         x1 = (p >> 8) * (p >> 8);
  378.         x1 = (x1 * 3038) >> 16;
  379.         x2 = (-7357 * p) >> 16;
  380.          pressure = p + ((x1 + x2 + 3791) >> 4);

  381.          conversion(pressure);
  382.      DisplayOneChar(4,1,'P');    //显示压强
  383.      DisplayOneChar(5,1,':');
  384.          DisplayOneChar(6,1,shiwan);
  385.          DisplayOneChar(7,1,wan);   
  386.      DisplayOneChar(8,1,qian);
  387.      DisplayOneChar(9,1,'.');
  388.      DisplayOneChar(10,1,bai);
  389.      DisplayOneChar(11,1,shi);
  390.          DisplayOneChar(12,1,'K');   //气压单位
  391.          DisplayOneChar(13,1,'p');
  392.          DisplayOneChar(14,1,'a');

  393. }

  394. //*********************************************************
  395. //******主程序********
  396. //*********************************************************
  397. void main()
  398. {
  399.     delay(50);                           //上电延时               
  400.     InitLcd();                     //液晶初始化
  401.     Init_BMP085();                //初始化BMP085
  402.   while(1)                         //循环
  403.   {
  404.     bmp085Convert();
  405.         delay(1000);
  406.   }
  407. }
复制代码



BMP085气压模块 SYYYD.COM.rar (884.74 KB, 下载次数: 215)

                        

                    

回复

使用道具 举报

沙发
发表于 2012-2-20 11:09:05 | 只看该作者
您好:   
  想請問關於我使用的是stc89c52的晶片,然後用bmp085來測試您的程式,但跑出來的溫度及大氣壓力值不太多,lcd顯示溫度也有點問題,想請教一下可能是那裡出問題了。

晶體振盪為12M

LCD 為1602A

   大大的感謝
回复 支持 反对

使用道具 举报

板凳
发表于 2012-2-20 11:32:55 | 只看该作者
大大您好:
   我的環境為stc89c52 及bmp085 (iic介面) 還有1602A LCD測試此程式。但輸出的溫度及大氣壓力都有點問題,請大大指點迷津。謝謝!! 

   振盪頻率為12M

且目前我的身份無法下載附件,不知有何下載方式。謝謝

mail為
fcaibi@yahoo.com.tw
fcaibi0114@hotmail.com
回复 支持 反对

使用道具 举报

地板
发表于 2012-2-22 23:20:59 | 只看该作者
你好:  大大由於我測出來的數據有點不對,我使用的是STC89C52 及1602A的LCD還有BMP085的模塊,不知道是那裡出了問題??

使用的是YZ-200研展公司出的開JQ
回复 支持 反对

使用道具 举报

5#
 楼主| 发表于 2012-2-23 17:45:21 | 只看该作者
louischien 发表于 2012-2-20 11:32
大大您好:
   我的環境為stc89c52 及bmp085 (iic介面) 還有1602A LCD測試此程式。但輸出的溫度及大氣 ...

晶振 用  11.0592M 试试~

这个程序是淘宝上下载的,发出来方便大家的,我没有测试过这个程序。
回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|手机版|联系我们|闽公网安备 35012102000020号|闽ICP备11020110号-1|圣源电子

GMT+8, 2024-11-22 06:23 , Processed in 0.048119 second(s), 17 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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