树莓派学习笔记 ——I2C PCF8574 SysFs方式

1.前言
    树莓派的GPIO端口数量有限,可通过IO扩展芯片增加GPIO的数量,使得树莓派可以适应更多的应用。PCF8574为一款通过I2C总线扩展IO的芯片,单个PCF8574可扩展8个IO,一个I2C总线最多可挂载8个PCF8574,所以树莓派最多可扩展64个IO。
    树莓派扩展功能的开发方法有很多,例如wiringPi和bcm2835 C library都提供I2C API函数。这些集成库封装了linux平台I2C的相关操作,如果想回归linux驱动应用设计的本质可 使用sysfs方式。Sysfs 是 Linux 2.6 所提供的一种虚拟文件系统。这个文件系统不仅可以把设备(devices)和驱动程序(drivers) 的信息从内核输出到 用户空间,也可以用来对设备和驱动程序做设置【引用自维基百科】。

2.相关博文
    【 树莓派学习笔记——I2C PCF8574 BCM2835 Library】使用BCM2835 Library实现本文相同的内容

3.PCF8574使用简述
    PCF8574的采用7位I2C地址,7位I2C地址中的低3位从高到低分别为A2 A1和A0,该3位为地址选择位,若地址选择全部接GND,那么PCF8574的I2C从机地址为0x20。图1为PCF8574的基本信息,左侧为芯片内部结构示意图,其中A2 A1和A0决定从机地址而从机地址直接影响I2C总线控制器,右侧上部为PCF8574引脚图,右侧下部为I2C从机地址组成示意图,从机地址的高4位为0100,该4位数字固定不变。

图1 PCF8574基本信息
    请注意I2C 7位从机地址和I2C 读控制字或i2C写控制器存在联系与区别,对于7位从机地址为0x20的PCF8574而言,读控制字为0x41,写控制字为0x40。若使用GPIO通过软件法模拟I2C时序时,通常把写控制字0x40定义为I2C从机地址,软件模拟时的I2C地址(0x40)和I2C 7位从机地址(0x41)存在区别。
    PCF8574内部含有8个准双向IO, 对PCF8574进行一次写操作可修改IO口的输出状态,对PCF8574进行一次读操作可获取IO口的输入状态。I2C总线的操作较为复杂,各芯片之间的差异较大,例如BH1750、AT24C04和ADXL345虽然均使用I2C接口,但是细节之处存在差异较大。

图2 PCF8574读写时序

4.代码实现——c语言
    新建一个名为pcf8574.c的文件
#include <stdio.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <errno.h>
#define I2C_ADDR 0x20
int main (void) {
    int i,value;
    int fd;
   
    // 打开设备,树莓派版本2位于i2c-1
    fd = open("/dev/i2c-1", O_RDWR);
    if (fd < 0) {
        printf("Error opening file: %s\n", strerror(errno));
        return 1;
    }
    // 设置I2C从设备地址
    if (ioctl(fd, I2C_SLAVE, I2C_ADDR) < 0) {
        printf("ioctl error: %s\n", strerror(errno));
        return 1;
    }
    while(1){
        for( i = 0 ; i < 4 ; i++ ){
           
            // 向PCF8574写入一个字节内容,实现流水灯
            value = (1<<i);
            if( write( fd , &value, 1 ) != 1) {
                printf("Error writing file: %s\n", strerror(errno));
            }
           
            // 延时100ms,usleep的延时单位为1us
            usleep(100000);
        }
    }
   
    return 0;
}

编译和执行
    gcc -o pcf8574 pcf8574.c
    sudo ./pcf8574

代码解释
fd = open("/dev/i2c-1", O_RDWR); 
    打开设备,树莓派版本2的I2C设备位于i2c-1,打开方式为可读可写。如果打开失败那么文件句柄fd为一个负数。

ioctl(fd, I2C_SLAVE, I2C_ADDR) ;
    设置I2C从设备地址,此时PCF8574的从机地址为0x20。I2C总线上可以挂在多个设备,如果需要同时操作多个I2C设备,那么使用open获得的文件句柄fd是不同的,其实文件句柄fd可以理解成一个设备的编号,不同的设备编号不同。

write( fd , &value, 1 );
    向PCF8574写入一个字节,value便是写入的内容,写入的长度为1.PCF8574内部只有一个寄存器,写该寄存器可以设置IO输出状态,读该寄存器可以获得IO输入状态。具体过程请见图2——PCF8574读写时序。与write函数对应的为read函数。其他的I2C操作函数好包括:

    【1】写入一个字节,不需要寄存器地址
  __s32 i2c_smbus_read_byte(int file);

    【2】读取一个字节,不需要寄存器地址
  __s32 i2c_smbus_write_byte(int file, __u8 value);

    【3】读取一个字节,需要写入寄存器地址
  __s32 i2c_smbus_read_byte_data(int file, __u8 command);

    【4】写入一个字节,需要写入寄存器地址
  __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value);

    【5】读取多个字节,需要写入寄存器起始地址
  __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values);

    【6】写入多个字节,需要写入寄存器起始地址
  __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length, __u8 *values);

6.总结
    突然发现linux驱动部分与I2C设备的相关的函数还不少,这些函数又和I2C设备的操作仅仅关联。请各位期待后面的博客吧。

7.参考资料
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
STM32 PCF8574是基于STM32微控制器的外设模块,其实际上是一个I2C IO扩展芯片。PCF8574具有8个IO引脚,可通过I2C总线与STM32微控制器通信。在STM32上使用PCF8574,我们可以通过I2C协议来控制和读取外部设备,从而有效扩展了STM32的IO口数量。 在使用STM32 PCF8574之前,我们需要先进行一些初始化配置。首先,我们需要配置STM32的I2C外设。我们要设置I2C通信速率和I2C地址模式,然后使能I2C,以便和PCF8574建立通信。接下来,我们可以使用相关的I2C库函数来进行I2C数据读写操作。 要控制PCF8574的GPIO输出,我们可以使用I2C库函数发送相应的命令和数据。比如,我们可以发送一个写命令和数据到PCF8574,使其输出某种电平信号。通过控制PCF8574的GPIO输出,我们可以控制外部设备,比如LED灯、继电器等。 同时,我们可以通过I2C库函数读取PCF8574的输入状态。通过读取PCF8574的输入状态,我们可以获取外部设备产生的信号,比如按键、开关等。 需要注意的是,使用PCF8574扩展IO时,由于使用了I2C总线,通信速度会相对较慢,因此需要合理规划IO资源和优化程序。此外,还需要注意I2C地址冲突的问题,确保在系统中所有I2C设备的地址唯一。 总之,STM32 PCF8574是一个非常实用的外设模块,能够帮助扩展STM32的IO口数量,实现更多的应用需求。它的使用主要涉及到STM32的I2C外设的配置和相关的数据读写操作,能够满足我们对外部设备控制和状态读取的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值