rt-thread i2c 使用教程

rt-thread i2c 使用教程

rt-thread studio


1. 创建基础工程

使用芯片级的基础工程作为环境。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eGeqJ6Zv-1657039855097)(images/markdown/rtthread_i2c使用教程/image-20220706004456178.png)]

2. 配置i2c

打开i2c

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r0pjOOJ3-1657039855097)(images/markdown/rtthread_i2c使用教程/image-20220706004526762.png)]

配置驱动。

在这里插入图片描述

CTRL+S保存配置后,会重新生成工程。

修改board.h文件。取消 BSP_USING_I2C1 的注释。

/** if you want to use i2c bus(soft simulate) you can use the following instructions.
 *
 * STEP 1, open i2c driver framework(soft simulate) support in the RT-Thread Settings file
 *
 * STEP 2, define macro related to the i2c bus
 *                 such as     #define BSP_USING_I2C1
 *
 * STEP 3, according to the corresponding pin of i2c port, modify the related i2c port and pin information
 *                 such as     #define BSP_I2C1_SCL_PIN    GET_PIN(port, pin)   ->   GET_PIN(C, 11)
 *                             #define BSP_I2C1_SDA_PIN    GET_PIN(port, pin)   ->   GET_PIN(C, 12)
 */

#define BSP_USING_I2C1
#ifdef BSP_USING_I2C1
#define BSP_I2C1_SCL_PIN    GET_PIN(B, 10)
#define BSP_I2C1_SDA_PIN    GET_PIN(B, 11)
#endif
3. 代码

使用i2c 读取BMP280温湿度计。使用rt_i2c_transfer来读取和写入数据到传感器芯片。这里的温湿度驱动是我自己实现的。

#include <rtthread.h>
#include <rtdevice.h>
#include <stdio.h>
#include "bme280_i2c.h"

#define BMP280_I2C_BUS_NAME       "i2c1"
#define BME280_ADDR               0X76

static struct rt_i2c_bus_device *i2c_bus = RT_NULL;
static rt_bool_t initialized = RT_FALSE;

static int write_bytes(struct rt_i2c_bus_device *bus, uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t len)
{
    uint8_t buffer[128] = { 0 };
    buffer[0] = reg_addr;
    memcpy(buffer + 1, data, len);

    struct rt_i2c_msg msgs;
    msgs.addr = BME280_ADDR;
    msgs.flags = RT_I2C_WR;
    msgs.buf = buffer;
    msgs.len = len + 1;

    if (rt_i2c_transfer(bus, &msgs, 1) == 1)
    {
        return RT_EOK;
    }
    else
        return -RT_ERROR;
}

static int read_bytes(struct rt_i2c_bus_device *bus, uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t len)
{
    struct rt_i2c_msg msgs[2];
    msgs[0].addr = BME280_ADDR;
    msgs[0].flags = RT_I2C_WR;
    msgs[0].buf = &reg_addr;
    msgs[0].len = 1;

    msgs[1].addr = BME280_ADDR;
    msgs[1].flags = RT_I2C_RD;
    msgs[1].buf = data;
    msgs[1].len = len;

    if (rt_i2c_transfer(bus, msgs, 2) == 2)
    {
        return RT_EOK;
    }
    else
        return -RT_ERROR;
}

static int write(uint8_t slave_addr, uint8_t reg_addr, uint8_t *bytes, uint32_t len)
{
    return write_bytes(i2c_bus, BME280_ADDR, reg_addr, bytes, len);
}

static int read(uint8_t slave_addr, uint8_t reg_addr, uint8_t *bytes, uint32_t len)
{
    return read_bytes(i2c_bus, BME280_ADDR, reg_addr, bytes, len);
}

static void delay_us(uint32_t us)
{
    rt_thread_mdelay(us / 1000);
}

static int i2c_test(void)
{
    i2c_bus = (struct rt_i2c_bus_device *) rt_device_find(BMP280_I2C_BUS_NAME);
    if (i2c_bus == RT_NULL)
    {
        rt_kprintf("can't find %s device!\n", BMP280_I2C_BUS_NAME);
        return RT_ERROR;
    }

    bme280_init(write, read, delay_us, NULL, 0);
    int32_t temperature = 0;
    bme280_read_temperature(&temperature);
    rt_kprintf("temp: %d\n", temperature);

    return RT_EOK;
}

