找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC90C52RC+BMP180+1602温度气压显示

  [复制链接]
跳转到指定楼层
楼主
bmp180模块非常便宜,5块钱居然能实现温度和气压采集,还能学习IIC接口,在网上找了个例程,很容易就实现了。

20151125_115544.jpg (1.84 MB, 下载次数: 392)

bmp180模块

bmp180模块

20151125_115551.jpg (1.91 MB, 下载次数: 327)

连接p1.0,p1.1

连接p1.0,p1.1

20151125_115714.jpg (2.06 MB, 下载次数: 159)

最小系统板和1602

最小系统板和1602

20151125_121026.jpg (2.12 MB, 下载次数: 164)

和卡西欧登山表对比

和卡西欧登山表对比

bmp180.rar

3.23 KB, 下载次数: 270, 下载积分: 黑币 -5

评分

参与人数 2黑币 +55 收起 理由
coodz + 5 很给力!
admin + 50 共享资料的积分奖励!

查看全部评分

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

使用道具 举报

沙发
ID:1 发表于 2015-11-26 21:02 | 只看该作者
楼主的程序我发出来,给大家省点黑币
  1. //***************************************
  2. // BMP180 IIC测试程序
  3. // 使用单片机STC90C52RC
  4. // 晶振:11.0592M
  5. // 显示:LCD1602
  6. // 编译环境 Keil uVision3
  7. // 参考宏晶网站24c04通信程序
  8. //****************************************
  9. #include  <REG52.H>          
  10. #include  <math.h>    //Keil library  
  11. #include  <stdlib.h>  //Keil library  
  12. #include  <stdio.h>   //Keil library       
  13. #include  <INTRINS.H> //Keil library  
  14. #define   uchar unsigned char
  15. #define   uint unsigned int       
  16. #define   DataPort P0    //LCD1602数据端口
  17. sbit          SCL=P1^0;      //IIC时钟引脚定义
  18. sbit           SDA=P1^1;      //IIC数据引脚定义
  19. sbit      LCM_RS=P2^0;   //LCD1602命令端口               
  20. sbit      LCM_RW=P2^1;   //LCD1602命令端口               
  21. sbit      LCM_EN=P2^2;   //LCD1602命令端口

  22. #define        BMP180_SlaveAddress   0xee          //定义器件在IIC总线中的从地址                              

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

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

  41. void delay(unsigned int k);
  42. void InitLcd();                            //初始化lcd1602

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

  47. void  Single_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data);   //单个写入数据
  48. uchar Single_Read(uchar REG_Address);                                      //单个读取内部寄存器数据
  49. void  Multiple_Read(uchar,uchar);                                          //连续的读取内部寄存器数据
  50. //------------------------------------
  51. void Delay5us();
  52. void Delay5ms();
  53. void BMP180_Start();
  54. void BMP180_Stop();
  55. void BMP180_SendACK(bit ack);
  56. bit  BMP180_RecvACK();
  57. void BMP180_SendByte(BYTE dat);
  58. BYTE BMP180_RecvByte();
  59. void BMP180_ReadPage();
  60. void BMP180_WritePage();
  61. //-----------------------------------

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

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

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

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

  151.     while (n--);
  152. }

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

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

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

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

  198.     return CY;
  199. }

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

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

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

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

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

  274.     msb = BMP180_RecvByte();                 //BUF[0]存储
  275.     BMP180_SendACK(0);                       //回应ACK
  276.     lsb = BMP180_RecvByte();     
  277.         BMP180_SendACK(1);                       //最后一个数据需要回NOACK

  278.     BMP180_Stop();                           //停止信号
  279.     Delay5ms();
  280.     _data = msb << 8;
  281.         _data |= lsb;       
  282.         return _data;
  283. }
  284. //********************************************************************
  285. long bmp180ReadTemp(void)
  286. {

  287.     BMP180_Start();                  //起始信号
  288.     BMP180_SendByte(BMP180_SlaveAddress);   //发送设备地址+写信号
  289.     BMP180_SendByte(0xF4);                  // write register address
  290.     BMP180_SendByte(0x2E);               // write register data for temp
  291.     BMP180_Stop();                   //发送停止信号
  292.         delay(10);        // max time is 4.5ms
  293.        
  294.         return (long) Multiple_read(0xF6);
  295. }
  296. //*************************************************************
  297. long bmp180ReadPressure(void)
  298. {
  299.         long pressure = 0;

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

  313. //**************************************************************

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

  348.          //*************

  349.          conversion(temperature);
  350.          DisplayOneChar(0,0,'W');        //温度显示
  351.          DisplayOneChar(1,0,'e');
  352.          DisplayOneChar(2,0,'n');
  353.          DisplayOneChar(3,0,'D');
  354.          DisplayOneChar(4,0,'u');
  355.      DisplayOneChar(5,0,':');
  356.      DisplayOneChar(7,0,bai);      
  357.      DisplayOneChar(8,0,shi);
  358.      DisplayOneChar(9,0,'.');
  359.          DisplayOneChar(10,0,ge);
  360.          DisplayOneChar(11,0,0XDF);     //温度单位
  361.          DisplayOneChar(12,0,'C');

  362.          
  363.      //*************
  364.        
  365.         b6 = b5 - 4000;
  366.         x1 = (b2 * (b6 * b6 >> 12)) >> 11;
  367.         x2 = ac2 * b6 >> 11;
  368.         x3 = x1 + x2;
  369.         b3 = (((long)ac1 * 4 + x3) + 2)/4;
  370.         x1 = ac3 * b6 >> 13;
  371.         x2 = (b1 * (b6 * b6 >> 12)) >> 16;
  372.         x3 = ((x1 + x2) + 2) >> 2;
  373.         b4 = (ac4 * (unsigned long) (x3 + 32768)) >> 15;
  374.         b7 = ((unsigned long) up - b3) * (50000 >> OSS);
  375.         if( b7 < 0x80000000)
  376.              p = (b7 * 2) / b4 ;
  377.            else  
  378.                     p = (b7 / b4) * 2;
  379.         x1 = (p >> 8) * (p >> 8);
  380.         x1 = (x1 * 3038) >> 16;
  381.         x2 = (-7357 * p) >> 16;
  382.          pressure = p + ((x1 + x2 + 3791) >> 4);

  383.          conversion(pressure);
  384.      DisplayOneChar(0,1,'Q');    //显示压强
  385.          DisplayOneChar(1,1,'i');
  386.          DisplayOneChar(2,1,'Y');
  387.          DisplayOneChar(3,1,'a');
  388.      DisplayOneChar(5,1,':');
  389.          DisplayOneChar(6,1,shiwan);
  390.          DisplayOneChar(7,1,wan);   
  391.      DisplayOneChar(8,1,qian);
  392.      DisplayOneChar(9,1,'.');
  393.      DisplayOneChar(10,1,bai);
  394.      DisplayOneChar(11,1,shi);
  395.          DisplayOneChar(12,1,'K');   //气压单位
  396.          DisplayOneChar(13,1,'p');
  397.          DisplayOneChar(14,1,'a');

  398. }

  399. //*********************************************************
  400. //******主程序********
  401. //*********************************************************
  402. void main()
  403. {
  404.     delay(50);                           //上电延时               
  405.     InitLcd();                     //液晶初始化
  406.     Init_BMP180();                //初始化BMP085
  407.   while(1)                         //循环
  408.   {
  409.     bmp180Convert();
  410.         delay(1000);
  411.   }
  412. }
