PCF8591是具有IIC接口的8位A/D和D/A转换芯片,具有4路模拟输入、一路DAC输出和一个IIC总线接口。其主要的功能特性如下:
●单电源供电,典型值为5V。
●通过3个硬件地址引脚编址。
●8位逐次逼近式A/D转换。
●片上跟踪与保持电路,采样速率取决与IIC总线速度。
●4路模拟输入可编程为单端输入或查分输入。
●自动增量通道选择。
●带一个模拟输出的乘法DAC。
PCF8591的设备地址包括固定部分和可编程部分。可编程部分需要根据硬件引脚A0、A1和A2来设置。设备地址的最后一位用于设置数据传输的方向,即读/写位。格式如下图:
在IIC总线协议中,设备地址是起始信号后第一个发送的字节。如果硬件地址引脚A0、A1、A2均接地,那么,PCF8591的设备的读操作地址为:0x91;而写操作地址则为:0x90。
在设备地址之后,发送到PCF8591的第二个字节将被存储在控制寄存器中,用于控制器件功能。该寄存器的具体定义如下:
在蓝桥杯单片机设计与开发赛项使用的CT107D单片机开发平台中,PCF8591的三个硬件引脚地址均接地,两路模拟信号均为单端输入,分别是:
光敏传感器接到AIN1,通道1;控制寄存器应写入:0x01。
电位器Rb2接到AIN3,通道3;控制寄存器应写入:0x03。
一个A/D转换的周期的开始,总是在发送有效的读设备地址给PCF8591之后,A/D转换在应答时钟脉冲的后沿被触发。PCF8591的A/D转换程序设计流程,可以分为四个步骤:
1--发送写设备地址,选择IIC总线上的PCF8591器件。
2--发送控制字节,选择模拟量输入模式和通道。
3--发送读设备地址,选择IIC总线上的PCF8591器件。
4--读取PCF8591中目标通道的数据。
下面以蓝桥杯单片机设计与开发竞赛中,采样可变电阻Rb2的电压为例,展示PCF8591的A/D转换具体代码实现:
void Read_AIN3()
{
IIC_Start(); //IIC总线起始信号
IIC_SendByte(0x90); //PCF8591的写设备地址
IIC_WaitAck(); //等待从机应答
IIC_SendByte(0x03); //写入PCF8591的控制字节
IIC_WaitAck(); //等待从机应答
IIC_Stop(); //IIC总线停止信号
IIC_Start(); //IIC总线起始信号
IIC_SendByte(0x91); //PCF8591的读设备地址
IIC_WaitAck(); //等待从机应答
dat = IIC_RecByte(); //读取PCF8591通道3的数据
IIC_Ack(0); //产生非应答信号
IIC_Stop(); //IIC总线停止信号
}
#include "regx52.h"
#include "absacc.h"
#include "intrins.h"
#include "iic.h"
sbit S4 = P3^3;
unsigned char dat_rd1;
unsigned char dat_rb2;
unsigned char stat = 0;
unsigned char code SMG_duanma[18]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
void DelaySMG(unsigned int t)
{
while(t--);
}
void DisplaySMG_Bit(unsigned char pos, unsigned char value)
{
XBYTE[0xE000] = 0xFF;
XBYTE[0xC000] = 0x01 << pos;
XBYTE[0xE000] = value;
}
void DisplaySMG_ADC(unsigned char channel, unsigned char dat)
{
DisplaySMG_Bit(0, SMG_duanma[16]);
DelaySMG(100);
DisplaySMG_Bit(1, SMG_duanma[channel]);
DelaySMG(100);
DisplaySMG_Bit(2, SMG_duanma[16]);
DelaySMG(100);
DisplaySMG_Bit(3, 0xFF);
DisplaySMG_Bit(4, 0xFF);
DisplaySMG_Bit(5, SMG_duanma[dat / 100]);
DelaySMG(100);
DisplaySMG_Bit(6, SMG_duanma[(dat % 100) / 10]);
DelaySMG(100);
DisplaySMG_Bit(7, SMG_duanma[dat % 10]);
DelaySMG(100);
}
void Read_RD1()
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x01);
IIC_WaitAck();
IIC_Stop();
DisplaySMG_ADC(1,dat_rd1);
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
dat_rd1 = IIC_RecByte();
IIC_Ack(0);
IIC_Stop();
DisplaySMG_ADC(1,dat_rd1);
}
void Read_RB2()
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Stop();
DisplaySMG_ADC(3,dat_rb2);
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
dat_rb2 = IIC_RecByte();
IIC_Ack(0);
IIC_Stop();
DisplaySMG_ADC(3,dat_rb2);
}
void Scan_Keys()
{
if(S4 == 0)
{
DelaySMG(100);
if(S4 == 0)
{
if(stat == 0)
{
stat = 1;
while(S4 == 0)
{
DisplaySMG_ADC(1,dat_rd1);
}
}
else if(stat == 1)
{
stat = 0;
while(S4 == 0)
{
DisplaySMG_ADC(3,dat_rb2);
}
}
}
}
}
main()
{
XBYTE[0x8000] = 0xff;
XBYTE[0xa000] = 0x00;
while(1)
{
Scan_Keys();
if(stat == 0)
{
Read_RD1();
}
else if(stat == 1)
{
Read_RB2();
}
}
}
【小蜜蜂笔记:广东职业技术学院 欧浩源 [email protected]】