基于C51单片机的BMP180驱动程序

BMP180是一款气压传感器,直接以数字量的形式表达出气压值,接口是IIC,可以直接挂载在单片机上使用,现在我们使用C51单片机来挂载BMP180进行气压测量

电路连接

LCD1602:

数据端口>>>P2

RS>>>P1.2

RW>>>P1.1

EN>>>P1.3

BMP180:

SCL>>>P3.6

SDA>>>P3.7

 

BMP180的电源是1.8-3.6V,电压过高有可能烧坏传感器,在接5V单片机是需要注意降压使用。

由于单片机IO口电平5V,如果使用IIC推荐的4.7K上拉电阻,传感器会由于电压过高出现数据错误,读取到的气压值出现乱码,解决方法是去掉IIC上的上拉电阻。

显示效果如下

程序如下


#include  <REG52.H>	  
#include  <math.h> 
#include  <stdlib.h>  
#include  <stdio.h>   
#include  <INTRINS.H> 

#include "1602.h"



#define   uchar unsigned char
#define   uint unsigned int	
#define   DataPort P2    
sbit	  SCL=P3^6;      
sbit 	  SDA=P3^7;      
sbit      LCM_RS=P1^2;   	
sbit      LCM_RW=P1^1;   
sbit      LCM_EN=P1^3;   

#define	BMP085_SlaveAddress   0xee	                              

#define OSS 0	
							   
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();                           

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(0x0e,1);	
WriteCommandLCM(0x3c,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;
}

void BMP085_SendByte(BYTE dat)
{
    BYTE i;

    for (i=0; i<8; i++)        
    {
        dat <<= 1;             
        SDA = CY;              
        SCL = 1;               
        Delay5us();            
        SCL = 0;               
        Delay5us();            
    }
    BMP085_RecvACK();
}

BYTE BMP085_RecvByte()
{
    BYTE i;
    BYTE dat = 0;

    SDA = 1;                   
    for (i=0; i<8; i++)        
    {
        dat <<= 1;
        SCL = 1;               
        Delay5us();            
        dat |= SDA;            
        SCL = 0;               
        Delay5us();            
    }
    return dat;
}
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();                 
    BMP085_SendACK(0);                       
    lsb = BMP085_RecvByte();     
	BMP085_SendACK(1);                    

    BMP085_Stop();                           
    Delay5ms();
    _data = msb << 8;
	_data |= lsb;	
	return _data;
}
long bmp085ReadTemp(void)
{

    BMP085_Start();                
    BMP085_SendByte(BMP085_SlaveAddress); 
    BMP085_SendByte(0xF4);	     
    BMP085_SendByte(0x2E);      
    BMP085_Stop();                 
	delay(10);
	
	return (long) Multiple_read(0xF6);
}
long bmp085ReadPressure(void)
{
	long pressure = 0;

    BMP085_Start();                
    BMP085_SendByte(BMP085_SlaveAddress); 
    BMP085_SendByte(0xF4);	    
    BMP085_SendByte(0x34);    
    BMP085_Stop();            
	delay(10);    	          
	
	pressure = Multiple_read(0xF6);
	pressure &= 0x0000FFFF;
	
	return pressure;	
}
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);
	 play(4,0,'T');      
	 play(5,0,':'); 
	 play(7,0,bai);       
	 play(8,0,shi); 
	 play(9,0,'.'); 
	 play(10,0,ge); 
	 play(11,0,0XDF);    
	 play(12,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);
	 play(4,1,'P');   
	 play(5,1,':'); 
	 play(6,1,shiwan); 
	 play(7,1,wan);    
	 play(8,1,qian); 
	 play(9,1,'.'); 
	 play(10,1,bai); 
	 play(11,1,shi); 
		play(12,1,ge); 
	 play(13,1,'K');  
	 play(14,1,'p'); 
	 play(15,1,'a'); 

}

void main()
{ 
    delay(50);	              
  init_lcd();  
//	InitLcd();               
    Init_BMP085();          
  while(1)              
  { 
		
    bmp085Convert();
	delay(1000); 
  }
} 

 

LCD1602的驱动程序如下

