0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于RT-Thread的RoboMaster电控框架(二)

冬至子 来源:螺丝松掉的人 作者:螺丝松掉的人 2023-09-20 15:16 次阅读

由于 RT-Thread 稳定高效的内核,丰富的文档教程,积极活跃的社区氛围,以及设备驱动框架、Kconfig、Scons、日志系统、海量的软件包……很难不选择 RT-Thread 进行项目开发。但也正是因为这些优点的覆盖面较广,很多初学者会觉得无从下手,但只要步入 RT-Thread 的大门,你就发现她的美好。这系列文档将作为本人基于 RT-Thread 开发 RoboMaster 电控框架的记录与分享,希望能帮助到更多初识 RT-Thread 的小伙伴,也欢迎大家交流分享,指正不足,共同进步。

背景

使用的开发板为大疆的 RoboMaster-C 型开发板,基础工程为 rt-thread>bsp>stm32f407-robomaster-c

ist8310磁力计模块开发

ist8310 为 robomaster-c 开发板上集成的三轴磁力计,使用 I2C 通讯

添加 I2C 读写 API

首先将飞控程序中针对 RT-Thread 的 I2C 设备驱动封装的 I2C 读写函数借鉴过来:

rt_err_t i2c_read_reg(struct rt_i2c_bus_device bus, uint16_t slave_addr, uint8_t reg, uint8_t buffer)
{
rt_size_t ret;
struct rt_i2c_msg msgs[2];
msgs[0].addr = slave_addr;
msgs[0].flags = RT_I2C_WR | bus->flags;
msgs[0].buf = ®
msgs[0].len = 1;
msgs[1].addr = slave_addr;
msgs[1].flags = RT_I2C_RD | bus->flags;
msgs[1].buf = buffer;
msgs[1].len = 1;
ret = rt_i2c_transfer(bus, msgs, 2);
return ret == 2 ? RT_EOK : RT_ERROR;
}
rt_err_t i2c_write_reg(struct rt_i2c_bus_device *bus, uint16_t slave_addr, uint8_t reg, uint8_t val)
{
rt_size_t ret;
rt_uint8_t buffer[2];
struct rt_i2c_msg msgs;
buffer[0] = reg;
buffer[1] = val;
msgs.addr = slave_addr;
msgs.flags = RT_I2C_WR | bus->flags;
msgs.buf = buffer;
msgs.len = 2;
ret = rt_i2c_transfer(bus, &msgs, 1);
return ret == 1 ? RT_EOK : RT_ERROR;
}
rt_err_t i2c_read_regs(struct rt_i2c_bus_device bus, uint16_t slave_addr, uint8_t reg, uint8_t buffer, uint16_t count)
{
rt_size_t ret;
struct rt_i2c_msg msgs[2];
msgs[0].addr = slave_addr;
msgs[0].flags = RT_I2C_WR | bus->flags;
msgs[0].buf = ®
msgs[0].len = 1;
msgs[1].addr = slave_addr;
msgs[1].flags = RT_I2C_RD | bus->flags;
msgs[1].buf = buffer;
msgs[1].len = count;
ret = rt_i2c_transfer(bus, msgs, 2);
return ret == 2 ? RT_EOK : RT_ERROR;
}
rt_err_t i2c_write_regs(struct rt_i2c_bus_device bus, uint16_t slave_addr, uint8_t reg, uint8_t vals, uint16_t count)
{
rt_size_t ret;
struct rt_i2c_msg msgs[2];
msgs[0].addr = slave_addr;
msgs[0].flags = RT_I2C_WR | bus->flags;
msgs[0].buf = ®
msgs[0].len = 1;
msgs[1].addr = slave_addr;
msgs[1].flags = RT_I2C_WR | bus->flags;
msgs[1].buf = vals;
msgs[1].len = count;
ret = rt_i2c_transfer(bus, msgs, 2);
return ret == 2 ? RT_EOK : RT_ERROR;
}

BSP 中 STM32 I2C 设备驱动使用的是软件 I2C,于是进入到 menuconfig 中对 I2C 引脚进行配置:

/* Notice: PA8 --> 8; PC9 --> 41 */
#define BSP_I2C1_SCL_PIN 8
#define BSP_I2C1_SDA_PIN 41
IST8310 驱动

