添加ads111x驱动,侦测各电源总线状态

This commit is contained in:
sc committed 2026-01-01 14:00:05 +08:00
1 parent 5bdb8cbe2b
commit 7f6c30553b
8 files changed
+273 -8

No files matched your search

+4
View File
@@ -132,6 +132,10 @@ void pasre_DAT(const char *api, const char *json_str)
cJSON_AddItemToObject(dat,"SYSHUM",cJSON_CreateNumber(sys_humidity));
cJSON_AddItemToObject(dat,"SYSTIME",cJSON_CreateString(systime));
cJSON_AddItemToObject(dat,"NAME",cJSON_CreateString(machine_name));
cJSON_AddItemToObject(dat,"PBAT",cJSON_CreateNumber(pow_bat));
cJSON_AddItemToObject(dat,"PCODE",cJSON_CreateNumber(pow_code));
cJSON_AddItemToObject(dat,"PDEV1",cJSON_CreateNumber(pow_dev1));
cJSON_AddItemToObject(dat,"PDEV2",cJSON_CreateNumber(pow_dev2));
cJSON_AddItemToObject(dat,"VAR",cJSON_CreateString(sys_var));
}
else if (strcmp(api, "SC810") == 0)
+4 -1
View File
@@ -8,7 +8,10 @@ rt_int32_t sys_humidity;//主机环境湿度
char sys_var[8];//主机版本0.0.00A
unsigned char sys_time[6];//系统时间
unsigned int sys_run_time;//运行时间
int pow_bat;//电池电压
int pow_code;//主电压
int pow_dev1;//设备电压.通讯
int pow_dev2;//设备电压,其它
// 动态数据缓冲区(初始化为 NULL,后续分配)
char *DATA_dat;
+4
View File
@@ -9,6 +9,10 @@ extern rt_int32_t sys_humidity;//主机环境湿度
extern char sys_var[8];//主机版本0.0.00A
extern unsigned char sys_time[6];//系统时间
extern unsigned int sys_run_time;//运行时间
extern int pow_bat;//电池电压
extern int pow_code;//主电压
extern int pow_dev1;//设备电压.通讯
extern int pow_dev2;//设备电压,其它
// ===== 字符串变量 =====
extern char *DATA_dat;
+226
View File
@@ -0,0 +1,226 @@
/*
* Copyright (c) 2025, Your Name
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-12-27 Developer First version for ADS1115 on RT-Thread
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include "Variable.h"
#define DBG_TAG "sensor.ads1115"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
/* ADS1115 I2C 地址(A0 引脚接地时为 0x48) */
#define ADS1115_I2C_ADDR 0x48
/* 使用的 I2C 总线设备名 */
#define ADS1115_I2C_BUS_NAME "i2c2" // 根据你的板子修改,如 "i2c1"
/* ADS1115 寄存器地址 */
#define ADS1115_REG_CONVERT 0x00
#define ADS1115_REG_CONFIG 0x01
static struct rt_i2c_bus_device *i2c_bus = RT_NULL;
/**
* 向 ADS1115 写入配置寄存器
*/
static rt_err_t ads1115_write_config(rt_uint16_t config)
{
rt_uint8_t buf[3] = {
ADS1115_REG_CONFIG,
(rt_uint8_t)(config >> 8),
(rt_uint8_t)(config & 0xFF)
};
struct rt_i2c_msg msgs[1] = {
{
.addr = ADS1115_I2C_ADDR,
.flags = RT_I2C_WR,
.buf = buf,
.len = 3,
}
};
if (rt_i2c_transfer(i2c_bus, msgs, 1) != 1)
{
LOG_E("Failed to write config register.");
return -RT_ERROR;
}
return RT_EOK;
}
/**
* 从 ADS1115 读取转换结果
*/
static rt_err_t ads1115_read_conversion(rt_int16_t *value)
{
rt_uint8_t buf[2] = {0};
struct rt_i2c_msg msgs[2] = {
{
.addr = ADS1115_I2C_ADDR,
.flags = RT_I2C_WR,
.buf = (rt_uint8_t[]){ADS1115_REG_CONVERT},
.len = 1,
},
{
.addr = ADS1115_I2C_ADDR,
.flags = RT_I2C_RD,
.buf = buf,
.len = 2,
}
};
if (rt_i2c_transfer(i2c_bus, msgs, 2) != 2)
{
LOG_E("Failed to read conversion register.");
return -RT_ERROR;
}
*value = (rt_int16_t)((buf[0] << 8) | buf[1]);
return RT_EOK;
}
/**
* 读取指定通道的 ADC 值(单端输入)
* channel: 0 ~ 3 (对应 AIN0~AIN3 对 GND)
* 返回:RT_EOK 或错误码
*/
static rt_err_t ads1115_read_channel(rt_uint8_t channel, rt_int16_t *raw_value)
{
if (channel > 3)
{
LOG_E("Invalid channel: %d", channel);
return -RT_EINVAL;
}
// 配置:OS=1, MUX=100+ch (单端), PGA=001 (±4.096V), MODE=1 (single), DR=100 (128SPS)
rt_uint16_t config = 0x8000 | // OS = 1
((0x04 | channel) << 12) | // MUX: AINx vs GND
(0x01 << 9) | // PGA = ±4.096V
(0x01 << 8) | // MODE = single-shot
(0x04 << 5); // DR = 128 SPS
if (ads1115_write_config(config) != RT_EOK)
{
return -RT_ERROR;
}
rt_thread_mdelay(10); // 等待转换完成(128SPS ≈ 8ms)
return ads1115_read_conversion(raw_value);
}
/**
* 将原始 ADC 值转换为毫伏(mV)
* 假设使用 ±2.048V 量程(PGA=1),则 LSB = 2.048V / 32768 ≈ 0.0625 mV/LSB
* 但因为是单端且参考地,实际范围 0~2.048V → 满量程 2.048V = 32768 LSB
* 所以:Voltage(mV) = raw * (2048 / 32768) = raw * 0.0625
*/
static rt_int32_t ads1115_raw_to_mv(rt_int16_t raw)
{
/* 注意:单端模式下,raw 应为正数(0 ~ 32767)*/
return (rt_int32_t)(((rt_int64_t)raw * 125) / 1000); // 等价于 raw * 0.0625 * 1000
}
/**
* ADS1115 读取线程(示例:读取 AIN0)
*/
static void ads1115_thread_entry(void *parameter)
{
rt_int16_t raw = 0 ,mt = 3600;
while (1)
{
if(mt>3600)
{
if (ads1115_read_channel(0, &raw) == RT_EOK)
{
pow_bat = ads1115_raw_to_mv(raw);
}
else
{
LOG_E("Failed to read ADS1115 P_BAT");
}
}
else
{
mt = 0;
}
if (ads1115_read_channel(1, &raw) == RT_EOK)
{
pow_code = ads1115_raw_to_mv(raw);
}
else
{
LOG_E("Failed to read ADS1115 P_CODE");
}
if (ads1115_read_channel(2, &raw) == RT_EOK)
{
pow_dev1 = ads1115_raw_to_mv(raw);
}
else
{
LOG_E("Failed to read ADS1115 P_DEV1");
}
if (ads1115_read_channel(3, &raw) == RT_EOK)
{
pow_dev2 = ads1115_raw_to_mv(raw);
}
else
{
LOG_E("Failed to read ADS1115 P_DEV2");
}
rt_thread_mdelay(1000); // 每 秒读取一次
}
}
/**
* ADS1115 驱动初始化函数
*/
static int rt_hw_ads1115_init(void)
{
i2c_bus = rt_i2c_bus_device_find(ADS1115_I2C_BUS_NAME);
if (i2c_bus == RT_NULL)
{
LOG_E("Failed to find I2C bus: %s", ADS1115_I2C_BUS_NAME);
return -RT_ENOSYS;
}
LOG_I("Found I2C bus: %s", ADS1115_I2C_BUS_NAME);
/* 创建读取线程 */
rt_thread_t tid = rt_thread_create("ads1115",
ads1115_thread_entry,
RT_NULL,
512,
RT_THREAD_PRIORITY_MAX - 2,
10);
if (tid != RT_NULL)
{
rt_thread_startup(tid);
}
else
{
LOG_E("Failed to create ADS1115 thread.");
return -RT_ERROR;
}
return RT_EOK;
}
/* 自动初始化 */
INIT_APP_EXPORT(rt_hw_ads1115_init);