MSP430 序列通道单次转换问题

[复制链接]
1432|26
手机看帖
扫描二维码
随时随地手机跟帖
Brand2|  楼主 | 2017-11-21 16:47 | 显示全部楼层 |阅读模式
我想实现的功能为:通过8个通道采集AD,定时器触发采样率为1个周期80个点,然后将通道ADC12CH_0和通道ADC12CH_1采集的数据存储在开辟的两段FRAM区域里面,用序列通道(ADC12CONSEQ_1)采。但是,不能进入中断。不知道啥原因,下面是程序部分,请各位大神帮忙解答!万分感谢。(注:我用的MCU是MSP430FR5969)

#include <msp430.h>

#define FRAM_TEST_START0 0x9000
#define FRAM_TEST_START1 0xD000

volatile unsigned long ADC_Data[8];
unsigned char count = 0;
unsigned long *FRAM_write_ptr;


void GPIOInit(void)
{

    // Configure all un-used GPIO to lowest power state
    P1DIR = 0xFF;
    P1OUT = 0;

    P1SEL1 |= BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5;// Configure P1.0 P1.1 P1.2 P1.3 P1.4 P1.5for ADC
    P1SEL0 |= BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5;// A0~A5


    P2DIR = 0xFF;
    P2OUT = 0;
//    P2OUT = 0xFF;
    P2SEL1 |= BIT3 | BIT4; // Configure P2.3 and P2.4 for ADC
    P2SEL0 |= BIT3 | BIT4; // A6~A7

    P3DIR = 0xFF;
    P3OUT = 0;
//    P2OUT = 0xFF;

    P4DIR = 0xFF;
    P4OUT = 0;


    PJOUT = 0;
    PJSEL0 = BIT4 | BIT5;                   // For XT1
    PJDIR = 0xFFFF;

    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings
    PM5CTL0 &= ~LOCKLPM5;
}

void clockInit(void)
{
    // Clock System Setup
    CSCTL0_H = CSKEY >> 8;                  // Unlock CS registers
    CSCTL1 = DCOFSEL_6;                     // Set DCO to 8MHz
    CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;   // Set ACLK = XT1; MCLK = SMCLK = DCO
    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;   // Set all dividers
    CSCTL4 &= ~LFXTOFF;                     // Enable LFXT1
    do
    {
        CSCTL5 &= ~LFXTOFFG;                // Clear XT1 fault flag
        SFRIFG1 &= ~OFIFG;
    } while (SFRIFG1 & OFIFG);              // Test oscillator fault flag
    CSCTL0_H = 0;                           // Lock CS registers

}

void TimerInit(void)
{

    // Configure Timer0_A
    TA0CCR0 = 8-1;                          // 32K/32 = 1000Hz freq.
    TA0CCTL1 = OUTMOD_7;                      // CCR1 reset/set
    TA0CCR1 = 4;                             // 16/32 = 50% duty cycl
    TA0CTL = TASSEL__ACLK | MC__UP | TACLR;   // ACLK, up mode, clear TAR
}

void FRAMWrite(unsigned long data)
{


    *FRAM_write_ptr++ = data;

}


void ADC12Init()
{
    // By default, REFMSTR=1 => REFCTL 是配置内部参考电压的寄存器
    // while(REFCTL0 & REFGENBUSY);                              // 如果参考电压发生器busy, 等待
    // REFCTL0 |= REFVSEL_2 | REFON;                           // 选择内部参考源 ref = 2.5V,使能内部参考源

    // Configure ADC12
    ADC12CTL0 = ADC12SHT0_2 | ADC12ON | ADC12MSC;      // Sampling time, S&H=16, ADC12 on
    ADC12CTL1 = ADC12SHP + ADC12SHS_1 + ADC12SSEL_1 + ADC12CONSEQ_1;     // Use sampling timer, Use TA0CCR1 output as trigger , sequence channel
    ADC12CTL2 |= ADC12RES_2 + ADC12PWRMD;   // 12-bit conversion results, low power mode         ADC12CTL3 = ADC12CSTARTADD_0;// | ADC12CSTARTADD_1;

   // while(!(REFCTL0 & REFGENRDY));         // 等待参考源生效

    ADC12IER0 |= ADC12IE0;                  //开中断

    ADC12MCTL7 |= ADC12INCH_7 | ADC12VRSEL_1;        // A2 ADC input select; Vref=AVCC
    ADC12MCTL1 |= ADC12INCH_1 | ADC12VRSEL_1;
    ADC12MCTL0 |= ADC12INCH_2 | ADC12VRSEL_1;
    ADC12MCTL3 |= ADC12INCH_3 | ADC12VRSEL_1;
    ADC12MCTL4 |= ADC12INCH_4 | ADC12VRSEL_1;
    ADC12MCTL5 |= ADC12INCH_5 | ADC12VRSEL_1;
    ADC12MCTL6 |= ADC12INCH_6 | ADC12VRSEL_1;
    ADC12MCTL0 |= ADC12INCH_0 | ADC12VRSEL_1 + ADC12EOS;

    ADC12CTL0 |= ADC12ENC | ADC12SC;    //转换使能,开始转换
}


