網上查看有卡爾曼濾波,怎么跟程序結合起來,keil中為什么寫入pow函數就會出錯
- #include <REG51.H>
- #include <math.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <INTRINS.H> //包含_nop_()函數定義的頭文件
- #define uchar unsigned char
- #define uint unsigned int
- #define BMP180_SlaveAddress 0xee //定義器件在IIC總線中的從地址
- #define OSS 0 // 過采樣設置(注意:代碼沒有設置為使用其他oss值)
- #define DataPort P0 //LCD1602數據端口
- sbit LCM_RS=P3^5; //LCD1602命令端口寄存器選擇位,輸入
- sbit LCM_RW=P3^6; //LCD1602命令端口讀寫
- sbit LCM_EN=P3^4; //LCD1602命令端口使能
- sbit SCL=P2^1; //IIC時鐘引腳定義
- sbit SDA=P2^0; //IIC數據引腳定義
- int dis_data; //變量
- typedef unsigned char BYTE;
- typedef unsigned short WORD;
- long temperature;//溫度值
- long pressure;//壓力值
- long height;//相對海拔高度值
- short ac1;
- short ac2;
- short ac3;
- unsigned short ac4;
- unsigned short ac5;
- unsigned short ac6;
- short b1;
- short b2;
- short mb;
- short mc;
- short md;
- /***************延時函數**********************/
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /**************寫命令到lcm子函數*****************/
- void write_com(uchar com)
- {
- LCM_RS=0;
- LCM_RW=0;
- LCM_EN=0;
- P0=com;
- delay(5);
- LCM_EN=1;
- delay(5);
- LCM_EN=0;
- }
- /***************寫數據到lcm子函數****************/
- void write_data(uchar date)
- {LCM_RS=1;
- P0=date;
- delay(5);
- LCM_EN=1;
- delay(5);
- LCM_EN=0;
- }
- /**************初始化LCD1602*********************/
- void InitLcd()
- {
- write_com(0x38); //設置16X2顯示,5X7點陣,8位數據接口
- write_com(0x0c);//設置開顯示,不顯示光標
- write_com(0x06);//寫一個字符后地址指針加1
- write_com(0x01);//顯示清0,數據指針清0
- }
- /****************顯示指定坐標的一個字符*******************/
- void DisplayOneChar(uchar X,uchar Y,uchar WData)
- {
- Y&=1;
- X&=15;
- if(Y)X|=0x40;
- X|=0x80;
- write_com(X);
- write_data(WData);
- }
- /*************************************延時5微秒函數**************************************/
- void Delay5us()
- {
- _nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();
- }
- /************************************延時5毫秒函數*************************************/
- void Delay5ms()
- {
- WORD n = 560;
- while (n--);
- }
- //獲取BMP180設備ID默認值為0x55
- /*uchar GetBMP180DevicelD()
- {
- uchar DevicelD=0;
- BMP180_Start(); //起始信號
- BMP180_SendByte(BMP180_SlaveAddress);; //發送設備地址+寫信號
- BMP180_SendByte(0xD0); //發送存儲單元地址OD為ID存儲寄存器
- BMP180_Start(); //起始信號
- BMP180_SendByte(BMP180_SlaveAddress); //發送設備地址+讀信號
- DevicelD =BMP180_SendByte(0xee);
- BMP180_Stop();
- return DevicelD;
- }*/
- /**************************************開始信號(bmp180啟動)**************************************/
- void BMP180_Start()
- {
- SDA = 1; //拉高數據線
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SDA = 0; //產生下降沿
- Delay5us(); //延時
- SCL = 0; //拉低時鐘線
- }
- /**************************************停止信號(停止)**************************************/
- void BMP180_Stop()
- {
- SDA = 0; //拉低數據線
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SDA = 1; //產生上升沿
- Delay5us(); //延時
- }
- /**************************************發送應答信號**************************************/
- void BMP180_SendACK(bit ack)
- {
- SDA = ack; //寫應答信號
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- }
- /**************************************接收應答信號**************************************/
- bit BMP180_RecvACK()
- {
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- CY = SDA; //讀應答信號
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- return CY;
- }
- /**************************************向IIC總線發送一個字節數據**************************************/
- void BMP180_SendByte(BYTE dat)
- {
- BYTE i;
- for (i=0; i<8; i++) //8位計數器
- {
- dat <<= 1; //移出數據的最高位
- SDA = CY; //送數據口
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- }
- BMP180_RecvACK();
- }
- /**************************************從IIC總線接收一個字節數據**************************************/
- BYTE BMP180_RecvByte()
- {
- BYTE i;
- BYTE dat = 0;
- SDA = 1; //使能內部上拉,準備讀取數據,
- for (i=0; i<8; i++) //8位計數器
- {
- dat <<= 1;
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- dat |= SDA; //讀數據
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- }
- return dat;
- }
- /*******************從BMP180中讀取兩字節數據******************************/
- short Multiple_read(uchar ST_Address)
- {
- uchar msb, lsb;
- short _data;
- BMP180_Start(); //起始信號
- BMP180_SendByte(BMP180_SlaveAddress); //發送設備地址+寫信號
- BMP180_SendByte(ST_Address); //發送存儲單元地址
- BMP180_Start(); //起始信號
- BMP180_SendByte(BMP180_SlaveAddress+1); //發送設備地址+讀信號
- msb = BMP180_RecvByte(); //BUF[0]存儲
- BMP180_SendACK(0); //主機發送應答信號,回應ACK
- lsb = BMP180_RecvByte();
- BMP180_SendACK(1); //最后一個數據需要回非ACK
- BMP180_Stop(); //停止信號
- Delay5ms();
- _data = msb << 8;
- _data |= lsb;
- return _data;
- }
- /******************************溫度讀取**************************************/
- long bmp180ReadTemp(void)
- {
- BMP180_Start(); //起始信號
- BMP180_SendByte(BMP180_SlaveAddress); //發送設備地址+寫信號
- BMP180_SendByte(0xF4); // write register address
- BMP180_SendByte(0x2E); // write register data for temp
- BMP180_Stop(); //發送停止信號
- delay(10);// max time is 4.5ms
- return (long) Multiple_read(0xF6); //返回溫度,0.1℃
- }
- /************************壓強讀取*************************************/
- long bmp180ReadPressure(void)
- {
- long pressure = 0;
- BMP180_Start(); //起始信號
- BMP180_SendByte(BMP180_SlaveAddress); //發送設備地址+寫信號
- BMP180_SendByte(0xF4); // write register address
- BMP180_SendByte(0x34); // write register data for pressure
- BMP180_Stop(); //發送停止信號
- delay(10); // max time is 4.5ms
- pressure = Multiple_read(0xF6);
- pressure &= 0x0000FFFF;
- return pressure; //返回氣壓值,pa
- }
- /****************初始化BMP180,讀出內部標定參數**************/
- void Init_BMP180()
- {
- ac1 = Multiple_read(0xAA);
- ac2 = Multiple_read(0xAC);
- ac3 = Multiple_read(0xAE);
- ac4 = Multiple_read(0xB0);
- ac5 = Multiple_read(0xB2);
- ac6 = Multiple_read(0xB4);
- b1 = Multiple_read(0xB6);
- b2 = Multiple_read(0xB8);
- mb = Multiple_read(0xBA);
- mc = Multiple_read(0xBC);
- md = Multiple_read(0xBE);
- }
- double pow(double a,double b)
- {
- double result=1;
- for(;b>0;b--)
- {
- result*=a;
- }
- return result;
- }
- /*************************獲取氣壓、溫度并顯示******************************/
- void bmp180Convert()
- {
- unsigned int ut;
- unsigned long up;
-
- long x1, x2, b5, b6, x3, b3, p;
- unsigned long b4, b7;
-
- long temp,y;
-
- ut = bmp180ReadTemp(); // 讀取溫度
- up = bmp180ReadPressure(); // 讀取壓強
-
- //根據芯片手冊提供的公式計算補償后的溫度
- x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;//x1=((ut-ac6)*ac5)/(2^15)
- x2 = ((long) mc << 11) / (x1 + md); //x2=(mc*2^11)/(x1+md)
- b5 = x1 + x2; //b5=x1+x2
- temperature = (b5 + 8) >> 4; //t=(b5+8)/(2^4)
- // 根據芯片手冊提供的公式計算補償后的氣壓
- b6 = b5 - 4000;
- x1 = (b2 * (b6 * b6)>>12)>>11;
- x2 = (ac2 * b6)>>11;
- x3 = x1 + x2;
- b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2; // Calculate B4
- x1 = (ac3 * b6)>>13;
- x2 = (b1 * ((b6 * b6)>>12))>>16;
- x3 = ((x1 + x2) + 2)>>2;
- b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
- b7 = ((unsigned long)(up - b3) * (50000>>OSS));
- if (b7 < 0x80000000)
- p = (b7<<1)/b4;
- else
- p = (b7/b4)<<1;
- x1 = (p>>8) * (p>>8);
- x1 = (x1 * 3038)>>16;
- x2 = (-7357 * p)>>16;
- pressure = p+((x1 + x2 + 3791)>>4);
- delay(50);
-
- temp=1.0563;
- y=0.1987;
- pow(temp,y);
-
- /*temp=pressure/101325;
- y=1/5.255;
- temp=pow(temp,y);
- //height=(44330*(1-temp));*/
- //height= 44330*(1-pow((pressure/101325.0),(1.0/5.255)));
- height=(101325-pressure)*843/1000;
- if(height<0)
- {
- height=(-height);
- //height=(-123);
- DisplayOneChar(0,0,'T');//溫度部分
- DisplayOneChar(1,0,':');
- DisplayOneChar(2,0,temperature%1000/100+0x30);
- DisplayOneChar(3,0,temperature%100/10+0x30);
- DisplayOneChar(4,0,'.');
- DisplayOneChar(5,0,temperature%10+0x30);
- DisplayOneChar(6,0,0XDF);
- DisplayOneChar(7,0,'C');
- DisplayOneChar(8,0,'H');//海拔部分
- DisplayOneChar(9,0,'-');
- DisplayOneChar(10,0,height%10000/1000+0x30);
- DisplayOneChar(11,0,height%1000/100+0x30);
- DisplayOneChar(12,0,height%100/10+0x30);
- DisplayOneChar(13,0,height%10+0x30);
- DisplayOneChar(14,0,'.');
- DisplayOneChar(15,0,height*10%10+0x30);
- //DisplayOneChar(15,0,'m');
- DisplayOneChar(0,1,'P');//氣壓部分
- DisplayOneChar(1,1,':');
- DisplayOneChar(2,1,pressure%1000000/100000+48);
- DisplayOneChar(3,1,pressure%100000/10000+48);
- DisplayOneChar(4,1,pressure%10000/1000+48);
- DisplayOneChar(5,1,'.');
- DisplayOneChar(6,1,pressure%1000/100+48);
- DisplayOneChar(7,1,pressure%100/10+48);
- //DisplayOneChar(8,1,pressure%10/1+48);
- DisplayOneChar(8,1,'K');
- DisplayOneChar(9,1,'p');
- DisplayOneChar(10,1,'a');
-
- }
- else
- {
- DisplayOneChar(0,0,'T');//溫度部分
- DisplayOneChar(1,0,':');
- DisplayOneChar(2,0,temperature%1000/100+0x30);
- DisplayOneChar(3,0,temperature%100/10+0x30);
- DisplayOneChar(4,0,'.');
- DisplayOneChar(5,0,temperature%10+0x30);
- DisplayOneChar(6,0,0XDF);
- DisplayOneChar(7,0,'C');
- DisplayOneChar(8,0,' ');
- DisplayOneChar(9,0,'H');//海拔部分
- DisplayOneChar(10,0,height%10000/1000+0x30);
- DisplayOneChar(11,0,height%1000/100+0x30);
- DisplayOneChar(12,0,height%100/10+0x30);
- DisplayOneChar(13,0,height%10+0x30);
- DisplayOneChar(14,0,'.');
- DisplayOneChar(15,0,height*10%10+0x30);
- //DisplayOneChar(15,0,'m');
- DisplayOneChar(0,1,'P');//氣壓部分
- DisplayOneChar(1,1,':');
- DisplayOneChar(2,1,pressure%1000000/100000+48);
- DisplayOneChar(3,1,pressure%100000/10000+48);
- DisplayOneChar(4,1,pressure%10000/1000+48);
- DisplayOneChar(5,1,'.');
- DisplayOneChar(6,1,pressure%1000/100+48);
- DisplayOneChar(7,1,pressure%100/10+48);
- //DisplayOneChar(8,1,pressure%10/1+48);
- DisplayOneChar(8,1,'K');
- DisplayOneChar(9,1,'p');
- DisplayOneChar(10,1,'a');
- }
- }
- /**********************主程序***************************/
- void main()
- { long icid;
- delay(50); //上電延時
- InitLcd(); //液晶初始化
- Init_BMP180(); //初始化BMP180
- /*icid = Multiple_read(0xD0);
- if (icid==0xee)
- DisplayOneChar(8,1,'y');
- else DisplayOneChar(9,1,'n');
- while(1);*/
- while(1) //循環
- {
- bmp180Convert();
- delay(100);
- }
- }
復制代碼
|