主要就是先对 IST8310 进行初始化,设置相关采样参数,之后就可以读取磁力计的信息

static rt_err_t mag_raw_measure(int16_t mag[3])
{
uint8_t buffer[6];
i2c_read_regs(i2c_bus, IST8310_ADDRESS, REG_DATA_OUT_X_L, buffer, sizeof(buffer));
/* swap the data /
mag[0] = ((int16_t)buffer[1] << 8) | (int16_t)buffer[0];
mag[1] = ((int16_t)buffer[3] << 8) | (int16_t)buffer[2];
mag[2] = ((int16_t)buffer[5] << 8) | (int16_t)buffer[4];
/
start next measurement /
// i2c_write_reg(i2c_bus, IST8310_ADDRESS, REG_CTRL1, CTRL1_ODR_SINGLE));
return RT_EOK;
}
static rt_err_t mag_measure(float mag[3])
{
int16_t raw[3];
mag_raw_measure(raw);
mag[0] = _range_scale * raw[0];
mag[1] = _range_scale * raw[1];
mag[2] = _range_scale * raw[2];
ist8310_rotate_to_frd(mag);
if (ist8310_user_calibrate != RT_NULL) {
/
do user defined calibration */
ist8310_user_calibrate(mag);
}
return RT_EOK;
}

其中 ist8310_user_calibrate 和 ist8310_rotate_to_frd 为预留的虚函数,用户可根据校准及转化需求,自行定义实现。

attribute ((weak)) void ist8310_user_calibrate(float data[3]);
/* Re-implement this function to define customized rotation /
attribute ((weak)) void ist8310_rotate_to_frd(float
data);

抽象设备

为提高程序的模块化,选用不同传感器时的灵活性,将 ist8310 抽象为 mag 一类设备,抽象出 mag_init 和 mag_read 两个操作方法。

struct mag_ops{
rt_err_t (mag_init)(const char i2c_bus_name);
rt_err_t (*mag_read)(float data[3]);
};

项目选用不同的磁力计传感器时,对接这两个接口即可,以 ist8310 为例:

/**

@brief 调用此函数初始化 ist8310

@param i2c_bus_name ist8310 所挂载的总线名称

@return RT_EOK
/
static rt_err_t drv_ist8310_init(const char
i2c_bus_name);
/**
@brief 调用此函数读取 ist8310 数据

@param data[3] 存储读取数据的数组

@return 读取成功 RT_EOK ; 读取失败 -RT_ERROR
*/
static rt_err_t ist8310_read(float data[3]);
struct mag_ops mag = {
.mag_init = drv_ist8310_init,
.mag_read = ist8310_read,
};

应用层需要使用磁力计时,调用 mag_ops 中的操作方法即可:

static float read_data[3];
mag.mag_init("i2c1"); // 初始化 mag 设备
mag.mag_read(read_data); // 将设备数据读取到 read_data 中

到此就可以方便的使用磁力计模块啦

存在问题及优化方向

目前为了提高性能,mag设备的注册对接形式是比较简陋的。
后续考虑能不能也优化为,read,write,control 等形式。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 传感器
    +关注

    关注

    2550

    文章

    51071

    浏览量

    753330
  • STM32
    +关注

    关注

    2270

    文章

    10897

    浏览量

    355865
  • I2C通信
    +关注

    关注

    0

    文章

    22

    浏览量

    8827
  • 三轴磁力计
    +关注

    关注

    0

    文章

    7

    浏览量

    8389
  • RT-Thread
    +关注

    关注

    31

    文章

    1286

    浏览量

    40109
