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.

zigbee协议栈adc通道0使用方法?

Other Parts Discussed in Thread: CC2530

void GenericApp_Init( uint8 task_id )
{
APCFG |= 1<<0 ; //p0_0口设置为adc功能
HalAdcInit();
HalAdcSetReference(HAL_ADC_REF_125V);
Init_GPIO();

我代码中关于ad通道0的处理是这样的,但是为什么这个ad的口好像拉不低的样子,只要是往ad输入一个低于2.5v的采样值,他就会莫名其妙拉到2.8v,是什么原因啊?是我哪边设置出了问题吗,具体该如何使用?

  • 你有用 HalAdcRead(HAL_ADC_CHN_AIN0,HAL_ADC_RESOLUTION_10)去讀adc通道0?
  • for(i=0;i<100;i++)
    {
    sum += HalAdcRead(HAL_ADC_CHANNEL_0,HAL_ADC_RESOLUTION_12);
    }
    voltage = sum / 100 ;
    嗯,只不过我用的是12位的
  • 你设置一下IO为输入.
  • 设置了,但是发现一个很尴尬的,我1点几伏的电压过去,值却很大,6,7000
  • 举个例子:
    HAL_ADC_REF_125V 对吧

    你硬件有没有问题啊,你测一下你p0_0给的进去的电压是多少

    我怀疑你板子是不是p0_0有可能被设置为led了

  • 是不是程序其他地方把adc通道0設置成其他IO使用了
  • 按照道理来讲,1.15v过去,ad值应该是2047或者4095才对吧,这不是12位的吗?
  • 你到底是几位的,12bit最大到2047,你先去看看你的P0_0 有没有其他复用
  • 能不能把一个标准写法过来,我看看是不是我这边哪边出了问题
  • 他打不开的,我把你的贴一下:
    1. Read ADC value from P0_2 using HAL_ADC_REF_125V as reference voltage and HAL_ADC_RESOLUTION_10 as ADC resolution.

    uint16 adc_ain2=0;
    HalAdcSetReference(HAL_ADC_REF_125V);
    adc_ain2=HalAdcRead(HAL_ADC_CHN_AIN2,HAL_ADC_RESOLUTION_10);



    The max measurable voltage of P0_2 is 1.15 because I am using HAL_ADC_REF_125V as reference voltage here. If the input voltage is larger than 1.15V, the ADC reading adc_ain2 will be always 511. If I connect P0_2 to 0.5V, I will have ADC reading adc_ain2=223. Then, we can convert the reading 223 to measured voltage using the following equation.
    measured voltage = 1.15x223/511=0.501...

    2. If I change HAL_ADC_RESOLUTION_12 (the max reading is 2047) as ADC resolution and connect P0_2 to 0.5V, I will have ADC reading adc_ain2=886. Then, we can convert the reading 889 to measured voltage using the following equation.
    measured voltage = 1.15x889/2047=0.499...


    3. If I change HAL_ADC_RESOLUTION_14 (the max reading is 8191) as ADC resolution and connect P0_2 to 0.5V, I will have ADC reading adc_ain2=3550. Then, we can convert the reading 3550 to measured voltage using the following equation.
    measured voltage = 1.15x3550/8191=0.498...
  • 打开网页失败
  • Alvin已經幫忙把网页內文貼給你了
  • 又碰到了类似的问题,用的是0通道,12位精度,我的P0_0的电压是1.0v,按照计算应该是1700多,但是我实际读到的值确实900多,严重偏差,这到底是个什么原因啊?上次我没怎么听明白
  • 你用電錶量P0_0的电压是1.0v?可以把你的adc源碼貼上來看看嗎?
  • Init_GPIO();
    HalAdcInit();
    HalAdcSetReference(HAL_ADC_REF_125V);
    for(int i=0;i<100;i++)
    {
    Delay_ms(1);
    sum += HalAdcRead(HAL_ADC_CHN_AIN0, HAL_ADC_RESOLUTION_12);
    }

    voltage = sum / 100;




    void Init_GPIO(void)
    {
    //设置为标准IO口
    P0SEL &= ~(1<<0|1<<1|1<<3|1<<5|1<<7);
    P1SEL &= ~(1<<0|1<<2|1<<3|1<<5|1<<7);

    //设置为输入
    P0DIR &= ~(1<<0);
    APCFG |= 1<<0; //p0.0 设置为adc功能
    P1DIR &= ~(1<<3|1<<5|1<<7);
    P1INP &= ~(1<<3|1<<5|1<<7); //将P13、P15、P17设为上下拉输入
    P2INP |= 1<<6; //端口1设置为下拉输入

    //设置为输出
    P0DIR |= 1<<1|1<<3|1<<5|1<<7;
    P1DIR |= 1<<0|1<<2;
    }
  • 还有我看在 HalAdcRead()这个库函数中,我把那个值带进去后,好像是用的10位分别率啊
  • 10位分辨率最高应该也就1023吧,不应该是2047啊
  • 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 < 8)
    {
    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 */
    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);
    }



    这个协议栈里的adc函数,ADCCON3 最后的值是 0x20应该是256抽取率(10位分辨率),转换完成后禁用通道0,从adc数据位取值(有效位14位),又因为采用的是10位分辨率,所以说最后值又右移了4位,最后得到一个值(最大值1023),应该是这么理解的吧
  • 剛剛用CC2530DK測試了一次,從P0.0用"HalAdcRead(HAL_ADC_CHN_AIN0, HAL_ADC_RESOLUTION_12);"讀ADC是沒有問題的,1.0V輸入讀值約1860
  • 但是我对着数据手册,看着源码好像是用的一个10位的分辨率,而不是11位的分辨率,而且获得的值也是14位有效值向右移位4位啊。
    而且,我这边的话,一个1.020v的电压,依HAL_ADC_RESOLUTION_12 是10位分辨率算的话,计算得出来的电压是1.024v。
    就是您能不能把您的测试代码发过来一下还有那个hal_adc.c和hal_adc.h文件,我和我的比较一下看看。看一下是哪边出了问题,谢谢了
  •        uint16 adc_ain2=0;

           HalAdcSetReference(HAL_ADC_REF_125V);

           adc_ain2=HalAdcRead(HAL_ADC_CHN_AIN0,HAL_ADC_RESOLUTION_12);

    /**************************************************************************************************
      Filename:       hal_adc.c
      Revised:        $Date: 2010-03-12 16:10:36 -0800 (Fri, 12 Mar 2010) $
      Revision:       $Revision: 21910 $
    
      Description:    This file contains the interface to the HAL ADC.
    
    
      Copyright 2006-2010 Texas Instruments Incorporated. All rights reserved.
    
      IMPORTANT: Your use of this Software is limited to those specific rights
      granted under the terms of a software license agreement between the user
      who downloaded the software, his/her employer (which must be your employer)
      and Texas Instruments Incorporated (the "License").  You may not use this
      Software unless you agree to abide by the terms of the License. The License
      limits your use, and you acknowledge, that the Software may not be modified,
      copied or distributed unless embedded on a Texas Instruments microcontroller
      or used solely and exclusively in conjunction with a Texas Instruments radio
      frequency transceiver, which is integrated into your product.  Other than for
      the foregoing purpose, you may not use, reproduce, copy, prepare derivative
      works of, modify, distribute, perform, display or sell this Software and/or
      its documentation for any purpose.
    
      YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
      PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
      INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
      NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
      TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
      NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
      LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
      INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
      OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
      OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
      (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
    
      Should you have any questions regarding your right to use this Software,
      contact Texas Instruments Incorporated at www.TI.com.
    **************************************************************************************************/
    
    /**************************************************************************************************
     *                                           INCLUDES
     **************************************************************************************************/
    
    #include  "hal_adc.h"
    #include  "hal_defs.h"
    #include  "hal_mcu.h"
    #include  "hal_types.h"
    
    /**************************************************************************************************
     *                                            CONSTANTS
     **************************************************************************************************/
    #define HAL_ADC_EOC         0x80    /* End of Conversion bit */
    #define HAL_ADC_START       0x40    /* Starts Conversion */
    
    #define HAL_ADC_STSEL_EXT   0x00    /* External Trigger */
    #define HAL_ADC_STSEL_FULL  0x10    /* Full Speed, No Trigger */
    #define HAL_ADC_STSEL_T1C0  0x20    /* Timer1, Channel 0 Compare Event Trigger */
    #define HAL_ADC_STSEL_ST    0x30    /* ADCCON1.ST =1 Trigger */
    
    #define HAL_ADC_RAND_NORM   0x00    /* Normal Operation */
    #define HAL_ADC_RAND_LFSR   0x04    /* Clock LFSR */
    #define HAL_ADC_RAND_SEED   0x08    /* Seed Modulator */
    #define HAL_ADC_RAND_STOP   0x0c    /* Stop Random Generator */
    #define HAL_ADC_RAND_BITS   0x0c    /* Bits [3:2] */
    
    #define HAL_ADC_DEC_064     0x00    /* Decimate by 64 : 8-bit resolution */
    #define HAL_ADC_DEC_128     0x10    /* Decimate by 128 : 10-bit resolution */
    #define HAL_ADC_DEC_256     0x20    /* Decimate by 256 : 12-bit resolution */
    #define HAL_ADC_DEC_512     0x30    /* Decimate by 512 : 14-bit resolution */
    #define HAL_ADC_DEC_BITS    0x30    /* Bits [5:4] */
    
    #define HAL_ADC_STSEL       HAL_ADC_STSEL_ST
    #define HAL_ADC_RAND_GEN    HAL_ADC_RAND_STOP
    #define HAL_ADC_REF_VOLT    HAL_ADC_REF_AVDD
    #define HAL_ADC_DEC_RATE    HAL_ADC_DEC_064
    #define HAL_ADC_SCHN        HAL_ADC_CHN_VDD3
    #define HAL_ADC_ECHN        HAL_ADC_CHN_GND
    
    /* ------------------------------------------------------------------------------------------------
     *                                       Local Variables
     * ------------------------------------------------------------------------------------------------
     */
    
    #if (HAL_ADC == TRUE)
    static uint8 adcRef;
    #endif
    
    /**************************************************************************************************
     * @fn      HalAdcInit
     *
     * @brief   Initialize ADC Service
     *
     * @param   None
     *
     * @return  None
     **************************************************************************************************/
    void HalAdcInit (void)
    {
    #if (HAL_ADC == TRUE)
      adcRef = HAL_ADC_REF_VOLT;
    #endif
    }
    
    /**************************************************************************************************
     * @fn      HalAdcRead
     *
     * @brief   Read the ADC based on given channel and resolution
     *
     * @param   channel - channel where ADC will be read
     * @param   resolution - the resolution of the value
     *
     * @return  16 bit value of the ADC in offset binary format.
     *
     *          Note that the ADC is "bipolar", which means the GND (0V) level is mid-scale.
     *          Note2: This function assumes that ADCCON3 contains the voltage reference.
     **************************************************************************************************/
    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 < 8)
      {
        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 */
      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);
    }
    
    /**************************************************************************************************
     * @fn      HalAdcSetReference
     *
     * @brief   Sets the reference voltage for the ADC and initializes the service
     *
     * @param   reference - the reference voltage to be used by the ADC
     *
     * @return  none
     *
     **************************************************************************************************/
    void HalAdcSetReference ( uint8 reference )
    {
    #if (HAL_ADC == TRUE)
      adcRef = reference;
    #endif
    }
    
    /*********************************************************************
     * @fn      HalAdcCheckVdd
     *
     * @brief   Check for minimum Vdd specified.
     *
     * @param   vdd - The board-specific Vdd reading to check for.
     *
     * @return  TRUE if the Vdd measured is greater than the 'vdd' minimum parameter;
     *          FALSE if not.
     *
     *********************************************************************/
    bool HalAdcCheckVdd(uint8 vdd)
    {
      ADCCON3 = 0x0F;
      while (!(ADCCON1 & 0x80));
      return (ADCH > vdd);
    }
    
    /**************************************************************************************************
    **************************************************************************************************/
    
    hal_adc.h

  • 一摸一样的操作,但是我这边就是只是读到911,而且我的P0_0引脚电压量是1.020v。

    hal_adc.c文件里的HalAdcRead函数中的ADCCON3 = channel | resbits | adcRef;这句函数,把值带进去后,操作寄存器后最后是一个10位的分辨率啊,而且后面还是把得到的一个值右移了4位。。。 这个到底该如何理解啊?而且,相同的代码,基本上相同的测量电压,最后得到的值感觉差距太大了。我得到的那个值如果以10位的分辨率计算的话,就非常精准了,但是这个函数。。。
  • 就是现在这种情况,相同的测试代码和相同的协议栈的adc采样函数,基本相同的测试坏境,但是现在读出来的值,相差很大,您那边读出来的值1800多,我读出来的值才900多,相差太多了。
  • 你用的板子是TI的CC2530DK,還是外面買的模塊,可以在TI的CC2530dk測試看看嗎?

  • ADC数据低位只取2~7位仅有6个有效位,ADC高位全取,加起来也就14位,最后又右移了4位,不应该只剩下10位的一个数吗?我不知道我这么理解对不对,所以说想请教您一下。还有就是这个TI的CC2530DK和外面的模块有什么区别吗?我用的是外面买的模块,
  • reading = (int16) (ADCL);
    reading |= (int16) (ADCH << 8);
    ...

    case HAL_ADC_RESOLUTION_12:
    reading >>= 4;
    break;
    ...
    reading由ADCL跟ADCH的2個位元組合成,所以是16 bits,然後右移4 bits不就是12 bits嗎?然後這12 bits是2s-complement,所以最大值是2047

    我用的是TC CC2530DK測試是沒有問題的,才想說是不是你模塊線路上有什麼問題
  • 但是这个不是对应的一个10位分辨率吗?刚才我理解错了,这个reading是由ADCL和ADCH2个元素构成,16bits右移4bits确实是12bits,但是我看数据手册里面显示ADCL不是只有2-7位是有效的吗?右移4位确实是把这个ADCL最后2位的无效位给移掉了,但是把值带进HalAdcRead()这个函数里后,ADCCON3 = 0 | 0x20 |0 ,最后的值是0x20,对应的应该是一个10位分辨率啊
  • 0x20是10 bits ENOB並不是resolution為10 bits
  • 对对,是10位有效位,resolution是12位,但是现在现象是这样子的一个现象?会是什么原因导致的呢?难道是这个模块的线路有问题?但是,它的AD0通道上的电压确实是一个1v左右啊,,,会是什么电路原因导致它读取的值会这么小?
  • 你有你用的CC2530模塊跟ADC的線路嗎?拍張照片來看看你的ADC是怎樣接到CC2530模塊
  • 确定原因了,是因为加的电阻的整体输入阻抗发生变化,导致出的问题,和模块没关系。就还有一个问题,我们的硬件工程师是以2.8v作为工作电压,那这个基准电压为多少?我用1.15v为基准电压的话,出现了20mv的误差
  • HAL_ADC_REF_125V的參考電壓就是1.15v,有誤差的話可能需要程序裡面去做軟體校正