复制代码
回复

使用道具 举报

板凳
ID:65908 发表于 2015-11-26 22:12 | 只看该作者
厉害太厉害了
回复

使用道具 举报

地板
ID:87193 发表于 2015-11-27 10:51 | 只看该作者
楼主很厉害,学习一下
回复

使用道具 举报

5#
ID:98591 发表于 2016-1-10 17:09 | 只看该作者
我也在学,问下,为什么我的读出来的校正系数是0x0000啊(2块都是这样),同样的函数,读出来的未校正的有关温度的那个正常,手摸会变化
回复

使用道具 举报

6#
ID:96769 发表于 2016-3-12 22:42 | 只看该作者
楼主,这个程序有两个地方不懂啊,比如signal单字节写入BMP180内部数据,单字节读取BMP180内部数据都没用到,而且用到的也有没  BMP180_SendByte(REG_Address); 的地址传入啊,求解答。
回复

使用道具 举报

7#
ID:112181 发表于 2016-4-4 17:03 | 只看该作者
很好的资料
回复

使用道具 举报

8#
ID:171545 发表于 2017-4-8 23:04 | 只看该作者
有没有这个装置的电路原理图呀,求一个
回复

使用道具 举报

9#
ID:195089 发表于 2017-4-30 19:37 | 只看该作者
xiexlouzhu
回复

