TI中文支持网
TI专业的中文技术问题搜集分享网站

关于CC2540的AD口输入电流过大的问题

Dear TI

        想用CC2540的AD口来进行采集,开了P0.4,P0.5,P0.6,P0.7四个口,发现同样的配置。当在P0.4,P0.5口加电压的时候,系统功耗会上升很多。

        在测量的时候发现,当4个AD口都不加电压的时候,功耗大约在12.5mA左右,将电压加在P0.6,P0.7上时,功耗也几乎没有变化,但当将电压加在P0.4上是,功耗瞬间上到20mA,同时再加1路到P0.5时,系统功耗上到了26mA。测试几块板子都是这个问题。

        基本上排除了外围硬件问题,所以想问下TI的工程师,CC2540的P0.4,P0.5口怎么会吸收那么大的电流?有可能是我还有哪儿的配置有问题吗?还是什么问题。

        这是我的ADC的GPIO的配置代码:

void hal_gpio_set_adc()
{P0&= ~(BV(4)|BV(5)|BV(6)|BV(7));  //P0口低电平P0DIR&= ~(BV(4)|BV(5)|BV(6)|BV(7));  //P0口 模式:输入P0INP|= (BV(4)|BV(5)|BV(6)|BV(7));//P0口 模式:三态P0SEL|= (BV(4)|BV(5)|BV(6)|BV(7));//P0口 IO模式:第二功能
}

        外部参考电压选的 AVDD5。

        通过进一步测量发现,当将P0.4,P0.5通过1K电阻接到VCC上时,P0.4,P0.5口会流进2mA左右的电流,算出来内部大约是500欧的内阻。

        通过补充测试,为排除协议栈的干扰,在新建一个空的工程之后,在里面只做了ADC的IO口的初始化,通过1K电阻接VCC,再重新测量,发现。P0.0,P0.1,P0.2,P0.6,P0.7的电流都很小,大约只有0.02——0.05mA左右。但是P0.3,P0.4,P0.5口有2.6mA左右的电流。

        还希望TI的工程师能够不惜赐教~o(∩_∩)o 哈哈

Bob Chen2:

回复 wenzhong shen:

你好 Wenzhong Shen

        谢谢您的回复,我会进行补充测试。

        CC2540的用户手册我有看过,上面有提到在使用之前,需要将相应引脚的APCFG这个寄存器置1。

        但是,看了HalAdcRead()这个函数的代码,当它在使用哪个端口进行测量的时候,会在HalAdcRead()中将相应位的APCFG(在函数里面是ADCFG,发现和宏APCFG是一个地址)置1;并在测量完成了,将APCFG清0。所以APCFG这个寄存器并不需要我设置啊。

        这是我暂时的看法,在进行过进一步的测试之后,再给您回复~o(∩_∩)o 哈哈

Bob Chen2:

回复 wenzhong shen:

你好 Wenzhong Shen

        感谢你的指导,确实如你所说,是APCFG的问题。

P0SEL
ADCCON2
P0SEL
P0.0
P0.1
P0.2
P0.3
P0.4
P0.5
P0.6
P0.7
备注

0x00
\
\
0
0
0
0
0
0
0
0
IO口三态,不开启第二功能

0xff
0x00
0x00
0
0
0
2.2
2.2
2.2
0
0
开启IO口第二功能

0xff
0xb0
0x00
0
0
0
2.1
2.1
2.1
0
0
只配置 ADCCON2

0xff
0xb0
0xff
0
0
0
0
0
0
0
0
令 APCFG=0xff

这是在AD口接1K电阻到VCC后的补充测量结果。确实如你所说,是APCFG的配置对其有影响。通过实验发现

1.IO口只设置为3态输入,不开启第2功能的时候     无电流

2.开启第2功能的时候,不开启ADC                           有电流

3.开启第2功能,并将APCFG全置1的时候                无电流

总结:

还不知道是CC2540内部的什么外设,在初始化的时候占用了IO口,导致始终有电流流入。而在设置APCFG让AD模块独占IO口之后,电流消失。

办法:

重写了原有的 HalAdcRead()函数,取消掉其中对APCFG的配置部分。并且默认让IO口属于3态输入状态,只有真正需要测量的时候,才设置P0SEL,让它开启第二功能。

