高通ADC

adc dtsi中的属性配置详解:

 qcom,pre-scaling的缩放的比例是1:1还是1:3主要和要读取的电压值范围有关系,如果参考电压为1.8V,需要读取的电压范围超过1.8V,那么就要选择1:3的adc通道,这样adc可读取的电压范围就变为0~5.4V

 

 

 

在adc通道选择时,高通主要分为四类通道:无内部上拉,上拉30K、上拉100K、上拉400K电阻。

怎样去选择这几种类型的adc通道呢?

  • 读电压一般选择无内部上拉
  • 读电流或者温度会选择上拉,上拉电阻的大小和外部下拉的电阻大小有关。
  • 注意,经实际示波器抓adc信号,当配置adc通道为内部上拉时,万用表是量不出adc电压的,可能为了省电,这个adc信号是个脉冲,不是一个直流电平信号。

内部上拉的目的是给电路供电,在读温度时,adc外部接的NTC电阻,大概的原理图如下:

 

 

 NTC电阻的阻值随着温度的变化而变化,所以NTC电阻的分压也会产生变化。

 

 

 

                              NTC电阻阻值和温度对照表

软件中的对应表:qcom-vadc-common.c

 

 

 软件会进行计算出NTC电阻的分压,公式为:

1
(ADC code * vref_vadc (1.875V)) / full_scale_code

并通过对应表,读出相应的温度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
static int qcom_vadc_scale_hw_calib_therm(
                const struct vadc_prescale_ratio *prescale,
                const struct adc_data *data,
                u16 adc_code, int *result_mdec)
{
    s64 voltage = 0, result = 0;
    int ret;
 
    if (adc_code > VADC5_MAX_CODE)
        adc_code = 0;
/* (ADC code * vref_vadc (1.875V)) / full_scale_code */
    voltage = (s64) adc_code * ADC_HC_VDD_REF * 1000;
    voltage = div64_s64(voltage, (data->full_scale_code_volt
                                * 1000));              
    ret = qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb_1875_vref,
                 ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref),
                 voltage, &result);
    if (ret)
        return ret;
 
    *result_mdec = result;
 
    return 0;
}
adcmap_100k_104ef_104fb_1875_vref表对应的是100k上拉和SCALE_HW_CALIB_XOTHERM
1
2
3
4
case SCALE_HW_CALIB_THERM_100K_PULLUP:
case SCALE_HW_CALIB_XOTHERM:
    return qcom_vadc_scale_hw_calib_therm(prescale, data,
                    adc_code, result);

由下面代码可知此adc的分辨率为0x70e4

1
2
3
4
5
6
7
8
9
const struct adc_data data_pmic5 = {
    .full_scale_code_volt = 0x70e4,
    /* On PM8150B, IBAT LSB = 10A/32767 */
    .full_scale_code_cur = 10000,
    .adc_chans = adc_chans_pmic5,
    .decimation = (unsigned int []) {250, 420, 840},
    .hw_settle = (unsigned int []) {15, 100, 200, 300, 400, 500, 600, 700,
                    800, 900, 1, 2, 4, 6, 8, 10},
}; 

adc读出来的电压计算公式:

实际电压/1.875=raw值(adc值)/0x70e4(10进制为28900)。  

驱动中添加ADC通道是的注意点:

 这个ADC5_CHAN_VOLT的第二个参数为选择的分频系数,具体是按照下面这个表选择的,如果是1:1,则为0,其它的同理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static const struct vadc_prescale_ratio adc5_prescale_ratios[] = {
        {.num =  1, .den =  1},
        {.num =  1, .den =  3},
        {.num =  1, .den =  4},
        {.num =  1, .den =  6},
        {.num =  1, .den = 20},
        {.num =  1, .den =  8},
        {.num = 10, .den = 81},
        {.num =  1, .den = 10},
        {.num =  1, .den = 16},
        {.num = 40, .den = 41},         /* PM7_SMB_TEMP */
        /* Prescale ratios for current channels below */
        {.num = 32, .den = 100},        /* IIN_FB, IIN_SMB */
        {.num = 16, .den = 100},        /* ICHG_SMB */
        {.num = 1280, .den = 4100},     /* IIN_SMB_new */
        {.num = 640, .den = 4100},      /* ICHG_SMB_new */
        {.num = 1000, .den = 305185},   /* ICHG_FB */
        {.num = 1000, .den = 610370},   /* ICHG_FB_2X */
        {.num = 1000, .den = 366220},   /* ICHG_FB ADC5_GEN3 */
        {.num = 1000, .den = 732440}    /* ICHG_FB_2X ADC5_GEN3 */
};

  

 

posted @   轻轻的吻  阅读(118)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示