DebugLab 发表于 2023-10-11 20:42:39

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

本程序实现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模块长这样:





串口和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;                //Uart1接收缓存
unsigned char xdata      T_Buffer;                //Uart1发送缓存
unsigned int                Temp;
unsigned char code      Hex_to_Ascii={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='T';
                T_Buffer='=';
                T_Buffer=Hex_to_Ascii;
                T_Buffer=Hex_to_Ascii;
                T_Buffer='.';
                T_Buffer=Hex_to_Ascii;
                T_Buffer=Hex_to_Ascii;
                T_Buffer='C';
                T_Buffer=' ';
                T_Buffer='P';
                T_Buffer='=';
                T_Buffer=Hex_to_Ascii;
                T_Buffer=Hex_to_Ascii;
                T_Buffer=Hex_to_Ascii;
                T_Buffer='.';
                T_Buffer=Hex_to_Ascii;
                T_Buffer=Hex_to_Ascii;
                T_Buffer=Hex_to_Ascii;
                T_Buffer='K';
                T_Buffer='P';
                T_Buffer='a';
                T_Buffer=0x0d;
                T_Buffer=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=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++;
                }
                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;                //Uart1接收缓存
unsigned char xdata      T_Buffer;                //Uart1发送缓存
unsigned int                Temp;
unsigned char code      Hex_to_Ascii={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=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++;
                }
                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);
}

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

完整工程见附件:






NTC 发表于 2023-11-4 20:37:12

本帖最后由 NTC 于 2024-7-21 19:44 编辑

好巧,正在找,谢谢。
移植到了 STC32, USB-CDC 串口打印。


2024.7.21 更新

wangxiangtan 发表于 2023-11-10 08:30:43

好复杂的样子

li23108 发表于 2024-1-16 21:56:25

学习中 好复杂

wangxiangtan 发表于 2024-1-16 22:53:11

有用,我也买了个温湿度模块,AHT20+BMP280,

soma 发表于 2024-5-18 13:29:55

有个bmp280有空移植到stc8h上面

giveyou 发表于 2024-11-21 13:32:55

{:4_165:}
页: [1]
查看完整版本: I2C接口,BMP280, 读取温度气压从串口发送程序