【蓝桥杯】PCF8591AD转换模块

1、PCF8591模块简介

PCF8591是一个单片集成、单独供电、低功耗、8-bit CMOS数据获取器件。PCF8591具有4个模拟输入、1个模拟输出和1个串行I²C总线接口。
在PCF8591器件上输入输出的地址、控制和数据信号都是通过双线双向I2C总线以串行的方式进行传输。

2、电路连接图

PCF8591电路连接图
【蓝桥杯】PCF8591AD转换模块
AIN0~AIN3:模拟信号输入端。
A0~A2:器件地址的低3位。
VSS:电源负极。
SDA、SCL:I2C 总线的数据线、时钟线。
OSC:外部时钟输入端,内部时钟输出端。
EXT:内部/外部时钟选择线,使用内部时钟时EXT 接地。
AGND:模拟信号地。
VREF:基准电源端。
AOUT:D/A 转换输出端。
VDD:电源端。(2.5~6V)
AINI外接了一个光敏电阻和一个定值电阻,读取的是定值电阻两端的电压,因此,光照越强,光敏电阻阻值越小,即电压越小,然后R31电压增大,所以总的来看,读取到的电压是随光照增加而增大的。
AIN3外接一个电位器RB2,读取到的是AIN3向接地部分的电阻,因此是随电阻增大,电压减小
【蓝桥杯】PCF8591AD转换模块
这里J3的18、19两根引脚,一个AIN0是ADC读取,一个OUT是DAC输出,都是可以外接设备的,通过跳线帽连接,可以读取out输出值。
【蓝桥杯】PCF8591AD转换模块

3、器件地址

与AT24C0D相同,PCF8591的3个地址引脚A0, A1和A2可用于硬件地址编程,也就是编写器件地址第2、3、4位。最后一位地址的最后一位为方向位R/W ,当主控器对A/D 器件进行读操作时为1,进行写操作时为0。前四位固定为1001,因此允许在同个I2C总线上接入8个PCF8591器件,而无需额外的硬件。
即0X90——写操作地址+器件地址
0X91——读操作地址+器件地址

4、DA转换功能

①启动IIC
②发送器件地址+写:0x90
③发送通道选择命令:0x40-0x43 (0x00-0x03 )
④重新启动IIC
⑤发送器件地址+读:0x91
⑥读取转换数据

unsigned char read_rb(unsigned char channel)//选择通道,取值0、1、2、3
{
  unsigned char dat;
  IIC_Start();
  IIC_SendByte(0x90); //写
  IIC_WaitAck();
  IIC_SendByte(40+channel);
  IIC_WaitAck();

  IIC_Start();
  IIC_SendByte(0x91); //读
  IIC_WaitAck();
  dat = IIC_RecByte();
  IIC_SendAck(1);
  IIC_Stop();
  return dat;
}

5、AD转换功能

读取的第一个字节是上一次转换的结果。读取上一个字节后,才开始进行这次转换的采样,所以读取的第二个字节才是这次的转换结果。所以读取转换结果的步骤是:发送转换命令,将上次的结果读走,然后等一会儿,然后读取结果。
①启动
②发送器件地址+写:0x90
③发送DAC使能:0x40
④发送数字信号值:X

void write_DAC(unsigned char x)
{
  IIC_Start();
  IIC_SendByte(0x90); //写
  IIC_WaitAck();
 
  IIC_SendByte(0x43); //允许输出
  IIC_WaitAck();
  IIC_SendByte(x);
  IIC_WaitAck();
  IIC_Stop();
 
}

6、IIC通信

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

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

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

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}
//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

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

//发送应答
void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					// 0:应答,1:非应答
    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;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<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;  
}

//从I2C总线上接收数据
unsigned char 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;    
}
上一篇:STC89C52单片机单线通信(DS18B20温度)


下一篇:P7097-[yLOI2020]牵丝戏【dp】