int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;                 // Stop WDT
    GPIOInit();
    clockInit();
    TimerInit();
    ADC12Init();


    while (1)
    {
        __bis_SR_register(LPM3_bits | GIE); // LPM3, ADC12_ISR will force exit
        __no_operation();                   // For debugger
    }

}


#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
{
    switch(__even_in_range(ADC12IV, ADC12IV_ADC12RDYIFG))
    {
        case ADC12IV_NONE:        break;    // Vector  0:  No interrupt
        case ADC12IV_ADC12OVIFG:  break;    // Vector  2:  ADC12MEMx Overflow
        case ADC12IV_ADC12TOVIFG: break;    // Vector  4:  Conversion time overflow
        case ADC12IV_ADC12HIIFG:  break;    // Vector  6:  ADC12BHI
        case ADC12IV_ADC12LOIFG:  break;    // Vector  8:  ADC12BLO
        case ADC12IV_ADC12INIFG:  break;    // Vector 10:  ADC12BIN
        case ADC12IV_ADC12IFG0:             // Vector 12:  ADC12MEM0 Interrupt


            ADC_Data[0] = ADC12MEM0;
            ADC_Data[1] = ADC12MEM1;

            FRAM_write_ptr = (unsigned long *)FRAM_TEST_START0;
            FRAMWrite(ADC_Data[0]);                            // Endless loop
            ADC12MCTL0&=~ADC12INCH_2; //通道清2

            FRAM_write_ptr = (unsigned long *)FRAM_TEST_START1;
            FRAMWrite(ADC_Data[1]);                            // Endless loop
            ADC12MCTL1&=~ADC12INCH_3; //通道清3


                // Exit from LPM0 and continue executing main
                __bic_SR_register_on_exit(LPM3_bits);
            break;
        case ADC12IV_ADC12IFG1:   break;    // Vector 14:  ADC12MEM1
        case ADC12IV_ADC12IFG2:   break;    // Vector 16:  ADC12MEM2
        case ADC12IV_ADC12IFG3:   break;    // Vector 18:  ADC12MEM3
        case ADC12IV_ADC12IFG4:   break;    // Vector 20:  ADC12MEM4
        case ADC12IV_ADC12IFG5:   break;    // Vector 22:  ADC12MEM5
        case ADC12IV_ADC12IFG6:   break;    // Vector 24:  ADC12MEM6
        case ADC12IV_ADC12IFG7:   break;    // Vector 26:  ADC12MEM7
        case ADC12IV_ADC12IFG8:   break;    // Vector 28:  ADC12MEM8
        case ADC12IV_ADC12IFG9:   break;    // Vector 30:  ADC12MEM9
        case ADC12IV_ADC12IFG10:  break;    // Vector 32:  ADC12MEM10
        case ADC12IV_ADC12IFG11:  break;    // Vector 34:  ADC12MEM11
        case ADC12IV_ADC12IFG12:  break;    // Vector 36:  ADC12MEM12
        case ADC12IV_ADC12IFG13:  break;    // Vector 38:  ADC12MEM13
        case ADC12IV_ADC12IFG14:  break;    // Vector 40:  ADC12MEM14
        case ADC12IV_ADC12IFG15:  break;    // Vector 42:  ADC12MEM15
        case ADC12IV_ADC12IFG16:  break;    // Vector 44:  ADC12MEM16
        case ADC12IV_ADC12IFG17:  break;    // Vector 46:  ADC12MEM17
        case ADC12IV_ADC12IFG18:  break;    // Vector 48:  ADC12MEM18
        case ADC12IV_ADC12IFG19:  break;    // Vector 50:  ADC12MEM19
        case ADC12IV_ADC12IFG20:  break;    // Vector 52:  ADC12MEM20
        case ADC12IV_ADC12IFG21:  break;    // Vector 54:  ADC12MEM21
        case ADC12IV_ADC12IFG22:  break;    // Vector 56:  ADC12MEM22
        case ADC12IV_ADC12IFG23:  break;    // Vector 58:  ADC12MEM23
        case ADC12IV_ADC12IFG24:  break;    // Vector 60:  ADC12MEM24
        case ADC12IV_ADC12IFG25:  break;    // Vector 62:  ADC12MEM25
        case ADC12IV_ADC12IFG26:  break;    // Vector 64:  ADC12MEM26
        case ADC12IV_ADC12IFG27:  break;    // Vector 66:  ADC12MEM27
        case ADC12IV_ADC12IFG28:  break;    // Vector 68:  ADC12MEM28
        case ADC12IV_ADC12IFG29:  break;    // Vector 70:  ADC12MEM29
        case ADC12IV_ADC12IFG30:  break;    // Vector 72:  ADC12MEM30
        case ADC12IV_ADC12IFG31:  break;    // Vector 74:  ADC12MEM31
        case ADC12IV_ADC12RDYIFG: break;    // Vector 76:  ADC12RDY
        default: break;
    }
}

