1. 项目概述
CH347/339W是一款功能强大的USB转多协议接口芯片,能够实现SPI、I2C、JTAG、SWD、UART和GPIO等多种接口功能。这个开源项目旨在利用CH347芯片的I2C接口功能,实现与SHT40温湿度传感器的通信和数据采集。
作为一名嵌入式开发者,我经常需要与各种传感器打交道。在实际项目中,一个稳定可靠的接口转换工具可以大大提升开发效率。CH347系列芯片正好满足了这个需求,特别是其I2C接口功能,让我们能够方便地连接和测试各种I2C设备。
2. 硬件准备与连接
2.1 所需硬件清单
要完成这个项目,你需要准备以下硬件:
- CH347/339W开发板或模块
- SHT40温湿度传感器
- 杜邦线若干
- 5V电源(可选,如果使用USB供电则不需要)
- 面包板(可选,方便连接)
2.2 硬件连接示意图
SHT40与CH347的I2C接口连接非常简单:
- SHT40的VCC引脚连接CH347的3.3V或5V电源输出
- SHT40的GND引脚连接CH347的GND
- SHT40的SCL引脚连接CH347的I2C_SCL
- SHT40的SDA引脚连接CH347的I2C_SDA
注意:SHT40的工作电压范围是2.3V-5.5V,可以根据实际情况选择3.3V或5V供电。如果使用5V供电,确保CH347的I2C接口电平与SHT40兼容。
3. 软件环境搭建
3.1 开发工具准备
在Windows环境下开发CH347的I2C功能,需要准备以下工具:
- CH347的Windows驱动(可从沁恒官网下载)
- Visual Studio(建议2015或以上版本)
- CH347的SDK开发包
- i2c-tools工具(用于初步测试)
3.2 i2c-tools工具的使用
在正式开始编程前,建议先用i2c-tools工具测试硬件连接是否正常。这个工具可以扫描I2C总线上的设备,确认SHT40是否被正确识别。
bash复制# 下载编译好的i2c-tools工具
git clone https://github.com/ZhiyuanYuanNJ/CH347-I2C-TOOLS
cd CH347-I2C-TOOLS
# 运行i2c检测命令
i2cdetect -l # 列出所有I2C总线
i2cdetect -y 0 # 扫描总线0上的设备
如果一切正常,你应该能看到SHT40的I2C地址0x44出现在扫描结果中。
4. 程序设计实现
4.1 程序框架设计
整个程序采用面向对象的设计思路,主要包含以下几个部分:
- CH347设备控制类:封装CH347的打开、关闭和基本操作
- I2C通信类:专门处理I2C协议的读写操作
- 数据采集线程:周期性读取传感器数据
- 用户界面:显示温湿度数据和提供控制选项
4.2 关键代码解析
4.2.1 设备初始化
cpp复制// 打开CH347设备
m_hDev = CH347OpenDevice(m_devIndex);
if (m_hDev == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to open CH347 device" << std::endl;
return false;
}
// 设置I2C接口速率
// 位1-位0: I2C接口速度/SCL频率
// 00=低速/20KHz,01=标准/100KHz(默认值),10=快速/400KHz,11=高速/750KHz
CH347I2C_Set(m_devIndex, 1); // 设置为标准模式100KHz
4.2.2 数据采集实现
cpp复制// SHT40设备地址和命令定义
#define SHT40_ADDR 0x44
#define SHT40_COMMAND 0xfd
// 准备写入数据:设备地址(左移1位) + 命令字节
unsigned char writedata[2] = {SHT40_ADDR << 1, SHT40_COMMAND};
unsigned char readdata[6] = {0};
ULONG sht40_sensor = 0;
// 发送测量命令
BOOL ret = CH347StreamI2C_RetACK(m_devIndex, 2, writedata, 0, NULL, &sht40_sensor);
if (ret == FALSE) {
std::cerr << "Write command failed" << std::endl;
return false;
}
// 等待10ms让传感器完成测量
std::this_thread::sleep_for(std::chrono::milliseconds(10));
// 读取测量结果
ret = CH347StreamI2C_RetACK(m_devIndex, 1, writedata, 6, readdata, &sht40_sensor);
if (ret == FALSE || sht40_sensor == 0) {
std::cerr << "Read data failed" << std::endl;
return false;
}
// 数据处理
uint16_t temp_raw = (readdata[0] << 8) | readdata[1];
uint16_t rh_raw = (readdata[3] << 8) | readdata[4];
// 转换为实际温湿度值
temperature = -45.0f + 175.0f * temp_raw / 65535.0f;
humidity = -6.0f + 125.0f * rh_raw / 65535.0f;
4.3 用户界面设计
程序界面采用简单的Win32 API实现,主要包含以下元素:
- 温湿度数据显示区域
- 采集间隔设置滑块
- 开始/停止采集按钮
- 连接状态指示
界面更新通过定时器或单独的UI线程实现,确保数据显示的实时性。
5. 关键技术与原理
5.1 I2C通信协议解析
I2C协议是一种同步、半双工的串行通信协议,主要特点包括:
- 只需要两根线:SCL(时钟)和SDA(数据)
- 支持多主多从架构
- 每个设备有唯一的7位或10位地址
- 标准模式速度100Kbps,快速模式400Kbps,高速模式3.4Mbps
在SHT40的通信中,我们使用标准模式(100Kbps)进行数据传输。
5.2 SHT40传感器工作原理
SHT40是Sensirion公司推出的高精度温湿度传感器,主要特性:
- 温度测量范围:-40°C ~ +125°C
- 湿度测量范围:0% ~ 100% RH
- 温度精度:±0.2°C
- 湿度精度:±1.5% RH
- 工作电流:0.4μA(待机)~ 800μA(测量)
传感器内部集成了加热元件和信号调理电路,能够提供稳定可靠的测量结果。
5.3 CH347的I2C接口实现
CH347芯片通过USB接口模拟I2C主设备,主要特点:
- 支持标准/快速/高速模式
- 内置上拉电阻(可配置)
- 支持时钟延展
- 提供丰富的API函数
在Windows环境下,CH347通过DLL提供API接口,开发者可以方便地调用这些函数实现I2C通信。
6. 常见问题与解决方案
6.1 设备无法识别
问题现象:运行程序后无法检测到CH347设备或SHT40传感器。
可能原因及解决方案:
-
驱动未正确安装
- 重新安装CH347官方驱动
- 检查设备管理器中是否有未知设备
-
硬件连接错误
- 检查电源连接是否正确
- 确认I2C线序(SCL/SDA)没有接反
- 确保SHT40的地址设置正确(0x44)
-
I2C上拉电阻缺失
- CH347内部有可配置的上拉电阻,确保已启用
- 或外接4.7K上拉电阻
6.2 数据读取不稳定
问题现象:偶尔读取失败或数据明显错误。
解决方案:
-
降低I2C通信速率
cpp复制CH347I2C_Set(m_devIndex, 0); // 设置为低速模式20KHz -
增加读取后的延迟
cpp复制std::this_thread::sleep_for(std::chrono::milliseconds(20)); -
检查电源稳定性
- 确保电源电压稳定
- 在VCC和GND之间添加0.1μF去耦电容
6.3 性能优化建议
-
合理设置采集间隔
- 根据应用需求平衡刷新率和资源占用
- 一般环境监测0.5-1秒采集一次足够
-
批量读取数据
- 如果需要读取多个传感器,可以合理安排读取顺序
- 减少不必要的设备开关操作
-
错误处理机制
- 添加重试机制
- 实现数据校验
7. 扩展应用与进阶开发
7.1 多传感器集成
CH347的I2C接口支持多设备连接,可以同时接入多个传感器:
- 光照传感器(如BH1750)
- 气压传感器(如BMP280)
- 空气质量传感器(如SGP30)
只需为每个传感器分配不同的I2C地址,就可以实现集中监测。
7.2 数据记录与分析
扩展程序功能,实现:
- 数据存储(CSV或数据库)
- 历史数据曲线显示
- 异常报警功能
7.3 跨平台开发
除了Windows平台,还可以考虑:
- Linux平台开发(使用libusb)
- 嵌入式平台集成(如树莓派)
- 移动端APP开发(通过USB OTG)
8. 项目总结与心得
在实际开发过程中,我发现CH347芯片的I2C接口功能非常稳定可靠,特别适合快速原型开发。通过这个项目,我总结了以下几点经验:
-
硬件连接要仔细检查,特别是电源和信号线的连接顺序。我曾经因为SCL和SDA线接反,调试了半天才发现问题。
-
I2C通信速率不是越快越好。在长线或干扰较大的环境中,适当降低通信速率可以提高稳定性。
-
传感器测量需要一定的稳定时间。最初我没有添加足够的延迟,导致读取的数据不准确。后来通过示波器观察通信波形,确定了合适的等待时间。
-
错误处理很重要。在实际应用中,各种异常情况都可能发生,良好的错误处理机制可以让程序更加健壮。
这个项目展示了CH347芯片强大的多功能接口能力,后续我计划继续探索它的SPI、JTAG等功能,开发更多实用的工具和应用。