资讯详情

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

一、MPX介绍4115型压传感器

1.1 引脚说明

也就是说,为模拟输出,2引脚接地,3引脚接地,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、A所有接地,所以写地址为0x90,读地址为0x91。

3.4控制字说明

我们在这个例子中做的是AD转换,所以第6位为0,不允许模拟电压输出;单端输入,所以第5、4位为0、0;在这个例子中,只有一个模拟输入AD因此,关闭自动增量使能,即第二位为0;选择模拟输入通道AIN因此,第一和第0是1,1。因此,控制字为0x30。

3.5 输出特性曲线

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

四、Proteus仿真电路

5.完整的例程(例程是自己编写的,在模拟中测试通过)

< style="text-indent:0;">使用单片机为AT89C52,工作频率为12MHz

#include<reg52.h>
#include<intrins.h>

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;
		

	}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

标签: w4g传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台