相关帖子

Soraka| | 2017-11-21 17:16 | 显示全部楼层
应该在中断里边采数据吧!

使用特权

评论回复
Garen2| | 2017-11-21 17:29 | 显示全部楼层
定时器触发一直都在采集数据的,中断里面是将我采集的数据度给FRAM中

使用特权

评论回复
Ryze| | 2017-11-21 17:39 | 显示全部楼层

开通连续采集是吧

使用特权

评论回复
Varus| | 2017-11-21 17:53 | 显示全部楼层
ADC12IER0 |= ADC12IE0;                  //开中断
这句有问题
应该开中断7,并且在中断ADC12IV_ADC12IFG7里进行数据提取

使用特权

评论回复
Snow7| | 2017-11-21 18:05 | 显示全部楼层
开通连续采集是吧

楼主是序列通道单次采集

使用特权

评论回复
baimiaocun2015| | 2017-11-23 23:00 | 显示全部楼层
AD数据采集的设计,的看具体的寄存器的

使用特权

评论回复
cemaj| | 2017-12-4 21:13 | 显示全部楼层
楼主不使用中断?

使用特权

评论回复
10299823| | 2017-12-4 21:14 | 显示全部楼层
硬件不能实现对吧。

使用特权

评论回复
jimmhu| | 2017-12-4 21:15 | 显示全部楼层
楼主说的不进入ADC中断吗?

使用特权

评论回复
lihuami| | 2017-12-4 21:20 | 显示全部楼层
void ADC12()
{

  P6SEL = 0x0F;                             // Enable A/D channel inputs

  ADC12CTL0 = ADC12ON+ADC12MSC+ADC12SHT0_15; // Turn on ADC12, extend sampling time
                                            // to avoid overflow of results
  ADC12CTL1 = ADC12SHP+ADC12CONSEQ_3;       // Use sampling timer, repeated sequence
  ADC12MCTL0 = ADC12INCH_0;                 // ref+=AVcc, channel = A0
  ADC12MCTL1 = ADC12INCH_1+ADC12EOS;                 // ref+=AVcc, channel = A1
  //ADC12MCTL2 = ADC12INCH_2+ADC12EOS;                 // ref+=AVcc, channel = A2
  //ADC12MCTL3 = ADC12INCH_3+ADC12EOS;        // ref+=AVcc, channel = A3, end seq.
  ADC12IE = 0x02;                           // Enable ADC12IFG.2
  ADC12CTL0 |= ADC12ENC;                    // Enable conversions
  ADC12CTL0 |= ADC12SC;                     // Start convn - software trigger

}
#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR(void)
{
  static unsigned int index = 0;
  u16 c;
  switch(__even_in_range(ADC12IV,34))
  {
  case  0: break;                           // Vector  0:  No interrupt
  case  2: break;                           // Vector  2:  ADC overflow
  case  4: break;                           // Vector  4:  ADC timing overflow
  case  6: break;                           // Vector  6:  ADC12IFG0
  case  10: break;                           // Vector  8:  ADC12IFG2
  case 12: break;                           // Vector 10:  ADC12IFG3
  case 8:                                  // Vector 12:  ADC12IFG1
    A0results[index] = ADC12MEM0;           // Move A0 results, IFG is cleared
    A1results[index] = ADC12MEM1;           // Move A1 results, IFG is cleared
...
  case 14: break;                           // Vector 14:  ADC12IFG4
  case 16: break;                           // Vector 16:  ADC12IFG5
  case 18: break;                           // Vector 18:  ADC12IFG6
  case 20: break;                           // Vector 20:  ADC12IFG7
  case 22: break;                           // Vector 22:  ADC12IFG8
  case 24: break;                           // Vector 24:  ADC12IFG9
  case 26: break;                           // Vector 26:  ADC12IFG10
  case 28: break;                           // Vector 28:  ADC12IFG11
  case 30: break;                           // Vector 30:  ADC12IFG12
  case 32: break;                           // Vector 32:  ADC12IFG13
  case 34: break;                           // Vector 34:  ADC12IFG14
  default: break;
  }
}

