首页 > 其他分享 >PCF8591(A/D,D/A 转换)

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

时间:2023-03-31 20:12:10浏览次数:40  
标签:SCL 转换 信号 应答 --- PCF8591 SDA IIC

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();
}

标签:SCL,转换,信号,应答,---,PCF8591,SDA,IIC
From: https://www.cnblogs.com/ttduck/p/17277371.html

相关文章

  • 生成时间以及时间转换
    1、时间戳:importtimet=int(time.time())#1499825149秒t1=int(round(time.time()*1000))#1666321307232毫秒t2=int(round(time.time()*1000000))#1499825149257892微秒2、获取当前时间:importdatetimedt=datetime.datetime.now().strftime('%Y-%m-......
  • 实体类转化为DataTable,,DataTable 转换为List 集合
    点击查看代码///<summary>///C#List转换成DataTable///</summary>///<paramname="list"></param>///<returns></returns>publicstaticDataTableListToDataTable(IList......
  • 关于lib-flexible插件中的单位转换
    lib-flexible是淘宝项目组开发出来的一个小插件,属于开源项目。一般而言,lib-flexible并不独立出现,而是搭配px2rem-loader一起做适配方案,目的是自动将css中的px转换成rem。lib-flexible:根元素html的font-size为此时屏幕宽度/10,也就有1rem=html的font-size大小。1.但是当分辨率(屏......
  • 字符串和json对象之间的转换关系——一定不要再导错包
    添加依赖<!--fastjson依赖--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.33</version></dependency>  一定不要导错包  字符串转换为json对象importcom.ali......
  • 0203 强制转换
    强制转换1​ 如果把一个取值范围大的数值赋值给取值范围小的变量,是不允许直接赋值的,如果一定要这么做就要加入强制转换2​ 格式inta=(byte)b;inta=300;byteb=(byte)a;//这种情况下会出现错误,因为byte的取值范围小于int,会出现无法转换的情况举例packagecom......
  • pcm音频的录制、播放及转换
    操作系统:Windows10_x64pcm格式为原始音频数据,有时候会遇到需要录制、播放及转换的情况,这里记录下。一、录制pcm音频这里演示下使用Audacity进行pcm音频录音的过程。Audacity的使用可参考这篇文章:Audacity开源音频处理软件使用入门1)打开Audacity软件;采样率使用16000HZ,使......
  • Android图片转换类 1. Bitmap去色,…
    publicclassImageTools{publicstaticBitmaptoGrayscale(BitmapbmpOriginal){intwidth,height;height=bmpOriginal.getHeight();width=bmpOriginal.getWidth();BitmapbmpGrayscale=Bitmap.createBitmap(width,height......
  • Linux系统把时间类型值转换为数值型的方法是什么?
    在实际工作中,我们往往会遇到各式各样的需求,今天老男孩教育小编给大家介绍一下,如何把时间类型值转换为数值类型,以下是详细的内容:1.取子串函数格式:substr(c,n1.n2)功能:取字符串C第n1个字符起的n2个字符.返回值类型是字符型.例:取姓名字符串中的姓.store"......
  • min 与 + 运算转换成类似于矩阵乘法的推导过程
    记录下由$\min$与$+$运算转换成类似于矩阵乘法的推导过程,有错误请在评论区指出qwq。我们先简单证明一下矩阵乘法的结合律。设有矩阵$A_{n\timesm}$,$B_{m......
  • 年月日时分秒转换为几个小时前
    将年月日转换为-几个小时前之类的传入的时间是字符串类型方法一点击查看代码functiontimeFormat(time){varnowTime=newDate();varday=nowTime.......