通过ntc热敏电阻实现电池温度检测

您所在的位置:网站首页 电池温度监测 通过ntc热敏电阻实现电池温度检测

通过ntc热敏电阻实现电池温度检测

2024-07-10 16:50| 来源: 网络整理| 查看: 265

1,硬件实现:电池 NTC电阻电路如下图左侧,NTC电阻与一个10K电阻并联分压,上拉电阻为10K。CPU端通过ADC_IN2读取电压值

2,查看使用的10KC热敏电阻CN0603R103B3435JT芯片书册,查看电阻温度对照表:

3,软件实现,请参考如下:

diff --git a/arch/arm64/boot/dts/rockchip/tablet.dtsi b/arch/arm64/boot/dts/rockchip/tablet.dtsi index ff7d463..e6ea15d 100644 --- a/arch/arm64/boot/dts/rockchip/tablet.dtsi +++ b/arch/arm64/boot/dts/rockchip/tablet.dtsi @@ -195,6 +195,12 @@          };      };   +    adc_temp: adc-temp { +               compatible = "adc-bat-temperature"; +               io-channels = ; +               io-channel-names = "temp"; +       }; +      sdio_pwrseq: sdio-pwrseq {          compatible = "mmc-pwrseq-simple";          clocks = ; @@ -798,6 +804,7 @@  };    &saradc { +    vref-supply = ;      status = "okay";  };   diff --git a/arch/arm64/configs/tablet_defconfig b/arch/arm64/configs/tablet_defconfig index 3697548..4a14f6d 100644 --- a/arch/arm64/configs/tablet_defconfig +++ b/arch/arm64/configs/tablet_defconfig @@ -516,6 +516,7 @@ CONFIG_BATTERY_RK817=y  CONFIG_CHARGER_RK817=y  CONFIG_BATTERY_RK818=y  CONFIG_CHARGER_RK818=y +CONFIG_BAT_TEMP=y  CONFIG_THERMAL=y  CONFIG_THERMAL_WRITABLE_TRIPS=y  CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR=y diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index a972ebd..3b25573 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -558,6 +558,11 @@ config CHARGER_SGM41510         help           Say Y to enable support for the SGM41510 battery charger.   +config BAT_TEMP +       tristate "battery temperature driver" +       help +         Say Y to enable support for the battery temperature. +  config CHARGER_BQ24257      tristate "TI BQ24250/24251/24257 battery charger driver"      depends on I2C diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile index 02e7794..409cdc3 100644 --- a/drivers/power/supply/Makefile +++ b/drivers/power/supply/Makefile @@ -93,3 +93,4 @@ obj-$(CONFIG_CHARGER_RK817)    += rk817_charger.o  obj-$(CONFIG_BATTERY_RK818)    += rk818_battery.o  obj-$(CONFIG_CHARGER_RK818)    += rk818_charger.o  obj-$(CONFIG_CHARGER_SGM41510)    += sgm41510_charger.o +obj-$(CONFIG_BAT_TEMP) += battery_temp.o diff --git a/drivers/power/supply/battery_temp.c b/drivers/power/supply/battery_temp.c new file mode 100644 index 0000000..e5684c7 --- /dev/null +++ b/drivers/power/supply/battery_temp.c @@ -0,0 +1,220 @@ +/* + * Input driver for resistor ladder connected on ADC + * + * Copyright (c) 2016 Alexandre Belloni + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +struct adc_bat_temp_state { +    struct delayed_work update_work; +    struct iio_channel *channel; +    int temperature; +}; + +struct temp_data { +    int tempR; +    int tempC; +}; + +struct adc_bat_temp_state *g_adc_bat_temp; + +int g_value = -1; + +static const struct temp_data bat_temp_table[] = { +    {1956520, -40}, {1849171, -39}, {1748452, -38}, {1653910, -37}, {1565125, -36}, +    {1481710, -35}, {1403304, -34}, {1329576, -33}, {1260215, -32}, {1194936, -31}, +    {1133471, -30}, {1075649, -29}, {1021155, -28}, {969776, -27},  {921315, -26}, +    {875588, -25},  {832424, -24},  {791663, -23},  {753157, -22},  {716768, -21}, +    {682367, -20},  {649907, -19},  {619190, -18},  {590113, -17},  {562579, -16}, +    {536496, -15},  {511779, -14},  {488349, -13},  {466132, -12},  {445058, -11}, +    {425062, -10},  {405997, -9},   {387905, -8},   {370729, -7},   {354417, -6}, +    {338922, -5},   {324197, -4},   {310200, -3},   {296890, -2},   {284231, -1}, +    {272186, 0},    {260760, 1},    {249877, 2},    {239509, 3},    {229629, 4}, +    {220211, 5},    {211230, 6},    {202666, 7},    {194495, 8},    {186698, 9}, +    {179255, 10},   {172139, 11},   {165344, 12},   {158856, 13},   {152658, 14}, +    {146735, 15},   {141075, 16},   {135664, 17},   {130489, 18},   {125540, 19}, +    {120805, 20},   {116281, 21},   {111947, 22},   {107795, 23},   {103815, 24}, +    {100000, 25},   {96342, 26},    {92835, 27},    {89470, 28},    {86242, 29}, +    {83145, 30},    {80181, 31},    {77337, 32},    {74609, 33},    {71991, 34}, +    {69479, 35},    {67067, 36},    {64751, 37},    {62526, 38},    {60390, 39}, +    {58336, 40},    {56357, 41},    {54454, 42},    {52623, 43},    {50863, 44}, +    {49169, 45},    {47539, 46},    {45971, 47},    {44461, 48},    {43008, 49}, +    {41609, 50},    {40262, 51},    {38964, 52},    {37714, 53},    {36510, 54}, +    {35350, 55},    {34231, 56},    {33152, 57},    {32113, 58},    {31110, 59}, +    {30143, 60},    {29224, 61},    {28337, 62},    {27482, 63},    {26657, 64}, +    {25861, 65},    {25093, 66},    {24351, 67},    {23635, 68},    {22943, 69}, +    {22275, 70},    {21627, 71},    {21001, 72},    {20396, 73},    {19811, 74}, +    {19245, 75},    {18698, 76},    {18170, 77},    {17658, 78},    {17164, 79}, +    {16685, 80},    {16224, 81},    {15777, 82},    {15345, 83},    {14927, 84}, +    {14521, 85},    {14129, 86},    {13749, 87},    {13381, 88},    {13025, 89}, +    {12680, 90},    {12343, 91},    {12016, 92},    {11700, 93},    {11393, 94}, +    {11096, 95},    {10807, 96},    {10528, 97},    {10256, 98},    {9993, 99}, +    {9738, 100},    {9492, 101},    {9254, 102},    {9022, 103},    {8798, 104}, +     +}; + +#define BAT_TEMP_TEBLE_NUM (sizeof(bat_temp_table) / sizeof(bat_temp_table[0])) + +static int temp_adc_cal(const int val) +{ +    int i = 0; +    int tempR = 0; +    int retV = 0; +     +    if (val bat_temp_table[i + 1].tempR) && (tempR channel, &value); +    if (unlikely(ret < 0)) { +        /* Forcibly release key if any was pressed */ +        printk("%s --- %d adc chanel error\n", __func__,__LINE__); +    } else { +        //printk("%s --- %d adc chanel val=%d\n", __func__,__LINE__,value); +        st->temperature = temp_adc_cal(value)*10; +    } +    g_value = st->temperature; +    //printk("%s --- %d, temperature = %d\n", __func__,__LINE__,g_value); +} + +static void  my_work(struct work_struct *work) +{ +    struct adc_bat_temp_state *st = container_of(work, struct adc_bat_temp_state, +                                update_work.work); +     //int ret; +    //printk("%s %d\n",__func__,__LINE__); +         adc_bat_temp_poll(st); +    queue_delayed_work(system_wq, &st->update_work, +                        msecs_to_jiffies(1000)); +} + +static int adc_keys_probe(struct platform_device *pdev) +{ +    struct device *dev = &pdev->dev; +    struct adc_bat_temp_state *st; +    enum iio_chan_type type; +    //int value; +    int error; + +    st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); +    if (!st) +        return -ENOMEM; + +    st->channel = devm_iio_channel_get(dev, "temp"); +    if (IS_ERR(st->channel)) +        return PTR_ERR(st->channel); + +    if (!st->channel->indio_dev) +        return -ENXIO; + +    error = iio_get_channel_type(st->channel, &type); +    if (error < 0) +        return error; + +    if (type != IIO_VOLTAGE) { +        dev_err(dev, "Incompatible channel type %d\n", type); +        return -EINVAL; +    } +/* +    if (device_property_read_u32(dev, "keyup-threshold-microvolt", +                     &st->keyup_voltage)) { +        dev_err(dev, "Invalid or missing keyup voltage\n"); +        return -EINVAL; +    } +*/ +    st->temperature = -1; +    g_adc_bat_temp = st;     + +    INIT_DELAYED_WORK(&st->update_work, +            my_work); +    queue_delayed_work(system_wq, &st->update_work, msecs_to_jiffies(300)); + + +    return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id adc_bat_temp_of_match[] = { +    { .compatible = "adc-bat-temperature", }, +    { } +}; +MODULE_DEVICE_TABLE(of, adc_bat_temp_of_match); +#endif + +static struct platform_driver __refdata adc_battery_temp_driver = { +    .driver = { +        .name = "adc_batterry_temp", +        .of_match_table = of_match_ptr(adc_bat_temp_of_match), +    }, +    .probe = adc_keys_probe, +}; + +static int __init bat_temp_driver_init(void) +{ +    return platform_driver_register(&adc_battery_temp_driver); +} + +fs_initcall_sync(bat_temp_driver_init); + +static void __exit bat_temp_driver_exit(void) +{ +    platform_driver_unregister(&adc_battery_temp_driver); +} +module_exit(bat_temp_driver_exit); + +MODULE_AUTHOR("Alexandre Belloni "); +MODULE_DESCRIPTION("Battery temp for resistor ladder connected on ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c index a1d9ab9..ce6678e 100644 --- a/drivers/power/supply/cw2015_battery.c +++ b/drivers/power/supply/cw2015_battery.c @@ -49,6 +49,8 @@ static int cw_read_word(struct i2c_client *client, u8 reg, u8 buf[])      return i2c_smbus_read_i2c_block_data(client, reg, 2, buf);  }   +extern int get_bat_temp(void);//add by andy +  int cw_update_config_info(struct cw_battery *cw_bat)  {      int ret; @@ -661,7 +663,7 @@ static int cw_battery_get_property(struct power_supply *psy,          break;        case POWER_SUPPLY_PROP_TEMP: -        val->intval = VIRTUAL_TEMPERATURE; +        val->intval = get_bat_temp();          break;        default:



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3