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

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

3天内不再提示

RT-Thread记录(十八、SHT21与24C02软件包)

矜辰所致 来源:矜辰所致 作者:矜辰所致 2022-07-08 11:07 次阅读
本文学习测试一下几款典型设备的 RT-Thread  I2C软件包

目录

  • 前言
  • 一、RT-Thread I2C 总线注册
    • 1.1 I2C 设备使用步骤
    • 1.2 检查问题
  • 二、温湿度传感器软件包
    • 2.1 添加及基本测试
    • 2.2 程序中使用
  • 三、EEPROM 软件包
    • 3.1 添加及基本测试
    • 3.2 程序中使用
  • 结语

前言

组件与软件包部分之前文章我们学习了 2 个组件: SFUD组件与 AT组件。 RT-Thread 丰富的生态系统,除了一些标准的组件, 还支持各种各样的软件包,上一篇文章我们已经接触过 at_device 软件包。在实际应用中很多常用的设备,都有开发者已经写好了软件包,我们可以直接添加到自己的工程使用。

本文我们就以我们常用的 I2C 设备为例,说明一下软件包的使用方式。

专栏更新到这里已经可以结尾了,组件与软件包我们只做使用记录说明,目的在于介绍一下如何使用现成的组件和软件包, 所有的包中都有作者写的 README 文件,这是最权威也最值得参考的文件,大家都可以看到说明和使用方式。

说明,本文的 I2C 接口为软件 I2C。

在开发板上,我们有2个 I2C 设备,一个是 EEPROM 24C02 和 一个 温湿度传感器 SHT21。


EEPROM:

pYYBAGLHn4GARvzGAACAh8SNL40859.png

温湿度传感器:

poYBAGLHn4GAB4jGAAB6gz1I3sY188.png

在 RT-Thread 专栏应用篇中,我们已经实现过 I2C 代码的移植,成功读取到了 温湿度的数据,这里我再次测试,是通过 RT-Thread 软件包的使用实现数据读取。