MSH_CMD_EXPORT(i2c_test, i2c test);
4. 测试

使用i2c_test 进行demo测试,读取温度为27.28℃。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a2PYPUyI-1657039855098)(images/markdown/rtthread_i2c使用教程/image-20220706004857734.png)]

KEIL


暂时无。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
RT-Thread中,可以使用DMA来提高I2C传输的效率。具体实现步骤如下: 1. 配置I2C设备 通过RT-Thread的设备驱动框架,可以配置I2C设备。在I2C设备初始化的过程中,需要指定I2C总线号、设备地址等参数。 例如,配置I2C1总线,设备地址为0x50,可以使用以下代码: ```c /* 获取I2C设备 */ struct rt_i2c_bus_device *i2c_bus = (struct rt_i2c_bus_device *)rt_device_find("i2c1"); /* 配置I2C参数 */ struct rt_i2c_msg msgs[2]; rt_uint8_t data[2]; /* 设置读写数据 */ data[0] = 0x00; data[1] = 0x01; /* 设置写数据消息 */ msgs[0].addr = 0x50; msgs[0].flags = RT_I2C_WR; msgs[0].len = 2; msgs[0].buf = data; /* 设置读数据消息 */ msgs[1].addr = 0x50; msgs[1].flags = RT_I2C_RD; msgs[1].len = 2; msgs[1].buf = data; /* 发送I2C消息 */ rt_i2c_transfer(i2c_bus, msgs, 2); ``` 2. 配置DMA设备 通过RT-Thread的设备驱动框架,可以配置DMA设备。在DMA设备初始化的过程中,需要指定DMA通道号、传输方向等参数。 例如,配置DMA1通道3,传输方向为从外设到内存,可以使用以下代码: ```c /* 获取DMA设备 */ struct rt_dma_device *dma_device = (struct rt_dma_device *)rt_device_find("dma1"); /* 配置DMA参数 */ struct rt_dma_config dma_config; dma_config.direction = RT_DMA_DEV_TO_MEM; dma_config.tran_width = RT_DMA_WIDTH_8BITS; dma_config.priority = RT_DMA_PRIORITY_HIGH; dma_config.mburst = RT_DMA_BURST_SINGLE; dma_config.pburst = RT_DMA_BURST_SINGLE; dma_config.src_addr = (rt_uint32_t)(&I2C1->DR); dma_config.dst_addr = (rt_uint32_t)(&data[0]); dma_config.buffer_size = 2; dma_config.callback = NULL; /* 配置DMA通道 */ rt_dma_configure(dma_device, 3, &dma_config); ``` 3. 启用DMA传输 在I2C设备和DMA设备都初始化之后,可以启用DMA传输。可以使用RT-Thread的设备接口函数rt_device_control来启用DMA传输。 例如,启用I2C1总线和DMA1通道3的传输,可以使用以下代码: ```c /* 启用DMA传输 */ rt_i2c_dma_transfer(i2c_bus, msgs, 2, dma_device, 3); ``` 启用DMA传输之后,当I2C总线有数据需要传输时,DMA通道就会自动进行数据传输,从而提高I2C传输的效率。 需要注意的是,启用DMA传输之前,需要先将I2C总线的中断禁用,否则可能会引起冲突。在DMA传输完成后,需要重新启用I2C总线的中断。可以使用以下代码来实现: ```c /* 禁用I2C中断 */ rt_interrupt_disable(I2C1_EV_IRQn); rt_interrupt_disable(I2C1_ER_IRQn); /* 启用DMA传输 */ rt_i2c_dma_transfer(i2c_bus, msgs, 2, dma_device, 3); /* 等待DMA传输完成 */ while (rt_dma_get_status(dma_device, 3) != RT_EOK); /* 启用I2C中断 */ rt_interrupt_enable(I2C1_EV_IRQn); rt_interrupt_enable(I2C1_ER_IRQn); ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值