“MPX4115型压力传感器+PCF8591型AD+模拟IIC总线”的Proteus仿真

Kersen ·
更新时间:2024-11-10
· 884 次阅读

一、MPX4115型压力传感器介绍

1.1 引脚说明

即:1引脚为模拟量输出,2引脚接地,三引脚接电源,4、5、6引脚空

 

1.2 输出特性图

选择典型曲线,我们可以得知转换公式:压力值=(电压值/5.1+0.095)/0.009。

 

二、模拟IIC总线

因为本例子采用的为51单片机,因此需要自己模拟IIC总线协议。

2.1 IIC总线工作时序如下

 

2.2 根据上图所示IIC总线工作协议进行IIC工作模拟

2.2.1 IIC总线启动

void I2c_start() { sda=1; scl=1; Delay1(DELAY_TIME); sda=0; Delay1(DELAY_TIME); scl=0; }

2.2.2 IIC发送一个字节

void I2c_sendbyte(uchar byt) { uchar i; for(i=0;i<8;i++) { scl=0; Delay1(DELAY_TIME); if(byt&0x80) { sda=1; } else { sda=0; } Delay1(DELAY_TIME); scl=1; byt <<= 1; Delay1(DELAY_TIME); } scl=0; }

2.2.3 IIC等待响应

