STM32驱动PCF8591模块,实现ADDA转换

2023-04-03  

模块外观



原理图



PCF8591 模块原理图

模块说明:

  1. 模块所用芯片为 PCF8591T,贴片封装支持 4 路模拟电压采集信号输入(电压输入范围 0--5V)模块带电源指示灯 1 个(D1)模块带 DA 输出指示灯 1 个(D2),当 DA 输出电压达到一定值时,该指示灯亮,电压值越高,指示灯越亮模块集成 1 路 0--5V 电压输入采集(通过蓝白电位器调节输入电压)模块集成 1 路光敏电阻(型号:5537),可以通过 AD 采集环境光线强度模块集成 1 路热敏电阻(型号:MF58),可以通过 AD 采集环境温度

PCF8591 特点:

  1. 单电源供电;正常工作电源电压范围为 2.5V~6V;通过 I2C 总线完成数据的输入 / 输出;器件地址由 3 个地址引脚决定;

由上面的原理图可以看出 A0、A1、A2 与 GND 相连。
  1. 采样频率由 I2C 总线传输速率决定;4 路模拟量输入可编程为单端输入或差分输入;可配置转换通道号自动增加功能;模拟电压范围为 VSS~VDD;片上跟踪保持功能;8 位逐次逼近 A/D 转换;带有一路模拟量输出的 D/A 转换。

接线说明

接线示意图

PCF8591 模块 含义 STM32 核心板
SDA IIC 数据接口 U3R PB11
SCL IIC 时钟接口 U3T PB10
VCC 电源正 3V3
GND 电源负 GND



接线示意图

实际连接图



硬件连接

模块输出调试引脚

PCF8591 模块 含义
AOUT 模块 DA 输出端口
AIN3 模拟输入信号接口 3
AIN2 模拟输入信号接口 2
AIN1 模拟输入信号接口 1
AIN0 模拟输入信号接口 0
GND 模块的 GND
INPUT2 已连接至热敏电阻信号输入口
INPUT1 已连接至光敏电阻信号输入口
INPUT0 已连接至电位器信号输入口

跳线帽使用说明

  • AIN0 与 INPUT0 连接跳线帽时,选择电位器接入电路 AIN1 与 INPUT1 连接跳线帽时,选择光敏电阻接入电路 AIN2 与 INPUT2 连接跳线帽时,选择热敏电阻接入电路需要外接模拟信号输入时,请断开跳线帽,将该模拟信号接入 AIN0----AIN3

芯片手册

地址



从模块原理图得知 A0,A1,A2 接地,所以模块的地址为:1001000X,那么其地址就是 0x90 或者是 0x91,看是读还是写来决定。

最后一位,当是 0 时,表示下一个字节往总线上写数据;当是 1 时,表示下一个字节从总线上读取数据。

#define PCF8591Addr 0x90        // 写操作地址
PCF8591Addr|0x01                // 读操作地址

控制字



控制字位说明:

  • bit0-bit1:AD 转换通道选择,当值为 00 时,为 AIN0;bit2:自动增量使能 bit4-bit5:单端输入 / 差分输入选择,00 为单端输入 bit6:为 1 时为允许模拟电压输出

假设我需要从通道 0 单端获得 A/D 转换数据,那么 control byte 就是 01000000 = 0x40 。

所以我们获取四个通道 ADC 值的函数如下调用:

adcData[0] = PCF8591_ADC_Input(0x90 ,0x40);
adcData[1] = PCF8591_ADC_Input(0x90 ,0x41);
adcData[2] = PCF8591_ADC_Input(0x90 ,0x42);
adcData[3] = PCF8591_ADC_Input(0x90 ,0x43);

D/A 转换时序



D/A 转换时序图

具体实现代码如下:

u8 PCF8591_DAC_Output(unsigned char WriteAddr,unsigned char c,  unsigned char Val)
{
    IIC_Start();              // 启动总线
    
    IIC_Send_Byte(WriteAddr); // 发送写操作地址
   
    IIC_Wait_Ack();  
    
    IIC_Send_Byte(c);        // 发送控制字
   
    IIC_Wait_Ack();  
    
    IIC_Send_Byte(Val);     // 发送 DAC 的数值
   
    IIC_Wait_Ack();  
    
    IIC_Stop();             // 结束总线
    
    return(1);
}

输出 DAC 的值参考下面换算关系计算:


简单理解就是,发送的 DAC 数值IIC_Send_Byte(Val); ,将 Vref 分成 0xFF 份,Vagnd 对应第一份;Vref 对应最后一份。

A/D 转换时序


A/D 转换时序图

u8 PCF8591_ADC_Input(unsigned char WriteAddr,unsigned char Channel)
{
    u8 temp=0;
    
    IIC_Start();                  // 启动总线
    
    IIC_Send_Byte(WriteAddr);     // 发送写操作地址
   
    IIC_Wait_Ack();  
    
    IIC_Send_Byte(Channel);       // 写入控制字
   
    IIC_Wait_Ack();
    
    IIC_Stop();                   // 结束此次写操作,结束总线
    
    IIC_Start(); 
    
    IIC_Send_Byte(WriteAddr|0x01);// 发送读操作地址
   
    IIC_Wait_Ack();  
    
    temp=IIC_Read_Byte(0);
    
    IIC_Stop();                   // 结束总线
    
    return temp;
}

若要完成一次 AD 转换,应严格按照时序图进行:开启总线 -->发送写操作地址 -->等待 PCF8591 的应答 -->发送控制字 -->等待 PCF8591 的应答 -->结束总线 -->重新开启总线 -->发送读操作地址 -->等待 PCF8591 的应答 -->读取 ADC 数据(1 字节)-->发送非应答信号 -->停止总线

上面IIC_开头的函数都与 24C02 那个例程中的函数一致,不需要修改。

移植过程

在网文:STM32 I2C 通信操作 24C02 写数据、读数据 的实例代码基础上,完成移植,具体过程如下:

1. 将驱动文件拷贝到自己工程中 HARDWARE 目录下



2. 添加驱动文件所在文件夹至工程中



3. 添加 .c 文件至工程中



4. main 函数中调用



成果展示

先旋转电位器,然后用手遮挡光敏电阻,串口助手中具体现象如下:


动图封面


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。