气压传感器MPX4115学习笔记

MPX4115学习笔记

MPX4115是一款常用的压力传感器件,它长这样:

管脚说明

1 2 3 4 5 6
V o u t V_{out} G N D GND V c c V_{cc} N / S N/S N / S N/S N / S N/S

管脚1输出测量压力得到的电压,管脚2接地,管脚3常接5V工作电压,管脚4、5、6可以悬空

输出电压与压力的关系

如下图所示,横坐标为压力(单位kPa),纵坐标电压值(V),Vs指工作电压

  1. 压力测量范围为 15 115 k P a 15-115kPa ,工作温度 0 85 C 0-85C^{\circ}
  2. 在测量范围内,压力与输出电压大致呈线性关系
  3. V o u t V s V_{out}、V_{s} P P 有定量关系 V o u t = V s × ( 0.009 P 0.095 ) ± E r r o r V_{out}=V_{s}\times(0.009P-0.095){\pm}Error

实例

参考例子如下,这个例子的电路图与我之前的那篇数字电阻表非常类似,在此基础上稍加修改即可,即使得ADC0832的输入信号为MPX4115的输出电压,而程序还需要增加一些数据转换部分。

电路图:
在这里插入图片描述

main.c

#include <reg51.h>
#include <intrins.h>
//ADC0832 引脚
sbit ADCS = P2 ^ 0;  //AD的片选 
sbit ADDI = P3 ^ 7;
sbit ADDO = P3 ^ 7;
sbit ADCLK = P3 ^ 6;  //AD的CLK 

unsigned char dispbitcode[8] = { 0xF7,0xFB,0xFD,0xFE,0xEF,0xDF,0xBF,0x7F }; //位扫描
unsigned char dispcode[11] = { 0xC0,0xF9,0xA4,0xbB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF };  //最后一个是全亮,防止出现一些问题 
//段选码 共阳极
unsigned char dispbuf[4];
unsigned int temp;
unsigned char getdata;

void delay_1ms(void)
{
	unsigned char x, y;
	x = 3;
	while (x--)
	{
		y = 40;
		while (y--);
	}
}
void display(void)
{
	char k;
	for (k = 0; k < 4; k++)
	{
		P1 = ~dispbitcode[k];
		P0 = ~dispcode[dispbuf[k]];
		if (k == 1)
			P0 = P0 + 0x80;
		delay_1ms();
	}
}

unsigned int ADC0832(unsigned char channel)  //AD转换,返回结果
{
	unsigned char i = 0;
	unsigned char j;
	unsigned int dat = 0;
	unsigned char ndat = 0;

	if (channel == 0) channel = 2;
	if (channel == 1) channel = 3;
	ADDI = 1;
	_nop_();
	_nop_();
	ADCS = 0;
	_nop_();
	_nop_();
	ADCLK = 1;
	_nop_();
	_nop_();
	ADCLK = 0;
	_nop_();
	_nop_();
	ADCLK = 1;
	ADDI = channel & 0x1;
	_nop_();
	_nop_();
	ADCLK = 0;
	_nop_();
	_nop_();
	ADCLK = 1;
	ADDI = (channel >> 1) & 0x1;
	_nop_();
	_nop_();
	ADCLK = 0;
	ADDI = 1;
	_nop_();
	_nop_();
	dat = 0;
	for (i = 0; i < 8; i++)
	{
		dat |= ADDO;
		ADCLK = 1;
		_nop_();
		_nop_();
		ADCLK = 0;
		_nop_();
		_nop_();
		dat <<= 1;
		if (i == 7) dat |= ADDO;
	}
	for (i = 0; i < 8; i++)
	{
		j = 0;
		j = j | ADDO;
		ADCLK = 1;
		_nop_();
		_nop_();
		ADCLK = 0;
		_nop_();
		_nop_();
		j = j << 7;
		ndat = ndat | j;
		if (i < 7) ndat >>= 1;
	}
	ADCS = 1;
	ADCLK = 0;
	ADDO = 1;
	dat <<= 8;
	dat |= ndat;
	return(dat);
}
void main(void)
{
	while (1)
	{
		unsigned int temp;
		float press;
		getdata = ADC0832(0);   //使用CH0 
		if (14 < getdata < 243)   //压力测量范围 
		{
			int vary = getdata;
			/*压力传感器将压力转换为电压量,AD将这个电压值进行数模转换,但是电压值并不直接意味着压力的大小
			例如5V并不意味着5kPa,因此还需要一步转换*/ 
			press = ((10.0 / 23.0)*vary) + 9.3; //press即是电压 
			temp = (int)(press * 10);
			//显示buff,一共四位 
			dispbuf[3] = temp / 1000;  //最高位 
			dispbuf[2] = (temp % 1000) / 100;
			dispbuf[1] = ((temp % 1000) % 100) / 10;
			dispbuf[0] = ((temp % 1000) % 100) % 10;  //最低位 
			display();
		}
	}
}

/*
输入  15--115kPA压力信号
         输出  00h--ffh数字信号(adc0832)
         在LCD上显示实际的压力值,如果超限则报警

线性区间标度变换公式:    y=(115-15)/(243-13)*X+9.3kpa   
*/ 
  1. 代码的做到了低耦合,分块化做得很好,这个程序中的子程序可以保存起来随时使用
  2. 线性区间标度变换公式: y=(115-15)/(243-13)*X+9.3kpa
    这个公式是怎么来的呢?
    2.1 测量115kPa时,AD转换后的数字为243
    2.2 15kPa时,AD转换后的数字为13
    2.3 又因为压力与电压有线性关系,因此两者的比例关系为 y=(115-15)/(243-13)
    再加上9.3kPa的修正值即可

参考

发布了44 篇原创文章 · 获赞 12 · 访问量 9501

猜你喜欢

转载自blog.csdn.net/qq_42138454/article/details/104614413