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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

BMP180大氣壓力芯片51單片機程序

[復制鏈接]
跳轉到指定樓層
樓主
BMP180.rar (7.25 KB, 下載次數: 99) 用的普中實驗板,找個一個程序修改好,在開發板上測試可用。現在分享給新手參考,哈哈我自己也是個小白。在測試過程中時間久了偶爾顯示屏會顯示錯誤不知道什么原因。另外本想用這個改成BMP280傳感器使用的,可是簡單修改后數據不準。

/*
* BMP085模塊
* 用途:BMP085模塊IIC測試程序
*/
#include<reg51.h>
#include"lcd.h"
//#include  <REG51.H>          
#include  <math.h>    //Keil library  
#include  <stdlib.h>  //Keil library  
#include  <stdio.h>   //Keil library       
#include  <INTRINS.H> //Keil library  
#define   uchar unsigned char
#define   uint unsigned int       

#define   DataPort P0        //P2 LCD1602數據端口
sbit        SCL=P2^1;      //IIC時鐘引腳定義
sbit        SDA=P2^0;      //IIC數據引腳定義
sbit    LCM_RS=P2^6;   //P0^2;LCD1602命令端口               
sbit    LCM_RW=P2^5;   //P0^1;LCD1602命令端口               
sbit    LCM_EN=P2^7;   //P0^0;LCD1602命令端口  

#define        BMP085_SlaveAddress   0xEE          //定義器件在IIC總線中的從地址 BMP180=0xee,BMP280=0xec                              

#define OSS 0        // Oversampling Setting (note: code is not set up to use other OSS values)
                                                          
typedef unsigned char  BYTE;
typedef unsigned short WORD;
          
uchar ge,shi,bai,qian,wan,shiwan;           //顯示變量
int  dis_data;                              //變量

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(unsigned int k);
void InitLcd();                            //初始化lcd1602

void WriteDataLCM(uchar dataW);
void WriteCommandLCM(uchar CMD,uchar Attribc);
void DisplayOneChar(uchar X,uchar Y,uchar DData);
void conversion(long temp_data);

void  Single_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data);   //單個寫入數據
uchar Single_Read(uchar REG_Address);                                      //單個讀取內部寄存器數據
void  Multiple_Read(uchar,uchar);                                          //連續的讀取內部寄存器數據
//------------------------------------
void Delay5us();
void Delay5ms();
void BMP085_Start();
void BMP085_Stop();
void BMP085_SendACK(bit ack);
bit  BMP085_RecvACK();
void BMP085_SendByte(BYTE dat);
BYTE BMP085_RecvByte();
void BMP085_ReadPage();
void BMP085_WritePage();
//-----------------------------------

//*********************************************************
void conversion(long temp_data)  
{  

    shiwan=temp_data/100000+0x30 ;
    temp_data=temp_data%100000;   //取余運算
    wan=temp_data/10000+0x30 ;
    temp_data=temp_data%10000;   //取余運算
        qian=temp_data/1000+0x30 ;
    temp_data=temp_data%1000;    //取余運算
    bai=temp_data/100+0x30   ;
    temp_data=temp_data%100;     //取余運算
    shi=temp_data/10+0x30    ;
    temp_data=temp_data%10;      //取余運算
    ge=temp_data+0x30;        
}

/*******************************/
void delay(unsigned int k)       
{                                               
unsigned int i,j;                               
for(i=0;i<k;i++)
{                       
for(j=0;j<121;j++)                       
{;}}                                               
}
/*******************************/
void WaitForEnable(void)       
{                                       
DataPort=0xff;               
LCM_RS=0;LCM_RW=1;_nop_();
LCM_EN=1;_nop_();_nop_();
while(DataPort&0x80);       
LCM_EN=0;                               
}                                       
/*******************************/
void WriteCommandLCM(uchar CMD,uchar Attribc)
{                                       
if(Attribc)WaitForEnable();       
LCM_RS=0;LCM_RW=0;_nop_();
DataPort=CMD;_nop_();       
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}                                       
/*******************************/
void WriteDataLCM(uchar dataW)
{                                       
WaitForEnable();               
LCM_RS=1;LCM_RW=0;_nop_();
DataPort=dataW;_nop_();       
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}               
/***********************************/
void InitLcd()                               
{                       
WriteCommandLCM(0x38,1);       
WriteCommandLCM(0x08,1);       
WriteCommandLCM(0x01,1);       
WriteCommandLCM(0x06,1);       
WriteCommandLCM(0x0c,1);
}                       
/***********************************/
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{                                               
Y&=1;                                               
X&=15;                                               
if(Y)X|=0x40;                                       
X|=0x80;                       
WriteCommandLCM(X,0);               
WriteDataLCM(DData);               
}                                               

