久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2132|回復: 0
打印 上一主題 下一主題
收起左側

單片機+bmp180高度計輸出壓強,溫度都有波動,高度算出來更是變化很多,怎么濾波

[復制鏈接]
跳轉到指定樓層
樓主
ID:507691 發表于 2019-4-26 16:35 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
網上查看有卡爾曼濾波,怎么跟程序結合起來,keil中為什么寫入pow函數就會出錯
  1. #include  <REG51.H>
  2. #include  <math.h>     
  3. #include  <stdlib.h>   
  4. #include  <stdio.h>   
  5. #include  <INTRINS.H> //包含_nop_()函數定義的頭文件

  6. #define   uchar unsigned char
  7. #define   uint unsigned int
  8. #define BMP180_SlaveAddress 0xee  //定義器件在IIC總線中的從地址                              
  9. #define OSS 0  // 過采樣設置(注意:代碼沒有設置為使用其他oss值)
  10. #define   DataPort P0    //LCD1602數據端口

  11. sbit      LCM_RS=P3^5;   //LCD1602命令端口寄存器選擇位,輸入               
  12. sbit      LCM_RW=P3^6;   //LCD1602命令端口讀寫               
  13. sbit      LCM_EN=P3^4;   //LCD1602命令端口使能
  14. sbit      SCL=P2^1;      //IIC時鐘引腳定義
  15. sbit      SDA=P2^0;      //IIC數據引腳定義

  16. int  dis_data;                              //變量
  17. typedef unsigned char  BYTE;
  18. typedef unsigned short WORD;
  19. long  temperature;//溫度值
  20. long  pressure;//壓力值
  21. long  height;//相對海拔高度值

  22. short ac1;
  23. short ac2;
  24. short ac3;
  25. unsigned short ac4;
  26. unsigned short ac5;
  27. unsigned short ac6;
  28. short b1;
  29. short b2;
  30. short mb;
  31. short mc;
  32. short md;

  33. /***************延時函數**********************/
  34. void delay(uint z)
  35. {
  36. uint x,y;
  37. for(x=z;x>0;x--)
  38. for(y=110;y>0;y--);
  39. }

  40. /**************寫命令到lcm子函數*****************/
  41. void write_com(uchar com)
  42. {
  43. LCM_RS=0;
  44.         LCM_RW=0;
  45.   LCM_EN=0;        
  46. P0=com;
  47. delay(5);
  48. LCM_EN=1;
  49. delay(5);
  50. LCM_EN=0;
  51. }

  52. /***************寫數據到lcm子函數****************/
  53. void write_data(uchar date)
  54. {LCM_RS=1;
  55. P0=date;
  56. delay(5);
  57. LCM_EN=1;
  58. delay(5);
  59. LCM_EN=0;
  60. }

  61. /**************初始化LCD1602*********************/
  62. void InitLcd()                                
  63. {
  64. write_com(0x38); //設置16X2顯示,5X7點陣,8位數據接口
  65. write_com(0x0c);//設置開顯示,不顯示光標
  66. write_com(0x06);//寫一個字符后地址指針加1
  67. write_com(0x01);//顯示清0,數據指針清0

  68. }

  69. /****************顯示指定坐標的一個字符*******************/
  70. void DisplayOneChar(uchar X,uchar Y,uchar WData)
  71. {                                                
  72. Y&=1;                                                
  73. X&=15;                                                
  74. if(Y)X|=0x40;                                       
  75. X|=0x80;                        
  76. write_com(X);               
  77. write_data(WData);               
  78. }                                                
  79. /*************************************延時5微秒函數**************************************/
  80. void Delay5us()
  81. {
  82. _nop_();_nop_();_nop_();_nop_();
  83. _nop_();_nop_();_nop_();_nop_();
  84. _nop_();_nop_();_nop_();_nop_();
  85. _nop_();_nop_();_nop_();_nop_();
  86. }
  87. /************************************延時5毫秒函數*************************************/
  88. void Delay5ms()
  89. {
  90.     WORD n = 560;
  91.     while (n--);
  92. }
  93. //獲取BMP180設備ID默認值為0x55
  94. /*uchar GetBMP180DevicelD()
  95. {

  96.       uchar DevicelD=0;
  97.       BMP180_Start();  //起始信號
  98.       BMP180_SendByte(BMP180_SlaveAddress);;  //發送設備地址+寫信號
  99.       BMP180_SendByte(0xD0);  //發送存儲單元地址OD為ID存儲寄存器
  100.       BMP180_Start();  //起始信號
  101.       BMP180_SendByte(BMP180_SlaveAddress);  //發送設備地址+讀信號
  102.             DevicelD =BMP180_SendByte(0xee);
  103.       BMP180_Stop();
  104.       return DevicelD;
  105. }*/
  106. /**************************************開始信號(bmp180啟動)**************************************/
  107. void BMP180_Start()
  108. {
  109.     SDA = 1;                    //拉高數據線
  110.     SCL = 1;                    //拉高時鐘線
  111.     Delay5us();                 //延時
  112.     SDA = 0;                    //產生下降沿
  113.     Delay5us();                 //延時
  114.     SCL = 0;                    //拉低時鐘線
  115. }
  116. /**************************************停止信號(停止)**************************************/
  117. void BMP180_Stop()
  118. {
  119.     SDA = 0;                    //拉低數據線
  120.     SCL = 1;                    //拉高時鐘線
  121.     Delay5us();                 //延時
  122.     SDA = 1;                    //產生上升沿
  123.     Delay5us();                 //延時
  124. }

  125. /**************************************發送應答信號**************************************/
  126. void BMP180_SendACK(bit ack)
  127. {
  128.     SDA = ack;                  //寫應答信號
  129.     SCL = 1;                    //拉高時鐘線
  130.     Delay5us();                 //延時
  131.     SCL = 0;                    //拉低時鐘線
  132.     Delay5us();                 //延時
  133. }
  134. /**************************************接收應答信號**************************************/
  135. bit BMP180_RecvACK()
  136. {
  137.     SCL = 1;                    //拉高時鐘線
  138.     Delay5us();                 //延時
  139.     CY = SDA;                   //讀應答信號
  140.     SCL = 0;                    //拉低時鐘線
  141.     Delay5us();                 //延時
  142.     return CY;
  143. }
  144. /**************************************向IIC總線發送一個字節數據**************************************/
  145. void BMP180_SendByte(BYTE dat)
  146. {
  147.     BYTE i;
  148.     for (i=0; i<8; i++)         //8位計數器
  149.     {
  150.         dat <<= 1;              //移出數據的最高位
  151.         SDA = CY;               //送數據口
  152.         SCL = 1;                //拉高時鐘線
  153.         Delay5us();             //延時
  154.         SCL = 0;                //拉低時鐘線
  155.         Delay5us();             //延時
  156.     }
  157.     BMP180_RecvACK();
  158. }
  159. /**************************************從IIC總線接收一個字節數據**************************************/
  160. BYTE BMP180_RecvByte()
  161. {
  162.     BYTE i;
  163.     BYTE dat = 0;
  164.     SDA = 1;                    //使能內部上拉,準備讀取數據,
  165.     for (i=0; i<8; i++)         //8位計數器
  166.     {
  167.         dat <<= 1;
  168.         SCL = 1;                //拉高時鐘線
  169.         Delay5us();             //延時
  170.         dat |= SDA;             //讀數據              
  171.         SCL = 0;                //拉低時鐘線
  172.         Delay5us();             //延時
  173. }
  174.     return dat;
  175. }
  176. /*******************從BMP180中讀取兩字節數據******************************/
  177. short Multiple_read(uchar ST_Address)
  178. {
  179.     uchar msb, lsb;
  180.     short _data;
  181.     BMP180_Start();                          //起始信號
  182.     BMP180_SendByte(BMP180_SlaveAddress);    //發送設備地址+寫信號
  183.     BMP180_SendByte(ST_Address);             //發送存儲單元地址
  184.     BMP180_Start();                          //起始信號
  185.     BMP180_SendByte(BMP180_SlaveAddress+1);         //發送設備地址+讀信號
  186.     msb = BMP180_RecvByte();                 //BUF[0]存儲
  187.           BMP180_SendACK(0);                       //主機發送應答信號,回應ACK
  188.     lsb = BMP180_RecvByte();   
  189.     BMP180_SendACK(1);                       //最后一個數據需要回非ACK
  190.     BMP180_Stop();                           //停止信號
  191.     Delay5ms();
  192.     _data = msb << 8;
  193.     _data |= lsb;
  194.     return _data;
  195. }
  196. /******************************溫度讀取**************************************/
  197. long bmp180ReadTemp(void)
  198. {
  199.     BMP180_Start();                  //起始信號
  200.     BMP180_SendByte(BMP180_SlaveAddress);   //發送設備地址+寫信號
  201.     BMP180_SendByte(0xF4);          // write register address
  202.     BMP180_SendByte(0x2E);       // write register data for temp
  203.     BMP180_Stop();                   //發送停止信號
  204.     delay(10);// max time is 4.5ms
  205.     return (long) Multiple_read(0xF6);      //返回溫度,0.1℃
  206. }
  207. /************************壓強讀取*************************************/
  208. long bmp180ReadPressure(void)
  209. {
  210.     long pressure = 0;
  211.     BMP180_Start();                   //起始信號
  212.     BMP180_SendByte(BMP180_SlaveAddress);   //發送設備地址+寫信號
  213.     BMP180_SendByte(0xF4);          // write register address
  214.     BMP180_SendByte(0x34);         // write register data for pressure
  215.     BMP180_Stop();                    //發送停止信號
  216.     delay(10);                      // max time is 4.5ms
  217.     pressure = Multiple_read(0xF6);
  218.     pressure &= 0x0000FFFF;
  219.     return pressure;               //返回氣壓值,pa

  220. }

  221. /****************初始化BMP180,讀出內部標定參數**************/
  222. void Init_BMP180()
  223. {
  224.     ac1 = Multiple_read(0xAA);
  225.     ac2 = Multiple_read(0xAC);
  226.     ac3 = Multiple_read(0xAE);
  227.     ac4 = Multiple_read(0xB0);
  228.     ac5 = Multiple_read(0xB2);
  229.     ac6 = Multiple_read(0xB4);
  230.     b1 =  Multiple_read(0xB6);
  231.     b2 =  Multiple_read(0xB8);
  232.     mb =  Multiple_read(0xBA);
  233.     mc =  Multiple_read(0xBC);
  234.     md =  Multiple_read(0xBE);
  235. }
  236. double pow(double a,double b)
  237. {
  238.         double result=1;
  239.         for(;b>0;b--)
  240.         {
  241.           result*=a;
  242.         }
  243.         return result;
  244. }
  245. /*************************獲取氣壓、溫度并顯示******************************/
  246. void bmp180Convert()
  247. {
  248.   unsigned int ut;
  249.   unsigned long up;
  250.         
  251.   long x1, x2, b5, b6, x3, b3, p;
  252.   unsigned long b4, b7;
  253.         
  254.         long temp,y;
  255.         
  256.   ut = bmp180ReadTemp();   // 讀取溫度
  257.   up = bmp180ReadPressure();  // 讀取壓強
  258.         
  259.         //根據芯片手冊提供的公式計算補償后的溫度
  260.   x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;//x1=((ut-ac6)*ac5)/(2^15)
  261.   x2 = ((long) mc << 11) / (x1 + md);           //x2=(mc*2^11)/(x1+md)
  262.   b5 = x1 + x2;                                //b5=x1+x2
  263.   temperature = (b5 + 8) >> 4;                 //t=(b5+8)/(2^4)

  264.         // 根據芯片手冊提供的公式計算補償后的氣壓
  265.         b6 = b5 - 4000;
  266.   x1 = (b2 * (b6 * b6)>>12)>>11;
  267.   x2 = (ac2 * b6)>>11;
  268.   x3 = x1 + x2;
  269.   b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;  // Calculate B4
  270.   x1 = (ac3 * b6)>>13;
  271.   x2 = (b1 * ((b6 * b6)>>12))>>16;
  272.   x3 = ((x1 + x2) + 2)>>2;
  273.   b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
  274.   b7 = ((unsigned long)(up - b3) * (50000>>OSS));
  275.   if (b7 < 0x80000000)
  276.     p = (b7<<1)/b4;
  277.   else
  278.     p = (b7/b4)<<1;
  279.   x1 = (p>>8) * (p>>8);
  280.   x1 = (x1 * 3038)>>16;
  281.   x2 = (-7357 * p)>>16;
  282.   pressure = p+((x1 + x2 + 3791)>>4);
  283.         delay(50);
  284.         
  285.         temp=1.0563;
  286.         y=0.1987;
  287.         pow(temp,y);
  288.         
  289.         /*temp=pressure/101325;
  290.         y=1/5.255;
  291.         temp=pow(temp,y);
  292.         //height=(44330*(1-temp));*/
  293. //height= 44330*(1-pow((pressure/101325.0),(1.0/5.255)));  
  294.          height=(101325-pressure)*843/1000;
  295.   if(height<0)
  296.         {
  297.         height=(-height);
  298.         //height=(-123);
  299.         DisplayOneChar(0,0,'T');//溫度部分
  300.   DisplayOneChar(1,0,':');
  301.         DisplayOneChar(2,0,temperature%1000/100+0x30);
  302.   DisplayOneChar(3,0,temperature%100/10+0x30);
  303.   DisplayOneChar(4,0,'.');
  304.         DisplayOneChar(5,0,temperature%10+0x30);
  305.   DisplayOneChar(6,0,0XDF);
  306.   DisplayOneChar(7,0,'C');
  307.   DisplayOneChar(8,0,'H');//海拔部分
  308.         DisplayOneChar(9,0,'-');        
  309.   DisplayOneChar(10,0,height%10000/1000+0x30);
  310.   DisplayOneChar(11,0,height%1000/100+0x30);
  311.   DisplayOneChar(12,0,height%100/10+0x30);
  312.         DisplayOneChar(13,0,height%10+0x30);
  313.   DisplayOneChar(14,0,'.');
  314.         DisplayOneChar(15,0,height*10%10+0x30);
  315.   //DisplayOneChar(15,0,'m');
  316.   DisplayOneChar(0,1,'P');//氣壓部分
  317.   DisplayOneChar(1,1,':');
  318.         DisplayOneChar(2,1,pressure%1000000/100000+48);
  319.   DisplayOneChar(3,1,pressure%100000/10000+48);
  320.   DisplayOneChar(4,1,pressure%10000/1000+48);
  321.   DisplayOneChar(5,1,'.');
  322.         DisplayOneChar(6,1,pressure%1000/100+48);
  323.         DisplayOneChar(7,1,pressure%100/10+48);
  324.         //DisplayOneChar(8,1,pressure%10/1+48);
  325.         DisplayOneChar(8,1,'K');
  326.   DisplayOneChar(9,1,'p');
  327.         DisplayOneChar(10,1,'a');
  328.         
  329.         }
  330.         else
  331.         {
  332.         DisplayOneChar(0,0,'T');//溫度部分
  333.   DisplayOneChar(1,0,':');
  334.         DisplayOneChar(2,0,temperature%1000/100+0x30);
  335.   DisplayOneChar(3,0,temperature%100/10+0x30);
  336.   DisplayOneChar(4,0,'.');
  337.         DisplayOneChar(5,0,temperature%10+0x30);
  338.   DisplayOneChar(6,0,0XDF);
  339.   DisplayOneChar(7,0,'C');
  340.   DisplayOneChar(8,0,' ');
  341.         DisplayOneChar(9,0,'H');//海拔部分
  342.   DisplayOneChar(10,0,height%10000/1000+0x30);
  343.   DisplayOneChar(11,0,height%1000/100+0x30);
  344.   DisplayOneChar(12,0,height%100/10+0x30);
  345.         DisplayOneChar(13,0,height%10+0x30);
  346.   DisplayOneChar(14,0,'.');
  347.         DisplayOneChar(15,0,height*10%10+0x30);
  348.   //DisplayOneChar(15,0,'m');
  349.   DisplayOneChar(0,1,'P');//氣壓部分
  350.   DisplayOneChar(1,1,':');
  351.         DisplayOneChar(2,1,pressure%1000000/100000+48);
  352.   DisplayOneChar(3,1,pressure%100000/10000+48);
  353.   DisplayOneChar(4,1,pressure%10000/1000+48);
  354.   DisplayOneChar(5,1,'.');
  355.         DisplayOneChar(6,1,pressure%1000/100+48);
  356.         DisplayOneChar(7,1,pressure%100/10+48);
  357.         //DisplayOneChar(8,1,pressure%10/1+48);
  358.   DisplayOneChar(8,1,'K');
  359.   DisplayOneChar(9,1,'p');
  360.         DisplayOneChar(10,1,'a');
  361.   }
  362. }
  363. /**********************主程序***************************/
  364. void main()
  365. { long icid;
  366.   delay(50);                           //上電延時               
  367.   InitLcd();                      //液晶初始化
  368.   Init_BMP180();                  //初始化BMP180
  369.         /*icid = Multiple_read(0xD0);
  370.         if (icid==0xee)
  371.                    DisplayOneChar(8,1,'y');
  372.         else DisplayOneChar(9,1,'n');
  373.         while(1);*/
  374.   while(1)                        //循環
  375.   {
  376.     bmp180Convert();
  377.         delay(100);
  378.   }
  379. }
