- 一、 压力传感器MPX4115
MPX4115 是一款常用的压力传感器型号,它可以测量压力并将其转换为电信号输出。显示屏上的 “101.1”是当前测量到的压力值,单位是kPa 。引脚用于连接外部电路,以实现信号传输和供电等功能。
引脚说明:引脚1输出测量压力得到的电压,引脚2接地,引脚3常接5V工作电压,引脚4、5、6可以悬空。
输出电压与压力的关系:

(1)压力值,电压值,指工作电压。选择典型曲线,我们可以得知转换公式:
(2)压力信号范围:15 ~115(kpa);
(3)A/D转换后传输的数据范围为13~243(243是压力值为115时所对应的A/D转换后的数据,13是压力值为15时所对应的A/D转换后的数据);
(4)线性区间变换公式:
其中,x 为A/D转换后的数据,y 为压力值,9.3 为修正值。
二、 Proteus仿真

三、Keil编程
主程序:
void main()
{
uchar adc = 0;
uint ADC;
uint temp;
float press = 0;
uchar ADC_show_1[16] = {" ADC: "};//ADC显示缓冲
uchar PRE_show_2[16] = {" Press: Kpa"};//电压显示缓冲
Init_LCD1602();//1602初始化
while(1)
{
adc = Adc0832(0);//读取adc值
if(0<adc<243)
{
ADC_show_1[7] = adc / 100 + '0'; //取adc百位
ADC_show_1[8] = adc % 100 / 10 + '0'; //取adc十位
ADC_show_1[9] = adc % 10 + '0'; //取adc个位
press = (115.0-15.0)/(243.0-13.0)*adc+9.3;//将adc值换算成压力值
temp=(int)(press*10);//取整,显示4位数
PRE_show_2[7] = temp /1000+'0' ;
PRE_show_2[8] = (temp%1000)/100+'0' ;
PRE_show_2[9] = ((temp%1000)%100)/10+'0' ;
PRE_show_2[10] = '.';
PRE_show_2[11] = temp%10+'0' ;
LCD1602_Dis_Str(0, 0, &ADC_show_1[0]); //在第一行显示ADC
LCD1602_Dis_Str(0, 1, &PRE_show_2[0]); //在第二行显示压力
}
}
}
四、 联合仿真结果