/**************************************
延時5微秒(STC90C52RC@12M)
不同的工作環境,需要調整此函數,注意時鐘過快時需要修改
當改用1T的MCU時,請調整此延時函數
**************************************/
void Delay5us()
{
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
}

/**************************************
延時5毫秒(STC90C52RC@12M)
不同的工作環境,需要調整此函數
當改用1T的MCU時,請調整此延時函數
**************************************/
void Delay5ms()
{
    WORD n = 560;

    while (n--);
}

/**************************************
起始信號
**************************************/
void BMP085_Start()
{
    SDA = 1;                    //拉高數據線
    SCL = 1;                    //拉高時鐘線
    Delay5us();                 //延時
    SDA = 0;                    //產生下降沿
    Delay5us();                 //延時
    SCL = 0;                    //拉低時鐘線
}

/**************************************
停止信號
**************************************/
void BMP085_Stop()
{
    SDA = 0;                    //拉低數據線
    SCL = 1;                    //拉高時鐘線
    Delay5us();                 //延時
    SDA = 1;                    //產生上升沿
    Delay5us();                 //延時
}

/**************************************
發送應答信號
入口參數:ack (0:ACK 1:NAK)
**************************************/
void BMP085_SendACK(bit ack)
{
    SDA = ack;                  //寫應答信號
    SCL = 1;                    //拉高時鐘線
    Delay5us();                 //延時
    SCL = 0;                    //拉低時鐘線
    Delay5us();                 //延時
}

/**************************************
接收應答信號
**************************************/
bit BMP085_RecvACK()
{
    SCL = 1;                    //拉高時鐘線
    Delay5us();                 //延時
    CY = SDA;                   //讀應答信號
    SCL = 0;                    //拉低時鐘線
    Delay5us();                 //延時

    return CY;
}

/**************************************
向IIC總線發送一個字節數據
**************************************/
void BMP085_SendByte(BYTE dat)
{
    BYTE i;

    for (i=0; i<8; i++)         //8位計數器
    {
        dat <<= 1;              //移出數據的最高位
        SDA = CY;               //送數據口
        SCL = 1;                //拉高時鐘線
        Delay5us();             //延時
        SCL = 0;                //拉低時鐘線
        Delay5us();             //延時
    }
    BMP085_RecvACK();
}

