基于PCF8591芯片的使用

8位A/D和D/A转换器
1、特性 单电源供电 
工作电压:2.5 V ~ 6 V 待机电流低 . I2C总线串行输入/输出 通过 3个硬件地址引脚编址 采样速率取决于 I2C总线速度 . 4个模拟输入可编程为单端或差分输入 自动增量通道选择 
模拟电压范围:VSS~VDD 片上跟踪与保持电路 . 8位逐次逼近式 A/D转换 
带一个模拟输出的乘法 DAC 2、应用 闭环控制系统 用于远程数据采集的低功耗转换器 电池供电设备 
在汽车、音响和 TV应用方面的模拟数据采集 3、概述 PCF8591是单片、单电源低功耗 8位 CMOS数据采集器件,具有 4个模拟输入、一个输出和一个串行 I2C总线接口。3个地址引脚 A0、A1和 A2用于编程硬件地址,允许将最多 8个器件连接至 I2C总线而不需要额外硬件。器件的地址、控制和数据通过两线双向 I2C总线传输。器件功能包括多路复用模拟输入、片上跟踪和保持功能、 8位模数转换和 8位数模拟转换。最大转换速率取决于 I2C总线的最高速率。

引脚图如下

功能描述

功能描述

地址

I2C 总线系统中的每一片 PCF8591 通过发送有效地址到该器件来激活。该地址包括固定部分和可编程部分。可编程部分必须根据地址引脚A0、A1 和A2 来设置。在I2C 总线协议中地址必须是起始条件后作为第一个字节发送。地址字节的最后一位是用于设置以后数据传输方向的读/写位

 

控制字

发送到 PCF8591 的第二个字节将被存储在控制寄存器,用于控制器件功能。 控制寄存器的高半字节用于允许模拟输出,和将模拟输入编程为单端或差分输入。低半字节选择一个由高半字节定义的模拟输入通道(见图5)。如果自动增量(auto-increment)标志置1,每次A/D 转换后通道号将自动增加。

如果自动增量(auto-increment)模式是使用内部振荡器的应用中所需要的,那么控制字中模拟输出允许标志应置1。这要求内部振荡器持续运行,因此要防止振荡器启动延时的转换错误结果。模拟输出允许标志可以在其他时候复位以减少静态功耗。

选择一个不存在的输入通道将导致分配最高可用的通道号。所以,如果自动增量(auto-increment) 被置1,下一个被选择的通道将总是通道0。两个半字节的最高有效位(即bit 7 和bit 3)是留给未来的功能,必须设置为逻辑0。控制寄存器的所有位在上电复位后被复位为逻辑0。D/A 转换器和振荡器在节能时被禁止。模拟输出被切换到高阻态。

 

图5 控制字

 

发送给PCF8591 的第三个字节被存储到DAC 数据寄存器,并使用片上D/A 转换器转换成对应的模

 

拟电压。这个D/A 转换器由连接至外部参考电压的具有256 个接头的电阻分压电路和选择开关组成。接头译码器切换一个接头至DAC 输出线。

 

模拟输出电压由自动清零单位增益放大器缓冲。这个缓冲放大器可通过设置控制寄存器的模拟输出允许标志来开户或关闭。在激活状态,输出电压将保持到新的数据字节被发送。

片上D/A 转换器也可用于逐次逼近A / D 转换(successive approximation A/D conversion)。为释放用于 A/D 转换周期的 DAC,单位增益放大器还配备了一个跟踪和保持电路。在执行 A/D 转换时该电路保持输出电压。

提供给模拟输出AOUT 的输出电压由图7 中的公式给出。D/A 转换顺序的波形。

在此处由于篇幅有限仅列出部分功能说明书,如有需要请私信,会提供全部全部说明书

后续为代码部分。

声明函数

#ifndef _IIC_H
#define _IIC_H

//函数声明
void IIC_Start(void); 
void IIC_Stop(void);  
void IIC_Ack(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
bit IIC_WaitAck(void);  
unsigned char IIC_RecByte(void); 
unsigned char iic_read(unsigned add);
void iic_write(unsigned char add,dat);
unsigned char eeprom_read(unsigned char add);
void eeprom_write(unsigned char add,dat);

#endif

 参考代码部分

#include "reg52.h"
#include "intrins.h"

#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();}    


#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */


//总线启动条件
void IIC_Start(void)
{
	SDA = 1;
	SCL = 1;
	somenop;
	SDA = 0;
	somenop;
	SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
	SDA = 0;
	SCL = 1;
	somenop;
	SDA = 1;
}

//应答位控制
void IIC_Ack(bit ackbit)
{
	if(ackbit) 
	{	
		SDA = 0;
	}
	else 
	{
		SDA = 1;
	}
	somenop;
	SCL = 1;
	somenop;
	SCL = 0;
	SDA = 1; 
	somenop;
}

//等待应答
bit IIC_WaitAck(void)
{
	SDA = 1;
	somenop;
	SCL = 1;
	somenop;
	if(SDA)    
	{   
		SCL = 0;
		IIC_Stop();
		return 0;
	}
	else  
	{ 
		SCL = 0;
		return 1;
	}
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{   
		if(byt&0x80) 
		{	
			SDA = 1;
		}
		else 
		{
			SDA = 0;
		}
		somenop;
		SCL = 1;
		byt <<= 1;
		somenop;
		SCL = 0;
	}
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
	unsigned char da;
	unsigned char i;
	
	for(i=0;i<8;i++)
	{   
		SCL = 1;
		somenop;
		da <<= 1;
		if(SDA) 
		da |= 0x01;
		SCL = 0;
		somenop;
	}
	return da;
}
unsigned char iic_read(unsigned char add)
{
	unsigned char temp;
	IIC_Start();
	IIC_SendByte(0X90);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0X91);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();
	return temp;
}
void iic_write(unsigned char add)
{
	IIC_Start();
	IIC_SendByte(0X90);
	IIC_WaitAck();
	IIC_SendByte(0X40);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Stop();
}
unsigned char eeprom_read(unsigned char add)
{
	unsigned char temp;
	IIC_Start(); 
	IIC_SendByte(0XA0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Stop();
	
	
	IIC_Start(); 
	IIC_SendByte(0XA1);
	
	temp=IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();
	return temp;
}

void eeprom_write(unsigned char add,dat)
{
	IIC_Start();
	IIC_SendByte(0XA0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳&怡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值