e起DIY 低功耗I2C采集温湿度
NXP FRDM-MCXW71 主板 和DHT20温湿度传感器。
zephyr 安装和运行要大量内存和空间,因此考虑先用 NXP MCUXpresso IDE进行,先调试可采集温湿度,采用LPI2C方式。
Config Tools 配置:
启用 LPI2C1,波特率 100000。
引脚配置:A2 → SDA,A3 → SCL(功能选择对应 LPI2C1)。
DT20温湿度传感器 :硬件连接:VCC → 3.3V,GND → GND,SCL → A3, SDA → A2
先 建立driver_dht20.h,driver_dht20.C 文件来配置DHT20温湿度传感器,此代码可在网络找到。
再在主程序中用LPI2C方式将温湿度数据在串口助手上显示。
主程序如下:
#include <stdio.h>
#include "board.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "fsl_debug_console.h"
#include "peripherals.h" // 由 Config Tools 生成,包含 LPI2C 初始化
#include "fsl_lpi2c.h"
#include "driver_dht20.h" // LibDriver 驱动
// 定义 I2C 基址(与 Config Tools 配置一致,通常为 LPI2C1)
#define DHT20_I2C_BASE LPI2C1
// 定义 I2C 设备地址(驱动内部使用 0x70,即 0x38 左移一位)
#define DHT20_DEV_ADDR 0x70
// 1. I2C 初始化
static uint8_t iic_init(void) {
// 若 BOARD_InitPeripherals() 已调用,无需重复初始化
return 0; // 成功
}
// 2. I2C 去初始化
static uint8_t iic_deinit(void) {
// 一般不需要
return 0;
}
// 3. I2C 读函数:
static uint8_t iic_read_cmd(uint8_t addr, uint8_t *buf, uint16_t len) {
lpi2c_master_transfer_t transfer = {
// .slaveAddress = addr, // 0x70
.slaveAddress = addr >> 1, // 0x70 >> 1 = 0x38
.direction = kLPI2C_Read,
.data = buf,
.dataSize = len,
.flags = kLPI2C_TransferDefaultFlag
};
status_t status = LPI2C_MasterTransferBlocking(DHT20_I2C_BASE, &transfer);
return (status == kStatus_Success) ? 0 : 1;
}
// 4. I2C 写函数:
static uint8_t iic_write_cmd(uint8_t addr, uint8_t *buf, uint16_t len) {
lpi2c_master_transfer_t transfer = {
// .slaveAddress = addr, // 0x70
.slaveAddress = addr >> 1, // 0x70 >> 1 = 0x38
.direction = kLPI2C_Write,
.data = buf,
.dataSize = len,
.flags = kLPI2C_TransferDefaultFlag
};
status_t status = LPI2C_MasterTransferBlocking(DHT20_I2C_BASE, &transfer);
return (status == kStatus_Success) ? 0 : 1;
}
// 5. 毫秒延时
static void delay_ms(uint32_t ms) {
SDK_DelayAtLeastUs(ms * 1000, SystemCoreClock);
}
// 6. 调试打印(使用串口)
static void debug_print(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
va_end(args);
}
int main(void) {
// 1. 板级初始化(包括时钟、引脚、调试串口)
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
CLOCK_EnableClock(kCLOCK_Lpi2c1);
// IOCON_PinMuxSet(IOCON, 2U, IOCON_MODE_PULLUP | IOCON_FUNC1); // A2 SDA
// IOCON_PinMuxSet(IOCON, 3U, IOCON_MODE_PULLUP | IOCON_FUNC1); // A3 SCL
// 2. 初始化外设(Config Tools 生成,包含 LPI2C 初始化)
BOARD_InitPeripherals();
PRINTF("DHT20 test started.\r\n");
// 3. 创建句柄并链接底层函数
dht20_handle_t handle;
DRIVER_DHT20_LINK_INIT(&handle, dht20_handle_t); // 清空结构体
DRIVER_DHT20_LINK_IIC_INIT(&handle, iic_init);
DRIVER_DHT20_LINK_IIC_DEINIT(&handle, iic_deinit);
DRIVER_DHT20_LINK_IIC_READ_CMD(&handle, iic_read_cmd);
DRIVER_DHT20_LINK_IIC_WRITE_CMD(&handle, iic_write_cmd);
DRIVER_DHT20_LINK_DELAY_MS(&handle, delay_ms);
DRIVER_DHT20_LINK_DEBUG_PRINT(&handle, debug_print); // 可置 NULL
// 4. 初始化芯片
SDK_DelayAtLeastUs(500000, SystemCoreClock); // 500ms
if (dht20_init(&handle) != 0) {
PRINTF("DHT20 init failed.\r\n");
while (1);
}
PRINTF("DHT20 ready.\r\n");
// 5. 循环读取
while (1) {
uint32_t temp_raw, humi_raw;
float temp_c;
uint8_t humi_percent; // 0~100
if (dht20_read_temperature_humidity(&handle, &temp_raw, &temp_c, &humi_raw, &humi_percent) == 0) {
PRINTF("Temp: %.2f C, Humi: %d %%\r\n", temp_c, humi_percent);
} else {
PRINTF("Read failed.\r\n");
}
SDK_DelayAtLeastUs(2000000, SystemCoreClock); // 2秒
}
}
程序运行结果:在串口助手上显示温湿度数据。
我要赚赏金
