找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机读取BMP280 180 280气压值1602显示程序

[复制链接]
跳转到指定楼层
楼主
ID:318730 发表于 2018-4-29 08:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
51单片机读取BMP280 180 280气压值1602显示程序

单片机源程序如下:
  1. //***************************************
  2. // BMP085 IIC测试程序
  3. // 使用单片机STC89C51
  4. // 晶振:11.0592M
  5. // 显示:LCD1602
  6. // 编译环境 Keil uVision2
  7. // 参考宏晶网站24c04通信程序
  8. //****************************************
  9. #include  <REG51.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^4;   //LCD1602命令端口               
  20. sbit      LCM_RW=P2^5;   //LCD1602命令端口               
  21. sbit      LCM_EN=P2^6;   //LCD1602命令端口

  22. #define        BMP085_SlaveAddress   0xec          //定义器件在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 BMP085_Start();
  54. void BMP085_Stop();
  55. void BMP085_SendACK(bit ack);
  56. bit  BMP085_RecvACK();
  57. void BMP085_SendByte(BYTE dat);
  58. BYTE BMP085_RecvByte();
  59. void BMP085_ReadPage();
  60. void BMP085_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 BMP085_Start()
  157. {
  158.     SDA = 1;                    //拉高数据线
  159.     SCL = 1;                    //拉高时钟线
  160.     Delay5us();                 //延时
  161.     SDA = 0;                    //产生下降沿
  162.     Delay5us();                 //延时
  163.     SCL = 0;                    //拉低时钟线
  164. }

  165. /**************************************
  166. 停止信号
  167. **************************************/
  168. void BMP085_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 BMP085_SendACK(bit ack)
  181. {
  182.     SDA = ack;                  //写应答信号
  183.     SCL = 1;                    //拉高时钟线
  184.     Delay5us();                 //延时
  185.     SCL = 0;                    //拉低时钟线
  186.     Delay5us();                 //延时
  187. }

  188. /**************************************
  189. 接收应答信号
  190. **************************************/
  191. bit BMP085_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 BMP085_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.     BMP085_RecvACK();
  216. }

  217. /**************************************
  218. 从IIC总线接收一个字节数据
  219. **************************************/
  220. BYTE BMP085_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. //单字节写入BMP085内部数据*******************************

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

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

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

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

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

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

  314. //初始化BMP085,根据需要请参考pdf进行修改**************
  315. void Init_BMP085()
  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 bmp085Convert()
  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 = bmp085ReadTemp();
  340.         ut = bmp085ReadTemp();           // 读取温度
  341.         up = bmp085ReadPressure();
  342.         up = bmp085ReadPressure();  // 读取压强
  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(4,0,'T');       //温度显示
  351.      DisplayOneChar(5,0,':');
  352.      DisplayOneChar(7,0,bai);      
  353.      DisplayOneChar(8,0,shi);
  354.      DisplayOneChar(9,0,'.');
  355.          DisplayOneChar(10,0,ge);
  356.          DisplayOneChar(11,0,0XDF);     //温度单位
  357.          DisplayOneChar(12,0,'C');

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

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

  391. }

  392. //*********************************************************
  393. //******主程序********
  394. //*********************************************************
  395. void main()
  396. {
  397.     delay(50);                           //上电延时               
  398.     InitLcd();                     //液晶初始化
  399.     Init_BMP085();                //初始化BMP085
  400.   while(1)                         //循环
  401.   {
  402.     bmp085Convert();
  403.         delay(100);
  404.   }
  405. }
复制代码
以上代码Keil工程51hei附件下载:
51读气压计.rar (44.5 KB, 下载次数: 117)


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

使用道具 举报

沙发
ID:382786 发表于 2018-8-26 15:04 | 只看该作者
亲,有连线吗

回复

使用道具 举报

板凳
ID:919104 发表于 2021-5-11 08:42 | 只看该作者
还要连线?不是吧兄弟
回复

使用道具 举报

地板
ID:902232 发表于 2021-9-19 22:45 | 只看该作者
为啥温度不会变化呢?而且气压数值也不对

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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