模块外观
原理图
PCF8591 模块原理图
模块说明:
模块所用芯片为 PCF8591T,贴片封装支持 4 路模拟电压采集信号输入(电压输入范围 0--5V)模块带电源指示灯 1 个(D1)模块带 DA 输出指示灯 1 个(D2),当 DA 输出电压达到一定值时,该指示灯亮,电压值越高,指示灯越亮模块集成 1 路 0--5V 电压输入采集(通过蓝白电位器调节输入电压)模块集成 1 路光敏电阻(型号:5537),可以通过 AD 采集环境光线强度模块集成 1 路热敏电阻(型号:MF58),可以通过 AD 采集环境温度
PCF8591 特点:
单电源供电;正常工作电源电压范围为 2.5V~6V;通过 I2C 总线完成数据的输入 / 输出;器件地址由 3 个地址引脚决定;
由上面的原理图可以看出 A0、A1、A2 与 GND 相连。
采样频率由 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 函数中调用
成果展示
先旋转电位器,然后用手遮挡光敏电阻,串口助手中具体现象如下: