<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
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 總線設備?。。。。?! = =?。?/strong>

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

    文章

    92

    瀏覽量

    11451
  • 24c02
    +關注

    關注

    0

    文章

    67

    瀏覽量

    30617
  • SHT21
    +關注

    關注

    0

    文章

    3

    瀏覽量

    9016
  • RT-Thread
    +關注

    關注

    31

    文章

    1184

    瀏覽量

    39003
收藏 人收藏

    評論

    相關推薦

    RT-Thread Studio添加軟件包報錯怎么解決?

    RT-Thread Studio添加軟件包報錯ImportError: No module named psutil
    發表于 03-01 08:41

    送給工程師路上正迷茫的你:RT-Thread 軟件包構建指南

    對應的軟件包平臺,軟件包生態對于一門語言的選擇至關重要,本次講座將會講述如何快速構建一個可通用的軟件包,介紹RT-Thread可兼容的標準, 如posix標準;重點講解如何移植開源倉庫
    發表于 09-27 15:53

    RT-Thread OneNET軟件包的功能特點是什么?

    有哪位大神能否介紹一下OneNET 平臺 。 RT-Thread OneNET 軟件包功能特點是什么?
    發表于 04-02 06:39

    介紹RT-Thread軟件包

    學習要點介紹 RT-Thread軟件包;簡介 nRF24L01 軟件包的使用,講解如何使用此軟件包將數據正確發送和接收;學習線程間的通信
    發表于 07-27 06:07

    如何在RT-Thread Studio開發環境下使用nrf24L01軟件包?

    如何在RT-Thread Studio開發環境下使用nrf24L01軟件包?
    發表于 12-17 07:52

    使用RT-Thread操作系統驅動教程簡單記錄

    ESP8266 軟件包,此處連接的串口為 uart4 。本章使用 RT-Thread 的 STemWin 軟件包,使用 STM32 的 FSMC 接口做 lcd 的驅動,運行 STemWin的例程。為節省片
    發表于 03-22 10:51

    使用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里添加軟件包失敗怎么解決?

    rt-thread studio里使用軟件包功能,添加軟件包之后,點擊保存,在項目欄測沒有軟件包的添加
    發表于 02-13 14:14

    使用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 ?5286次閱讀

    RT-Thread軟件包定義和使用

    RT-Thread軟件包是運行于RT-Thread物聯網操作系統平臺上,面向不同應用領域的通用軟件組件 。RT-Thread 同時提供了開放
    的頭像 發表于 05-21 11:29 ?9788次閱讀
    <b class='flag-5'>RT-Thread</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軟件包使用的版本是latest。
    的頭像 發表于 10-11 15:09 ?485次閱讀
    <b class='flag-5'>RT-Thread</b>使用cjson<b class='flag-5'>軟件包</b>發送64位長整型數據

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

    在上一篇文章 RT-Thread中Lan8720和lwip協議棧的使用的工程基礎上添加mymqtt軟件包。 使能mqtt example和mqtt test,保存,等待下載更新軟件包。
    的頭像 發表于 10-13 10:44 ?624次閱讀
    <b class='flag-5'>RT-Thread</b>中mymqtt<b class='flag-5'>軟件包</b>的使用方法
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>