通过ntc热敏电阻实现电池温度检测 |
您所在的位置:网站首页 › 电池温度监测 › 通过ntc热敏电阻实现电池温度检测 |
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 |