打印

利用单片机自带的AD采集电源电压时利用内部参考源的问题

[复制链接]
6187|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
      该问题就是我用MSP430F5310单片机的自带AD的A0通道采集系统电源电压,附件中为我的电压采集电路,参考源悬起的为单片机的内部参考电压2.5V。R2、R4原来均为10M,当VBAT =4.10V时,得到Vad=1.35V ,此时利用单片机的程序来采集该电压的时候,发现选取的内部电压2.5V使用不成,AD采集的结果十分不稳定也不准确,当选取外部的参考电压3.0V的时候,就可以得到稳定的采集值。
     后来当将R2、R4 的阻值均换成附件中的47k 的时候,同样的程序选用内部参考电源就OK啦,值得一提的是此时VBAT=4.10V时,Vad=2.05V。
   所以当时就想着是参考源的问题,后来试验的时候就变成了分压电阻的问题,有些不太明白的,请教各位大虾了啊。。。。

AD_VCC.jpg (20.2 KB )

AD_VCC.jpg

相关帖子

沙发
vivilzb1985|  楼主 | 2013-3-5 17:53 | 只看该作者
#include <msp430f5310.h>

signed int ADC_Result;
void delay(void);
void int_clk()  
{
  WDTCTL = WDTPW+WDTHOLD;                   //关闭看门狗
  PMAPPWD = 0x02D52;                        // Enable Write-access to modify port mapping registers
  P4MAP7 = PM_MCLK;
  PMAPPWD = 0;                                    // Disable Write-Access to modify port mapping registers
   UCSCTL3 |= SELREF_2;                      // Set DCO FLL reference = REFO
  UCSCTL4 |= SELA_2;                        // Set ACLK = REFO

  // Increase Vcore setting to level1 to support fsystem=12MHz
  // NOTE: Change core voltage one level at a time..
  //SetVcoreUp (0x01);

  // Initialize DCO to 12MHz  
  __bis_SR_register(SCG0);                  // Disable the FLL control loop
  UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
  UCSCTL1 = DCORSEL_5;                      // Select DCO range 24MHz operation
  UCSCTL2 = FLLD_1 + 374;                   // Set DCO Multiplier for 12MHz
                                            // (N + 1) * FLLRef = Fdco
                                            // (374 + 1) * 32768 = 12MHz
                                            // Set FLL Div = fDCOCLK/2
  __bic_SR_register(SCG0);                  // Enable the FLL control loop

  // Worst-case settling time for the DCO when the DCO range bits have been
  // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
  // UG for optimization.
  // 32 x 32 x 12 MHz / 32,768 Hz = 375000 = MCLK cycles for DCO to settle
  __delay_cycles(375000);
       
  // Loop until XT1,XT2 & DCO fault flag is cleared
  do
  {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
                                            // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG;                      // Clear fault flags
  }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
// UCSCTL4 =0x0233;                  
}

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
P1DIR |= BIT0;                            // Set P1.0 to output direction
  int_clk();
  // Configure ADC
  while(REFCTL0 & REFGENBUSY);              // If ref generator busy, WAIT
  REFCTL0 |= REFVSEL_2+REFON;               // Select internal ref = 2.5V
  ADC10CTL0 |= ADC10SHT_2 + ADC10ON;        // ADC10ON, S&H=16 ADC clks
  ADC10CTL1 |= ADC10SHP+ ADC10CONSEQ_0;                    // ADCCLK = MODOSC; sampling timer
  ADC10CTL2 |= ADC10RES;    // + ADC10DF      // 10-bit conv result; signed format
  ADC10MCTL0 |= ADC10INCH_0+ADC10SREF_1;      // A0 ADC input select; Vref=AVCC

// ADC10IE |= ADC10IE0;                      // Enable ADC conv complete interrupt
__bis_SR_register(GIE);
  for (;;)
  {
    __delay_cycles(5000);  
    ADC10CTL0 |= ADC10ENC + ADC10SC;        // Sampling and conversion start
    //__bis_SR_register(CPUOFF + GIE);        // LPM0, ADC10_ISR will force exit
    while (ADC10CTL1 & ADC10BUSY);  
    ADC_Result = (int)ADC10MEM0;  
    __no_operation();                       // For debug only
    if (ADC_Result  < 0)
      P1OUT &= ~BIT0;                       // Clear P1.0 LED off
    else
      P1OUT |= BIT0;                        // Set P1.0 LED on
  }

使用特权

评论回复
板凳
vivilzb1985|  楼主 | 2013-3-5 17:53 | 只看该作者
void delay(void)
{
  volatile unsigned long i;
  for (i = 0x7FFF; i > 0; i--);
}


// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
  switch(__even_in_range(ADC10IV,12))
  {
    case  0: break;                          // No interrupt
    case  2: break;                          // conversion result overflow
    case  4: break;                          // conversion time overflow
    case  6: break;                          // ADC10HI
    case  8: break;                          // ADC10LO
    case 10: break;                          // ADC10IN
    case 12: ADC_Result = (int)ADC10MEM0;         
//            __bic_SR_register_on_exit(CPUOFF);                                             
             break;                          // Clear CPUOFF bit from 0(SR)                        
    default: break;
  }
}

使用特权

评论回复
地板
vivilzb1985|  楼主 | 2013-3-5 17:55 | 只看该作者
调试的程序代码的也分享给大家了,将ADC10MCTL0 |= ADC10INCH_0+ADC10SREF_1;      // A0 ADC input select; Vref=AVCC

换成ADC10MCTL0 |=  ADC10INCH_1;就变成使用外部的参考电压了

使用特权

评论回复
5
vivilzb1985|  楼主 | 2013-3-5 17:57 | 只看该作者
外部参考电压电路的见附件

参考电压电路.jpg (69.46 KB )

参考电压电路.jpg

使用特权

评论回复
6
vivilzb1985|  楼主 | 2013-7-18 21:13 | 只看该作者
这个问题的看来大家没人经历过啊,这长时间了,这个贴的都沉底了:'(:L:L

使用特权

评论回复
7
vivilzb1985|  楼主 | 2013-7-18 21:15 | 只看该作者
我后来是调整了下两个分压电阻的,效果就比较好了,不够还是有些不大明白的

使用特权

评论回复
8
vivilzb1985|  楼主 | 2013-7-18 21:16 | 只看该作者
我是将两个47K的分压电阻的都调整到10K的,就好了,。

使用特权

评论回复
9
vivilzb1985|  楼主 | 2013-7-18 21:18 | 只看该作者
我的判断是两个分压电阻太大了,单片机的AD输入口本身也存在阻抗的,这样不太匹配的了,就导致该分压不准确了

使用特权

评论回复
10
vivilzb1985|  楼主 | 2013-7-18 21:20 | 只看该作者
好了,我也处理下该贴的了,这个经验的也分享给大家了,分压电阻不要太大的就可以了

使用特权

评论回复
11
ywzqhl| | 2013-7-19 11:43 | 只看该作者
楼主你要在R4上面并联一个0.01的电容试一试,电阻可以用大电阻的,我用的1M的都没问题,不过我用的是449的芯片。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:后来乍到,前辈们多多包涵了啊。。

88

主题

4276

帖子

6

粉丝