PCF8591(A/D,D/A 转换)

发布时间 2023-03-31 20:11:04作者: 魏图图

PCF8591 芯片介绍

PCF8691 是具有 IIC 总线接口的 8 位 A/D 及 D/A 转换器。有 4 路 A/D 转换输入,1 路 D/A 模拟输出,具体如下图。

标志 引脚 描述
AIN0 1 模拟输入通道1(A/D转换器)
AIN1 2 模拟输入通道2(A/D转换器)
AIN2 3 模拟输入通道3(A/D转换器)
AIN3 4 模拟输入通道4(A/D转换器)
A0 5 硬件地址
A1 6 硬件地址
A2 7 硬件地址
Vss 8 负电源电压
SDA 9 IIC数据输入/输出
SCL 10 IIC时钟
OSC 11 振荡器inputioutput
EXT 12 振荡器输入的外部和内部开关
AGND 13 模拟地
Vref 14 参考电压输入
AOUT 15 模拟输出(D/A转换器)
Vdd 16 正极

特性:

  • I2C总线串行输入/输出
  • 通过三个硬件地址引脚编址
  • 4 个模拟输入可编程为单端或差分输入(蓝桥杯比赛只有两个,一个控制滑动变阻器,一个控制光敏电阻)

总体框图如下:
SCL:时钟线
SDA:数据线

AIN0 ~ AIN3:用于接入滑动变阻器或者光敏电阻这些(在比赛中用到的只有 AIN1 和 AIN3 )

寻址

IIC 总线系统中,每个 PCF8591 通过发送有效地址来激活器件,类似于温度传感器的序列号

  • 注:最后一位是 0,则写入命令到芯片,若为 1,则从芯片中读出命令

控制字节

控制字节用于实现器件的各种功能

其中,
D1、D0 是A/D通道编号:00 ---> 通道 0,01 ---> 通道 1,10 ---> 通道 2,11 ---> 通道 3

D2 :自动增益选择(有效位为 1,一般不选择 --->即为 0 )

D5、D4 模拟量输入选择:00 ---> 四路单数入,01 ---> 三路差分输入,10 ---> 单端与差分配合输入,11 ---> 模拟输入允许有效

D6:当系统为 A/D 转换时,模拟输出允许为 1;

IIC 协议

简介

IIC 一共只有两个总线:一条是双向的串行数据线 SDA,一条是串行时钟线 SCL

SDA:传输数据
SCL:控制数据发送给的时序

所有接到 IIC 总线设备上的串行数据 SDA 都接到总线的 SDA 上,各设备的时钟线 SCL 接到总线的 SCL 上,IIC 总线上的每个设备都有自己唯一的地址,来确保不同设备件访问的准确性。

主要特点

主设备控制时钟线(即控制 SCL 高低电平的变换)

  • IIC 主设备:主要产生时钟,产生起始信号和停止信号
  • IIC 从设备:可编程 IIC 的地址检测,停止位检测
  • 优点支持多主控,主控能够控制信号的传输和时钟频率(在任何时间点上,只有一个主控)
  • 支持不同速率的通讯速度,标准速度(最高100KHZ),快速(最高400KHZ)
  • SCL 和 SDA 都需要上拉电阻(大小由速度和容性负载决定,一般在 3.3K~10K之间),保证数据的稳定性,减少干扰
  • IIC 是半双工,不是全双工,同一时间只可单向通信
  • 为了避免总线信号的混乱,要求各设备连接到输出端时必须是漏极开路(OD)输出或集电极开路(OC)输出

IIC 协议层

IIC 总线在传送过程中共有三种类型信号,分别是:开始信号,结束信号和应答信号

  • 开始信号:SCL 为高电平时,SDA 由高电平向低电平跳变,开始传送数据。
  • 结束信号:SCL 为高电平时,SDA 由低电平向高电平跳变,结束传送数据。
  • 应答信号:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲,表示已收到数据。CPU 向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU 接收到应答信号后,根据实际情况做出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元故障。