使用道具 举报

10#
ID:196347 发表于 2017-5-4 18:30 | 只看该作者
加油~~让我看看程序吧。。。
回复

使用道具 举报

11#
ID:202296 发表于 2017-5-18 19:18 | 只看该作者
抱拳了 老铁
回复

使用道具 举报

12#
ID:202238 发表于 2017-5-18 19:25 | 只看该作者
里面有电路图吗?
回复

使用道具 举报

13#
ID:202296 发表于 2017-5-19 14:17 | 只看该作者
很可以 赞一个
回复

使用道具 举报

14#
ID:205217 发表于 2017-6-3 11:03 | 只看该作者
很好用,很给力
回复

使用道具 举报

15#
ID:205217 发表于 2017-6-3 21:42 | 只看该作者
大神啊,要是加个模块NRF2L01进行无线发射和接收,怎么改啊,不懂啊,
回复

使用道具 举报

16#
ID:155719 发表于 2017-8-2 11:14 | 只看该作者
好人啊
回复

使用道具 举报

17#
ID:227948 发表于 2017-8-16 18:17 | 只看该作者
还没试,先谢谢楼主啦
回复

使用道具 举报

18#
ID:136185 发表于 2017-10-30 22:43 | 只看该作者
读出来只有50多Kpa
回复

使用道具 举报

19#
ID:246166 发表于 2017-11-8 18:40 | 只看该作者
楼主太强了,学习学习
回复

使用道具 举报

20#
ID:264389 发表于 2017-12-23 18:47 | 只看该作者
你好,我用这个代码,为什么温度乱码,气压不变,一直都是99.7Kpa
回复

使用道具 举报

21#
ID:264389 发表于 2017-12-23 20:52 | 只看该作者
admin 发表于 2015-11-26 21:02
楼主的程序我发出来,给大家省点黑币

我用了你的程序,现在有问题,温度不能正常显示,气压是定值,还有把传感器不跟单片机连,也有气压。
回复

使用道具 举报

22#
ID:259858 发表于 2018-1-26 16:34 | 只看该作者
在32中两个I2C咋办
回复

使用道具 举报

23#
ID:388335 发表于 2018-8-22 16:29 | 只看该作者
用了之后,初始化居然都么有读出数值,温度监视变量为0,气压为一定值。
回复

使用道具 举报

24#
ID:461137 发表于 2019-3-14 17:37 | 只看该作者
很好,行号毕设用到,LZ能说说线怎么接的吗
回复

使用道具 举报

25#
ID:398105 发表于 2019-3-17 22:16 | 只看该作者
多谢楼主
回复

使用道具 举报

26#
ID:510419 发表于 2019-5-2 15:23 | 只看该作者
楼主,有原理图么,除了定义的还有些线不知道怎么连
回复

使用道具 举报

27#
ID:264360 发表于 2019-5-10 10:48 | 只看该作者
admin 发表于 2015-11-26 21:02
楼主的程序我发出来,给大家省点黑币

感谢热心分享  谢谢哈
回复

使用道具 举报

28#
ID:227784 发表于 2020-1-28 15:27 来自手机 | 只看该作者
刘小爷 发表于 2017-12-23 18:47
你好,我用这个代码,为什么温度乱码,气压不变,一直都是99.7Kpa


我的也是如此,温度乱码,气压99.97一直不变
回复

使用道具 举报

29#
ID:731275 发表于 2020-5-23 11:08 | 只看该作者
15393729688 发表于 2020-1-28 15:27
我的也是如此,温度乱码,气压99.97一直不变

问题解决了么老哥
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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