coolfzl2008 发表于 2011-4-6 20:39:55

新手求助:关于MSP430的AD转换的问题

最近在学习MSP430用的是利尔达的MSP430F449板子   看了书自己写个小程序可是就是调试不过去不知道问题出在哪里了? 请各位前辈帮忙看看~
我想从P6.0口采样一个信号源给的正弦信号,然后计算出电压 显示    这是我的程序
void Init_ADC(void)
{
       
    P6SEL = 0X01;    //设置P6.0为模拟输入通道            
   
    ADC12CTL0 &= ~(ENC);//设置ENC为0,从而修改ADC12寄存器的值,只有其为零时,ADC12才能修改。
   
    ADC12CTL0 =REF2_5V + REFON; //参考电压选择为内部电压2.5v;
   
    ADC12MCTL0 =INCH_0+SREF_1; //输入通道为A0,使用内部VR+作为参考电压正端,VR-作为负端。         
   
    ADC12CTL1 = 0X00;//寄存器清零
    ADC12CTL1 += CSTARTADD_0;//转换的起始地址为:ADCMEM0
       
    ADC12CTL1 += SHP;        //采样脉冲由采用定时器产生,触发信号 SHP=0时,由ADC12SC控制产生。
       
    ADC12CTL1 += CONSEQ_2;//转换模式为:单通道、多次转换
       
    ADC12CTL1 += ADC12SSEL_0;//内部时钟源
       
    ADC12CTL1 += ADC12DIV_0;//时钟分频为1
   
   // ADC12CTL0 += 8 * 0x100;
    ADC12CTL0 += MSC;//首次转换有SHI信号上升沿触发,而后的采样转换则在前一次转换完成后立即进行
    ADC12CTL0 += ADC12ON;//AD内核打开
   
    ADC12IE = 0;
        //关闭各个通道的转换中断
    ADC12IE |= 0X00;                       
    //使能ADC转换
    ADC12CTL0 |= ENC;                       
    return;
}
void Init_TimerA(void)
{
        // 选择SMCLK,清除TAR
    TACTL = TASSEL1 + TACLR;
        // 1/8 SMCLK
    TACTL += ID1;
    TACTL += ID0;            //ID0=ID1=1 是8分频
        // CCR0 中断允许
    CCTL0 = CCIE;
       
        // 时间间隔为 500us,当计数器=500时 变会复位并从0开始计时 所以时间间隔是500us
    CCR0 = 500;//暂时测试
        // 增记数模式
    TACTL |= MC0;       
    TACTL += TAIE;//定时器中断允许;
    return;
}
void Init_CLK(void)
{
    unsigned int i;
    FLL_CTL0 = 0X00;        //将寄存器的内容清零
                                    //XT2震荡器开启
                                        //LFTX1工作在低频模式
                                        //ACLK的分频因子为1
                                       
    do
    {
        IFG1 &= ~OFIFG;                     // 清除OSCFault标志
        for (i = 0x20; i > 0; i--);               
    }
    while ((IFG1 & OFIFG) == OFIFG);      // 如果OSCFault =1   
                                       
    FLL_CTL1 = 0X00;                        //将FLL+控制寄存器的内容清零
   FLL_CTL1 += SELM1;                //MCLK的时钟源为XT2CLK,分频因子为1
   FLL_CTL1 += SELS;                //SMCLK的时钟源为XT2CLK,分频因子为1
}


void main(void)
{      
        unsigned longADC_BUF_Temp;
      double AD_RESULT=0.0;
        int i;
        // 关闭看门狗
        WDTCTL = WDTPW + WDTHOLD;   
        // 关闭中断
    _DINT();                       
   
    // 初始化
    Init_CLK();
    Init_ADC();
    Init_TimerA();

        // 打开中断
        _EINT();
        // 循环处理
      
        while(1)
        {
               
                if(nADC_Flag == 1)
                {       CCTL0 &= ~CCIE;
                        nADC_Flag = 0;
                        for(i = 0;i < 40;i++)
                        {
                                ADC_BUF_Temp = ADC_BUF;
                        }
                }
               
                AD_RESULT=Deal_AD(ADC_BUF_Temp); //这是电压计算子函数
                DIS_AD(AD_RESULT);//这是显示的子函数
        }
      
}


#pragma vector=TIMERA0_VECTOR
__interrupt voidTimerA_ISR(void)
{
    unsigned long results;
    unsigned int nADC_Count=0;
        // 关闭转换
    ADC12CTL0 &= ~ENC;                       
    // 读出转换结果
    results = ADC12MEM0;                                          
    ADC_BUF = results;
    // 计数器加1
    nADC_Count += 1;
        // 采集完40个点
    if(nADC_Count == 40)
    {
                // 设置标志
      nADC_Flag = 1;
                // 计数器清0
      nADC_Count = 0;
    }       
        // 开启转换
ADC12CTL0 |= ENC + ADC12SC;               
}


问题1上面的程序 编译正通过 在Simulator下,单步运行没有问题,在FET DEBUGGER时如果没有从6.0口接入信号 可以下载进去 但是一旦我将信号的正端接到6.0口负端接到板子的GND时就会出现
   FATAL error:failed to write memory at 0x1100
      Session aborted!
的对话框提示,不知道怎么回事 ,然后我点击确定后 就会弹出通信错误的提示。这是怎么回事呢?

问题2如果下载时不接信号源的话则可以下载进去可是利用WATCH 观察寄存器值时 会发现ADC12MEM0就已经有了值像是一个4位随机数 而ADC_BUF_Temp中则也会出现随机数这是怎么回事呢?

问题3问题2的情况下 单步运行时会出现Wed Apr 06 20:32:58 2011: The stack pointer for stack 'Stack' (currently Memory:0x95C) is outside the stack range (Memory:0x9B0 to Memory:0xA00) 的警告这是什么原因呢?

我感觉可能是自己对芯片的理解还不够的原因 导致程序在哪里出现了错误 但是我实在找不到哪里有问题了愁死我了希望高手给指点一下谢谢啦!!!!

cc1989summer 发表于 2011-4-10 19:17:16

void main(void)
{

WDTCTL=WDTPW+WDTHOLD;
LCD_init();
P6SEL |= 0x03;                            // Enable A/D channel A0
ADC12CTL0 = ADC12ON+SHT0_0+MSC+REFON+REF2_5V;         // Turn on ADC12, set sampling time
ADC12CTL1 = SHP+CONSEQ_3;               // Use sampling timer, set mode
ADC12MCTL0 = SREF_1+INCH_0;                     
ADC12MCTL0 = SREF_1+INCH_1;   


ADC12IE = 0x03;                           // Enable ADC12IFG.0
ADC12CTL0 |= ENC;                         // Enable conversions
ADC12CTL0 |= ADC12SC;                     // Start conversion
_BIS_SR(LPM3_bits + GIE);               // Enter LPM0,Enable interrupts

}


#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR (void)
{
static unsigned int index = 0;
results = ADC12MEM0;               // Move results
results1 = ADC12MEM1;               // Move results
index = (index+1)%Num_of_Results;         // Increment results index, modulo


if(index==0)
                                 
{
    v=results;

   
    for(i=1;i<Num_of_Results;i++)
    {
    if(v<results)v=results;
    }
      
   v=((double)v/(double)4096)*2.5;
}


这是我做过的 单通道 测正弦交流信号 很好用



楼主的程序不知参照何处写的
感觉有点乱 看着费劲

建议参照TI的 官方例程修改吧
页: [1]
查看完整版本: 新手求助:关于MSP430的AD转换的问题