文档首页>
Atlas 200 DK 开发者套件(1.0.7.alpha)>
外围设备驱动接口操作指南>
GPIO操作指南>
PCA6416扩展GPIO操作示例>
操作示例>
用户态PCA6416扩展GPIO操作程序示例
更新时间:2021-03-18 GMT+08:00
用户态PCA6416扩展GPIO操作程序示例
此操作示例在用户态通过控制I2C设备实现对PCA6416的控制,从而实现对PCA6416扩展IO的输入输出操作。
- 由于PCA6416连接的是I2C-1,打开I2C-1设备文件,获取文件描述符;
- 通过I2C读写操作,读写PCA6416的寄存器,从而配置PCA6416扩展IO的输入输出特性,包括GPIO输入输出属性配置,GPIO输出电平配置,获取当前GPIO管脚电平状态等。
- 操作完成后,关闭I2C-1设备。
代码示例如下:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/select.h> #include <sys/time.h> #include <errno.h> #include <string.h> /* I2C Device*/ #define I2C0_DEV_NAME "/dev/i2c-0" #define I2C1_DEV_NAME "/dev/i2c-1" #define I2C2_DEV_NAME "/dev/i2c-2" #define I2C3_DEV_NAME "/dev/i2c-3" #define I2C_RETRIES 0x0701 #define I2C_TIMEOUT 0x0702 #define I2C_SLAVE 0x0703 #define I2C_RDWR 0x0707 #define I2C_BUS_MODE 0x0780 #define I2C_M_RD 0x01 #define PCA6416_SLAVE_ADDR 0x20 #define PCA6416_GPIO_CFG_REG 0x07 #define PCA6416_GPIO_PORARITY_REG 0x05 #define PCA6416_GPIO_OUT_REG 0x03 #define PCA6416_GPIO_IN_REG 0x01 //GPIO MASK #define GPIO3_MASK 0x10 #define GPIO4_MASK 0x20 #define GPIO5_MASK 0x40 #define GPIO6_MASK 0x80 #define GPIO7_MASK 0x08 struct i2c_msg { unsigned short addr; /* slave address */ unsigned short flags; unsigned short len; unsigned char *buf; /* message data pointer */ }; struct i2c_rdwr_ioctl_data { struct i2c_msg *msgs; /* i2c_msg[] pointer */ int nmsgs; /* i2c_msg Nums */ }; int fd = 0; /* * i2c_write, for configure PCA6416 register. */ int i2c_write(unsigned char slave, unsigned char reg, unsigned char value) { int ret; struct i2c_rdwr_ioctl_data ssm_msg = {0}; unsigned char buf[2] = {0}; ssm_msg.nmsgs = 1; ssm_msg.msgs = (struct i2c_msg *)malloc(ssm_msg.nmsgs * sizeof(struct i2c_msg)); if (ssm_msg.msgs == NULL) { printf("Memory alloc error!\n"); return -1; } buf[0] = reg; buf[1] = value; (ssm_msg.msgs[0]).flags = 0; (ssm_msg.msgs[0]).addr = (unsigned short)slave; (ssm_msg.msgs[0]).buf = buf; (ssm_msg.msgs[0]).len = 2; ret = ioctl(fd, I2C_RDWR, &ssm_msg); if (ret < 0) { printf("write error, ret=%#x, errorno=%#x, %s!\n", ret, errno, strerror(errno)); free(ssm_msg.msgs); ssm_msg.msgs = NULL; return -1; } free(ssm_msg.msgs); ssm_msg.msgs = NULL; return 0; } /* * i2c_read, for reading PCA6416 register. */ int i2c_read(unsigned char slave, unsigned char reg, unsigned char *buf) { int ret; struct i2c_rdwr_ioctl_data ssm_msg = {0}; unsigned char regs[2] = {0}; regs[0] = reg; regs[1] = reg; ssm_msg.nmsgs = 2; ssm_msg.msgs = (struct i2c_msg *)malloc(ssm_msg.nmsgs * sizeof(struct i2c_msg)); if (ssm_msg.msgs == NULL) { printf("Memory alloc error!\n"); return -1; } (ssm_msg.msgs[0]).flags = 0; (ssm_msg.msgs[0]).addr = slave; (ssm_msg.msgs[0]).buf = regs; (ssm_msg.msgs[0]).len = 1; (ssm_msg.msgs[1]).flags = I2C_M_RD; (ssm_msg.msgs[1]).addr = slave; (ssm_msg.msgs[1]).buf = buf; (ssm_msg.msgs[1]).len = 1; ret = ioctl(fd, I2C_RDWR, &ssm_msg); if (ret < 0) { printf("read data error,ret=%#x !\n", ret); free(ssm_msg.msgs); ssm_msg.msgs = NULL; return -1; } free(ssm_msg.msgs); ssm_msg.msgs = NULL; return 0; } /* * i2c_init, for access i2c device. */ int i2c_init(char *i2cdev_name) { // open i2c-1 device fd = open(i2cdev_name, O_RDWR); if (fd < 0) { printf("Can't open %s!\n", i2cdev_name); return -1; } // set i2c-1 retries time if (ioctl(fd, I2C_RETRIES, 1) < 0) { close(fd); fd = 0; printf("set i2c retry fail!\n"); return -1; } // set i2c-1 timeout time, 10ms as unit if (ioctl(fd, I2C_TIMEOUT, 1) < 0) { close(fd); fd = 0; printf("set i2c timeout fail!\n"); return -1; } return 0; } int main(int argc, char *argv[]) { char *dev_name = I2C1_DEV_NAME; unsigned char slave; unsigned char reg; unsigned char data; int ret; if (i2c_init(dev_name)) { printf("i2c init fail!\n"); return -1; } usleep(100); // set GPIO3 as output slave = PCA6416_SLAVE_ADDR; reg = PCA6416_GPIO_CFG_REG; data = 0; ret = i2c_read(slave, reg, &data); if (ret != 0) { close(fd); fd = 0; printf("read %s %#x %#x to %#x fail!\n", dev_name, slave, data, reg); return -1; } slave = PCA6416_SLAVE_ADDR; reg = PCA6416_GPIO_CFG_REG; data &= ~GPIO3_MASK; ret = i2c_write(slave, reg, data); if (ret != 0) { close(fd); fd = 0; printf("write %s %#x %#x to %#x fail!\n", dev_name, slave, data, reg); return -1; } // Set GPIO3 output high level slave = PCA6416_SLAVE_ADDR; reg = PCA6416_GPIO_OUT_REG; data = 0; ret = i2c_read(slave, reg, &data); if (ret != 0) { close(fd); fd = 0; printf("read %s %#x %#x to %#x fail!\n", dev_name, slave, data, reg); return -1; } slave = PCA6416_SLAVE_ADDR; reg = PCA6416_GPIO_OUT_REG; data |= GPIO3_MASK; ret = i2c_write(slave, reg, data); if (ret != 0) { close(fd); fd = 0; printf("write %s %#x %#x to %#x fail!\n", dev_name, slave, data, reg); return -1; } close(fd); fd = 0; return 0; }
父主题: 操作示例