/**************************************
從IIC總線接收一個字節數據
**************************************/
BYTE BMP085_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;
}
/*
//單字節寫入BMP085內部數據*******************************

void Single_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data)
{
    BMP085_Start();                  //起始信號
    BMP085_SendByte(SlaveAddress);   //發送設備地址+寫信號
    BMP085_SendByte(REG_Address);    //內部寄存器地址
    BMP085_SendByte(REG_data);       //內部寄存器數據
    BMP085_Stop();                   //發送停止信號
}
*/
/*
//單字節讀取BMP085內部數據********************************
uchar Single_Read(uchar REG_Address)
{  uchar REG_data;
    BMP085_Start();                          //起始信號
    BMP085_SendByte(BMP085_SlaveAddress);           //發送設備地址+寫信號
    BMP085_SendByte(REG_Address);            //發送存儲單元地址       
    BMP085_Start();                          //起始信號
    BMP085_SendByte(BMP085_SlaveAddress+1);         //發送設備地址+讀信號
    REG_data=BMP085_RecvByte();              //讀出寄存器數據
        BMP085_SendACK(1);   
        BMP085_Stop();                           //停止信號
    return REG_data;
}
*/
//*********************************************************
//讀出BMP085內部數據,連續兩個
//*********************************************************
short Multiple_read(uchar ST_Address)
{   
        uchar msb, lsb;
        short _data;
    BMP085_Start();                          //起始信號
    BMP085_SendByte(BMP085_SlaveAddress);    //發送設備地址+寫信號
    BMP085_SendByte(ST_Address);             //發送存儲單元地址
    BMP085_Start();                          //起始信號
    BMP085_SendByte(BMP085_SlaveAddress+1);         //發送設備地址+讀信號

    msb = BMP085_RecvByte();                 //BUF[0]存儲
    BMP085_SendACK(0);                       //回應ACK
    lsb = BMP085_RecvByte();     
        BMP085_SendACK(1);                       //最后一個數據需要回NOACK

    BMP085_Stop();                           //停止信號
    Delay5ms();
    _data = msb << 8;
        _data |= lsb;       
        return _data;
}
//********************************************************************
long bmp085ReadTemp(void)
{

    BMP085_Start();                  //起始信號
    BMP085_SendByte(BMP085_SlaveAddress);   //發送設備地址+寫信號
    BMP085_SendByte(0xF4);                  // write register address
        BMP085_SendByte(0x2E);               // write register data for temp 180:0x2E 280:0x22
    BMP085_Stop();                   //發送停止信號
        delay(10);        // max time is 4.5ms
       
        return (long) Multiple_read(0xF6); // 180=0xF6 280=0xFa
}
//*************************************************************
long bmp085ReadPressure(void)
{
        long pressure = 0;

    BMP085_Start();                   //起始信號
    BMP085_SendByte(BMP085_SlaveAddress);   //發送設備地址+寫信號
    BMP085_SendByte(0xF4);                  // write register address
    BMP085_SendByte(0x34);                 // write register data for pressure 180=0x34 280=0x22
    BMP085_Stop();                    //發送停止信號
        delay(10);                              // max time is 4.5ms
       
        pressure = Multiple_read(0xF6);   // 180=0xF6 280=0xF9
        pressure &= 0x0000FFFF;
       
        return pressure;       
        //return (long) bmp085ReadShort(0xF6);
}

//**************************************************************

//初始化BMP085,根據需要請參考pdf進行修改**************
void Init_BMP085()
{
        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);
}
//***********************************************************************
void bmp085Convert()
{
        long ut;
        long up;
        long x1, x2, b5, b6, x3, b3, p;
        unsigned long b4, b7;
        long  temperature;
        long  pressure;
       
        ut = bmp085ReadTemp();
        ut = bmp085ReadTemp();           // 讀取溫度
        up = bmp085ReadPressure();
        up = bmp085ReadPressure();  // 讀取壓強
       
        x1 = ((long)ut - ac6) * ac5 >> 15;
        x2 = ((long) mc << 11) / (x1 + md);
        b5 = x1 + x2;
         temperature = (b5 + 8) >> 4;

         //*************

         conversion(temperature);
         DisplayOneChar(3,0,'T');       //溫度顯示
     DisplayOneChar(4,0,':');
     DisplayOneChar(6,0,bai);      
     DisplayOneChar(7,0,shi);
     DisplayOneChar(8,0,'.');
         DisplayOneChar(9,0,ge);
         DisplayOneChar(10,0,0XDF);     //溫度單位
         DisplayOneChar(11,0,'C');

         
     //*************
       
        b6 = b5 - 4000;
        x1 = (b2 * (b6 * b6 >> 12)) >> 11;
        x2 = ac2 * b6 >> 11;
        x3 = x1 + x2;
        b3 = (((long)ac1 * 4 + x3) + 2)/4;
        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 * 2) / b4 ;
           else  
                    p = (b7 / b4) * 2;
        x1 = (p >> 8) * (p >> 8);
        x1 = (x1 * 3038) >> 16;
        x2 = (-7357 * p) >> 16;
         pressure = p + ((x1 + x2 + 3791) >> 4);

         conversion(pressure);
     DisplayOneChar(3,1,'P');    //顯示壓強
     DisplayOneChar(4,1,':');
         DisplayOneChar(5,1,shiwan);
         DisplayOneChar(6,1,wan);   
     DisplayOneChar(7,1,qian);
     DisplayOneChar(8,1,'.');
     DisplayOneChar(9,1,bai);
     DisplayOneChar(10,1,shi);
         DisplayOneChar(11,1,'K');   //氣壓單位
         DisplayOneChar(12,1,'p');
         DisplayOneChar(13,1,'a');

}