感想:

        还是不知道,具体是内部的什么吸收了那么大的电流。虽然这样处理解决了一部分问题,但仍然不是长久之策。因为如果解决不了这个问题的话,如果使用TI官方提供的HalAdcRead()函数,在不需要测量AD的时候,脚上是始终会消耗电流的,只能将第2功能暂时关闭来解决。

        还是希望能够找到那个外设,然后把它给停掉,这才是最终的解决之道。

        不过暂时就只能到这里了~

最后:

再次向你表示感谢~o(∩_∩)o 哈哈

wenzhong shen:

回复 Bob Chen2:

 

你好,原有的 HalAdcRead()函数,没有对APCFG进行配置,我不知道你用的BLE stack的哪个版本,我用的是BLE stack 1.4.0 。 下面附上原版的HalAdcRead()函数。正确的配置是,只需要在使用ADC前,对APCFG配置一下就可以了。很简单。不用配置3态输入和第二功能

uint16 HalAdcRead (uint8 channel, uint8 resolution){  int16  reading = 0;

#if (HAL_ADC == TRUE)  uint8   i, resbits;  uint8  adcChannel = 1;

  /*   * If Analog input channel is AIN0..AIN7, make sure corresponing P0 I/O pin is enabled.  The code   * does NOT disable the pin at the end of this function.  I think it is better to leave the pin   * enabled because the results will be more accurate.  Because of the inherent capacitance on the   * pin, it takes time for the voltage on the pin to charge up to its steady-state level.  If   * HalAdcRead() has to turn on the pin for every conversion, the results may show a lower voltage   * than actuality because the pin did not have time to fully charge.   */  if (channel <= HAL_ADC_CHANNEL_7)//转换序列0到7  {    for (i=0; i < channel; i++)    {      adcChannel <<= 1;    }

    /* Enable channel */    ADCCFG |= adcChannel;  }

  /* Convert resolution to decimation rate */  switch (resolution)  {    case HAL_ADC_RESOLUTION_8:      resbits = HAL_ADC_DEC_064;      break;    case HAL_ADC_RESOLUTION_10:      resbits = HAL_ADC_DEC_128;      break;    case HAL_ADC_RESOLUTION_12:      resbits = HAL_ADC_DEC_256;      break;    case HAL_ADC_RESOLUTION_14:    default:      resbits = HAL_ADC_DEC_512;      break;  }

  /* writing to this register starts the extra conversion */  ADCCON3 = channel | resbits | adcRef;

  /* Wait for the conversion to be done */  while (!(ADCCON1 & HAL_ADC_EOC));

  /* Disable channel after done conversion */  if (channel <= HAL_ADC_CHANNEL_7)    ADCCFG &= (adcChannel ^ 0xFF);

  /* Read the result */  reading = (int16) (ADCL);  reading |= (int16) (ADCH << 8);

  /* Treat small negative as 0 */  if (reading < 0)    reading = 0;

  switch (resolution)  {    case HAL_ADC_RESOLUTION_8:      reading >>= 8;      break;    case HAL_ADC_RESOLUTION_10:      reading >>= 6;      break;    case HAL_ADC_RESOLUTION_12:      reading >>= 4;      break;    case HAL_ADC_RESOLUTION_14:    default:      reading >>= 2;    break;  }#else  // unused arguments  (void) channel;  (void) resolution;#endif

  return ((uint16)reading);}

wenzhong shen:

回复 Bob Chen2:

奥,对不起,是我疏忽, HalAdcRead()确实有对APCFG进行了配置,原来APCFG和ADCCFG是指向同一个寄存器。

不过,你不用对IO进行第二功能和3态输入的配置

Bob Chen2:

回复 wenzhong shen:

你好 Wenzhong Shen

        谢谢你的指点,我都注意到了用户手册上的原话:

        "The settings in the APCFG register override the settings in P0SEL."

        但是却没有想到,我自己配置了P0SEL可能正是输入电流过大的原因。

        但如果照手册上说只是覆盖了P0SEL的配置的话,那是不是说三态其实还是需要自己配置的~o(∩_∩)o 哈哈

赞(0)
未经允许不得转载:TI中文支持网 » 关于CC2540的AD口输入电流过大的问题
分享到: 更多 (0)