#include "1602.h"
/*
LCD1602使用延时函数
*/
void delay_lcd(uint x)
{
	uint i;
	for(i=0;i<x;i++);
}
/*
给显示屏发送控制码
*/
void sentcode(uchar cod)
{
	show=cod;
	lcdrs=0;
	lcde=1;
	delay_lcd(10);
	lcde=0;
	delay_lcd(10);
}
/*
给显示屏发送显示数据
*/
void sentdata(uchar dat)
{
	show=dat;
	lcdrs=1;
	lcde=1;
	delay_lcd(10);
	lcde=0;
	delay_lcd(10);
}			 
/*
显示屏初始化,只定不读
*/
void init_lcd(void)
{
  lcdrw=0;
	sentcode(0x0e);
	sentcode(0x3c);
	sentcode(0x01);
  delay_lcd(100);
  
}
/*
在a行b列显示一个字符
*/
void play(uchar a,uchar b,uchar dat)
{
	uchar dress;
	if(b)
	dress=0xc0+a;
	else
	dress=0x80+a;
	sentcode(dress);
	sentdata(dat);
}
/*
在x行y列开始显示字符串
字符串指针*p
speed:显示每一个字符后停留的时间
delay:显示完一屏后停留的时间
clear:显示完一屏后是否进行清屏操作,0为不清屏,其余为清屏
*/
void ShowStr(uchar x , uchar y , char *p , uint speed , uint delay , uchar clear)
{
  uchar dress;
  while(*p!='\0')
  {
    if(y)
    {
      dress = 0xc0+x;
      sentcode(dress);
      sentdata(*p);
      p++;
      x++;
      if((dress-0xc0)>14)
      {
        dress = 0x80+x;
        y=0;
        x=0;
        delay_lcd(delay);
        if(clear)
        {
          sentcode(LCD_CLEAR_SCREEN);
        }
      }
      
    }
    else
    {
      dress = 0x80+x;
      sentcode(dress);
      sentdata(*p);
      p++;
      x++;
      if((dress-0x80)>14)
      {
        dress = 0x80+x;
        y=1;
        x=0;
      }
    }
    delay_lcd(speed);
  }
}
/*
清屏操作
*/
void lcd_clear(void)
{
  sentcode(LCD_CLEAR_SCREEN);
//  sentcode(LCD_HOMING);
}

 

LCD1602的头文件如下

#ifndef __1602_h__
#define __1602_h__

#include "reg52.h"

#define uchar unsigned char
#define uint unsigned int
  
#define show P2//显示数据总线
sbit lcdrs=P1^2;//控制/数据指示
sbit lcdrw=P1^1;//读/写指示
sbit lcde=P1^3;//使能


#define LCD_CLEAR_SCREEN	0x01      // 清屏
#define LCD_HOMING  		0x02      // 光标返回原点

void delay_lcd(uint x);
void sentcode(uchar cod);
void sentdata(uchar dat);
void init_lcd(void);
void play(uchar a,uchar b,uchar dat);
void ShowStr(uchar x , uchar y , char *p , uint speed , uint delay , uchar clear);
void lcd_clear(void);




#endif

 

  • 8
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
MCU C51单片机是一种常用的微控制器,用于控制各种电子设备。在小车驱动程序中,我们可以使用C语言编写代码来实现各种功能。 首先,我们需要设置IO口的输入和输出,以便与电机连线。我们可以通过设置端口的高低电平来控制电机的转向和速度。比如,我们可以使用P0口来控制左右电机的转向,P1口来控制左右电机的PWM信号。 接下来,我们可以编写函数来控制小车的运动。例如,我们可以编写一个函数来控制小车前进,将左右电机的引脚设置为正向旋转,并且给予PWM信号来控制速度。另外,我们还可以编写函数来控制小车后退、左转、右转等动作。 除了基本的运动控制外,我们还可以为小车添加传感器和避障功能。例如,我们可以添加红外避障传感器,当检测到障碍物时,自动停止或改变方向。我们还可以添加超声波传感器,用于检测前方距离,避免与前方障碍物碰撞。 在编写小车驱动程序时,我们需要考虑定时器的使用。通过设置定时器,我们可以定时中断程序,以达到控制小车运动的目的。例如,我们可以使用定时器来控制小车的前进时间和速度,达到精确控制的效果。 总之,MCU C51单片机可以用于控制小车驱动程序。通过编写适当的代码,我们可以实现小车的各种运动功能,并且可以根据需要添加传感器和避障功能,提高小车的智能性和安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值