//*********************************************************
//******主程序********
//*********************************************************
void main()
{
    delay(50);                           //上電延時               
    InitLcd();                     //液晶初始化
    Init_BMP085();                //初始化BMP085
  while(1)                         //循環
  {
    bmp085Convert();
        delay(1000);
  }
}




/*********************LCD.C******開始*******************************/

/*********************LCD.h******開始*******************************/


#include"lcd.h"

/*******************************************************************************
* 函 數 名         : Lcd1602_Delay1ms
* 函數功能                   : 延時函數,延時1ms
* 輸    入         : c
* 輸    出         : 無
* 說    名         : 該函數是在12MHZ晶振下,12分頻單片機的延時。
*******************************************************************************/

void Lcd1602_Delay1ms(uint c)   //誤差 0us
{
    uchar a,b;
        for (; c>0; c--)
        {
                 for (b=199;b>0;b--)
                 {
                          for(a=1;a>0;a--);
                 }      
        }
           
}

/*******************************************************************************
* 函 數 名         : LcdWriteCom
* 函數功能                   : 向LCD寫入一個字節的命令
* 輸    入         : com
* 輸    出         : 無
*******************************************************************************/
#ifndef         LCD1602_4PINS         //當沒有定義這個LCD1602_4PINS時
void LcdWriteCom(uchar com)          //寫入命令
{
        LCD1602_E = 0;     //使能
        LCD1602_RS = 0;           //選擇發送命令
        LCD1602_RW = 0;           //選擇寫入
       
        LCD1602_DATAPINS = com;     //放入命令
        Lcd1602_Delay1ms(1);                //等待數據穩定

        LCD1602_E = 1;                  //寫入時序
        Lcd1602_Delay1ms(5);          //保持時間
        LCD1602_E = 0;
}
#else
void LcdWriteCom(uchar com)          //寫入命令
{
        LCD1602_E = 0;         //使能清零
        LCD1602_RS = 0;         //選擇寫入命令
        LCD1602_RW = 0;         //選擇寫入

        LCD1602_DATAPINS = com;        //由于4位的接線是接到P0口的高四位,所以傳送高四位不用改
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;         //寫入時序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;

//        Lcd1602_Delay1ms(1);
        LCD1602_DATAPINS = com << 4; //發送低四位
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;         //寫入時序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 數 名         : LcdWriteData
* 函數功能                   : 向LCD寫入一個字節的數據
* 輸    入         : dat
* 輸    出         : 無
*******************************************************************************/                  
#ifndef         LCD1602_4PINS                  
void LcdWriteData(uchar dat)                        //寫入數據
{
        LCD1602_E = 0;        //使能清零
        LCD1602_RS = 1;        //選擇輸入數據
        LCD1602_RW = 0;        //選擇寫入

        LCD1602_DATAPINS = dat; //寫入數據
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;   //寫入時序
        Lcd1602_Delay1ms(5);   //保持時間
        LCD1602_E = 0;
}
#else
void LcdWriteData(uchar dat)                        //寫入數據
{
        LCD1602_E = 0;          //使能清零
        LCD1602_RS = 1;          //選擇寫入數據
        LCD1602_RW = 0;          //選擇寫入

        LCD1602_DATAPINS = dat;        //由于4位的接線是接到P0口的高四位,所以傳送高四位不用改
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;          //寫入時序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;

        LCD1602_DATAPINS = dat << 4; //寫入低四位
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;          //寫入時序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 數 名       : LcdInit()
* 函數功能                 : 初始化LCD屏
* 輸    入       : 無
* 輸    出       : 無
*******************************************************************************/                  
#ifndef                LCD1602_4PINS
void LcdInit()                                                  //LCD初始化子程序
{
        LcdWriteCom(0x38);  //開顯示
        LcdWriteCom(0x0c);  //開顯示不顯示光標
        LcdWriteCom(0x06);  //寫一個指針加1
        LcdWriteCom(0x01);  //清屏
        LcdWriteCom(0x80);  //設置數據指針起點
}
#else
void LcdInit()                                                  //LCD初始化子程序
{
        LcdWriteCom(0x32);         //將8位總線轉為4位總線
        LcdWriteCom(0x28);         //在四位線下的初始化
        LcdWriteCom(0x0c);  //開顯示不顯示光標
        LcdWriteCom(0x06);  //寫一個指針加1
        LcdWriteCom(0x01);  //清屏
        LcdWriteCom(0x80);  //設置數據指針起點
}
#endif



/*********************LCD.C******結束*******************************/


#ifndef __LCD_H_
#define __LCD_H_
/**********************************
當使用的是4位數據傳輸的時候定義,
使用8位取消這個定義
**********************************/
//#define LCD1602_4PINS

/**********************************
包含頭文件
**********************************/
#include<reg51.h>

//---重定義關鍵詞---//
#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint
#define uint unsigned int
#endif

/**********************************
PIN口定義
**********************************/
#define LCD1602_DATAPINS P0
sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;

/**********************************
函數聲明
**********************************/
/*在51單片機12MHZ時鐘下的延時函數*/
void Lcd1602_Delay1ms(uint c);   //誤差 0us
/*LCD1602寫入8位命令子函數*/
void LcdWriteCom(uchar com);
/*LCD1602寫入8位數據子函數*/       
void LcdWriteData(uchar dat)        ;
/*LCD1602初始化子程序*/               
void LcdInit();                                                  

#endif



/*********************LCD.h******結束*******************************/

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:705277 發表于 2020-3-15 09:34 | 只看該作者
樓主,可以互相留個聯系方式嗎?我最近也在做這個,我是純小白  陷入了困境。
回復

使用道具 舉報

板凳
ID:214276 發表于 2020-3-16 01:12 | 只看該作者
幻想就youth 發表于 2020-3-15 09:34
樓主,可以互相留個聯系方式嗎?我最近也在做這個,我是純小白  陷入了困境。

我自己現在編個定時程序都搞不定,小白的很,你有什么問題估計我也幫不上什么忙呀。
回復

使用道具 舉報

地板
ID:975054 發表于 2021-11-21 22:30 | 只看該作者
剛搞清楚,我用的是STC8 硬件I2C+BMP280方案,暫時只需要氣壓讀數。不知道你們具體用的什么MCU? 軟硬件I2C又不同,具體細節太多。。。。

testBMP280ID:
bmp280 id is right...
0101 1000
temp                    press
0000 0000 0000 0001 1000 1011 1000 1111
回復

使用道具 舉報

5#
ID:975054 發表于 2021-11-21 22:36 | 只看該作者
不喜歡用【Arduino】了,那么多驅動模塊搭積木。喜歡直接在最簡小核心板上試驗
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美色a v | 人妖无码 | 亚洲一区欧美一区 | 国产一区二区影院 | 亚洲成av | 国产一区二| 成人性生交大片免费看中文带字幕 | 国产一区二区麻豆 | 国产精品视频一区二区三区 | 91久久精 | 国产一区二区久久 | 久草视频在 | www九色 | 成人国产一区二区三区精品麻豆 | 国内精品久久久久 | 7777奇米影视| 国产精品美女久久久久久久网站 | 国产精品久久免费观看 | 一区二区三区 在线 | 超碰精品在线 | 久久毛片 | 国产69精品久久99不卡免费版 | 久久久国产精品入口麻豆 | 日韩中文在线视频 | 国产在线观| 欧美成人精品一区二区男人看 | 一区二区三区欧美 | 夜夜爽99久久国产综合精品女不卡 | va在线| 国产一区二区三区在线视频 | 欧美a在线| 一级看片免费视频囗交动图 | 午夜爱爱毛片xxxx视频免费看 | 国产视频久久久 | 精产国产伦理一二三区 | 国产午夜精品一区二区三区嫩草 | 成人免费看黄 | 久草在线影 | 一区二区三区小视频 | 国内激情av片 | 色婷婷综合久久久中字幕精品久久 |