引言
PCF8591 是单电源,低功耗8 位CMOS 数据采集器件,具有4 个模拟输入、一个输出和一个串行I2C 总线接口。3 个地址引脚A0、A1 和A2 用于编程硬件地址,允许将最多8 个器件连接至I2C总线而不需要额外硬件。PCF8591由于其使用的简单方便和集成度高,在单片机应用系统中得到了广泛的应用,这篇文章是介绍IIC通信在ADDA转换芯片PCF8591中的应用。
关于IIC
IIC总线通信协议的介绍在"
PCF8591是单片、单电源低功耗8位CMOS数据采集器件,具有4个模拟输入、一个输出和一个串行I2C总线接口。3个地址引脚A0、A1 和A2 用于编程硬件地址,允许将最多8个器件连接至I2C总线而不需要额外硬件。器件的地址、控制和数据通过两线双向I2C总线传输。器件功能包括多路复用模拟输入、片上跟踪和保持功能、8位模数转换和8位数模拟转换。最大转换速率取决于I2C总线的最高速率。 PCF8591的操作和AT24C02非常类似,只不过AT24C02是写入或读出数据,而PCF8591是AIN端口输入模拟电压,然后PCF8591将转换后的数字量通过IIC总线发送给单片机,或是单片机通过IIC总线给一个数字量,然后PCF8591通过AOUT端口将模拟电压输出. 最高位默认为0 第6位是选择是否允许模拟电压输出,在DA转换时设置为1,AD转换时设置为0或1均可 第5/4位是选择模拟电压输出方式,一般选择00单端输入方式,其他的几种方式如下图所示 第3位默认为0 第2位是自动增量使能位,如果自动增量(auto-increment)标志置1,每次A/D 转换后通道号将自动增加。 第1/0为是在AD转换时选择哪一个通道输入的电压转换为数字量. 每一个IIC器件都有一个器件地址,来区分不同的IIC设备,下面是PCF8591的地址 它的地址是由1001和A2A1A0组成的,在原理图中可以看出,A2A1A0均为0,所以器件地址为0x90/0x91,最后一位是读写方向位,0表示下一个字节往总线上写数据,1表示下一个字节从总线上读取数据. AD转换即将AIN端口输入的模拟电压转换为数字量并发送到总线上,可以知道该函数需要指定输入的通道,还要将转换后的数字量返回,所以该函数有返回值,和一个形参 程序实现: /*读取某一个通道转换后的数字量*/ DA转换即将从总线上接收到的数字量通过AOUT输出,该函数无返回值,有一个形参 程序实现: 我们可以用一个转换公式,将AD转换后的数字量转换为对应的电压值,在数码管或液晶上显示,公式如下: 这样就可以实时显示输入的电压值了.还可以将电压值输出到led亮度显示出来.这样就可以作为一个简易的小量程(5v)的电压表了 从程序可以看出PCF8591的操作和AT24C02基本一致,就是增加了控制字的内容,相比于其他的ADDA转换芯片,它结构简单,不需要外围的电路,可以直接使用,而且容易实现模块化设计,在大多数单片机系统中ADDA几乎是不可缺少的,而PCF8591只需要两个IO口(时钟和数据)和电源就可以实现,大大节省了IO口的使用。 关于AT24C02的使用,请看我另一篇随笔:“基于51单片机IIC通信的AT24C02学习笔记” 我的其他博文: 欢迎大家关注我的个人博客: 或微信扫码关注我的公众号关于PCF8591
控制字格式
PCF8591的器件地址
AD转换函数
uchar Read_D(uchar Channel)
{
uchar dat;
start();
write_byte(0x90); //器件地址+0
ack();
write_byte(Channel); //控制字0x01表示通道1
ack();
start();
write_byte(0x91); //器件地址+1,下一个字节要读取
ack();
dat=read_byte();
ack();
stop();
// AD_led=0; //转换成功显示
return dat;
}DA转换函数
void Out_A(uchar Digital)
{
start();
write_byte(0x90); //器件地址+0,下一个字节为写入
ack();
write_byte(0x40); //设置控制字 0100 0000 允许模拟输出,不自增单端
ack();
write_byte(Digital); //将要转换的数字量写入
ack();
stop();
// DA_led=0; //转换成功显示
}
转换公式
#define fun(x) (int)(5*x/255.0*100+0.5) //数字电压x转换为模拟电压的公式
主函数调用
dat1 = Read_D(0x01); //将通道1(电位器v2)的模拟电压转换的数字量读出
Out_A(dat1); //将数字量转换为模拟量输出到led显示
dis_Voltage1(fun(dat1)); //数码管显示电压值
Delay_Ms(5); //延时缓冲
总结
参考资料:
PCF8591_百度百科
iic_百度百科
www.wangchaochao.top