uchar I2c_waitack() { uchar ackbit; sda=1;//释放数据线 Delay1(DELAY_TIME); scl=1; Delay1(DELAY_TIME); ackbit=sda;//获取响应信号,低电平为有效 scl=0; Delay1(DELAY_TIME); return sda; }

2.2.4 IIC接收一个字节

uchar I2c_receivebyte() { uchar da; uchar i; for(i=0;i<8;i++) { scl=1; Delay1(DELAY_TIME); da<<=1; if(sda) { da|=0x01; } scl=0; Delay1(DELAY_TIME); } return da; }

2.2.5 IIC发送响应

void I2c_sendack(uchar ackbit) { scl=0; sda=ackbit; //0:发送应答信号;1:发送非应答信号 Delay1(DELAY_TIME); scl=1; Delay1(DELAY_TIME); scl=0; sda=1; Delay1(DELAY_TIME); }

2.2.6 IIC总线结束

void I2c_stop() { sda=0; scl=1; Delay1(DELAY_TIME); sda=1; Delay1(DELAY_TIME); }

 

三、PCF8591型AD介绍

3.1 介绍

PCF8591 是单电源,低功耗8 位CMOS 数据采集器件,具有4 个模拟输入、一个输出和一个串行I2C 总线接口。3 个地址引脚A0、A1 和A2 用于编程硬件地址,允许将最多8 个器件连接至I2C总线而不需要额外硬件。PCF8591由于其使用的简单方便和集成度高,在单片机应用系统中得到了广泛的应用。

 

3.2 引脚说明

 

3.3 器件地址说明

每一个IIC器件都有一个器件地址,来区分不同的IIC设备,下面是PCF8591的地址格式

在本例子中,我将A0、A1、A2全部接地,因此写地址为0x90,读地址为0x91。

 

3.4 控制字说明

在该例子中我们进行的是AD转换,因此第6位为0,不允许模拟电压输出;采用单端输入,因此第5、4位为0、0;该例子中只进行一个模拟输入量的AD转换,因此关闭自动增量使能,即第2位为0;模拟输入通道选择AIN3,因此第1位与第0位为1、1。因此,控制字为0x30。

 

3.5 输出特性曲线

在该例子中,我们让Vagnd=0V,Vref=5V。因此可得转换公式为:电压值=(5.0/256.0)*AD模块的读数。

 

四、Proteus仿真电路

五、完整例程(例程均为自己编写且在仿真中测试通过)

使用单片机为AT89C52,工作频率为12MHz

#include #include typedef unsigned char uchar; typedef unsigned int uint; #define DELAY_TIME 5 sbit scl = P2^0;//时钟总线接口 sbit sda = P2^1;//数据总线接口 sbit w2=P2^2;//位选2 sbit w3=P2^3;//位选3 sbit w4=P2^4;//位选4 void I2c_start(void);//IIC总线启动条件 void I2c_stop(void);//IIC总线结束条件 void I2c_sendbyte(uchar byt);//IIC总线发送一个字节 uchar I2c_receivebyte(void);//IIC总线接收一个字节 void I2c_sendack(uchar ackbit);//IIC总线发送应答 void Delay1(uchar t);//读写操作中的延时 void Delay2(uchar t);//等待初始化子函数 void Init_pcf8591(void);//PCF8951初始化 uchar I2c_waitack(void);//IIC等待回应子函数 uchar Read_value(void);//读取AD值 void Show(uchar Out);//显示压力值 void main() { uchar G_value;//AD值 float V_value,P_value;//电压值,压力值 uchar Out;//对压力值进行四舍五入后的输出值 Read_value(); G_value=Read_value(); V_value=(5.0/256.0)*G_value; P_value=(V_value/5.1+0.095)/0.009; Out=P_value;//进行四舍五入 if(P_value-Out>=0.5) { Out+=1; } Show(Out); } /****************************读取AD值******************************************/ uchar Read_value(void) { uchar result; Init_pcf8591(); I2c_start(); I2c_sendbyte(0x91);//进行读操作(A0、A1、A2均接地) I2c_waitack(); result=I2c_receivebyte(); I2c_sendack(1); I2c_stop(); return result; } /**********************PCF8591初始化函数*************************************/ void Init_pcf8591(void) { I2c_start(); I2c_sendbyte(0x90);//进行写操作(A0、A1、A2均接地) I2c_waitack(); I2c_sendbyte(0x03); //选择通道AIN3进行转化 I2c_waitack(); I2c_stop(); Delay2(10); } /**********************IIC总线启动*************************************/ void I2c_start() { sda=1; scl=1; Delay1(DELAY_TIME); sda=0; Delay1(DELAY_TIME); scl=0; } /********************IIC发送一个字节***********************************/ void I2c_sendbyte(uchar byt) { uchar i; for(i=0;i<8;i++) { scl=0; Delay1(DELAY_TIME); if(byt&0x80) { sda=1; } else { sda=0; } Delay1(DELAY_TIME); scl=1; byt <<= 1; Delay1(DELAY_TIME); } scl=0; } /********************IIC等待回应***********************************/ uchar I2c_waitack() { uchar ackbit; sda=1;//释放数据线 Delay1(DELAY_TIME); scl=1; Delay1(DELAY_TIME); ackbit=sda;//获取响应信号,低电平为有效 scl=0; Delay1(DELAY_TIME); return sda; } /********************IIC接收一个字节******************************/ uchar I2c_receivebyte() { uchar da; uchar i; for(i=0;i<8;i++) { scl=1; Delay1(DELAY_TIME); da<<=1; if(sda) { da|=0x01; } scl=0; Delay1(DELAY_TIME); } return da; } /********************IIC发送回应***********************************/ void I2c_sendack(uchar ackbit) { scl=0; sda=ackbit; //0:发送应答信号;1:发送非应答信号 Delay1(DELAY_TIME); scl=1; Delay1(DELAY_TIME); scl=0; sda=1; Delay1(DELAY_TIME); } /**********************IIC总线结束*************************************/ void I2c_stop() { sda=0; scl=1; Delay1(DELAY_TIME); sda=1; Delay1(DELAY_TIME); } /**********************IIC中延时函数*************************************/ void Delay1(uchar t) { do { _nop_(); } while(t--); } /**************************等待初始化延时***************************************/ void Delay2(uchar t) { unsigned char i; while(t--) { for(i=0; i<112; i++); } } /**********************显示函数*************************************/ void Show(uchar Out) { char code duan[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//段码 while(1) { w4=0;//显示第百位 w3=0; w2=1; Delay2(5); P1=duan[(Out/100)%10]; Delay2(15); P1=0xff; w4=0;//显示第十位 w3=1; w2=0; Delay2(5); P1=duan[(Out/10)%10]; Delay2(15); P1=0xff; w4=1;//显示第个位 w3=0; w2=0; Delay2(5); P1=duan[Out%10]; Delay2(15); P1=0xff; } }

 

 

左肩理想,右肩担当。君子不怨永远不会停下脚步!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


作者:君子不怨



iic 压力 proteus pcf8591 传感器

需要 登录 后方可回复, 如果你还没有账号请 注册新账号