打印

关于MSP430launchpad AD问题

[复制链接]
2014|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
1546683471|  楼主 | 2013-7-11 13:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人初学430,我想用G2553做一个多通道采样程序,例如P1.0,p1.1作为模拟输入,可是看了一下G2553的用户手册,发现G2553只有一个ADC10MEM,不像F149一样,每个通道都有一个MEM,请问一下大家,G2553的多通道采样是怎么实现的,例如P1.0的模数转换存在MEM中,那P1.1又存在哪,中断的工作时序又是怎样的,先谢过大家了

相关帖子

沙发
wangyy608| | 2013-7-11 13:54 | 只看该作者
如果只有1个MEM,显然就是存在它里面了,切换到哪个通道,那么MEM里面就是哪个通道的结果

使用特权

评论回复
板凳
dirtwillfly| | 2013-7-11 13:57 | 只看该作者
MEM接到数据后,抓紧读走

使用特权

评论回复
地板
1546683471|  楼主 | 2013-7-11 14:35 | 只看该作者
能不能请大家给个例子学习一下呢,谢谢

使用特权

评论回复
5
dirtwillfly| | 2013-7-11 21:51 | 只看该作者
从网上找了一段程序:
基于msp430g2553内部ADC10多通道(2通道)详解
其中的液晶显示这里就不再多述了
#include "lcd1602.h"
uchar d[16]="The Volt1: .   V";
uchar d1[16]="The Volt0: .   V";
uchar table_num[]={"0123456789"};
uint a[8],b[3];
uint i,j,ad1,ad0,real;
void display()
{
  delay(250);
  uint ptr[4];
  
  ad1=(int)(b[1]);//根据需要,可以更改这里的数值,将量程调到0~1024
  ad0=(int)(b[2]);//根据需要,可以更改这里的数值,将量程调到0~1024
  //通道A1的值
    real=(int)((3.3*ad1)/1023*1000);//扩大1000倍
    ptr[0] = real / 1000;        
    ptr[1] = (real - ptr[0]*1000)/100;
    ptr[2] = (real - ptr[0]*1000 - ptr[1]*100)/10;
    ptr[3] = (real - ptr[0]*1000 - ptr[1]*100 - ptr[2]*10);
    d[10]=table_num[ptr[0]];
    for(i=1;i<4;i++)
      d[i+11]=table_num[ptr[i]];
    display_string(d,0xc0);        
  //通道A0的值
    real=(int)((3.3*ad0)/1023*1000);//扩大1000倍
    ptr[0] = real / 1000;        
    ptr[1] = (real - ptr[0]*1000)/100;
    ptr[2] = (real - ptr[0]*1000 - ptr[1]*100)/10;
    ptr[3] = (real - ptr[0]*1000 - ptr[1]*100 - ptr[2]*10);
    d1[10]=table_num[ptr[0]];
    for(i=1;i<4;i++)
      d1[i+11]=table_num[ptr[i]];
    display_string(d1,0x80);            
}
void main()
{      
  WDTCTL = WDTPW + WDTHOLD;
  //主系统时钟切换为外部高速晶振   
  if (CALBC1_8MHZ == 0xFF || CALDCO_8MHZ == 0xFF)
  {
      while(1);   // If calibration constants erased, trap CPU!!
  }
  // Configure Basic Clock
  BCSCTL1 = CALBC1_8MHZ;     // Set range
  DCOCTL = CALDCO_8MHZ;    // Set DCO step + modulation*/      
  
  P2SEL=0x00;//P2为I/O模式
  P2DIR|=0xff;//P2为LCD输出
  P1SEL|=BIT1+BIT2+BIT0;//P1.1和P1.2设置为ADC功能A1和A2
  
  ADC10CTL1|=CONSEQ_3+INCH_2+INCH_0+INCH_1;//序列通道多次转换+最大通道为A2
  ADC10CTL0|=ADC10SHT_2+MSC+ADC10ON+ADC10IE;
  ADC10DTC1|=0x08;//一共采样8次
  ADC10AE0|=BIT0+BIT1+BIT3;//打开A0和A1的模拟输入通道
  
  init_lcd();//lcd初始化
  
  while(1)
  {
    ADC10CTL0&=~ENC;//关闭采样使能
    while(ADC10CTL1&BUSY);//检测AD是否繁忙
    ADC10CTL0|=ENC+ADC10SC;//启动ADC
    ADC10SA=(unsigned int)a;//获取a[]的首地址。首先对A1、A0采样,放入a[0]和a[1]中。再对A1、A0采样,放入a[2]和a[3]中,如此循环下去。
    _BIS_SR(LPM0_bits+GIE);//低功耗模式0,开中断
     for(i=0;i<2;i++)
    {
      b[i]=0;
      for(j=0;j<4;j++)
        b[i]+=a[i+j*2];//b[0]=a[偶数]相加之和,b[1]=a[奇数]相加之和,每个b有4组数
    }
    for(i=0;i<2;i++)
    {  
      b[i]=b[i]/4;//对b[0],b[1]求平均值
      _NOP();
    }
    display();//lcd显示
  }
}
#pragma vector=ADC10_VECTOR
__interrupt void ADC(void)
{
     LPM0_EXIT;//退出低功耗模式
}

