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.

关于msp430f149的12adc采集问题



采用默认的参考电压3.3v,结果只能采集到2047-1.65v,当外部电压高于1.65时,采集的电压有变为0-2047(0-1.65v),只能采集到外部电压的一半,这是怎么回事???

  •  参考这个代码

    VCC 作为 参考

    /* --COPYRIGHT--,BSD_EX
     * Copyright (c) 2012, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     *******************************************************************************
     * 
     *                       MSP430 CODE EXAMPLE DISCLAIMER
     *
     * MSP430 code examples are self-contained low-level programs that typically
     * demonstrate a single peripheral function or device feature in a highly
     * concise manner. For this the code may rely on the device's power-on default
     * register values and settings such as the clock configuration and care must
     * be taken when combining code from several examples to avoid potential side
     * effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware
     * for an API functional library-approach to peripheral configuration.
     *
     * --/COPYRIGHT--*/
    //******************************************************************************
    //  MSP-FET430P140 Demo - ADC12, Sample A0, Set P1.0 if A0 > 0.5*AVcc
    //
    //  Description: A single sample is made on A0 with reference to AVcc.
    //  Software sets ADC10SC to start sample and conversion - ADC12SC
    //  automatically cleared at EOC. ADC12 internal oscillator times sample (16x)
    //  and conversion. In Mainloop MSP430 waits in LPM0 to save power until ADC12
    //  conversion complete, ADC12_ISR will force exit from LPM0 in Mainloop on
    //  reti. If A0 > 0.5*AVcc, P1.0 set, else reset.
    //
    //                MSP430F149
    //             -----------------
    //         /|\|              XIN|-
    //          | |                 |
    //          --|RST          XOUT|-
    //            |                 |
    //      Vin-->|P6.0/A0      P1.0|--> LED
    //
    //  M. Buccini
    //  Texas Instruments Inc.
    //  Feb 2005
    //  Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.21A
    //******************************************************************************
    
    #include <msp430.h>
    
    int main(void)
    {
      WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
      ADC12CTL0 = SHT0_2 + ADC12ON;             // Set sampling time, turn on ADC12
      ADC12CTL1 = SHP;                          // Use sampling timer
      ADC12IE = 0x01;                           // Enable interrupt
      ADC12CTL0 |= ENC;                         // Conversion enabled
      P6SEL |= 0x01;                            // P6.0 ADC option select
      P1DIR |= 0x01;                            // P1.0 output
    
      for (;;)
      {
        ADC12CTL0 |= ADC12SC;                   // Sampling open
        __bis_SR_register(CPUOFF + GIE);        // LPM0, ADC12_ISR will force exit
      }
    }
    
    // ADC12 interrupt service routine
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC12_VECTOR
    __interrupt void ADC12_ISR (void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
        if (ADC12MEM0 < 0x7FF)
          P1OUT &= ~0x01;                       // Clear P1.0 LED off
        else
          P1OUT |= 0x01;                        // Set P1.0 LED on
        __bic_SR_register_on_exit(CPUOFF);      // Clear CPUOFF bit from 0(SR)
  • 我的adc设置为:(采用了多次测量)

    void Init_ADC(void)
    {
    P6SEL |= 0x01; // 使能ADC通道
    ADC12CTL0 = ADC12ON + SHT0_10 + MSC; // 打开ADC,设置采样时间
    ADC12CTL1 = SHP + CONSEQ_2; // 使用采样定时器

    for ( int k=0; k<0x3600;k++){} //等待电压稳定

    ADC12IE = 0x01; // 使能ADC中断
    ADC12CTL0 |= ENC; // 使能转换
    ADC12CTL0 |= ADC12SC; // 开始转换
    }

    在中断处理里面,就是连续进行了32次采样,并求取平均值,具体为:

    #pragma vector=ADC_VECTOR
    __interrupt void ADC12ISR (void)
    {
    static uchar index = 0;

    results[index++] = ADC12MEM0; // Move results
    // average=ADC12MEM0;
    if(index == Num_of_Results)
    {
    uchar i;
    average = 0;
    for(i = 0; i < Num_of_Results; i++)
    {
    average += results[i];
    }
    average >>= 5; //测量32次,除以32,求品均值
    index = 0;
    tcnt++;
    if(tcnt == 250) //主要是降低串口发送速度
    {
    LPM1_EXIT;
    tcnt = 0;
    }
    }
    }

    就会出现这种情况。求助

  • 你好,请问这个问题你是这么解决的?

  • 设置32次采集有问题,设置为16次即可正常解决,我也不知道是怎么回事

  • /*********************************************************
    程序功能:将ADC对P6.0端口电压的转换结果按转换数据和对应的
    模拟电压的形式通过串口发送到PC机屏幕上显示
    -----------------------------------------------------------
    通信格式:N.8.1, 9600
    -----------------------------------------------------------
    测试说明:打开串口调试精灵,正确设置通信格式,观察接收数据
    **********************************************************/
    #include <msp430.h>
    #include "allfunc.h"
    #include "UART0_Func.c"
    #include "ADC_Func.c"

    #define Num_of_Results 16
    uint results[Num_of_Results]; //保存ADC转换结果的数组
    uint average;
    uchar tcnt = 0;

    /***********************主函数***********************/
    void main( void )
    {
    uchar i;
    uchar buffer[5];

    WDTCTL = WDTPW + WDTHOLD; //关狗

    /*下面六行程序关闭所有的IO口*/
    P1DIR = 0XFF;P1OUT = 0XFF;
    P2DIR = 0XFF;P2OUT = 0XFF;
    P3DIR = 0XFF;P3OUT = 0XFF;
    P4DIR = 0XFF;P4OUT = 0XFF;
    P5DIR = 0XFF;P5OUT = 0XFF;
    P6DIR = 0XFF;P6OUT = 0XFF;

    P6DIR |= BIT2;P6OUT |= BIT2; //关闭电平转换
    P6DIR|=BIT6;P6OUT&=~BIT6; //关闭数码管显示

    InitUART();
    Init_ADC();
    _EINT();

    buffer[4] = '\0';
    while(1)
    {
    LPM1;
    Hex2Dec(average,buffer);
    for(i = 0; i < 4; i++)
    buffer[i] += 0x30;
    PutString0("The digital value is: ");
    PutString(buffer);


    Trans_val(average,buffer);
    buffer[3] = buffer[2];
    buffer[2] = buffer[1];
    buffer[1] = 0x2e - 0x30;
    for(i = 0; i < 4; i++)
    buffer[i] += 0x30;
    PutString0("The analog value is: ");
    PutString(buffer);
    }

    }

    /*******************************************
    函数名称:ADC12ISR
    功 能:ADC中断服务函数,在这里用多次平均的
    计算P6.0口的模拟电压数值
    参 数:无
    返回值 :无
    ********************************************/
    #pragma vector=ADC_VECTOR
    __interrupt void ADC12ISR (void)
    {
    static uchar index = 0;

    results[index++] = ADC12MEM0; // Move results
    if(index == Num_of_Results)
    {
    uchar i;

    average = 0;
    for(i = 0; i < Num_of_Results; i++)
    {
    average += results[i];
    }
    average >>= 4; //除以32

    index = 0;
    tcnt++;
    if(tcnt == 250) //主要是降低串口发送速度
    {
    LPM1_EXIT;
    tcnt = 0;
    }
    }
    }

  • 我也这样尝试了,确实是这样的,修改为16次采集一次