❤️
本 RT-Thread 专栏记录的开发环境:
RT-Thread记录(一、RT-Thread 版本、RT-Thread Studio开发环境 及 配合CubeMX开发快速上手)
RT-Thread记录(二、RT-Thread内核启动流程 — 启动文件和源码分析)
❤️
RT-Thread 内核篇系列博文链接:
RT-Thread记录(三、RT-Thread 线程操作函数及线程管理与FreeRTOS的比较)
RT-Thread记录(四、RT-Thread 时钟节拍和软件定时器
RT-Thread记录(五、RT-Thread 临界区保护)
RT-Thread记录(六、IPC机制之信号量、互斥量和事件集)
RT-Thread记录(七、IPC机制之邮箱、消息队列)
RT-Thread记录(八、理解 RT-Thread 内存管理)
RT-Thread记录(九、RT-Thread 中断处理与阶段小结)
❤️
STM32L051C8 上使用 RT-Thread 应用篇系列博文连接:
RT-Thread 应用篇 — 在STM32L051上使用 RT-Thread (一、无线温湿度传感器 之 新建项目)
RT-Thread 应用篇 — 在STM32L051上使用 RT-Thread (二、无线温湿度传感器 之 CubeMX配置)
RT-Thread 应用篇 — 在STM32L051上使用 RT-Thread (三、无线温湿度传感器 之 I2C通讯)
RT-Thread 应用篇 — 在STM32L051上使用 RT-Thread (四、无线温湿度传感器 之 串口通讯)
❤️
RT-Thread 设备篇系列博文链接:
RT-Thread记录(十、全面认识 RT-Thread I/O 设备模型)
RT-Thread记录(十一、I/O 设备模型之UART设备 — 源码解析)
RT-Thread记录(十二、I/O 设备模型之UART设备 — 使用测试)
RT-Thread记录(十三、I/O 设备模型之PIN设备)
RT-Thread记录(十四、I/O 设备模型之ADC设备)
RT-Thread记录(十五、I/O 设备模型之SPI设备)
❤️
RT-Thread 组件与软件包系列博文链接:
RT-Thread记录(十六、SFUD组件 — SPI Flash的读写)
RT-Thread记录(十七、AT组件 — ESP8266使用 at_device 软件包联网)

一、RT-Thread I2C 总线注册

我们以前博文讲过,RT-Thread 组件和软件包基本都是基于 RT-Thread 的设备模型,和前面讲的 SPI 设备类似,I2C 设备软件包的使用也需要先注册 I2C 总线设备到 RT-Thread 的设备管理器。

如果没有注册总线,是无法使用软件包的,比如温湿度传感器的 sht2x 软件包测试如下:

pYYBAGLHn4GACHm7AAA4eyOTi2I950.png

1.1 I2C 设备使用步骤

有了以前的学习,注册 I2C 总线对我们来说已经是小菜一碟,直接在board.h中查看软件 I2C 使用步骤:

poYBAGLHn4KALZjAAADUUTtz9b8424.png

1、首先,在 RT-Thread Studio 工程中,打开 RT-Thread Settings,使能 软件I2C 驱动,如下图所示:

pYYBAGLHn4KAVxmZAADCbNyzaiI614.png

2、根据说明和原理图修改宏定义:

poYBAGLHn4KAM6-IAACFIkoynPg172.png

只需要上面2步,I2C 设备的使用前提就准备好了,我们把程序烧录开发本,就可以看到系统在初始化的时候已经自动注册好了2个 I2C 总线:

(出问题了,并没有i2c 总线设备!!!!!! = =!)

1.2 检查问题

上面使用 I2C 设备使能,一切看上去都是没问题了:

pYYBAGLHn4KAa1fpAAA-nhjIaHc513.png

我一开始很懵,这么简单的操作我哪里会出问题了,想了很久,然后还搞不明白为什么初始化不会注册i2c总线,最后还是得去看驱动代码?

但是压根没有看到注册总线的驱动函数……(后面发现并不是studio的问题,应该是自己很久以前误操作,删除了文件……)

pYYBAGLHn4OAAP_EAAEqvzxTmv0008.png

………… 花了 …… 好多时间……最后我直接从以前的工程中复制了一份文件进来:

poYBAGLHn4OAeX-7AACTF8iitMU533.png
/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-11-08     balanceTWK   first version
 */

#include 
#include "drv_soft_i2c.h"
#include "drv_config.h"

#ifdef RT_USING_I2C

//#define DRV_DEBUG
#define LOG_TAG              "drv.i2c"
#include 

#if !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2) && !defined(BSP_USING_I2C3) && !defined(BSP_USING_I2C4)
#error "Please define at least one BSP_USING_I2Cx"
/* this driver can be disabled at menuconfig → RT-Thread Components → Device Drivers */
#endif

static const struct stm32_soft_i2c_config soft_i2c_config[] =
{
#ifdef BSP_USING_I2C1
    I2C1_BUS_CONFIG,
#endif
#ifdef BSP_USING_I2C2
    I2C2_BUS_CONFIG,
#endif
#ifdef BSP_USING_I2C3
    I2C3_BUS_CONFIG,
#endif
#ifdef BSP_USING_I2C4
    I2C4_BUS_CONFIG,
#endif
};

static struct stm32_i2c i2c_obj[sizeof(soft_i2c_config) / sizeof(soft_i2c_config[0])];

/**
 * This function initializes the i2c pin.
 *
 * @param Stm32 i2c dirver class.
 */
static void stm32_i2c_gpio_init(struct stm32_i2c *i2c)
{
    struct stm32_soft_i2c_config* cfg = (struct stm32_soft_i2c_config*)i2c->ops.data;

    rt_pin_mode(cfg->scl, PIN_MODE_OUTPUT_OD);
    rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD);

    rt_pin_write(cfg->scl, PIN_HIGH);
    rt_pin_write(cfg->sda, PIN_HIGH);
}

/**
 * This function sets the sda pin.
 *
 * @param Stm32 config class.
 * @param The sda pin state.
 */
static void stm32_set_sda(void *data, rt_int32_t state)
{
    struct stm32_soft_i2c_config* cfg = (struct stm32_soft_i2c_config*)data;
    if (state)
    {
        rt_pin_write(cfg->sda, PIN_HIGH);
    }
    else
    {
        rt_pin_write(cfg->sda, PIN_LOW);
    }
}

/**
 * This function sets the scl pin.
 *
 * @param Stm32 config class.
 * @param The scl pin state.
 */
static void stm32_set_scl(void *data, rt_int32_t state)
{
    struct stm32_soft_i2c_config* cfg = (struct stm32_soft_i2c_config*)data;
    if (state)
    {
        rt_pin_write(cfg->scl, PIN_HIGH);
    }
    else
    {
        rt_pin_write(cfg->scl, PIN_LOW);
    }
}

/**
 * This function gets the sda pin state.
 *
 * @param The sda pin state.
 */