收藏 人收藏

    评论

    相关推荐

    RT-Thread记录(RT-Thread内核启动流程)

    在前面我们RT-Thread Studio工程基础之上讲一讲RT-Thread内核启动流程.
    的头像 发表于 06-20 00:30 5032次阅读
    <b class='flag-5'>RT-Thread</b>记录(<b class='flag-5'>二</b>、<b class='flag-5'>RT-Thread</b>内核启动流程)

    基于RT-ThreadRoboMaster电控框架设计

    由于 RT-Thread 稳定高效的内核,丰富的文档教程,积极活跃的社区氛围,以及设备驱动框架、Kconfig、Scons、日志系统、海量的软件包……很难不选择 RT-Thread 进行项目开发。
    发表于 09-06 15:21 701次阅读

    RT-Thread全球技术大会:RT-Thread上的单元测试框架与运行测试用例

    RT-Thread全球技术大会:RT-Thread上的单元测试框架与运行测试用例                 审核编辑:彭静
    的头像 发表于 05-27 16:21 1624次阅读
    <b class='flag-5'>RT-Thread</b>全球技术大会:<b class='flag-5'>RT-Thread</b>上的单元测试<b class='flag-5'>框架</b>与运行测试用例

    RT-Thread设备模型框架及创建注册设备的实现

    RT-Thread设备模型框架及创建注册设备的实现方式介绍如下:
    的头像 发表于 05-28 10:38 2185次阅读
    <b class='flag-5'>RT-Thread</b>设备模型<b class='flag-5'>框架</b>及创建注册设备的实现

    RT-Thread文档_RT-Thread 简介

    RT-Thread文档_RT-Thread 简介
    发表于 02-22 18:22 5次下载
    <b class='flag-5'>RT-Thread</b>文档_<b class='flag-5'>RT-Thread</b> 简介

    RT-Thread文档_RT-Thread SMP 介绍与移植

    RT-Thread文档_RT-Thread SMP 介绍与移植
    发表于 02-22 18:31 9次下载
    <b class='flag-5'>RT-Thread</b>文档_<b class='flag-5'>RT-Thread</b> SMP 介绍与移植

    RT-Thread文档_utest 测试框架

    RT-Thread文档_utest 测试框架
    发表于 02-22 18:43 2次下载
    <b class='flag-5'>RT-Thread</b>文档_utest 测试<b class='flag-5'>框架</b>

    浅析RT-Thread设备驱动框架

    RT-Thread 设备框架属于组件和服务层,是基于 RT-Thread 内核之上的上层软件。设备框架是针对某一类外设,抽象出来的一套统一的操作方法及接入标准,可以屏蔽硬件差异,为应用
    的头像 发表于 08-07 15:39 1963次阅读

    基于 RT-ThreadRoboMaster 电控框架(一)

    。但也正是因为这些优点的覆盖面较广,很多初学者会觉得无从下手,但只要步入 RT-Thread 的大门,你就发现她的美好。这系列文档将作为本人基于 RT-Thread 开发 RoboMaster
    的头像 发表于 09-19 19:55 763次阅读

    基于RT-ThreadRoboMaster电控框架(三)

    使用的开发板为大疆的 RoboMaster-C 型开发板,基础工程为 rt-thread>bsp>stm32f407-robomaster-c
    的头像 发表于 09-20 15:21 859次阅读

    基于RT-ThreadRoboMaster电控框架(四)

    使用的开发板为大疆的 RoboMaster-C 型开发板,基础工程为 rt-thread>bsp>stm32f407-robomaster-c
    的头像 发表于 09-20 15:28 725次阅读

    RT-Thread框架下的SMP支持

    使其支持 RT-Thread 框架下的 SMP,最近就一直在研究 SMP,并在 Raspberry-Pico 上做了一些实验。
    的头像 发表于 10-11 10:34 1129次阅读
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>框架</b>下的SMP支持

    基于rt-thread的socket通信设计

    最近再研究 rt-thread 的通信 ,想设计出 eps8266(多个) rt-thread(作为中控) 服务器的通信框架,使用的开发板是 潘多拉
    的头像 发表于 10-13 15:02 1365次阅读
    基于<b class='flag-5'>rt-thread</b>的socket通信设计

    基于RT-ThreadRoboMaster电控框架(五)

    使用的开发板为大疆的 RoboMaster-C 型开发板,基础工程为 rt-thread>bsp>stm32f407-robomaster-c
    的头像 发表于 10-30 17:10 1195次阅读

    基于RT-ThreadRoboMaster电控框架(六)

    使用的开发板为大疆的 RoboMaster-C 型开发板,基础工程为 rt-thread>bsp>stm32f407-robomaster-c
    的头像 发表于 10-30 17:41 484次阅读