找回密码
 立即注册
查看: 937|回复: 4

I2C接口,BMP280, 读取温度气压从串口发送程序

[复制链接]
  • TA的每日心情
    开心
    8 小时前
  • 签到天数: 109 天

    [LV.6]常住居民II

    25

    主题

    304

    回帖

    1025

    积分

    荣誉版主

    Cyber Hamster

    积分
    1025
    发表于 2023-10-11 20:42:39 | 显示全部楼层 |阅读模式
    本程序实现BMP280读取温度气压从串口发送的功能,分为直接赋值和printf两个版本,直接赋值版本使用定点计算,printf版本使用浮点计算,printf版本精度更高(示例:T=23.60335℃ P=100654.9Pa),BMP280在只读寄存器中有12个校准参数,均为16bit,地址为0x88~0xA1,但数据类型不同,具体请查看数据手册,其中3个温度校准参数,9个气压校准参数,用于校正每个BMP280的个体差异,这些参数在初始化时读取一次即可,在程序中要加载这些参数进行运算才能得到正确的测量值,实时读取的寄存器,温度地址为0xF7~0xF9,气压地址为0xFA~0xFC,均为20bit,数据类型为signed long,这两个值随温度和气压变化,要实时读取,这些值在数据手册中给出了测试值,用于验证算法是否正确,如需要验证,这些固定值取消注释即可,输出温度25.08℃,气压100653Pa,证明算法正确,当然本程序是已经验证过的。

    单片机STC8G1K08A-8PIN,时钟频率11.0592MHz,UART1 9600bps 8N1,BMP280使用成品模块。

    BMP280模块长这样:

    O1CN01hTm1uy2KzDakCSWhR_!!2210890229627.avif.jpg

    O1CN01OJEmfb2KzDaoPp6en_!!2210890229627.avif.jpg

    串口和printf的使用见此连接:

    https://www.stcaimcu.com/forum.php?mod=viewthread&tid=4598


    附带部分中文数据手册,重要部分已翻译。


    直接赋值版本:


    /*----------------------------分割线----------------------------*/

    #include <STC8G.H>
    #include "define.h"
    #include <intrins.h>
    #include <string.h>
    #define                RXD                P30
    #define                TXD                P31
    #define                SCL                P32
    #define                SDA                P33
    #define                FOSC                                11059200UL
    #define                BAUD                                9600UL
    #define                BRT                                        (0x10000-FOSC/BAUD/4)
    #define                T_Buffer_Len                64        //Uart1发送缓存长度
    #define                R_Buffer_Len                64        //Uart1接收缓存长度
    #define                BMP280_WRITE                0xEC
    #define                BMP280_READ                        0xED
    #define                BMP280_PRESS_ADDR        0xF7
    #define                BMP280_PRESS_MSB        0xF7
    #define                BMP280_PRESS_LSB        0xF8
    #define                BMP280_PRESS_XLSB        0xF9
    #define                BMP280_TEMP_ADDR        0xFA
    #define                BMP280_TEMP_MSB                0xFA
    #define                BMP280_TEMP_LSB                0xFB
    #define                BMP280_TEMP_XLSB        0xFC

    bit I2C_Busy;
    unsigned char                RP;                                                        //Uart1接收指针
    unsigned char                TP;                                                        //Uart1发送指针
    unsigned char                Uart_Send_Lenth;                        //Uart1发送长度
    unsigned char xdata        R_Buffer[R_Buffer_Len];                //Uart1接收缓存
    unsigned char xdata        T_Buffer[T_Buffer_Len];                //Uart1发送缓存
    unsigned int                Temp;
    unsigned char code        Hex_to_Ascii[16]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};
    unsigned int                dig_T1;
    signed int                        dig_T2;
    signed int                        dig_T3;
    unsigned int                dig_P1;
    signed int                        dig_P2;
    signed int                        dig_P3;
    signed int                        dig_P4;
    signed int                        dig_P5;
    signed int                        dig_P6;
    signed int                        dig_P7;
    signed int                        dig_P8;
    signed int                        dig_P9;
    signed long                        ADC_T,ADC_P;

    /*----------------------------延时10us@STC-Y6@11.0592MHz----------------------------*/
    void Delay_10us(void)
    {
            unsigned char i;
            i=35;
            while(--i);
    }

    /*----------------------------延时x10us----------------------------*/
    void Delay_x10us(unsigned char x)
    {
            while(x--)
                    Delay_10us();
    }

    /*----------------------------延时10ms@STC-Y6@11.0592MHz----------------------------*/
    void Delay_10ms(void)
    {
            unsigned char i,j;
            _nop_();
            _nop_();
            i=144;
            j=157;
            do
            {
                    while(--j);
            }while(--i);
    }

    /*----------------------------延时x10ms----------------------------*/
    void Delay_x10ms(unsigned char x)
    {
            while(x--)
                    Delay_10ms();
    }

    void UART_Send(unsigned int x)
    {
            TP=0;
            Uart_Send_Lenth=x;
            TI=1;
    }

    void I2C_Start(void)
    {
            I2C_Busy=1;
            I2CMSCR=0x81;
            while(I2C_Busy);
    }

    void I2C_SendData(unsigned char dat)
    {
            I2CTXD=dat;
            I2C_Busy=1;
            I2CMSCR=0x82;
            while(I2C_Busy);
    }

    void I2C_RecvACK(void)
    {
            I2C_Busy=1;
            I2CMSCR=0x83;
            while(I2C_Busy);
    }

    unsigned char I2C_RecvData(void)
    {
            I2C_Busy=1;
            I2CMSCR=0x84;
            while(I2C_Busy);
            return I2CRXD;
    }

    void I2C_SendACK(void)
    {
            I2CMSST=0x00;
            I2C_Busy=1;
            I2CMSCR=0x85;
            while(I2C_Busy);
    }

    //void I2C_SendNAK(void)
    //{
    //        I2CMSST=0x01;
    //        I2C_Busy=1;
    //        I2CMSCR=0x85;
    //        while(I2C_Busy);
    //}

    void I2C_Stop(void)
    {
            I2C_Busy=1;
            I2CMSCR=0x86;
            while(I2C_Busy);
    }

    void bmp280_WriteByte(unsigned char addr, unsigned char dat)
    {
            I2C_Start();
            I2C_SendData(BMP280_WRITE);
            I2C_RecvACK();
            I2C_SendData(addr);
            I2C_RecvACK();
            I2C_SendData(dat);
            I2C_RecvACK();
            I2C_Stop();
    }

    signed int Bmp280_Read_Two_Byte(unsigned char addr)
    {
            unsigned char msb,lsb;
            int temp=0;
            I2C_Start();
            I2C_SendData(BMP280_WRITE);
            I2C_RecvACK();
            I2C_SendData(addr);
            I2C_RecvACK();
            I2C_Start();
            I2C_SendData(BMP280_READ);
            I2C_RecvACK();
            lsb=I2C_RecvData();
            I2C_SendACK();
            msb=I2C_RecvData();
            I2C_Stop();
            temp=(unsigned int)msb<<8;
            temp|=(unsigned int)lsb;
            return temp;
    }

    signed long Bmp280_Read_Three_Byte(unsigned char addr)
    {
            unsigned char msb,lsb,xlsb;
            long temp=0;
            I2C_Start();
            I2C_SendData(BMP280_WRITE);
            I2C_RecvACK();
            I2C_SendData(addr);
            I2C_RecvACK();
            I2C_Start();
            I2C_SendData(BMP280_READ);
            I2C_RecvACK();
            msb=I2C_RecvData();
            I2C_SendACK();
            lsb=I2C_RecvData();
            I2C_SendACK();
            xlsb=I2C_RecvData();
            I2C_Stop();
            temp=(long)(((unsigned long)msb<<12)|((unsigned long)lsb<<4)|((unsigned long)xlsb>>4));
            return temp;
    }

    //Returns temperature in DegC, float precision. Output value of “51.23” equals 51.23 DegC.
    //t_fine carries fine temperature as global value
    //float bmp280_compensate_T_float(long adc_T)
    //{
    //        long t_fine;
    //        float var1,var2,T;
    //        var1=(((float)adc_T)/16384.0-((float)dig_T1)/1024.0)*((float)dig_T2);
    //        var2=((((float)adc_T)/131072.0-((float)dig_T1)/8192.0)*(((float)adc_T)/131072.0-((float) dig_T1)/8192.0))*((float)dig_T3);
    //        t_fine=(long)(var1+var2);
    //        T=(var1+var2)/5120.0;
    //        return T;
    //}

    //Returns pressure in Pa as float. Output value of “96386.2” equals 96386.2 Pa = 963.862 hPa
    //float bmp280_compensate_P_float(long adc_P)
    //{
    //        long t_fine;
    //        float var1,var2,p;
    //        var1=((float)t_fine/2.0)-64000.0;
    //        var2=var1*var1*((float)dig_P6)/32768.0;
    //        var2=var2+var1*((float)dig_P5)*2.0;
    //        var2=(var2/4.0)+(((float)dig_P4)*65536.0);
    //        var1=(((float)dig_P3) * var1 *var1/524288.0 +((float)dig_P2)*var1)/524288.0;
    //        var1=(1.0+var1/32768.0)*((float)dig_P1);
    //        if(var1==0.0)
    //        {
    //                return 0;        //avoid exception caused by division by zero
    //        }
    //        p=1048576.0-(float)adc_P;
    //        p=(p-(var2/4096.0))*6250.0/var1;
    //        var1=((float)dig_P9)*p*p/2147483648.0;
    //        var2=p*((float)dig_P8)/32768.0;
    //        p=p+(var1+var2+((float)dig_P7))/16.0;
    //        return p;
    //}

    //Returns temperature in DegC, resolution is 0.01 DegC. Output value of “5123” equals 51.23 DegC.
    //t_fine carries fine temperature as global value
    signed long bmp280_compensate_T_int32(long adc_T)
    {
            long t_fine;
            long var1,var2,T;
            var1=((((adc_T>>3)-((long)dig_T1<<1)))*((long)dig_T2))>>11;
            var2=(((((adc_T>>4)-((long)dig_T1))*((adc_T>>4)-((long)dig_T1)))>>12)*((long)dig_T3))>>14;
            t_fine=var1+var2;
            T=(t_fine*5+128)>>8;
            return T;
    }

    //Returns pressure in Pa as unsigned 32 bit integer. Output value of “96386” equals 96386 Pa = 963.86 hPa
    unsigned long bmp280_compensate_P_int32(long adc_P)
    {
            long t_fine;
            long var1,var2;
            unsigned long p;
            var1=(((long)t_fine)>>1)-(long)64000;
            var2=(((var1>>2)*(var1>>2))>>11)*((long)dig_P6);
            var2=var2+((var1*((long)dig_P5))<<1);
            var2=(var2>>2)+(((long)dig_P4)<<16);
            var1=(((dig_P3*(((var1>>2)*(var1>>2))>>13))>>3)+((((long)dig_P2)*var1)>>1))>>18;
            var1=((((32768+var1))*((long)dig_P1))>>15);
            if(var1==0)
            {
                    return 0;        //avoid exception caused by division by zero
            }
            p=(((unsigned long)(((long)1048576)-adc_P)-(var2>>12)))*3125;
            if(p<0x80000000)
            {
                    p=(p<<1)/((unsigned long)var1);
            }
            else
            {
                    p=(p/(unsigned long)var1)*2;
            }
            var1=(((long)dig_P9)*((long)(((p>>3)*(p>>3))>>13)))>>12;
            var2=(((long)(p>>2))*((long)dig_P8))>>13;
            p=(unsigned long)((long)p+((var1+var2+dig_P7)>>4));
            return p;
    }

    void Bmp280_Read(void)
    {
        ADC_T=Bmp280_Read_Three_Byte(BMP280_TEMP_ADDR);
        ADC_P=Bmp280_Read_Three_Byte(BMP280_PRESS_ADDR);
    //        ADC_T=519888;
    //        ADC_P=415148;
    }

    void Bmp280_Init(void)
    {
            bmp280_WriteByte(0xe0,0xb6);
            Delay_x10us(100);
            bmp280_WriteByte(0xf4,0xff);
            bmp280_WriteByte(0xf5,0x00);
            dig_T1=Bmp280_Read_Two_Byte(0x88);
        dig_T2=Bmp280_Read_Two_Byte(0x8a);
        dig_T3=Bmp280_Read_Two_Byte(0x8c);
        dig_P1=Bmp280_Read_Two_Byte(0x8e);
        dig_P2=Bmp280_Read_Two_Byte(0x90);
        dig_P3=Bmp280_Read_Two_Byte(0x92);
        dig_P4=Bmp280_Read_Two_Byte(0x94);
        dig_P5=Bmp280_Read_Two_Byte(0x96);
        dig_P6=Bmp280_Read_Two_Byte(0x98);
        dig_P7=Bmp280_Read_Two_Byte(0x9a);
        dig_P8=Bmp280_Read_Two_Byte(0x9c);
        dig_P9=Bmp280_Read_Two_Byte(0x9e);
    //        dig_T1=27504;
    //        dig_T2=26435;
    //        dig_T3=-1000;
    //        dig_P1=36477;
    //        dig_P2=-10685;
    //        dig_P3=3024;
    //        dig_P4=2855;
    //        dig_P5=140;
    //        dig_P6=-7;
    //        dig_P7=15500;
    //        dig_P8=-14600;
    //        dig_P9=6000;
    }

    void Init(void)
    {
            P_SW2|=EAXFR;
            
            P3M0=0x00;
            P3M1=0x00;
            P5M0=0x00;
            P5M1=0x00;
            P3PU=0x0c;
            
            AUXR=0x40;                //设置定时器0时钟为12T模式,设置定时器1为1T模式,设置定时器1为波特率发生器
            TMOD=0x01;                //设置定时器0为16位不自动重装载模式,设置定时器1为16位自动重装载模式
            TL0=0x00;                //设置定时器0初始值(5ms)
            TH0=0xEE;                //设置定时器0初始值(5ms)
            TF0=0;                        //清除TF0中断标志位
            ET0=1;                        //启用定时器0中断
            
            SCON=0x50;                //设置UART1模式为8位数据可变波特率
            TL1=BRT;                //设置UART1波特率
        TH1=BRT>>8;                //设置UART1波特率
            TR1=1;                        //打开定时器1
            ES=1;                        //启用UART1中断
            
            I2CCFG=0xC6;        //345.6K@11.0592M
            I2CMSCR=EMSI;
            I2CMSST=0x00;
            
            EA=1;                        //启用总中断
            
            Bmp280_Init();
    }

    void main(void)
    {
            unsigned long t,p;
            Init();
            while(1)
            {
                    Bmp280_Read();
                    t=bmp280_compensate_T_int32(ADC_T);
                    p=bmp280_compensate_P_int32(ADC_P);
                    T_Buffer[0]='T';
                    T_Buffer[1]='=';
                    T_Buffer[2]=Hex_to_Ascii[t%10000/1000];
                    T_Buffer[3]=Hex_to_Ascii[t%1000/100];
                    T_Buffer[4]='.';
                    T_Buffer[5]=Hex_to_Ascii[t%100/10];
                    T_Buffer[6]=Hex_to_Ascii[t%10];
                    T_Buffer[7]='C';
                    T_Buffer[8]=' ';
                    T_Buffer[9]='P';
                    T_Buffer[10]='=';
                    T_Buffer[11]=Hex_to_Ascii[p%1000000/100000];
                    T_Buffer[12]=Hex_to_Ascii[p%100000/10000];
                    T_Buffer[13]=Hex_to_Ascii[p%10000/1000];
                    T_Buffer[14]='.';
                    T_Buffer[15]=Hex_to_Ascii[p%1000/100];
                    T_Buffer[16]=Hex_to_Ascii[p%100/10];
                    T_Buffer[17]=Hex_to_Ascii[p%10];
                    T_Buffer[18]='K';
                    T_Buffer[19]='P';
                    T_Buffer[20]='a';
                    T_Buffer[21]=0x0d;
                    T_Buffer[22]=0x0a;
                    UART_Send(23);
                    Delay_x10ms(10);
            }
    }

    void Uart_Start(void)
    {
            TL0=0x00;
            TH0=0xEE;
            TR0=1;
    }

    void Uart_Stop(void)
    {
            TR0=0;
            TL0=0x00;
            TH0=0xEE;
            RP=0;
            memset(R_Buffer,0x00,sizeof R_Buffer);
    }

    void Timer0_Isr(void) interrupt 1
    {
            Uart_Stop();
    }

    void Uart_Isr(void) interrupt 4
    {
            if(RI)
            {
                    RI=0;
                    Uart_Start();
                    R_Buffer[RP]=SBUF;
                    if(RP==R_Buffer_Len-1)
                    {
                            Uart_Stop();
                    }
                    else if(TR0)
                    {
                            RP++;
                    }
            }
            if(TI)
            {
                    TI=0;
                    if(Uart_Send_Lenth!=0)
                    {
                            SBUF=(T_Buffer[TP]);
                            TP++;
                    }
                    if(TP==Uart_Send_Lenth)
                    {
                            TP=0;
                            Uart_Send_Lenth=0;
                    }
            }
    }

    void I2C_Isr(void) interrupt 24
    {
            _push_(P_SW2);
            P_SW2|=EAXFR;
            if(I2CMSST&MSIF)
            {
                    I2CMSST&=~MSIF;
                    I2C_Busy=0;
            }
            _pop_(P_SW2);
    }

    /*----------------------------分割线----------------------------*/

    printf版本:

    /*----------------------------分割线----------------------------*/

    #include <STC8G.H>
    #include "define.h"
    #include <intrins.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdarg.h>
    #define                RXD                P30
    #define                TXD                P31
    #define                SCL                P32
    #define                SDA                P33
    #define                FOSC                                11059200UL
    #define                BAUD                                9600UL
    #define                BRT                                        (0x10000-FOSC/BAUD/4)
    #define                T_Buffer_Len                64        //Uart1发送缓存长度
    #define                R_Buffer_Len                64        //Uart1接收缓存长度
    #define                BMP280_WRITE                0xEC
    #define                BMP280_READ                        0xED
    #define                BMP280_PRESS_ADDR        0xF7
    #define                BMP280_PRESS_MSB        0xF7
    #define                BMP280_PRESS_LSB        0xF8
    #define                BMP280_PRESS_XLSB        0xF9
    #define                BMP280_TEMP_ADDR        0xFA
    #define                BMP280_TEMP_MSB                0xFA
    #define                BMP280_TEMP_LSB                0xFB
    #define                BMP280_TEMP_XLSB        0xFC

    bit I2C_Busy;
    unsigned char                RP;                                                        //Uart1接收指针
    unsigned char                TP;                                                        //Uart1发送指针
    unsigned char                Uart_Send_Lenth;                        //Uart1发送长度
    unsigned char xdata        R_Buffer[R_Buffer_Len];                //Uart1接收缓存
    unsigned char xdata        T_Buffer[T_Buffer_Len];                //Uart1发送缓存
    unsigned int                Temp;
    unsigned char code        Hex_to_Ascii[16]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};
    unsigned int xdata        dig_T1;
    signed int xdata        dig_T2;
    signed int xdata        dig_T3;
    unsigned int xdata        dig_P1;
    signed int xdata        dig_P2;
    signed int xdata        dig_P3;
    signed int xdata        dig_P4;
    signed int xdata        dig_P5;
    signed int xdata        dig_P6;
    signed int xdata        dig_P7;
    signed int xdata        dig_P8;
    signed int xdata        dig_P9;
    signed long xdata        ADC_T,ADC_P;

    /*----------------------------延时10us@STC-Y6@11.0592MHz----------------------------*/
    void Delay_10us(void)
    {
            unsigned char i;
            i=35;
            while(--i);
    }

    /*----------------------------延时x10us----------------------------*/
    void Delay_x10us(unsigned char x)
    {
            while(x--)
                    Delay_10us();
    }

    /*----------------------------延时10ms@STC-Y6@11.0592MHz----------------------------*/
    void Delay_10ms(void)
    {
            unsigned char i,j;
            _nop_();
            _nop_();
            i=144;
            j=157;
            do
            {
                    while(--j);
            }while(--i);
    }

    /*----------------------------延时x10ms----------------------------*/
    void Delay_x10ms(unsigned char x)
    {
            while(x--)
                    Delay_10ms();
    }

    void UART_Send(unsigned int x)
    {
            TP=0;
            Uart_Send_Lenth=x;
            TI=1;
    }

    void Uart_Printf(unsigned char *v,...)
    {
            va_list ap;
            va_start(ap,v);
            UART_Send(vsprintf(T_Buffer,v,ap));
            va_end(ap);
    }

    void I2C_Start(void)
    {
            I2C_Busy=1;
            I2CMSCR=0x81;
            while(I2C_Busy);
    }

    void I2C_SendData(unsigned char dat)
    {
            I2CTXD=dat;
            I2C_Busy=1;
            I2CMSCR=0x82;
            while(I2C_Busy);
    }

    void I2C_RecvACK(void)
    {
            I2C_Busy=1;
            I2CMSCR=0x83;
            while(I2C_Busy);
    }

    unsigned char I2C_RecvData(void)
    {
            I2C_Busy=1;
            I2CMSCR=0x84;
            while(I2C_Busy);
            return I2CRXD;
    }

    void I2C_SendACK(void)
    {
            I2CMSST=0x00;
            I2C_Busy=1;
            I2CMSCR=0x85;
            while(I2C_Busy);
    }

    //void I2C_SendNAK(void)
    //{
    //        I2CMSST=0x01;
    //        I2C_Busy=1;
    //        I2CMSCR=0x85;
    //        while(I2C_Busy);
    //}

    void I2C_Stop(void)
    {
            I2C_Busy=1;
            I2CMSCR=0x86;
            while(I2C_Busy);
    }

    void bmp280_WriteByte(unsigned char addr, unsigned char dat)
    {
            I2C_Start();
            I2C_SendData(BMP280_WRITE);
            I2C_RecvACK();
            I2C_SendData(addr);
            I2C_RecvACK();
            I2C_SendData(dat);
            I2C_RecvACK();
            I2C_Stop();
    }

    signed int Bmp280_Read_Two_Byte(unsigned char addr)
    {
            unsigned char msb,lsb;
            int temp=0;
            I2C_Start();
            I2C_SendData(BMP280_WRITE);
            I2C_RecvACK();
            I2C_SendData(addr);
            I2C_RecvACK();
            I2C_Start();
            I2C_SendData(BMP280_READ);
            I2C_RecvACK();
            lsb=I2C_RecvData();
            I2C_SendACK();
            msb=I2C_RecvData();
            I2C_Stop();
            temp=(unsigned int)msb<<8;
            temp|=(unsigned int)lsb;
            return temp;
    }

    signed long Bmp280_Read_Three_Byte(unsigned char addr)
    {
            unsigned char msb,lsb,xlsb;
            long temp=0;
            I2C_Start();
            I2C_SendData(BMP280_WRITE);
            I2C_RecvACK();
            I2C_SendData(addr);
            I2C_RecvACK();
            I2C_Start();
            I2C_SendData(BMP280_READ);
            I2C_RecvACK();
            msb=I2C_RecvData();
            I2C_SendACK();
            lsb=I2C_RecvData();
            I2C_SendACK();
            xlsb=I2C_RecvData();
            I2C_Stop();
            temp=(long)(((unsigned long)msb<<12)|((unsigned long)lsb<<4)|((unsigned long)xlsb>>4));
            return temp;
    }

    //Returns temperature in DegC, float precision. Output value of “51.23” equals 51.23 DegC.
    //t_fine carries fine temperature as global value
    float bmp280_compensate_T_float(long adc_T)
    {
            long t_fine;
            float var1,var2,T;
            var1=(((float)adc_T)/16384.0-((float)dig_T1)/1024.0)*((float)dig_T2);
            var2=((((float)adc_T)/131072.0-((float)dig_T1)/8192.0)*(((float)adc_T)/131072.0-((float) dig_T1)/8192.0))*((float)dig_T3);
            t_fine=(long)(var1+var2);
            T=(var1+var2)/5120.0;
            return T;
    }

    //Returns pressure in Pa as float. Output value of “96386.2” equals 96386.2 Pa = 963.862 hPa
    float bmp280_compensate_P_float(long adc_P)
    {
            long t_fine;
            float var1,var2,p;
            var1=((float)t_fine/2.0)-64000.0;
            var2=var1*var1*((float)dig_P6)/32768.0;
            var2=var2+var1*((float)dig_P5)*2.0;
            var2=(var2/4.0)+(((float)dig_P4)*65536.0);
            var1=(((float)dig_P3) * var1 *var1/524288.0 +((float)dig_P2)*var1)/524288.0;
            var1=(1.0+var1/32768.0)*((float)dig_P1);
            if(var1==0.0)
            {
                    return 0;        //avoid exception caused by division by zero
            }
            p=1048576.0-(float)adc_P;
            p=(p-(var2/4096.0))*6250.0/var1;
            var1=((float)dig_P9)*p*p/2147483648.0;
            var2=p*((float)dig_P8)/32768.0;
            p=p+(var1+var2+((float)dig_P7))/16.0;
            return p;
    }

    //Returns temperature in DegC, resolution is 0.01 DegC. Output value of “5123” equals 51.23 DegC.
    //t_fine carries fine temperature as global value
    //signed long bmp280_compensate_T_int32(long adc_T)
    //{
    //        long t_fine;
    //        long var1,var2,T;
    //        var1=((((adc_T>>3)-((long)dig_T1<<1)))*((long)dig_T2))>>11;
    //        var2=(((((adc_T>>4)-((long)dig_T1))*((adc_T>>4)-((long)dig_T1)))>>12)*((long)dig_T3))>>14;
    //        t_fine=var1+var2;
    //        T=(t_fine*5+128)>>8;
    //        return T;
    //}

    //Returns pressure in Pa as unsigned 32 bit integer. Output value of “96386” equals 96386 Pa = 963.86 hPa
    //unsigned long bmp280_compensate_P_int32(long adc_P)
    //{
    //        long t_fine;
    //        long var1,var2;
    //        unsigned long p;
    //        var1=(((long)t_fine)>>1)-(long)64000;
    //        var2=(((var1>>2)*(var1>>2))>>11)*((long)dig_P6);
    //        var2=var2+((var1*((long)dig_P5))<<1);
    //        var2=(var2>>2)+(((long)dig_P4)<<16);
    //        var1=(((dig_P3*(((var1>>2)*(var1>>2))>>13))>>3)+((((long)dig_P2)*var1)>>1))>>18;
    //        var1=((((32768+var1))*((long)dig_P1))>>15);
    //        if(var1==0)
    //        {
    //                return 0;        //avoid exception caused by division by zero
    //        }
    //        p=(((unsigned long)(((long)1048576)-adc_P)-(var2>>12)))*3125;
    //        if(p<0x80000000)
    //        {
    //                p=(p<<1)/((unsigned long)var1);
    //        }
    //        else
    //        {
    //                p=(p/(unsigned long)var1)*2;
    //        }
    //        var1=(((long)dig_P9)*((long)(((p>>3)*(p>>3))>>13)))>>12;
    //        var2=(((long)(p>>2))*((long)dig_P8))>>13;
    //        p=(unsigned long)((long)p+((var1+var2+dig_P7)>>4));
    //        return p;
    //}

    void Bmp280_Read(void)
    {
        ADC_T=Bmp280_Read_Three_Byte(BMP280_TEMP_ADDR);
        ADC_P=Bmp280_Read_Three_Byte(BMP280_PRESS_ADDR);
    //        ADC_T=519888;
    //        ADC_P=415148;
    }

    void Bmp280_Init(void)
    {
            bmp280_WriteByte(0xe0,0xb6);
            Delay_x10us(100);
            bmp280_WriteByte(0xf4,0xff);
            bmp280_WriteByte(0xf5,0x00);
            dig_T1=Bmp280_Read_Two_Byte(0x88);
        dig_T2=Bmp280_Read_Two_Byte(0x8a);
        dig_T3=Bmp280_Read_Two_Byte(0x8c);
        dig_P1=Bmp280_Read_Two_Byte(0x8e);
        dig_P2=Bmp280_Read_Two_Byte(0x90);
        dig_P3=Bmp280_Read_Two_Byte(0x92);
        dig_P4=Bmp280_Read_Two_Byte(0x94);
        dig_P5=Bmp280_Read_Two_Byte(0x96);
        dig_P6=Bmp280_Read_Two_Byte(0x98);
        dig_P7=Bmp280_Read_Two_Byte(0x9a);
        dig_P8=Bmp280_Read_Two_Byte(0x9c);
        dig_P9=Bmp280_Read_Two_Byte(0x9e);
    //        dig_T1=27504;
    //        dig_T2=26435;
    //        dig_T3=-1000;
    //        dig_P1=36477;
    //        dig_P2=-10685;
    //        dig_P3=3024;
    //        dig_P4=2855;
    //        dig_P5=140;
    //        dig_P6=-7;
    //        dig_P7=15500;
    //        dig_P8=-14600;
    //        dig_P9=6000;
    }

    void Init(void)
    {
            P_SW2|=EAXFR;
            
            P3M0=0x00;
            P3M1=0x00;
            P5M0=0x00;
            P5M1=0x00;
            P3PU=0x0c;
            
            AUXR=0x40;                //设置定时器0时钟为12T模式,设置定时器1为1T模式,设置定时器1为波特率发生器
            TMOD=0x01;                //设置定时器0为16位不自动重装载模式,设置定时器1为16位自动重装载模式
            TL0=0x00;                //设置定时器0初始值(5ms)
            TH0=0xEE;                //设置定时器0初始值(5ms)
            TF0=0;                        //清除TF0中断标志位
            ET0=1;                        //启用定时器0中断
            
            SCON=0x50;                //设置UART1模式为8位数据可变波特率
            TL1=BRT;                //设置UART1波特率
        TH1=BRT>>8;                //设置UART1波特率
            TR1=1;                        //打开定时器1
            ES=1;                        //启用UART1中断
            
            I2CCFG=0xC6;        //345.6K@11.0592M
            I2CMSCR=EMSI;
            I2CMSST=0x00;
            
            EA=1;                        //启用总中断
            
            Bmp280_Init();
    }

    void main(void)
    {
            float t,p;
            Init();
            while(1)
            {
                    Bmp280_Read();
                    t=bmp280_compensate_T_float(ADC_T);
                    p=bmp280_compensate_P_float(ADC_P);
                    Uart_Printf("T=%2.5f℃ P=%6.1fPa\r\n",t,p);
                    Delay_x10ms(5);
            }
    }

    void Uart_Start(void)
    {
            TL0=0x00;
            TH0=0xEE;
            TR0=1;
    }

    void Uart_Stop(void)
    {
            TR0=0;
            TL0=0x00;
            TH0=0xEE;
            RP=0;
            memset(R_Buffer,0x00,sizeof R_Buffer);
    }

    void Timer0_Isr(void) interrupt 1
    {
            Uart_Stop();
    }

    void Uart_Isr(void) interrupt 4
    {
            if(RI)
            {
                    RI=0;
                    Uart_Start();
                    R_Buffer[RP]=SBUF;
                    if(RP==R_Buffer_Len-1)
                    {
                            Uart_Stop();
                    }
                    else if(TR0)
                    {
                            RP++;
                    }
            }
            if(TI)
            {
                    TI=0;
                    if(Uart_Send_Lenth!=0)
                    {
                            SBUF=(T_Buffer[TP]);
                            TP++;
                    }
                    if(TP==Uart_Send_Lenth)
                    {
                            TP=0;
                            Uart_Send_Lenth=0;
                    }
            }
    }

    void I2C_Isr(void) interrupt 24
    {
            _push_(P_SW2);
            P_SW2|=EAXFR;
            if(I2CMSST&MSIF)
            {
                    I2CMSST&=~MSIF;
                    I2C_Busy=0;
            }
            _pop_(P_SW2);
    }

    /*----------------------------分割线----------------------------*/

    完整工程见附件:






    BMP280.zip

    2.15 MB, 下载次数: 60

    (=・ω・=)
    回复 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    前天 08:08
  • 签到天数: 145 天

    [LV.7]常住居民III

    8

    主题

    77

    回帖

    1000

    积分

    金牌会员

    积分
    1000
    发表于 2023-11-4 20:37:12 | 显示全部楼层
    本帖最后由 NTC 于 2024-4-26 22:10 编辑

    32F-BMP280-OK.zip (37.54 KB, 下载次数: 0) 好巧,正在找,谢谢。
    移植到了 STC32, USB-CDC 串口打印。
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    慵懒
    15 小时前
  • 签到天数: 159 天

    [LV.7]常住居民III

    12

    主题

    341

    回帖

    1076

    积分

    金牌会员

    积分
    1076
    发表于 2023-11-10 08:30:43 | 显示全部楼层
    好复杂的样子
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-7 07:55
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    0

    主题

    11

    回帖

    90

    积分

    注册会员

    积分
    90
    发表于 2024-1-16 21:56:25 | 显示全部楼层
    学习中 好复杂
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    慵懒
    15 小时前
  • 签到天数: 159 天

    [LV.7]常住居民III

    12

    主题

    341

    回帖

    1076

    积分

    金牌会员

    积分
    1076
    发表于 2024-1-16 22:53:11 | 显示全部楼层
    有用,我也买了个温湿度模块,AHT20+BMP280,
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-5-2 23:16 , Processed in 0.067850 second(s), 48 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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