注:起始信号是必须的,结束信号和应答信号都可以不要

IIC 总线时序

数据和时钟线在不忙的时候总保持高电平。在时钟为高电平时,数据线上的一个由高到低的变化被定义为开始条件。时钟为高电平,数据线上的由低到高的变化被定义为停止条件。

总线启动

void IIC_Start(void)
{
	SDA = 1;
	SCL = 1;
	IIC_Delay(DELAY_TIME);
	SDA = 0;
	IIC_Delay(DELAY_TIME);
	SCL = 0;
}

总线停止

void IIC_Start(void)
{
	SDA = 0;
	SCL = 1;
	IIC_Delay(DELAY_TIME);
	SDA = 1;
	IIC_Delay(DELAY_TIME);
}

应答信号

每当主机向从机发送完一个字节的数据,主机总是需要等待从机给出的一个应答信号,以确认从机是否成功接收到了数据。

应答信号:主机 SCL 拉高,读取从机 SDA 的电平,为低电平表示产生应答

  • 应答信号为低电平时,规定为有效应答位(ACK,简称应答位),表示接收器已经成功的接收了该字节。
  • 应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。

发送应答
void IIC_SendACK(bit ackbit)
{
	SCL = 0;
	SDA = ackbit;
	IIC_Delay(DELAY_TIME);
	SCL = 1;
	IIC_Delay(DELAY_TIME);
	SCL = 0;
	SDA = 1;
	IIC_Delay(DELAY_TIME);
}
等待应答
bit IIC_WaitACK(void)
{
	bit ackbit;
	
	SCL = 1;
	IIC_Delay(DELAY_TIME);
	ackbit = SDA;
	IIC_Delay(DELAY_TIME);
	SCL = 0;
	IIC_Delay(DELAY_TIME);
	return ackbit;
}

数据传输

发送数据
void IIC_SendByte(unsigned char byt)
{
	unsigned char i;

	for(i = 0i < 8;i ++)
	{
		SCL = 0;
		IIC_Delay(DELAY_TIME);
		if(byt & 0x80) SDA = 1;
		else SDA = 0;
		IIC_Delay(DELAY_TIME);
		SCL = 1;
		byt <<= 1;
		IIC_Delay(DELAY_TIME);
	}
	SCL = 0;
}
接收数据
unsigned cahr IIC_RecByte(void)
{
	unsigned char i,da;

	for(i = 0;i < 8;i ++)
	{
		SCL = 1;
		IIC_Delay(DELAY_TIME);
		da <<= 1;
		if(SDA) da |= 1;
		SCL = 0;
		IIC_Delay(DELAY_TIME);
	}
	return da;
}

A/D 转换

流程:

IIC 开始信号 ---> 地址读 ---> 等待 PCF8591 回应 ---> 读 PCF8591 ---> 主机回应 ---> 继续读 ---> 主机回应 ---> ... ---> 直到想停止 AD 转换 ---> 不回应了 ---> 停止信号

注:A/D 转换周期总是在发送一个有效的读模式地址到 PCF8591 设备后开始。

代码编写

unsigned char AD_Read(unsigned char addr)
{
	unsigned char temp;
	
	IIC_Start();
	//0x90是写,0x91是读
	IIC_SendByte(0x90);
	IIC_WaitAck();
	//控制字节:选择光敏电阻(0x41)还是滑动变阻器(0x43)
	IIC_SendByte(addr);
	IIC_WaitAck();

	IIC_Start();
	//0x90是写,0x91是读
	IIC_SendByte(0x91);
	IIC_WaitAck();
	temp = IIC_RecByte();
	//发送非应答信号,只读一次
	IIC_SendAck(1);
	IIC_WaitAck();
	
	return temp;
}

D/A 转换

代码编写

void DA_Write(unsigned char addr)
{
	IIC_Start();
	//0x90是写,0x91是读
	IIC_SendByte(0x90);
	IIC_WaitAck();
	//允许DA输出
	IIC_SendByte(0x41);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_Stop();
}