前言

由于树莓派不能直接读取模拟信号,所以我们需要本篇博客中提到的模数转换器来替代实现读取模拟信号的功能

本篇博客的这个模数转换器比之前的模块复杂很多,我们需要一步一步弄明白它的原理,才能真正理解如何使用这个小东西

关注本专栏,和我一起学习树莓派开发板30+经典实验

C语言代码,0基础剖析!


1.实验器材

  • 树莓派开发板
  • 40p软排线+T型转接板+面包板
  • 双色LED模块(元老级朋友)
  • PCF8591模数转换器模块
  • 一些跳线
  • 一字或者十字螺丝刀🛠

IMG_20220421_205650

上:PCF8591模数转换器模块;下:双色LED


2.实验原理

2.0 元件介绍

PCF8591是一个单片集成、单独供电、低功耗、8-bit CMOS数据采集元件。

  • PCF8591具有4个模拟输入、1个模拟输出和1个串行I2C总线接口。
  • 它的3个地址引脚A0, A1和A2可用于硬件地址编程,从而允许使用多达8个链接到I2C总线的设备,而无需额外的硬件。
  • 在PCF8591器件上输入输出的地址、控制和数据信号都是通过双线双向I2C总线以串行的方式进行传输。

该元件的功能包括模拟输入多路复用,片上跟踪和保持功能,8位模数转换和8位数模转换。最大转换率由I2C总线的最大速度决定。

2.1 i2c总线

i2c总线是由飞利浦公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。

  • 飞利浦官方有一个关于PCF8591的详细介绍文档,不过它是英语的。我会上传到gitee仓库里面分享给大家,仓库链接在开头介绍过了🤦‍♂️回到开头

i2c总线系统中的每个PCF8591设备通过向该设备发送有效地址而被激活。地址由固定部分和可编程部分组成。可编程部分必须按照地址引脚A0,A1,A2进行设置。地址必须以邮寄方式发送。

在i2c总线协议中,在启动条件之后的第一个字节,地址字节的最后一个位是读/写位,它设置了下列数据传输的方向

image-20220421213703255

2.2 第一字节

PCF8591采用典型的I2C总线接口器件寻址方法,即总线地址由器件地址、引脚地址和方向位组成。

飞利浦公司规定A/D器件地址为1001,引脚地址为A2A1A0,其值由用户选择。因此I2C系统中最多可接2^3^个具有I2C总线接口的A/D器件。地址的最后一位为方向位R/L,当主控器对A/D器件进行写操作时为0,进行读操作时为1。

总线操作时,由器件地址、引脚地址和方向位组成的从地址为主控器发送的第一字节

2.3 控制字节

发送到PCF8591器件的第二个字节将被存储在其控制寄存器中,并且需要控制器件来实现功能。

image-20220421214941478

  • D1、D0 两位是A/D通道编号:00通道0,01通道1,10通道2,11通道3
  • D2 自动增量选择(0为禁止自动增量,1为允许自动增量),如果允许自动增量,则在每次A/D转换后,通道编号会自动递增。
  • D3 特征位:固定值为:0。
  • D5、D4 模拟量输入选择:00为四路单端输入、01为三路差分输入、10为两路单端与一路差分输入、11为两路差分输入。
  • D6 使能模拟输出AOUT有效(1为有效,0为无效)。
  • D7 特征位:固定值为:0。

上述内容参考@Maker张大佬的博客👉传送门

控制寄存器的高半字节用于模拟输出,并将模拟输入编程为单端或差分输入。下半字节选择由上半字节定义的一个模拟输入通道。如果设置了自动增加标志,则在每次A/D转换后,通道编号会自动递增。

image-20220421215527342

更多关于i2c总线的知识,可以查看百度百科的词条👉某度

2.4 模块电路

在本次实验中,AIN0(模拟输入0)端口用于接收来自电位计模块的模拟信号,AOUT(模拟输出)用于将模拟信号输出到双色LED模块,用于改变LED的亮度

12.PCF8591模块原理图

如果你有注意看电路图的话,你会发现AOUT上链接了一个D4-LED,它也会接收模拟输出信号,同步改变亮度

  • 而在我手头上的模块,D2-LED就是会同步改变亮度的,后文会提到

在实验之前,我们可以把AIN上的电位帽拔掉

image-20220421214132642

2.5 电路接线

树莓派T型转接板PCF8591
SDASDASDA
SCLSCLSCL
5V5VVCC
GNDGNDGND
双色LEDT型转接板PCF8591
R(中间)*AOUT
GND(-)GNDGND
G(S)**

12_PCF8591_bb

拍出来的接线图好像有亿点点乱😂

IMG_20220421_221900

正常接线后,主板上的D1-LED会亮起

我们可以根据原理图利用T型转接板来连接模数转换器和双色LED,也可以用这种双母头的线直接连接AOUT端口和双色LED的中间管脚

image-20220421230253395

3.程序控制

3.1 在树莓派中开启I2C

通过VNC打开树莓派的桌面,点击开始-首选项-Raspberry Pi Configuration-Interfaces,打开I2C的开关enable

image-20220421222449737

3.2 代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//PCF8591模数转换器
#include <stdio.h>
#include <wiringPi.h>
#include <pcf8591.h>//这个头文件是包含在库中的

#define makerobo_PCF 120 // 基础管脚120

// 主函数
int main ()
{
int pcf_value ;// 定义一个变量存储AIN的输入值

//初始化连接失败时,将消息打印到屏幕
if(wiringPiSetup() == -1){
printf("setup wiringPi failed !");
return 1;
}

pcf8591Setup (makerobo_PCF, 0x48);
// 在基本引脚120上设置pcf8591,地址0x48

while(1)
{
pcf_value = analogRead (makerobo_PCF + 0);
// 获取AIN0上的值,插上跳线帽之后,采用的是内部的电位器;
printf("%d\n", pcf_value);
// 打印出该值
analogWrite (makerobo_PCF + 0, pcf_value);
// 控制AOUT输出电平控制LED灯
delay (10) ; // 延时10ms
}
return 0 ;
}

头文件<pcf8591.h>

在wiringPi的官方库中,可以查找到关于PCF8591使用的相关函数👉点我

image-20220421225855471


3.3 编译代码

在控制台输入以下指令,编译出可执行文件TEST

1
gcc -Wall 12pcf8591.c -o TEST -lwiringPi

3.4 运行结果

在运行程序之前,我们需要先把AIN0INPUT0之间的跳线帽装上

随后./TEST运行可执行文件,屏幕上会打印出AIN0管脚上获取的值

image-20220421224306583

但是不管我咋拧模块上的白蓝电位计,这个数字都不动

后面发现这个代码必须要在树莓派的OS里面跑,才能实现控制功能,应该和3.1中的I2C总线功能有关


于是在Geany编译器中编译代码,开始执行

GIF

拧动白蓝电位计,屏幕上接收到的值会不断变化,同时LED小灯和主板上的D2-LED红色亮度也会产生变化

Screenshot_2022_0421_225038


结语

本次实验对于我这个模电小白来说就晕乎乎的,虽然查找了一些I2C相关的文档和博客,但还是没太弄明白这个模块的具体原理和进阶使用。

QQ图片20220413084241

不过通过本次这个简单的控制双色LED的实验,至少我知道了可以通过电位计来调节AOUT值,想必在更复杂的实验中,这个模块可以扮演不一样的角色!

那就只能期待未来我会用到它啦!(我怎么感觉不会呢?)

QQ图片20220419102702

纯小白,本篇博客可能有很大的纰漏,还请各位大佬无情指正!