復制代碼


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲一区视频在线 | 国产一二区视频 | 日韩在线免费播放 | 亚洲欧美一区二区三区在线 | 婷婷综合色 | 国产羞羞视频在线观看 | 免费观看的黄色网址 | 九色av | 国产91丝袜在线播放 | 亚洲综合区 | 欧美一级二级视频 | 国产精品国产亚洲精品看不卡15 | 欧美精品综合 | 黄色毛片免费看 | 日韩高清中文字幕 | 久久99精品久久久久久 | 欧美色综合一区二区三区 | 亚洲精品福利在线 | 国产在线观看av | 天堂中文在线观看 | 国产欧美精品一区二区色综合 | 国产精品69毛片高清亚洲 | 欧美极品一区二区 | www.五月婷婷.com | 国产精品久久久久久久久久 | 亚洲天堂中文字幕 | 91精品久久久久久久久久入口 | 国产欧美日韩一区二区三区在线 | 日韩欧美三级电影 | 亚洲成人免费电影 | 51ⅴ精品国产91久久久久久 | 一区二区三区电影在线观看 | 亚洲精品1区| 九九99九九精彩46 | 久草视频在线播放 | 草草网 | 国产精品久久久一区二区三区 | 久久男女视频 | 亚洲精品国产成人 | 欧美视频在线观看 | 中文字幕乱码一区二区三区 |