资料编号:149
视频讲解:
149-基于stm32单片机BMP180气压计海拔高度温度测量Proteus仿真(源码+仿真+全套资料)
本设计:
基于STM32的BMP180气压传感器(仿真+程序)
Proteus仿真版本:proteus 8.9
程序编译器:keil 5
编程语言:C语言
设计说明:
通过STM32读取BMP180输出的数据通过串口及LCD显示屏,将高度,温度大气压强信息显示出来。
stm32单片机最小系统讲解:
电源
电就是MCU要吃的饭,不吃饭,stm32芯片肯定不能工作。
stm32最小系统板需要5v和3.3v两种电压,一般可以直接通过USB提供5v电压,也可以用电源适配器提供5V电压。而3.3v电压可以通过稳压芯片如ASM1117-3.3v等,把5v电压降为3.3v输出。
参考电源电路如下:
图中J1是USB接口,提供的5v电压经过ASM1117-3.3v后降为3v3,C1,C2(10*10^4pF=0.1u)用于电源滤波,高频滤波用小电容,低频滤波用大电容。D3是一个led用以指示电源工况,其上的R1 510R即510.0Ω用以限流,防止led灯烧坏。
J3也是一个USB接口,提供5v电压,同时它也是一个模拟串口,其D-和D+引脚与ch340相应引脚连接构成一个串口设备。
stm32吃的是3v3将其VDD和VSS引脚分别连接到3v3和GND,就解决了stm32的吃饭问题。
注意:VBAT是stm32芯片的备用3.3v电源输入端,当没有备用电源是也需要将VBAT接到VDD上去。
VDDA和VSSA是模拟电源输入口,用以给stm32芯片内部ADC,复位电路供电因此必须分别接到VDD和VSS上。
复位电路
人工作久了容易自闭、精神恍惚,这时需要睡一觉就以重新焕发活力。stm32工作久了也容易“精神恍惚”————程序跑飞,也需要复位。
stm32的NRST引脚是复位信号接收引脚与RESET相连,芯片低电平复位。如上图所示,当芯片刚上电时,电容充电导通,此时RESET=0,芯片复位;当按下复位按钮时,RESET接地,芯片复位。
晶振电路
晶振是芯片的心跳,每一次脉冲激励芯片执行一条指令,因此晶振的重要性不言而喻。
上图是stm32的晶振电路,8M无源晶振,其中R9(1M)用于稳定晶振的脉冲波形,C8(20P)和C9(20P)一方面构成晶振起振的必要回路,另一方面匹配电容,同时还具有调节晶振电路频率的作用。
注意:OSC32IN是外部32.768K晶振输入口,可以直接接时钟信号,也可以不洁作IO用。OSCIN是外部系统时钟输入信号,可以接时钟信号,也可以不接做IO口用,此时stm32用芯片内部的RC电路起振产生时钟信号。
BMP180气压传感器部分源码展示:
//读出BMP085内部数据,连续两个
//*********************************************************
u16 Multiple_read(u8 ST_Address)
{
u8 msb, lsb;
u16 _data;
i2c_Start(); //起始信号
i2c_SendByte(BMP180_SlaveAddress); //发送设备地址+写信号
while(i2c_WaitAck());
i2c_SendByte(ST_Address); //发送存储单元地址
while(i2c_WaitAck());
i2c_Start(); //起始信号
i2c_SendByte(BMP180_SlaveAddress+1); //发送设备地址+读信号
while(i2c_WaitAck());
msb = i2c_ReadByte(); //BUF[0]存储
lsb = i2c_ReadByte(); //最后一个数据需要回NOACK
i2c_Stop(); //停止信号
HAL_Delay(5);
_data = msb << 8;
_data |= lsb;
return _data;
}
//********************************************************************
u16 bmp180ReadTemp(void)
{
i2c_Start(); //起始信号
i2c_SendByte(BMP180_SlaveAddress); //发送设备地址+写信号 BMP180_SlaveAddress 0xee 气压传感器器件地址
while(i2c_WaitAck());
i2c_SendByte(0xF4); // write register address
while(i2c_WaitAck());
i2c_SendByte(0x2E); // write register data for temp
while(i2c_WaitAck());
i2c_Stop(); //发送停止信号
HAL_Delay(10); // max time is 4.5ms
return Multiple_read(0xF6);
}
//*************************************************************
u16 bmp180ReadPressure(void)
{
//u16 pressure = 0;
i2c_Start(); //起始信号
i2c_SendByte(BMP180_SlaveAddress); //发送设备地址+写信号
while(i2c_WaitAck());
i2c_SendByte(0xF4); // write register address
while(i2c_WaitAck());
i2c_SendByte(0x34); // write register data for pressure
while(i2c_WaitAck());
i2c_Stop(); //发送停止信号
HAL_Delay(20); // max time is 4.5ms
//pressure = Multiple_read(0xF6);
//pressure &= 0x0FFFF;
return Multiple_read(0xF6);//pressure;
}
//**************************************************************
//初始化BMP085,根据需要请参考pdf进行修改**************
void Init_BMP180()
{
ac1 = Multiple_read(0xAA);
// printf("ac1 %d \r\n",ac1);
ac2 = Multiple_read(0xAC);
// printf("ac2 %d \r\n",ac2);
ac3 = Multiple_read(0xAE);
// printf("ac3 %d \r\n",ac3);
ac4 = Multiple_read(0xB0);
// printf("ac4 %d \r\n",ac4);
ac5 = Multiple_read(0xB2);
// printf("ac5 %d \r\n",ac5);
ac6 = Multiple_read(0xB4);
// printf("ac6 %d \r\n",ac6);
b1 = Multiple_read(0xB6);
// printf("b1 %d \r\n",b1);
b2 = Multiple_read(0xB8);
// printf("b2 %d \r\n",b2);
mb = Multiple_read(0xBA);
// printf("mb %d \r\n",mb);
mc = Multiple_read(0xBC);
// printf("mc %d \r\n",mc);
md = Multiple_read(0xBE);
// printf("md %d \r\n",md);
}
//***********************************************************************
void bmp180Convert()
{
unsigned int ut;
unsigned long up;
long x1, x2, b5, b6, x3, b3, p;
unsigned long b4, b7;
ut = bmp180ReadTemp(); // 读取温度
up = bmp180ReadPressure(); // 读取压强 return pressure;
//*************
x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
x2 = ((long) mc << 11) / (x1 + md);
b5 = x1 + x2;
result_UT = ((b5 + 8) >> 4);
//*************
b6 = b5 - 4000;
// Calculate B3
x1 = (b2 * (b6 * b6)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = x1 + x2;
b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
// Calculate B4
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<<1)/b4;
else
p = (b7/b4)<<1;
x1 = (p>>8) * (p>>8);
x1 = (x1 * 3038)>>16;
x2 = (-7357 * p)>>16;
result_UP = p+((x1 + x2 + 3791)>>4);
}
/****************************************************************
函数名称:BMP085_Get_Altitude
函数功能:获取海拔高度值
入口参数:无
出口参数:altitude //int型 2字节,当前海拔高度值
备 注: 返回的高度值单位为厘米,调用时再换算成带小数的以米为单位的高度值
*****************************************************************/
/*
double BMP085_Get_Altitude()
{
double altitude;
//pressure=(float)pressure; //获取气压值
altitude=44330.0*(1-pow((double)pressure/101325,1/5.255)); //根据芯片手册提供的公式计算海拔高度
//altitude*=100; //转换成厘米单位的高度值,调用时再换算成带小数的高度值,提高精度
return altitude;
}
*/
资料下载链接https://pan.baidu.com/s/11PU1GXJmi9wNtdiFQG0iwQ?pwd=g1aa