本文將會分別介紹——使用軟件I2C和硬件I2C在PSoC開發(fā)板上獲取SHT30數(shù)字溫濕度傳感器的數(shù)據(jù)。本文實驗使用的是4線的SHT30模組,通信接口為I2C,對外僅提供四根線,使用起來簡單、便捷。本文使用的開發(fā)環(huán)境為RT-Thread Studio,設(shè)備上運行的是RT-Thread實時系統(tǒng)。本文主旨在于,介紹如何在PSoC開發(fā)板上使用軟件I2C和硬件硬件I2C驅(qū)動外設(shè)。
如需離線閱讀,可以下載本文的完整pdf版本:
*附件:【英飛凌PSoC 6 RTT開發(fā)板試用】通過I2C接口讀取SHT30傳感器的溫濕度數(shù)據(jù) 28a12ba6538e461da5c07d6ff64279b1.pdf
一、環(huán)境準備
開始之前,需要準備實驗所需的硬件和軟件,接下來分別介紹。
1.1 硬件準備
本次實驗需要用到的硬件有:
- RTT&英飛凌PSoC6評估板
- SHT30模組
- 杜邦線4根
- USB Type-C數(shù)據(jù)線
- 個人電腦,Windows 10系統(tǒng)
1.2 軟件準備
本次實驗需要使用的軟件主要為:
- RT-Thread Studio
- MobaXterm(其他串口調(diào)試工具也可以)
假設(shè)你已經(jīng)成功在電腦上安裝了以上這些軟件。
二、硬件原理分析
2.1 硬件連接
硬件連接分為兩部分,一部分是PC和開發(fā)板,通過USB Type-C線連接;這個沒啥難度,不做過多介紹;需要注意的是,開發(fā)板一端接DAP口;否則無法正常下載程序。
另外一部分是,開發(fā)板和OLED屏幕之間的連接,具體如下表所示:
SHT30模組 | 開發(fā)板引腳 |
---|---|
SCL | A0 |
SDA | A1 |
GND | GND |
VCC | 3V3 |
開發(fā)板和OLED屏幕之間的硬件連接,如下圖所示:
2.2 開發(fā)板原理圖
首先,檢查開發(fā)板原理圖的Arduino接口A0/A1部分:
這里只能看到標號,看不到主控芯片的引腳名稱。
所以,還需要繼續(xù)搜索這兩個引腳的標號,找到主控芯片對應的引腳標號:
對照前面的傳感器與開發(fā)板的連接圖,以及這兩處原理圖,可以知道——傳感器模組I2C引腳和主控芯片直接的連接關(guān)系為:
- SCL:P10.0
- SDA:P10.1
2.3 芯片數(shù)據(jù)手冊
《PSoC 6 MCU: CY8C62x8, CY8C62xA Datasheet》文檔的 Pinouts 章節(jié),Table 8. Multiple Alternate Functions 引腳功能服用表,可以查到P10.0和P10.1的功能有:
可以看到,有scb[1].i2c_scl和scb[1].i2c_sda功能。
也就是說,P10.0和P10.1可以設(shè)置為硬件I2C功能。
三、軟件I2C獲取SHT30數(shù)據(jù)
接下來,將使用RT-Thread Studio創(chuàng)建項目,并通過添加軟件包和修改配置的方式,實現(xiàn)使用軟件I2C獲取SHT30的溫濕度數(shù)據(jù)。
3.1 創(chuàng)建RT-Thread項目
在RT-Thread Studio中,打開“文件”→“新建”→”RT-Thread項目”菜單,如下圖所示:
在彈出的創(chuàng)建項目界面中,Project name中填入psoc6_sht30,選中基于開發(fā)板的項目,如下圖所示:
點擊“完成”,稍等幾秒鐘,即可創(chuàng)建名為psoc6_sht30的項目。
3.2 添加ssd1306軟件包
創(chuàng)建項目后,雙擊項目資源管理器視圖中,項目下方的“RT-Thread Settings”,主編輯區(qū)如下圖所示:
點擊其中的“添加軟件包”,彈出的軟件包搜索界面,如下圖所示:
按照圖中標注的操作順序,即可將ssd1306軟件包添加到當前項目。
添加完成后,主編輯區(qū)如下圖所示:
此時,按Ctrl+S快捷鍵,保存對項目配置的修改。如果網(wǎng)絡(luò)通常,則會在控制臺窗口中看到ssd1306軟件包正常下載的日志:
這樣,ssd1306軟件包就成功添加到項目中了,位于packages子目錄下:
3.3 配置軟件I2C引腳
接下來,在RT-Thread Studio主編輯器,點擊詳細配置按鈕,按鈕位置如下圖所示:
主編輯器將會顯示詳細配置:
切換到“硬件”標簽頁,找到“Enable Software I2C”選項,并打開該選項,如下圖所示:
接著,打開“使能I2C1 BUS”,并將scl和sda中分別改為80和81,如下圖所示:
最后,按Ctrl+S保存對所有配置項的修改。
3.4 編譯和下載程序
首先,點擊工具欄的錘子圖標,或者按Ctrl+B快捷鍵,觸發(fā)項目構(gòu)建(全部編譯):
項目構(gòu)建完成后,可以在控制臺窗口看到生成了elf文件,以及預計Flash和RAM占用情況:
接著,點擊工具欄上的下載圖標,或者Ctrl+Alt+D快捷鍵,觸發(fā)下載程序二進制文件到開發(fā)板上,如下圖:
下載過程中以及下載完成后,控制臺窗都可以看到日志輸出:
PS:開始下載之前,需要確認開發(fā)板以及和PC正確連接了(開發(fā)板要連在DAP口上,并能夠正常識別)。
3.5 運行和測試程序
為了方便在串口中進行命令控制,運行之前,需要先打開MobaXterm(或者其他串口調(diào)試工具):
如上圖所示,選中對應的COM號,串口參數(shù)設(shè)置為:
- 波特率 115200
- 數(shù)據(jù)位 8
- 停止位 1
- 校驗 None
- 流控 None
之后,點OK確認連接。
連接成功后,按開發(fā)板的復位鍵,可以看到串口連接中輸出:
可以看到i2c1成功注冊的日志。
此時輸入help命令并回車:
可以看到,有sht3x命令了。
輸入sht3x命令并回車,將會輸出用法提示:
可以看到,使用 sht3x probe 加上i2c設(shè)備名稱,可以探測傳感器;
我們先用list device看看有哪些設(shè)備:
可以看到i2c1設(shè)備了。
接下來,使用 sht3x probe i2c1 探測設(shè)備:
已經(jīng)成功探測到了。
緊接著,使用sht3x read嘗試讀取傳感器溫濕度值:
成功讀取到了溫濕度數(shù)據(jù)!
接下來,我把手指放在傳感器上,多讀幾次(上下鍵翻歷史命令,再回車,可以避免重復復輸入),應該可以看到溫度和濕度都在不斷升高:
說明傳感器是正常工作的。
四、硬件I2C獲取SHT30數(shù)據(jù)
前面通過查詢原理圖,我們知道開發(fā)板Arduino接口的A0/A1引腳可以設(shè)置為I2C1功能,接下來將在前面創(chuàng)建的項目的基礎(chǔ)上,修改代碼,實現(xiàn)通過硬件I2C1獲取SHT30的溫濕度數(shù)據(jù)。
4.1 增加硬件I2C1配置和代碼
RT-Thread Studio默認創(chuàng)建的項目不支持硬件I2C1,不能實現(xiàn)硬件I2C1驅(qū)動SHT30。因此,需要先添加I2C4配置和代碼,才能進行后續(xù)操作。
首先,修改 board/Kconfig 文件,在config BSP_USING_HW_I2C3之前添加如下代碼行:
config BSP_USING_HW_I2C1
bool "Enable I2C1 Bus (User I2C)"
default n
if BSP_USING_HW_I2C1
comment "Notice: P10_0 -- > 80; P10_1 -- > 81"
config BSP_I2C1_SCL_PIN
int "i2c4 SCL pin number"
range 1 113
default 80
config BSP_I2C1_SDA_PIN
int "i2c4 SDA pin number"
range 1 113
default 81
endif
接著,修改 libraries/HAL_Drivers/SConscript 文件,找到 src += ['drv_i2c.c'] ,將其前面的條件修改為:
if GetDepend('BSP_USING_HW_I2C1') or GetDepend('BSP_USING_HW_I2C3') or GetDepend('BSP_USING_HW_I2C6'):
src += ['drv_i2c.c']
最后,修改 libraries/HAL_Drivers/drv_i2c.c 文件,具體修改內(nèi)容為:
--- a/libraries/HAL_Drivers/drv_i2c.c
+++ b/libraries/HAL_Drivers/drv_i2c.c
@@ -11,9 +11,19 @@
#include "board.h"
#if defined(RT_USING_I2C)
-#if defined(BSP_USING_HW_I2C3) || defined(BSP_USING_HW_I2C6)
#include
+#include "drv_log.h"
+
+#ifndef I2C1_CONFIG
+#define I2C1_CONFIG \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
+ { \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
+ .name = "i2c1", \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
+ .scl_pin = BSP_I2C1_SCL_PIN, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
+ .sda_pin = BSP_I2C1_SDA_PIN, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
+ }
+#endif
+
#ifndef I2C3_CONFIG
#define I2C3_CONFIG \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
{ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
@@ -22,7 +32,7 @@
.sda_pin = BSP_I2C3_SDA_PIN, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
}
#endif /* I2C3_CONFIG */
-#endif
+
#ifndef I2C6_CONFIG
#define I2C6_CONFIG \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
{ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
@@ -34,6 +44,9 @@
enum
{
+#ifdef BSP_USING_HW_I2C1
+ I2C1_INDEX,
+#endif
#ifdef BSP_USING_HW_I2C3
I2C3_INDEX,
#endif
@@ -59,6 +72,10 @@ struct ifx_i2c
static struct ifx_i2c_config i2c_config[] =
{
+#ifdef BSP_USING_HW_I2C1
+ I2C1_CONFIG,
+#endif
+
#ifdef BSP_USING_HW_I2C3
I2C3_CONFIG,
#endif
@@ -145,8 +162,7 @@ void HAL_I2C_Init(struct ifx_i2c *obj)
int rt_hw_i2c_init(void)
{
- rt_err_t result;
- cyhal_i2c_t mI2C;
+ rt_err_t result = RT_EOK;
for (int i = 0; i < sizeof(i2c_config) / sizeof(i2c_config[0]); i++)
{
@@ -157,18 +173,18 @@ int rt_hw_i2c_init(void)
i2c_objs[i].mI2C_cfg.address = 0;
i2c_objs[i].mI2C_cfg.frequencyhal_hz = (400000UL);
- i2c_objs[i].mI2C = mI2C;
-
i2c_objs[i].i2c_bus.ops = &i2c_ops;
HAL_I2C_Init(&i2c_objs[i]);
result = rt_i2c_bus_device_register(&i2c_objs[i].i2c_bus, i2c_config[i].name);
RT_ASSERT(result == RT_EOK);
+
+ LOG_I("Hardware I2C device %s registered!", i2c_config[i].name);
}
return 0;
}
INIT_DEVICE_EXPORT(rt_hw_i2c_init);
-#endif /* defined(BSP_USING_I2C1) || defined(BSP_USING_I2C2) */
+#endif /* defined(RT_USING_I2C) */