使用特权

评论回复
xiaoyaozt| | 2017-12-4 21:20 | 显示全部楼层
对序列通道进行单次转换要进行如下设置: x=CSStartAdd

使用特权

评论回复
uptown| | 2017-12-4 21:21 | 显示全部楼层
static uchar adc_flag = 0 ;
uint AD_TEMP = 0 ;
void int_clk()
{
uchar i ;
BCSCTL1&=~XT2OFF; //打开XT振荡器
BCSCTL2|=SELM1+SELS; //MCLK为8MHz,SMCLK为8MHz
do
{
IFG1&=~OFIFG; //清除振荡错误标志
for(i=0;i<100;i++)
_NOP(); //延时等待
}
while((IFG1&OFIFG)!=0); //如果标志为1,则继续循环等待
IFG1&=~OFIFG;
}
int_adc()
{
P6SEL |= BIT0 ; //选择AD通道
ADC12CTL0 |= ADC12ON + SHT0_2 + REF2_5V + REFON ; //采样保持时间为16个ADC12CLK
/*ADC12ON ADC模块电源控制位;
REF2_5V 内部参考电压选择位0:1.5V  1:2.5V
REFON 参考电压模块控制位0:关闭 1:打开*/
ADC12CTL1 |= ADC12SSEL0 + ADC12SSEL1 ; //ADC12时钟源选择控制位 00ADC12OSC 01ACLK 10MCLK 11SMCLK
ADC12MCTL0 = 0x10; // 连续转换结束通道,CHANNEL = A0 参考选择控制位
ADC12IE |= 0x01; //使能A/D转换器
ADC12CTL0 |= ENC ; //AD转换使能
}
#pragma vector = ADC_VECTOR
__interrupt void ADC12ISR(void)
{
while((ADC12CTL1 & 0x01)== 1); //等待转换完
adc_flag = 1 ;
AD_TEMP = ADC12MEM0 ; //设置AD转换完成标志,并读取ADC值
}
void main()
{
WDTCTL = WDTPW + WDTHOLD ;
int_clk();
int_adc();
_EINT(); //使能中断
adc_flag = 1 ;
while(1)
{
while(adc_flag == 1)
{
ADC12CTL0 |= ADC12SC ; //开启转换
ADC12CTL0 &= ~ADC12SC ;
adc_flag = 0 ; //清中断标志
}
}
}

使用特权

评论回复
cehuafan| | 2017-12-4 21:22 | 显示全部楼层
连续转换ADC完转换自始转换需要再启ADC工作

使用特权

评论回复
usysm| | 2017-12-4 21:23 | 显示全部楼层
1、设置通道                  

2、打开ADC,设置采样时间     

3、使用采用定时器                       

4、设置参考电压   

5、使能开始                  

6、采样开始               

7、等待转换完成                             

8、把转换的值存入变量     

使用特权

评论回复
typeof| | 2017-12-4 21:23 | 显示全部楼层
  ADCMCTL0=SREF_0;                                        //Vr+=AVcc,Vr-=AVss;

/*

SREF  参考电压选择位

*/

    ADC12CTL0|=ENC;                                               //首次转换由SAMPCON上升沿启动

/*

ENC 转换允许位

   0:ADC12为初始状态,不能启动A/D转换

   1:首次转换由采样信号上升沿启动

*/

    ADC12CTL0|=ADC12SC;                                     //采样/转换控制位开

/*

    ADC12SC  采样/转换控制位

*/

使用特权

评论回复
yujielun| | 2017-12-4 21:24 | 显示全部楼层
ADC转换过程包括两个过程:采样和量化。采样率决定了采样过程的时间及精度,量化位数直接决定量化过程的精度。

使用特权

评论回复
cemaj| | 2017-12-4 21:24 | 显示全部楼层
楼主后面说的使用什么进行采样?

使用特权

评论回复
10299823| | 2017-12-4 21:24 | 显示全部楼层
代码开启了中断了吗?

使用特权

评论回复
jimmhu| | 2017-12-4 21:24 | 显示全部楼层
还是定时器中断?

使用特权

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

本版积分规则

157

主题

824

帖子

2

粉丝