static rt_int32_t stm32_get_sda(void *data)
{
    struct stm32_soft_i2c_config* cfg = (struct stm32_soft_i2c_config*)data;
    return rt_pin_read(cfg->sda);
}

/**
 * This function gets the scl pin state.
 *
 * @param The scl pin state.
 */
static rt_int32_t stm32_get_scl(void *data)
{
    struct stm32_soft_i2c_config* cfg = (struct stm32_soft_i2c_config*)data;
    return rt_pin_read(cfg->scl);
}
/**
 * The time delay function.
 *
 * @param microseconds.
 */
static void stm32_udelay(rt_uint32_t us)
{
    rt_uint32_t ticks;
    rt_uint32_t told, tnow, tcnt = 0;
    rt_uint32_t reload = SysTick->LOAD;

    ticks = us * reload / (1000000 / RT_TICK_PER_SECOND);
    told = SysTick->VAL;
    while (1)
    {
        tnow = SysTick->VAL;
        if (tnow != told)
        {
            if (tnow < told)
            {
                tcnt += told - tnow;
            }
            else
            {
                tcnt += reload - tnow + told;
            }
            told = tnow;
            if (tcnt >= ticks)
            {
                break;
            }
        }
    }
}

static const struct rt_i2c_bit_ops stm32_bit_ops_default =
{
    .data     = RT_NULL,
    .set_sda  = stm32_set_sda,
    .set_scl  = stm32_set_scl,
    .get_sda  = stm32_get_sda,
    .get_scl  = stm32_get_scl,
    .udelay   = stm32_udelay,
    .delay_us = 1,
    .timeout  = 100
};

/**
 * if i2c is locked, this function will unlock it
 *
 * @param stm32 config class
 *
 * @return RT_EOK indicates successful unlock.
 */
static rt_err_t stm32_i2c_bus_unlock(const struct stm32_soft_i2c_config *cfg)
{
    rt_int32_t i = 0;

    if (PIN_LOW == rt_pin_read(cfg->sda))
    {
        while (i++ < 9)
        {
            rt_pin_write(cfg->scl, PIN_HIGH);
            stm32_udelay(100);
            rt_pin_write(cfg->scl, PIN_LOW);
            stm32_udelay(100);
        }
    }
    if (PIN_LOW == rt_pin_read(cfg->sda))
    {
        return -RT_ERROR;
    }

    return RT_EOK;
}

/* I2C initialization function */
int rt_hw_i2c_init(void)
{
    rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct stm32_i2c);
    rt_err_t result;

    for (int i = 0; i < obj_num; i++)
    {
        i2c_obj[i].ops = stm32_bit_ops_default;
        i2c_obj[i].ops.data = (void*)&soft_i2c_config[i];
        i2c_obj[i].i2c2_bus.priv = &i2c_obj[i].ops;
        stm32_i2c_gpio_init(&i2c_obj[i]);
        result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c2_bus, soft_i2c_config[i].bus_name);
        RT_ASSERT(result == RT_EOK);
        stm32_i2c_bus_unlock(&soft_i2c_config[i]);
        
        LOG_D("software simulation %s init done, pin scl: %d, pin sda %d",
        soft_i2c_config[i].bus_name, 
        soft_i2c_config[i].scl, 
        soft_i2c_config[i].sda);
    }

    return RT_EOK;
}
INIT_BOARD_EXPORT(rt_hw_i2c_init);

#endif /* RT_USING_I2C */

然后就一切正常了:

pYYBAGLHn4OAX5MYAAAnIzfzwxA751.png

最开始我以为是设置问题,当时陷入里面想不明白,隔了几天回头想想,好像是以前有人问我加载软件包没用,我自己测试了一下给了回复,但是当时还是 RT-Thread 记录专栏刚开始,不需要用到软件包,然后自己因为一些警告误删除了 这个文件 (灬ꈍ ꈍ灬)…

到头来想起来原来还是自己曾经的误操作… 尴尬…… 这种问题确实在实际中会遇到……,所以提醒一下自己。

二、温湿度传感器软件包

前面的莫名的问题太影响心情了,缓一缓希望接下来一切顺利。

2.1 添加及基本测试

对于我们使用的温湿度传感器,原理图上画的是 HTU21D ,是和 sht21 pin to pin 的程序也一样的温湿度传感器,我们在软件包中心找到 sht2x 软件包,如下图:

poYBAGLHn4OAHub8AADSy0lBPcU148.png

软件包并不需要过多的设置:

pYYBAGLHn4SAUt8qAADfxlOAUys021.png

