找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2796|回复: 0
收起左侧

基于单片机的气压计设计 程序源码

[复制链接]
ID:171545 发表于 2017-3-17 15:30 | 显示全部楼层 |阅读模式
  1. #include  <REG51.H>         
  2. #include  <math.h>    //Keil library  
  3. #include  <stdlib.h>  //Keil library  
  4. #include  <stdio.h>   //Keil library      
  5. #include  <INTRINS.H> //Keil library
  6. #include <key.h>
  7. #define   uchar unsigned char
  8. #define   uint unsigned int      
  9. #define   DataPort P0    //LCD1602数据端口
  10. sbit          SCL=P3^6;      //IIC时钟引脚定义
  11. sbit           SDA=P3^7;      //IIC数据引脚定义
  12. sbit      LCM_RS=P2^5;   //LCD1602命令端口               
  13. sbit      LCM_RW=P2^6;   //LCD1602命令端口               
  14. sbit      LCM_EN=P2^7;   //LCD1602命令端口
  15. sbit BEEP=P3^4;    //定义蜂鸣器
  16. #define        BMP085_SlaveAddress   0xee          //定义器件在IIC总线中的从地址                              
  17. #define OSS 0        // Oversampling Setting (note: code is not set up to use other OSS values)
  18.                                                            
  19. typedef unsigned char  BYTE;
  20. typedef unsigned short WORD;
  21.          
  22. uchar ge,shi,bai,qian,wan,shiwan;           //显示变量
  23. int  dis_data;                              //变量
  24. bit beep_st;     //蜂鸣器间隔标志
  25. uchar x=0;      //计数器
  26. short ac1;
  27. short ac2;
  28. short ac3;
  29. unsigned short ac4;
  30. unsigned short ac5;
  31. unsigned short ac6;
  32. short b1;
  33. short b2;
  34. short mb;
  35. short mc;
  36. short md;
  37. void delay(unsigned int k);
  38. void InitLcd();                            //初始化lcd1602
  39. void WriteDataLCM(uchar dataW);
  40. void WriteCommandLCM(uchar CMD,uchar Attribc);
  41. void DisplayOneChar(uchar X,uchar Y,uchar DData);
  42. void conversion(long temp_data);
  43. void  Single_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data);   //单个写入数据
  44. uchar Single_Read(uchar REG_Address); //单个读取内部寄存器数据
  45. void  Multiple_Read(uchar,uchar);     //连续的读取内部寄存器数据
  46. //------------------------------------
  47. void Delay5us();
  48. void Delay5ms();
  49. void BMP085_Start();
  50. void BMP085_Stop();
  51. void BMP085_SendACK(bit ack);
  52. bit  BMP085_RecvACK();
  53. void BMP085_SendByte(BYTE dat);
  54. BYTE BMP085_RecvByte();
  55. void BMP085_ReadPage();
  56. void BMP085_WritePage();
  57. //-----------------------------------
  58. void InitTimer(void)
  59. {
  60. TMOD=0x1;
  61. TH0=0x4c;
  62. TL0=0x00;     //50ms(晶振11.0592M)
  63. EA=1;      //全局中断开关
  64. TR0=1;
  65. ET0=1;      //开启定时器0
  66. }
  67. /*****定时器0中断服务程序*****/
  68. void timer0(void) interrupt 1
  69. {
  70. TH0=0x4c;
  71. TL0=0x00;
  72. x++;
  73. }
  74. void conversion(long temp_data)  
  75. {  
  76.    
  77.     shiwan=temp_data/100000+0x30 ;
  78.     temp_data=temp_data%100000;   //取余运算
  79.     wan=temp_data/10000+0x30 ;
  80.     temp_data=temp_data%10000;   //取余运算
  81.         qian=temp_data/1000+0x30 ;
  82.     temp_data=temp_data%1000;    //取余运算
  83.     bai=temp_data/100+0x30   ;
  84.     temp_data=temp_data%100;     //取余运算
  85.     shi=temp_data/10+0x30    ;
  86.     temp_data=temp_data%10;      //取余运算
  87.     ge=temp_data+0x30;        
  88. }
  89. /*******************************/
  90. void delay(unsigned int k)      
  91. {                                               
  92. unsigned int i,j;                              
  93. for(i=0;i<k;i++)
  94. {                       
  95. for(j=0;j<121;j++)                       
  96. {;}}                                               
  97. }
  98. unsigned char rolmove(unsigned  char m)
  99. {
  100.   
  101.   unsigned char   a,b,c,d,e,f,g,h;               
  102. a=(m&0x01)<<7;
  103. b=(m&0x02)<<5;
  104. c=(m&0x04)<<3;
  105. d=(m&0x08)<<1;
  106. e=(m&0x10)>>1;
  107. f=(m&0x20)>>3;
  108. g=(m&0x40)>>5;
  109. h=(m&0x80)>>7;
  110. m=a|b|c|d|e|f|g|h;
  111. return m;
  112. }
  113. /*******************************/
  114. void WaitForEnable(void)      
  115. {                                       
  116. DataPort=0xff;               
  117. LCM_RS=0;LCM_RW=1;_nop_();
  118. LCM_EN=1;_nop_();_nop_();
  119. while(rolmove(DataPort)&0x80);      
  120. LCM_EN=0;                              
  121. }                                       
  122. /*******************************/
  123. void WriteCommandLCM(uchar CMD,uchar Attribc)
  124. {                                       
  125. if(Attribc)WaitForEnable();      
  126. LCM_RS=0;LCM_RW=0;_nop_();
  127. DataPort=rolmove(CMD);_nop_();      
  128. LCM_EN=1;_nop_();_nop_();LCM_EN=0;
  129. }                                       
  130. /*******************************/
  131. void WriteDataLCM(uchar dataW)
  132. {                                       
  133. WaitForEnable();               
  134. LCM_RS=1;LCM_RW=0;_nop_();
  135. DataPort=rolmove(dataW);_nop_();      
  136. LCM_EN=1;_nop_();_nop_();LCM_EN=0;
  137. }               
  138. /***********************************/
  139. void InitLcd()                              
  140. {                       
  141. WriteCommandLCM(0x38,1);      
  142. WriteCommandLCM(0x08,1);      
  143. WriteCommandLCM(0x01,1);      
  144. WriteCommandLCM(0x06,1);      
  145. WriteCommandLCM(0x0c,1);
  146. }                       
  147. /***********************************/
  148. void DisplayOneChar(uchar X,uchar Y,uchar DData)
  149. {                                               
  150. Y&=1;                                               
  151. X&=15;                                               
  152. if(Y)X|=0x40;                                       
  153. X|=0x80;                       
  154. WriteCommandLCM(X,0);               
  155. WriteDataLCM(DData);               
  156. }                                               
  157. void Delay5us()
  158. {
  159.     _nop_();_nop_();_nop_();_nop_();
  160.     _nop_();_nop_();_nop_();_nop_();
  161.         _nop_();_nop_();_nop_();_nop_();
  162.         _nop_();_nop_();_nop_();_nop_();
  163. }
  164. void Delay5ms()
  165. {
  166.     WORD n = 560;
  167.     while (n--);
  168. }
  169. /**************************************
  170. 起始信号
  171. **************************************/
  172. void BMP085_Start()
  173. {
  174.     SDA = 1;                    //拉高数据线
  175.     SCL = 1;                    //拉高时钟线
  176.     Delay5us();                 //延时
  177.     SDA = 0;                    //产生下降沿
  178.     Delay5us();                 //延时
  179.     SCL = 0;                    //拉低时钟线
  180. }
  181. /**************************************
  182. 停止信号
  183. **************************************/
  184. void BMP085_Stop()
  185. {
  186.     SDA = 0;                    //拉低数据线
  187.     SCL = 1;                    //拉高时钟线
  188.     Delay5us();                 //延时
  189.     SDA = 1;                    //产生上升沿
  190.     Delay5us();                 //延时
  191. }
  192. void BMP085_SendACK(bit ack)
  193. {
  194.     SDA = ack;                  //写应答信号
  195.     SCL = 1;                    //拉高时钟线
  196.     Delay5us();                 //延时
  197.     SCL = 0;                    //拉低时钟线
  198.     Delay5us();                 //延时
  199. }
  200. /**************************************
  201. 接收应答信号
  202. **************************************/
  203. bit BMP085_RecvACK()
  204. {
  205.     SCL = 1;                    //拉高时钟线
  206.     Delay5us();                 //延时
  207.     CY = SDA;                   //读应答信号
  208.     SCL = 0;                    //拉低时钟线
  209.     Delay5us();                 //延时
  210.     return CY;
  211. }
  212. /**************************************
  213. 向IIC总线发送一个字节数据
  214. **************************************/
  215. void BMP085_SendByte(BYTE dat)
  216. {
  217.     BYTE i;
  218.     for (i=0; i<8; i++)         //8位计数器
  219.     {
  220.         dat <<= 1;              //移出数据的最高位
  221.         SDA = CY;               //送数据口
  222.         SCL = 1;                //拉高时钟线
  223.         Delay5us();             //延时
  224.         SCL = 0;                //拉低时钟线
  225.         Delay5us();             //延时
  226.     }
  227.     BMP085_RecvACK();
  228. }
  229. /**************************************
  230. 从IIC总线接收一个字节数据
  231. **************************************/
  232. BYTE BMP085_RecvByte()
  233. {
  234.     BYTE i;
  235.     BYTE dat = 0;
  236.     SDA = 1;                    //使能内部上拉,准备读取数据,
  237.     for (i=0; i<8; i++)         //8位计数器
  238.     {
  239.         dat <<= 1;
  240.         SCL = 1;                //拉高时钟线
  241.         Delay5us();             //延时
  242.         dat |= SDA;             //读数据               
  243.         SCL = 0;                //拉低时钟线
  244.         Delay5us();             //延时
  245.     }
  246.     return dat;
  247. }
  248. //读出BMP085内部数据,连续两个
  249. short Multiple_read(uchar ST_Address)
  250. {   
  251.         uchar msb, lsb;
  252.         short _data;
  253.     BMP085_Start();                          //起始信号
  254.     BMP085_SendByte(BMP085_SlaveAddress);    //发送设备地址+写信号
  255.     BMP085_SendByte(ST_Address);             //发送存储单元地址
  256.     BMP085_Start();                          //起始信号
  257.     BMP085_SendByte(BMP085_SlaveAddress+1);         //发送设备地址+读信号
  258.     msb = BMP085_RecvByte();                 //BUF[0]存储
  259.     BMP085_SendACK(0);                       //回应ACK
  260.     lsb = BMP085_RecvByte();     
  261.         BMP085_SendACK(1);                       //最后一个数据需要回NOACK
  262.     BMP085_Stop();                           //停止信号
  263.     Delay5ms();
  264.     _data = msb << 8;
  265.         _data |= lsb;      
  266.         return _data;
  267. }
  268. long bmp085ReadTemp(void)
  269. {
  270.     BMP085_Start();                  //起始信号
  271.     BMP085_SendByte(BMP085_SlaveAddress);   //发送设备地址+写信号
  272.     BMP085_SendByte(0xF4);                  // write register address
  273.     BMP085_SendByte(0x2E);               // write register data for temp
  274.     BMP085_Stop();                   //发送停止信号
  275.         delay(10);        // max time is 4.5ms
  276.       
  277.         return (long) Multiple_read(0xF6);
  278. }
  279. long bmp085ReadPressure(void)
  280. {
  281.         long pressure = 0;
  282.     BMP085_Start();                   //起始信号
  283.     BMP085_SendByte(BMP085_SlaveAddress);   //发送设备地址+写信号
  284.     BMP085_SendByte(0xF4);                  // write register address
  285.     BMP085_SendByte(0x34);                 // write register data for pressure
  286.     BMP085_Stop();                    //发送停止信号
  287.         delay(10);                              // max time is 4.5ms
  288.       
  289.         pressure = Multiple_read(0xF6);
  290.         pressure &= 0x0000FFFF;
  291.       
  292.         return pressure;      
  293.         //return (long) bmp085ReadShort(0xF6);
  294. }
  295. //初始化BMP085
  296. void Init_BMP085()
  297. {
  298.         ac1 = Multiple_read(0xAA);
  299.         ac2 = Multiple_read(0xAC);
  300.         ac3 = Multiple_read(0xAE);
  301.         ac4 = Multiple_read(0xB0);
  302.         ac5 = Multiple_read(0xB2);
  303.         ac6 = Multiple_read(0xB4);
  304.         b1 =  Multiple_read(0xB6);
  305.         b2 =  Multiple_read(0xB8);
  306.         mb =  Multiple_read(0xBA);
  307.         mc =  Multiple_read(0xBC);
  308.         md =  Multiple_read(0xBE);
  309. }
  310. void bmp085Convert()
  311. {
  312.         long ut;
  313.         long up;
  314.         long x1, x2, b5, b6, x3, b3, p;
  315.         unsigned long b4, b7;
  316.         long  temperature;
  317.         long  pressure;
  318.       
  319.         ut = bmp085ReadTemp();
  320.         ut = bmp085ReadTemp();           // 读取温度
  321.         up = bmp085ReadPressure();
  322.         up = bmp085ReadPressure();  // 读取压强
  323.       
  324.         x1 = ((long)ut - ac6) * ac5 >> 15;
  325.         x2 = ((long) mc << 11) / (x1 + md);
  326.         b5 = x1 + x2;
  327.         temperature = (b5 + 8) >> 4;
  328.         conversion(shangxian);//显示报警值
  329.         DisplayOneChar(4,1,'V');      
  330.      DisplayOneChar(5,1,':');
  331.         DisplayOneChar(6,1,shiwan);
  332.         DisplayOneChar(7,1,wan);   
  333.      DisplayOneChar(8,1,qian);
  334.      DisplayOneChar(9,1,'.');
  335.      DisplayOneChar(10,1,bai);
  336.      DisplayOneChar(11,1,shi);
  337.         DisplayOneChar(12,1,'K');   //气压单位
  338.         DisplayOneChar(13,1,'p');
  339.         DisplayOneChar(14,1,'a');
  340.         b6 = b5 - 4000;
  341.         x1 = (b2 * (b6 * b6 >> 12)) >> 11;
  342.         x2 = ac2 * b6 >> 11;
  343.         x3 = x1 + x2;
  344.         b3 = (((long)ac1 * 4 + x3) + 2)/4;
  345.         x1 = ac3 * b6 >> 13;
  346.         x2 = (b1 * (b6 * b6 >> 12)) >> 16;
  347.         x3 = ((x1 + x2) + 2) >> 2;
  348.         b4 = (ac4 * (unsigned long) (x3 + 32768)) >> 15;
  349.         b7 = ((unsigned long) up - b3) * (50000 >> OSS);
  350.         if( b7 < 0x80000000)
  351.              p = (b7 * 2) / b4 ;
  352.            else  
  353.                     p = (b7 / b4) * 2;
  354.         x1 = (p >> 8) * (p >> 8);
  355.         x1 = (x1 * 3038) >> 16;
  356.         x2 = (-7357 * p) >> 16;
  357.         pressure = p + ((x1 + x2 + 3791) >> 4);
  358. if(x>=2){beep_st=~beep_st;x=0;}
  359. if(pressure>shangxian&&beep_st==1)BEEP=1;
  360. else BEEP=0;
  361.         conversion(pressure);
  362.      DisplayOneChar(4,0,'P');    //显示压强
  363.      DisplayOneChar(5,0,':');
  364.         DisplayOneChar(6,0,shiwan);
  365.         DisplayOneChar(7,0,wan);   
  366.      DisplayOneChar(8,0,qian);
  367.      DisplayOneChar(9,0,'.');
  368.      DisplayOneChar(10,0,bai);
  369.      DisplayOneChar(11,0,shi);
  370.         DisplayOneChar(12,0,'K');   //气压单位
  371.         DisplayOneChar(13,0,'p');
  372.         DisplayOneChar(14,0,'a');
  373. }
  374. //******主程序********
  375. void main()
  376. {
  377.     delay(50);                           //上电延时               
  378.     InitLcd();                     //液晶初始化
  379.     Init_BMP085();                //初始化BMP085
  380. BEEP=0;
  381. InitTimer();    //初始化定时器
  382.   while(1)                         //循环
  383.   {
  384.     bmp085Convert();
  385.         delay(1000);
  386. checkkey();
  387. if(set_st==0) WriteCommandLCM(0x0c,1);
  388. if(set_st==1)
  389. {
  390. WriteCommandLCM(0xcb,1);
  391. WriteCommandLCM(0x0d,1);
  392.         Delay1(150);
  393. }
  394.   }
  395. }
复制代码


回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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