找回密码
 立即注册
查看: 2356|回复: 6

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

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 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, 下载次数: 224

DebugLab
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:464
  • 最近打卡:2025-04-29 08:25:45

10

主题

130

回帖

564

积分

高级会员

积分
564
发表于 2023-11-4 20:37:12 | 显示全部楼层
本帖最后由 NTC 于 2024-7-21 19:44 编辑

32F-BMP280-OK.zip (39.42 KB, 下载次数: 121) 好巧,正在找,谢谢。
移植到了 STC32, USB-CDC 串口打印。


2024.7.21 更新
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:512
  • 最近打卡:2025-05-01 09:14:27

21

主题

564

回帖

2674

积分

金牌会员

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

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2024-04-07 07:55:06

0

主题

11

回帖

92

积分

注册会员

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

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:512
  • 最近打卡:2025-05-01 09:14:27

21

主题

564

回帖

2674

积分

金牌会员

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

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:422
  • 最近打卡:2025-05-01 09:54:52
已绑定手机

19

主题

3190

回帖

4866

积分

论坛元老

积分
4866
发表于 2024-5-18 13:29:55 来自手机 | 显示全部楼层
有个bmp280有空移植到stc8h上面
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:186
  • 最近打卡:2025-03-06 09:49:49

14

主题

133

回帖

1149

积分

金牌会员

积分
1149
发表于 2024-11-21 13:32:55 | 显示全部楼层
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-1 19:43 , Processed in 0.120446 second(s), 90 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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