添加软件包完成,保存后重新编译工程烧录,可以看到有 sht20 的指令:

poYBAGLHn4SAO73bAACL7wwm548127.png

温湿度读取测试:

pYYBAGLHn4SAIVRXAAA3EmoU2A8923.png

2.2 程序中使用

上面我们通过命令行测试了软件包,使用起来感觉特别简单是不是,那么我们在程序中怎么调用呢?

从软件包的说明文档里面可以查看到他的操作API(只看我们测试用到的几个):

/*
根据总线名称,自动初始化对应的 SHT20 设备
参数	描述
name	i2c 设备名称
返回	描述
!= NULL	将返回 sht20 设备对象
= NULL	查找失败
*/
sht20_device_t sht20_init(const char *i2c_bus_name)

/*
读取温度
参数	描述
dev	sht20 设备对象
返回	描述
!= 0.0	测量温度值
=0.0	测量失败
*/
float sht20_read_temperature(sht20_device_t dev)

/*
读取湿度
参数	描述
dev	sht20设备对象
返回	描述
!= 0.0	测量湿度值
=0.0	测量失败
*/
float sht20_read_humidity(sht20_device_t dev)

我们用图文的方式说明一下,还是很简单的:

poYBAGLHn4SAbnxRAACp3VuCWkg499.png

测试结果:

pYYBAGLHn4WAeiZnAABrWDjlnyQ783.png

三、EEPROM 软件包

我们用的EEPROM 24C02,也有对应的软件包,有了上面传感器的例子,我们使用起来就很顺手了。

3.1 添加及基本测试

我们在软件包中心找到 at24cxx 软件包,如下图:

poYBAGLHn4WAQf4DAADY1UrNLXI903.png

软件包并不需要过多的设置:

pYYBAGLHn4WAC79gAABCSgziAjI336.png

添加软件包完成,保存后重新编译工程烧录,可以看到有 at24cxx 的指令:

poYBAGLHn4aAW9LFAABmhY4ZskI574.png

EEPROM读取测试:

这个指令读取有点小疑问,还不确定是从哪里开始读,读多少,也不知道从哪里开始写,写多少。
但是没有关系,我们如果在程序中使用,是直接调用软件包提供的 API。

poYBAGLHn4aAFK_AAABqgOiZd58881.png

3.2 程序中使用

从软件包的说明文档里面可以查看到他的操作API,或者直接找软件包的文件:

pYYBAGLHn4aAZBfDAACXldmv-zk573.png

这几个函数比较简单,从函数声明都能知道其使用方法,我们用图文的方式说明一下,首先是初始化:

poYBAGLHn4eAPOXlAABMxu-O6RM102.png

接着是读写操作:

pYYBAGLHn4eAXQEoAADvSlTRCAs072.png

测试结果:

poYBAGLHn4eAXOK2AABe7Nmy7VE010.png

结语

本文应该是很简单的软件包使用测试,没想到和上一篇文章一样,测试起来都不是那么顺利,各种坎坷 = =!

❤️
也正是说明不管东西有多简单,在实际使用过程中,难免会遇到一些意想不到的问题,理论知识是我们的立根之本,但是实际的操作才能让我们历经洗礼!

❤️
RT-Thread 组件与软件包部分使用的方式都差不多,我们暂时就更新这些,那么到目前为止 RT-Thread 专栏部分的内容也差不多可以完结了,有理论,有问题,有测试,有应用。

❤️
如果后期还有比较典型的应用,我会继续把专栏完善,希望大家多多支持!谢谢!

审核编辑:汤梓红

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

    关注

    0

    文章

    104

    浏览量

    11592
  • 24c02
    +关注

    关注

    0

    文章

    67

    浏览量

    30696
  • SHT21
    +关注

    关注

    0

    文章

    3

    浏览量

    9047
  • RT-Thread
    +关注

    关注

    31

    文章

    1286

    浏览量

    40110