使用特权

评论回复
6
1546683471|  楼主 | 2013-7-11 23:30 | 只看该作者
我找了两个代码:
(1)序列通道单次转换:
uint a[2];
uint ad1,ad0;
float i,j;

void main( void )
{
  WDTCTL = WDTPW + WDTHOLD;
  //停止看门狗
  ADC10CTL0 |= SREF_1 + ADC10SHT_2 + REFON + REF2_5V + MSC + ADC10ON + ADC10IE;
  //SREF_1表示参考选取的是VREF+   
  //ADC10SHT_2表示设置采样保持时间
  //REFON和REF2_5V表示的是选取参考电压为2.5V。
  //MSC是多次采样转换控制位
  //ADC10ON表示打开ADC10模块
  //ADC10IE表示使能ADC中断  
  ADC10CTL1 |=INCH_1 + CONSEQ_1;
  //A0 A1作为输入通道,序列通道单次转换模式
  //INCH_1转换的最高通道为A1
  ADC10DTC1 = 0x02;
  //一共采样2次
  ADC10AE0 |= BIT0 + BIT1;
  //打开A0和A1的模拟输入通道
  _EINT();
  //使能总中断
  
  while(1)
  {
    ADC10CTL0 &= ~ENC;
    //关闭采样使能
    while(ADC10CTL1&BUSY);
    //检查ADC是否繁忙
    ADC10SA = (uint)a;
    //数据传递的首地址
    //获取a[]的首地址,对A1、A0采样,放入a[0]和a[1]中
    ADC10CTL0 |= ENC + ADC10SC;
    //ADC10转换使能,并开始转换
    __bis_SR_register(CPUOFF + GIE);
    //低功耗模式0,开中断
    ad0 = a[0];
    i = ad0*2.5*1000/1023;
    ad1 = a[1];
    j = ad1*2.5*1000/1023;
    _NOP();
  }
}

#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
  LPM0_EXIT;
  // 退出低功耗模式0
}


(2)单通道单次转换

#include "msp430g2553.h"

#define uint unsigned int
#define uchar unsigned char

uint ad;
float v;
uchar flag=0;

int main( void )
{
  WDTCTL = WDTPW + WDTHOLD;//停止看门狗
  ADC10CTL0 |= ADC10SHT_2 + ADC10ON;//设置采样保持时间为16xADC10CLK,打开ADC10
  ADC10CTL1 |= INCH_0;//设置通道,P1.0作为采样输入通道
  ADC10AE0 |= 0x01;//模拟信号输入使能
  ADC10CTL0 |= ADC10IE + ENC + ADC10SC;//允许ADC10中断,ADC10转换使能,并开始转换
  _EINT();//打开中断
  while(!(flag));
}

#pragma vector=ADC10_VECTOR
__interrupt void ADC10 (void)
{
   ad = ADC10MEM;
   v = ad*3.3*1000/1023;
   flag = 1;
}



想问一下大家,上面的序列多通道转换没有用到ADCMEM,下面的单通道却用到了,若多通道转换要用ADCMEM该怎么写呢,再次感谢各位了。

使用特权

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

本版积分规则

29

主题

69

帖子

1

粉丝