打印
[MCU]

ADC检测值异样问题

[复制链接]
226|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jcky001|  楼主 | 2020-12-3 10:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我的单通道多次转换AD,已经有软件的平滑滤波,但是检测大于1V的信号是显示低于1V接近1V              检测200mV的信号显示0.956~0.542之间不断波动,总之是与实际值相差较大,检测2V以上信号时候还会相差200mV这样,求解为什么会是这样,怎解决。代码已经粘贴,无错的。




#include "msp430g2553.h"
#define uint unsigned int
#define uchar unsigned char

uint Results[32];         //存放ADC的转换结果
float Average=0;
uint ad_value=0;

//在此设置输入端口*************************************************************/
#define LCD_SID1 P2OUT|=BIT4
#define LCD_SID0 P2OUT&=~BIT4                     //WR 做数据传输使用sid
#define LCD_SCLK1 P2OUT|=BIT3
#define LCD_SCLK0 P2OUT&=~BIT3                    //EN 当做串行时钟使用sclk
#define LCD_SID_READ P2IN&0X10

#define CPU_F ((double)8000000)//cpu frequency8000000
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/2000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/2000.0))

#define com  0
#define dat   1


unsigned char s1[] ={"电压(V): "};
unsigned char s2[] ={"TI杯电子设计大赛"};



/*********************写命令或数据************************/

void wr_lcd(uchar dat_com,uchar data)
{
   uchar a,i,j;
   delay_us(50);
   a = data;
   LCD_SID1;       //WR=0;

   LCD_SCLK0;      //EN=0;
   for(i=0;i<5;i++)     //时序
   {
      LCD_SCLK1;
      LCD_SCLK0;
   }
    LCD_SID0;             //wr=0
      LCD_SCLK1;            //en=1
      LCD_SCLK0;            //en=0
       if(dat_com) LCD_SID1;   
      else         LCD_SID0;
      LCD_SCLK1;
      LCD_SCLK0;

      LCD_SID0;
      LCD_SCLK1;
      LCD_SCLK0;

      for(j=0;j<2;j++)      //8次循环写写一字节数据
      {
          for(i=0;i<4;i++)
          {
            if(a&0x80)
                 LCD_SID1;
              else
                 LCD_SID0;
            a=a<<1;
            LCD_SCLK1;
            LCD_SCLK0;
          }
          LCD_SID0;
          for(i=0;i<4;i++)  //时钟
          {
            LCD_SCLK1;
            LCD_SCLK0;
          }
      }
}


/*******************初始化***********************************/

void init_lcd(void)
{
   wr_lcd(com,0x30);//基本指令集操作
   wr_lcd(com,0x01);//清楚显示
   delay_ms(2);
   wr_lcd(com,0x30);//基本指令集操作
   wr_lcd(com,0x01);//清楚显示
   delay_ms(2);
   wr_lcd(com,0x06);//光标右移,AC自动加1,整体显示不移动
   wr_lcd(com,0x0c);//整体显示ON,光标显示OFF,光标位置不反白闪烁


}



/**********************写字符串,x0取值0-3,x取值0-7****************************/
void wr_string(uchar x,uchar x0,uchar *p)
{   
  uchar pos=0;//初始化
  uchar cnt=0;//传递过来的是指针 ,cnt为偏移量,然后一个字符一个字符的写入。
  switch(x0)
  {
      case 0: pos=0x80+x;break;
      case 1: pos=0x90+x;break;
      case 2: pos=0x88+x;break;
      case 3: pos=0x98+x;break;
      default: break;
  }
  wr_lcd(com,pos);//写地址

  while(*(p+cnt)!='\0')
  {
      wr_lcd(dat,*(p+cnt));//写数据
      cnt++;
  }
}



/********************************浮点型数据显示*******************************/
void wr_float(uchar x,uchar x0,float NUM)        
{
    uchar a_SHOW[7];
    long int t;
    t=(long int)(NUM*1000);
    a_SHOW[0]=(t/10000)%10+'0';//shi
    a_SHOW[1]=(t/1000)%10+'0' ;//ge
    a_SHOW[2]='.';               //
    a_SHOW[3]=(t/100)%10+'0';//shi fen
    a_SHOW[4]=(t/10)%10+'0'; //bai fen
    a_SHOW[5]=t%10+'0';      //qian fen
    a_SHOW[6]='\0';
    wr_string(x,x0,a_SHOW);        
}

/****************main***********************************/

void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;  
      P2DIR |= BIT3+BIT4;
  init_lcd();
    wr_string(0,3,s1);
     wr_string(0,0,s2);
  P1DIR&=~BIT0;
  ADC10AE0=BIT0;        //把普通引脚功能关掉,使能ADC10AEx
  P1DIR|=BIT6;  
  //P1OUT|=BIT6;

  //P1SEL|=BIT1;

  ADC10CTL0|=ADC10ON+MSC+ADC10SHT_3+ADC10IE;
  ADC10CTL1|=CONSEQ_2+INCH_0;
  ADC10CTL0|=ENC+ADC10SC;


  while(1)
  {   
   _BIS_SR(LPM0_bits + GIE);

  }
}
#pragma vector=ADC10_VECTOR
__interrupt void ADC10IN(void)
{
   static uchar index = 0;

    Results[index++] = ADC10MEM;                      // Move results, IFG is cleared
    if(index == 31)
    {
         uchar i;

         Average = 0;
         for(i = 0; i < 32; i++)
            Average += Results;
         Average = Average/32;                           //除以32求平均值
         Average=(Average*3.5)/1023;
         if (Average>30)     //给的电压过高,LED6亮
          P1OUT|=BIT6;
        else P1OUT&=~BIT6;
            wr_float(4,3,Average);
         index = 0;
           _BIC_SR_IRQ(LPM0_bits);                   // Clear LPM0

    }
}

使用特权

评论回复

相关帖子

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

本版积分规则

1443

主题

4019

帖子

6

粉丝