收藏 人收藏

    评论

    相关推荐

    介绍RT-Thread软件包

    学习要点介绍 RT-Thread软件包;简介 nRF24L01 软件包的使用,讲解如何使用此软件包将数据正确发送和接收;学习线程间的通信
    发表于 07-27 06:07

    如何在RT-Thread Studio开发环境下使用nrf24L01软件包

    如何在RT-Thread Studio开发环境下使用nrf24L01软件包
    发表于 12-17 07:52

    使用menuconfig配置基于RT-Thread的NimBLE软件包

    最近在学习 RT-Thread 中的 NimBLE 软件包,使用 menuconfig 配置选中 NimBLE 软件包,设置各种选项后,成功通过编译并且运行起来。不过这仅仅只是按照文档说明运行了起来
    发表于 06-27 11:18

    【原创精选】RT-Thread征文精选技术文章合集

    、I/O 设备模型之SPI设备)RT-Thread记录(十六、SFUD组件 Flash读写)RT-Thread记录(十七、 AT组件-使用at软件包
    发表于 07-26 14:56

    RT-THREAD studio 2.0.0不能添加软件包能帮忙看看是什么问题吗

    1.电脑联想小新15,intel平台2.windows10专业版64位系统3.问题描述:RT-THREAD studio 2.0.0不能添加软件包4.用两台联想笔记本电脑对比过,一台能够正常添加
    发表于 11-30 10:15

    使用RT-Thread Studio开发CH32V307实现按键软件包使用

    使用上篇帖子创建的工程,使用RT-Thread Studio软件包添加工具,快速实现MultiButton的使用在RT-Thread Studio工程内打开RT-Thread Sett
    发表于 04-15 21:16

    RT-Thread 软件包介绍

    RT-Thread 软件包介绍软件包的目的软件包在高级语言中非常常见,很多高级语言都有对应的软件包平台,比如 Python 的 PyPi,R
    发表于 05-21 19:38 5561次阅读

    RT-Thread软件包定义和使用

    RT-Thread软件包是运行于RT-Thread物联网操作系统平台上,面向不同应用领域的通用软件组件 。RT-Thread 同时提供了开放
    的头像 发表于 05-21 11:29 1w次阅读
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>软件包</b>定义和使用

    RT-Thread社区上有哪些优秀的软件包

    SX12XX 软件包是基于 semtech 官网 Firmware Drivers V2.1.0代码库的移植实现,目前只支持 SX1278 LoRa设备。该软件包在原代码库功能的基础上,对接 RT-Thread SPI 设备驱动
    的头像 发表于 04-03 15:35 7638次阅读

    2022 RT-Thread全球技术大会:RT-Thread软件包

    RT-Thread在2022年上半年新增几十个软件包:rtt-rust、LuatOS、gui-guider-demo。
    的头像 发表于 05-27 14:12 1056次阅读
    2022 <b class='flag-5'>RT-Thread</b>全球技术大会:<b class='flag-5'>RT-Thread</b><b class='flag-5'>软件包</b>

    RT-Thread全球技术大会:恩智浦新增100+软件包

    RT-Thread全球技术大会:恩智浦新增100+软件包,支持了很多有用的功能。             审核编辑:彭静
    的头像 发表于 05-27 14:26 958次阅读
    <b class='flag-5'>RT-Thread</b>全球技术大会:恩智浦新增100+<b class='flag-5'>软件包</b>

    RT-Thread在线软件包改为本地软件包的方法

    RT-Thread软件包,使用时需要手动通过 ENV 工具 更新到 本地的 packages 目录,并且 packages 目录默认不参与 Git 工程管理,软件包多了,偶尔需要更改软件包
    的头像 发表于 08-11 15:02 1216次阅读
    <b class='flag-5'>RT-Thread</b>在线<b class='flag-5'>软件包</b>改为本地<b class='flag-5'>软件包</b>的方法

    RT-Thread使用cjson软件包发送64位长整型数据

    开发环境:野火的stm32f407,rt-thread studio版本是版本: 2.2.6,stm32f4的资源为0.2.2,rt-thread版本为4.1.1,cjson软件包使
    的头像 发表于 10-11 15:09 923次阅读
    <b class='flag-5'>RT-Thread</b>使用cjson<b class='flag-5'>软件包</b>发送64位长整型数据

    RT-Thread中Agile Modbus软件包的使用方法

    开发环境:野火的stm32f407,rt-thread studio版本是版本: 2.2.6,stm32f4的资源为0.2.2,Agile Modbus软件包版本为v1.1.2。工程使用上一篇
    的头像 发表于 10-11 15:37 2721次阅读
    <b class='flag-5'>RT-Thread</b>中Agile Modbus<b class='flag-5'>软件包</b>的使用方法

    RT-Thread中mymqtt软件包的使用方法

    在上一篇文章 RT-Thread中Lan8720和lwip协议栈的使用的工程基础上添加mymqtt软件包。 使能mqtt example和mqtt test,保存,等待下载更新软件包
    的头像 发表于 10-13 10:44 987次阅读
    <b class='flag-5'>RT-Thread</b>中mymqtt<b class='flag-5'>软件包</b>的使用方法