I2C 例程#
概述#
K230 芯片内部集成了 5 个 I2C 硬件模块,支持标准模式(100 kb/s)、快速模式(400 kb/s)以及高速模式(3.4 Mb/s)。这些模块非常适合在开发板上进行 I2C 通信,例如连接外设(如传感器或显示器)。I2C 通道的输出 IO 可通过 IOMUX 模块进行配置。
示例1#
以下示例展示了如何使用 I2C 4 模块读写数据的例子。
#include<stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#include <rtthread.h>
#include <rtdevice.h>
#define RT_I2C_DEV_CTRL_10BIT (0x800 + 0x01)
#define RT_I2C_DEV_CTRL_TIMEOUT (0x800 + 0x03)
#define RT_I2C_DEV_CTRL_RW (0x800 + 0x04)
#define RT_I2C_DEV_CTRL_CLK (0x800 + 0x05)
enum dm_i2c_msg_flags
{
I2C_M_TEN = 0x0010, /* ten-bit chip address */
I2C_M_RD = 0x0001, /* read data, from slave to master */
I2C_M_STOP = 0x8000, /* send stop after this message */
I2C_M_NOSTART = 0x4000, /* no start before this message */
I2C_M_REV_DIR_ADDR = 0x2000, /* invert polarity of R/W bit */
I2C_M_IGNORE_NAK = 0x1000, /* continue after NAK */
I2C_M_NO_RD_ACK = 0x0800, /* skip the Ack bit on reads */
I2C_M_RECV_LEN = 0x0400, /* length is first received byte */
I2C_M_RESTART = 0x0002, /* restart before this message */
I2C_M_START = 0x0004, /* start before this message */
};
typedef struct {
uint16_t addr;
uint16_t flags;
uint16_t len;
uint8_t *buf;
} i2c_msg_t;
typedef struct {
i2c_msg_t *msgs;
size_t number;
} i2c_priv_data_t;
int main(int argc, char *argv[])
{
int fd;
char *name = "/dev/i2c4";
rt_uint32_t spped=100000;
if (argc >= 2)
name = argv[1];
if (argc >= 3)
spped = atoi(argv[2]);
fd = open(name, O_RDWR); //打开设备
if (fd < 0 ){
printf(" %s device open failed\n", name);
return -1;
}
if (ioctl(fd, RT_I2C_DEV_CTRL_CLK, &spped) != RT_EOK){ //设置速率
printf("set %s speed %d failed!\n", name, spped);
}
for (int i = 0x08; i < 0x78; i++){
unsigned char data;
i2c_msg_t msgs={i, I2C_M_RD, 1, &data};
i2c_priv_data_t privdata={&msgs, 1};
if (ioctl(fd, RT_I2C_DEV_CTRL_RW, &privdata) == 0){ //读写数据
printf("find device at add 0x%02hx and data=%x\n", i, data);
}
}
close(fd);
}
示例2#
以下示例展示了i2c做从设备时如何动态修改设备的地址及大小的例子。
#include<stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <dfs_poll.h>
#define I2C_SLAVE_IOCTL_SET_BUFFER_SIZE 0
#define I2C_SLAVE_IOCTL_SET_ADDR 1
int main(int argc, char *argv[])
{
int fd;
char add = 0x22;
int size = 20;
int ret = 0;
if(argc < 2) {
printf("examlpe: i2c_slave.elf /dev/i2c1_slave [slave_add] [dev_size] [data]]\n");
printf("examlpe: i2c_slave.elf /dev/i2c1_slave 33 32 90\n");
return 1;
}
fd = open(argv[1], O_RDWR);
if (fd < 0) {
printf("Can't open %s\n", argv[1]);
return 1;
}
if(argc >= 3) {
add = atoi(argv[2]);
ret = ioctl(fd, I2C_SLAVE_IOCTL_SET_ADDR, &add);
if (ret) {
printf("set add %x failed!\n", add);
return 1;
}
}
if(argc >= 4) {
size = atoi(argv[3]);
ret = ioctl(fd, I2C_SLAVE_IOCTL_SET_BUFFER_SIZE, &size);
if (ret) {
printf("set size %d failed!\n", size);
return 1 ;
}
}
if(argc >= 5) {
unsigned char data = atoi(argv[4]);
lseek(fd, 0,SEEK_SET);
for(int i = 0; i < size; i++,data++)
write(fd, &data, 1);
}
{
char buffer[16];
int size = 0;
lseek(fd, 0,SEEK_SET);
//do {
size = read(fd, buffer, sizeof(buffer));
for (unsigned i = 0; i < size; i++) {
printf("%02x ", buffer[i]);
}
printf("\n");
//} while (size != 0);
}
{
struct pollfd pfd;
pfd.fd = fd;
pfd.events = POLLIN;
ret = poll(&pfd, 1, -1);
}
//printf("ret=%x\n",ret);
usleep(1000);
//printf("func =%s l=%d \n", __func__, __LINE__);
{
char buffer[16];
int size = 0;
lseek(fd, 0,SEEK_SET);
//do {
size = read(fd, buffer, sizeof(buffer));
printf("func =%s l=%d size=%X \n", __func__, __LINE__, size);
for (unsigned i = 0; i < size; i++) {
printf("%02x ", buffer[i]);
}
printf("\n");
//} while (size != 0);
}
printf("i2c_slave_addr: 0x%02x, mem_size: %d\r\n",add,size);
usleep(1000);
close(fd);
return 0;
}
提示
有关 I2C 模块的详细接口和使用方法,请参考API文档