This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

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

Other Parts Discussed in Thread: CC2540

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.4P0.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 哈哈

  • 你好,你的问题应该出在你对IO口的配置上;我不知道你其他地方是否有问题,但这个地方应该有问题

    首先AD应配置成模拟输入方式,APCFG  = BV(HAL_ADC_CHANNEL_4) |BV(HAL_ADC_CHANNEL_5)| BV(HAL_ADC_CHANNEL_6) )| BV(HAL_ADC_CHANNEL_7) ;   APCFG会覆盖GPIO引脚的配置。

    然后调用uint16 HalAdcRead (uint8 channel, uint8 resolution),这个函数来读取AD转换的值。我测试过AD端口的电流几乎为零。

    附件上有CC254X的CPU用户指南,你可以看一下 每个外设的具体配置方法。

    swru191e CC254x 用户指南(含CPU).pdf
  • 你好 Wenzhong Shen

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

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

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

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

  • 你好 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 哈哈

  •  

    你好,原有的 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);
    }

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

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

  • 你好 Wenzhong Shen

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

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

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

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