MPX4115学习笔记
MPX4115是一款常用的压力传感器件,它长这样:
管脚说明
1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|
V o u t V_{out} Vout | G N D GND GND | V c c V_{cc} Vcc | N / S N/S N/S | N / S N/S N/S | N / S N/S N/S |
管脚1输出测量压力得到的电压,管脚2接地,管脚3常接5V工作电压,管脚4、5、6可以悬空
输出电压与压力的关系
如下图所示,横坐标为压力(单位kPa),纵坐标电压值(V),Vs指工作电压
- 压力测量范围为 15 − 115 k P a 15-115kPa 15−115kPa,工作温度 0 − 85 C ∘ 0-85C^{\circ} 0−85C∘
- 在测量范围内,压力与输出电压大致呈线性关系
- V o u t 、 V s V_{out}、V_{s} Vout、Vs、 P 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 Vout=Vs×(0.009P−0.095)±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
*/
- 代码的做到了低耦合,分块化做得很好,这个程序中的子程序可以保存起来随时使用
- 线性区间标度变换公式: 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的修正值即可