微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 新人求助,求基于单片机控制的数字气压计程序

新人求助,求基于单片机控制的数字气压计程序

时间:10-02 整理:3721RD 点击:

在网上找到了段程序,但是有点问题,缺少key的头文件,求大神帮忙,谢谢!


课题是基于单片机控制的数字气压计,单片机是STC80C52或AT89S52,传感器BMP085,显示器LCD1602

要求:1.LCD显示当前气压和气压报警值,超过报警值,蜂鸣器响,LED灯亮

      2.按下S1,恢复初始报警值,按下S2进入报警值设置,按下S3设置报警值+1.按下S 4设置报警值-1,再按下S2,退出报警值设置,LED正常显示

参考程序:

#include  <REG51.H>        

#include  <math.h>    //Keil library  

#include  <stdlib.h>  //Keil library  

#include  <stdio.h>   //Keil library   

#include  <INTRINS.H>//Keil library

#include <key.h>

#define   uchar unsigned char

#define   uint unsigned int   

#define   DataPort P0    //LCD1602数据端口

sbit   SCL=P3^6;     //IIC时钟引脚定义

sbit         SDA=P3^7;     //IIC数据引脚定义

sbit      LCM_RS=P2^5;   //LCD1602命令端口        

sbit      LCM_RW=P2^6;   //LCD1602命令端口              

sbit      LCM_EN=P2^7;   //LCD1602命令端口

sbit BEEP=P3^4;    //定义蜂鸣器

#define  BMP085_SlaveAddress   0xee       //定义器件在IIC总线中的从地址                              

#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;                              //变量

bit beep_st;     //蜂鸣器间隔标志

uchar x=0;      //计数器

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(ucharSlaveAddress,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 InitTimer(void)

{

TMOD=0x1;

TH0=0x4c;

TL0=0x00;     //50ms(晶振11.0592M)

EA=1;      //全局中断开关

TR0=1;

ET0=1;      //开启定时器0

}

/*****定时器0中断服务程序*****/

void timer0(void) interrupt 1

{

TH0=0x4c;

TL0=0x00;

x++;

}

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++)                     

{;}}                                    

}

unsigned char rolmove(unsigned char m)

{

  

  unsigned char   a,b,c,d,e,f,g,h;               

a=(m&0x01)<<7;

b=(m&0x02)<<5;

c=(m&0x04)<<3;

d=(m&0x08)<<1;

e=(m&0x10)>>1;

f=(m&0x20)>>3;

g=(m&0x40)>>5;

h=(m&0x80)>>7;

m=a|b|c|d|e|f|g|h;

return m;

}

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

void WaitForEnable(void)

{                                 

DataPort=0xff;           

LCM_RS=0;LCM_RW=1;_nop_();

LCM_EN=1;_nop_();_nop_();

while(rolmove(DataPort)&0x80);   

LCM_EN=0;                       

}                                 

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

void WriteCommandLCM(uchar CMD,uchar Attribc)

{                                 

if(Attribc)WaitForEnable();      

LCM_RS=0;LCM_RW=0;_nop_();

DataPort=rolmove(CMD);_nop_();

LCM_EN=1;_nop_();_nop_();LCM_EN=0;

}                                 

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

void WriteDataLCM(uchar dataW)

{                                 

WaitForEnable();        

LCM_RS=1;LCM_RW=0;_nop_();

DataPort=rolmove(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);           

}                                         

void Delay5us()

{

   _nop_();_nop_();_nop_();_nop_();

   _nop_();_nop_();_nop_();_nop_();

       _nop_();_nop_();_nop_();_nop_();

       _nop_();_nop_();_nop_();_nop_();

}

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();                 //延时

}

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内部数据,连续两个

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

    BMP085_Stop();                   //发送停止信号

       delay(10);     // max time is 4.5ms

      

       return (long)Multiple_read(0xF6);

}

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

    BMP085_Stop();                    //发送停止信号

       delay(10);                          // max time is 4.5ms

      

       pressure =Multiple_read(0xF6);

       pressure &= 0x0000FFFF;

      

       return pressure;  

       //return (long)bmp085ReadShort(0xF6);

}

//初始化BMP085

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(shangxian);//显示报警值

        DisplayOneChar(4,1,'V');      

     DisplayOneChar(5,1,':');

        DisplayOneChar(6,1,shiwan);

        DisplayOneChar(7,1,wan);   

     DisplayOneChar(8,1,qian);

     DisplayOneChar(9,1,'.');

     DisplayOneChar(10,1,bai);

     DisplayOneChar(11,1,shi);

        DisplayOneChar(12,1,'K');   //气压单位

        DisplayOneChar(13,1,'p');

        DisplayOneChar(14,1,'a');

       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);

if(x>=2){beep_st=~beep_st;x=0;}

if(pressure>shangxian&&beep_st==1)BEEP=1;

else BEEP=0;

        conversion(pressure);

    DisplayOneChar(4,0,'P');    //显示压强

     DisplayOneChar(5,0,':');

        DisplayOneChar(6,0,shiwan);

        DisplayOneChar(7,0,wan);   

     DisplayOneChar(8,0,qian);

     DisplayOneChar(9,0,'.');

     DisplayOneChar(10,0,bai);

     DisplayOneChar(11,0,shi);

        DisplayOneChar(12,0,'K');   //气压单位

        DisplayOneChar(13,0,'p');

        DisplayOneChar(14,0,'a');

}

//******主程序********

void main()

{

    delay(50);                       //上电延时            

    InitLcd();                     //液晶初始化

    Init_BMP085();                //初始化BMP085

BEEP=0;

InitTimer();    //初始化定时器

  while(1)                         //循环

  {

    bmp085Convert();

       delay(1000);

checkkey();

if(set_st==0) WriteCommandLCM(0x0c,1);

if(set_st==1)

{

WriteCommandLCM(0xcb,1);

WriteCommandLCM(0x0d,1);

       Delay1(150);

}

  }

}



我做过,我是做毕业设计的。加我QQ1552985179

这个很简单 我可以帮你搞定 加Q1925276216详谈

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top