#include <reg51.h>
#include <intrins.h>
#include <stdio.h>
#define uchar unsigned char //宏定义
#define uint unsigned int //宏定义
/***************引脚定义**************/
//LM016L液晶屏的引脚
sbit rs=P2^0; //液晶数据命令选择端
sbit rw=P2^1; //液晶读写选择端
sbit en=P2^2; //液晶使能端
//ADC0832的引脚
sbit ADCS =P2^3; //ADC0832 低电平片选使能
sbit ADDI =P2^5; //ADC0832 数据信号输入
sbit ADCLK =P2^4; //ADC0832 芯片时钟输入
sbit ADDO =P2^5; //ADC0832 数据信号输出
/***************函数声明**************/
void xiemingling(uchar mingling);//写命令函数声明
void xieshuju(uchar shuju);//写数据函数声明
void delay(uint ms);//延时函数声明
/**************************************************
LCD1602 写命令
***************************************************/
void xiemingling(uchar mingling)
{
en=0;//初始状态E设置为0
//RW为读写信号,高电平时进行读操作,低电平时进行写操作
rw=0;//低电平进行写操作
//RS数据、命令选择,高电平时选择数据寄存器,低电平时选择指令寄存器
rs=0;//指令寄存器
P0=mingling;//将要写的命令送到P0口
en=1;
delay(5);//延时 5ms
en=0;
}
/***************************************************
LCD1602 写数据
***************************************************/
void xieshuju(uchar shuju)
{
en=0;
rw=0;
rs=1;//数据寄存器
P0=shuju;//将要写的数据送到P0口
en=1;
delay(5);//延时 5ms
en=0;
}
//**************延时 1毫秒*******************
void delay(uint ms) //延时 1ms
{
uint i,j;
for(i=ms;i>0;i--)
for(j=120;j>0;j--);
}
/**************************************************
在指定位置显示字符串
***************************************************/
void LCD1602_Dis_Str(uchar x, uchar y, uchar *str)
{
if(y) x |= 0x40;//将数据指针设置到第一行的起始地址(0x40)
x |= 0x80; //将数据指针设置到第二行的起始地址(0x80)
xiemingling(x);
while(*str != '\0')
{
xieshuju(*str++);
}
}
/*************************************************
LCD1602 初始化
**************************************************/
void Init_LCD1602()
{
xiemingling(0x01); //清屏指令
xiemingling(0x06); //光标向右移动
xiemingling(0x0c); //显示功能,无光标,不闪烁
xiemingling(0x38); //数据总线8位,显示两行数据
}
/*****************************************
读ADC0832函数
****************************************/
//采集并返回
unsigned int Adc0832(uchar 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;
//------第1次下降沿之前 DI 置高,启动信号---------
ADDI=1;//在第1个时钟脉冲的下沉之前 DI 端必须是高电平,表示启始信号
_nop_();//用于短暂延时,确保芯片能够正确识别控制命令结束的状态
_nop_();
ADCS=0;//拉低CS端,低电平开始A/D转换
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成第1个时钟脉冲的下沉
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
//------在第2、3个脉冲下沉之前DI端应输入2位数据用于选择通道功能---------
ADDI=channel&0x1;//按位与操作,将channel的最低位(第0位)发送到ADDI引脚,用于选择通道功能
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成第2个时钟脉冲的下沉
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
ADDI=(channel>>1)&0x1;//右移按位与操作,将channel的第1位发送到ADDI引脚,用于选择通道功能。
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成第3个时钟脉冲的下沉
//------第四个下降沿之前,DI置高,准备接收数------
ADDI=1;//控制命令结束
_nop_();
_nop_();
dat=0;//初始化变量dat,用于存储从ADC0832读取的8位数据
//------第4~11共8个下降沿读数据,从最高有效位(MSB)到最低有效位(LSB)的顺序读取------
for(i=0;i<8;i++)
{
dat|=ADDO;//ADDO读取到的数据位与dat进行按位或操作,收数据
ADCLK=1;
_nop_();
_nop_();
ADCLK=0;//形成一次时钟脉冲
_nop_();
_nop_();
dat<<=1;//将dat左移一位
if(i==7)dat|=ADDO;//即读取第 8 位数据时,再次将ADDO的值与dat进行按位或操作
}
//------第11~18共8个下降沿读数据,读取顺序是从最低有效位(LSB)到最高有效位(MSB)------
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;//拉低CS端
ADCLK=0;//拉低CLK端
ADDO=1;//拉高数据端,回到初始状态
dat<<=8;
dat|=ndat;
return(dat);
}
void main()
{
uchar adc = 0;
uint ADC;
uint temp;
float press = 0;
uchar ADC_show_1[16] = {" ADC: "};//ADC显示缓冲
uchar PRE_show_2[16] = {" Press: Kpa"};//电压显示缓冲
Init_LCD1602();//1602初始化
while(1)
{
adc = Adc0832(0);//读取adc值
if(0<adc<243)
{
ADC_show_1[7] = adc / 100 + '0'; //取adc百位
ADC_show_1[8] = adc % 100 / 10 + '0'; //取adc十位
ADC_show_1[9] = adc % 10 + '0'; //取adc个位
press = (115.0-15.0)/(243.0-13.0)*adc+9.3;//将adc值换算成压力值
temp=(int)(press*10);//取整,显示4位数
PRE_show_2[7] = temp /1000+'0' ;
PRE_show_2[8] = (temp%1000)/100+'0' ;
PRE_show_2[9] = ((temp%1000)%100)/10+'0' ;
PRE_show_2[10] = '.';
PRE_show_2[11] = temp%10+'0' ;
LCD1602_Dis_Str(0, 0, &ADC_show_1[0]); //在第一行显示ADC
LCD1602_Dis_Str(0, 1, &PRE_show_2[0]); //在第二行显示压力
}
}
}