This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430FR5969:可以#39;不能立即选择不同的ADC12_B信道

Guru**** 2529560 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1093345/msp430fr5969-can-t-seem-to-select-a-different-adc12_b-channel-on-the-fly

部件号:MSP430FR5969

有时需要读取一个ADC通道,有时需要读取另一个通道,但我的代码不起作用。

有人能告诉您为什么此代码不起作用吗?  我意识到有一种序列等模式,但它看起来很复杂,我的代码必须非常接近工作。

提前感谢!  以下是代码...




void init_temp_monitor_adc (void){

 
 PM5CTL0 &=~LOCKLPM2;

 //默认情况下,REFMSTR=1 => REFCTL用于配置内部引用
 同时(REFCTL0和REFGENBUSY);
 
 //电压参考控制
 REFCTL0 = REFVSEL_2 | REFON_L | REFOUT_L;
 
  //配置ADC12
 ADC12CTL0 = ADC12SHT0_2 | ADC12ON;       //循环采样时间,ADC打开  
 ADC12CTL1 = ADC12SHP;                    //源时钟是采样计时器
 ADC12CTL2 || ADC12RES_2;                 // 12位转换
// ADC12IER0 |= ADC12IE0;                   //中断MEM0 --未使用--
 
 
 //********* 下一行似乎永远选择ADC12INCH_12或ADC12INCH_13,但我想在调用READ_TEMP_ADC()*******时选择它
 ADC12MCTL0 |= ADC12INCH_13 | ADC12VRSEL_1;//选择A13, Vref源=内部VREF (高于设置为2.5V)
 // ADC12MCTL0 |= ADC12INCH_12 | ADC12VRSEL_1;//选择A12, Vref源=内部VREF (高于设置为2.5V)
 
 
 while (!(REFCTL0 & REFGENRDY));//等待参考生成器稳定
 
}

//---------------------------
//参数选择要读取的通道
u16int_t read_temp_adc (u16int_t which){
 u16int_t val;
 

 IF (which == 1){
   ADC12MCTL0 |= ADC12INCH_12| ADC12VRSEL_1;//选择A12通道A
   
   while (!(REFCTL0 & REFGENRDY));//等待参考生成器稳定
   
   
   
    __DELAY周期(50);
   ADC12CTL0 || ADC12ENC | ADC12SC;  //开始转换
 
   //等待转换。
   //
   while (!(ADC12IFGR0和ADC12IFG0));//AA
      Val = ADC12MEM0; //
      
   ADC12MCTL0 &=~ADC12INCH_12;
 }
 否则 ,如果(which == 2){ // TTT
   ADC12MCTL0 |= ADC12INCH_13| ADC12VRSEL_1;//选择A13通道B
   
   while (!(REFCTL0 & REFGENRDY));//等待参考生成器稳定
   
   
   
    __DELAY周期(50);
   ADC12CTL0 || ADC12ENC | ADC12SC;  //开始转换
 
   //等待转换。
   //
   while (!(ADC12IFGR0和ADC12IFG0));//AA
      Val = ADC12MEM0; //
      
   ADC12MCTL0 &=~ADC12INCH_13;
 }
  
     
 ADC12CTL0 &=~ADC12ENC;//我们是否需要此项?
 
 返回值;
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    许多寄存器都有此注释适用的字段:“只能在ADC12ENC =0时修改。” 包括在ADC12MCTLx中。 所以你需要小心这一点。

    频道顺序并不难,在家庭指南中有详细介绍。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您对ADC12ENC的评论,但我在READ_TEMP_ADC()例程的开头添加了以下行,没有任何改进或明显的变化:

    ADC12CTL0 &=~ADC12ENC.

    您能看到其他问题吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我看不到您在哪里配置要由ADC模块控制的引脚,但我假设您这样做了。 我完全不在乎您在ADCMTL上使用"|="。 这里没有任何您想要保留的设置位,所以只需使用"="。

    您尝试清除转换后选定的ADC12INCH位,但ADC12ENC未被清除,因此这是一个问题。 使用"="时不需要的操作。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    以下是PIN的设置方式:

     
     P3SEL1 || BIT0;//为ADC A12配置WFP 3.0
     P3SEL0 |= BIT0;
     
     P3SEL1 |= BIT1;//为ADC A13配置WFP 3.1
     P3SEL0 |= BIT1;

    我从我在某处找到的示例代码中复制了代码,它可以读取一个ADC通道,我没有足够的知识来提问,但是如果不保留其他位,那么您是对的,最好不要使用“|=”,我会更改它。

    有趣的是,我可以从任一渠道读取,但需要重新编译,请参阅我的评论: "似乎选择永久"(实际上,它不是永久的,最后几次运行似乎read_temp_adc ()例程成功地选择了另一个通道,但随后它被卡在那个通道上。 可能需要时间来切换频道,延迟可能会有帮助。)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    以下是PIN的设置方式:

     
     P3SEL1 || BIT0;//为ADC A12配置WFP 3.0
     P3SEL0 |= BIT0;
     
     P3SEL1 |= BIT1;//为ADC A13配置WFP 3.1
     P3SEL0 |= BIT1;

    我从我在某处找到的示例代码中复制了代码,它可以读取一个ADC通道,我没有足够的知识来提问,但是如果不保留其他位,那么您是对的,最好不要使用“|=”,我会更改它。

    有趣的是,我可以从任一渠道读取,但需要重新编译,请参阅我的评论: "似乎选择永久"(实际上,它不是永久的,最后几次运行似乎read_temp_adc ()例程成功地选择了另一个通道,但随后它被卡在那个通道上。 可能需要时间来切换频道,延迟可能会有帮助。)

    也许这是错误的方法,如果有人可以将我引导到重复序列的示例代码,我想尝试一下!  我只需要一个有用的东西!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    最好不要使用"|=",我会更改它。

    现在您已做出改变,它的行为是否有所不同?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    由于这一变化,它似乎没有采取不同的行动,但在周末,我尝试了评估板,并且有一些代码似乎正确地更改了选定的ADC12_B通道。  我将在测试后将该代码发布到我们的实际目标板上。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    以下代码有效......

    (我不完全确定是否需要虚拟读取,也许有更好的方法)



    void init_temp_monitor_adc2(void){
     
     //针脚设置
     P3SEL1 || BIT0;//为ADC A12配置WFP 3.0
     P3SEL0 |= BIT0;
     
     P3SEL1 |= BIT1;//为ADC A13配置WFP 3.1
     P3SEL0 |= BIT1;

     P3SEL1 |= BIT2;//为ADC A14配置WFP 3.2
     P3SEL0 |= BIT2;
     //
     
     PM5CTL0 &=~LOCKLPM2;

     //默认情况下,REFMSTR=1 => REFCTL用于配置内部引用
     同时(REFCTL0和REFGENBUSY);
     
     //电压参考控制
     REFCTL0 = REFVSEL_2 | REFON_L | REFOUT_L;
     
      //配置ADC12
     ADC12CTL0 = ADC12SHT0_2 | ADC12ON;       //循环采样时间,ADC打开  
     ADC12CTL1 = ADC12SHP;                    //源时钟是采样计时器
     ADC12CTL2 || ADC12RES_2;                 // 12位转换
    // ADC12IER0 |= ADC12IE0;                   //中断MEM0 ---未使用
     ADC12MCTL0 |= ADC12INCH_12 | ADC12VRSEL_1;//选择A12, Vref =内部VREF (设置为上面的2.5V)  WE选择A10
     
     
     while (!(REFCTL0 & REFGENRDY));//等待参考生成器稳定
     
     
    }

    //
    //---------------
    //选择并读取ADC通道
    //如果chan == 0,则使用以前选择的通道,否则
    //选择一个新频道并阅读它
    u16int_t read_temp_adC2 (u16int_t chan){
     u16int_t val;
     
     
     如果(chan !=0){
        ADC12CTL0 &=~ADC12ENC;
       
        交换机(通道){    
         案例1:  // ADC选择A12通道A             
                 ADC12MCTL0 &=~ADC12INCH_14;
                 ADC12MCTL0 &=~ADC12INCH_13;
                 ADC12MCTL0 |= ADC12INCH_12;
                 中断;
                 
         案例2:  // ADC选择A13通道B
                 ADC12MCTL0 &=~ADC12INCH_14;
                 ADC12MCTL0 &=~ADC12INCH_12;
                 ADC12MCTL0 |= ADC12INCH_13;
                 中断;
                 
         案例3:  // ADC选择A14通道C
                 ADC12MCTL0 &=~ADC12INCH_13;
                 ADC12MCTL0 &=~ADC12INCH_12;
                 ADC12MCTL0 |= ADC12INCH_14;
                 中断;
                 
         默认值:     //不是有效通道
              //  返回;
                 中断;   
       }
     }

     
     __DELAY周期(50);
     ADC12CTL0 || ADC12ENC | ADC12SC;
      
     
     //等待转换。
     //
     同时(!(ADC12IFGR0和ADC12IFG0));
        Val = ADC12MEM0; //获取ADC值

       
     ADC12CTL0 &=~ADC12ENC;
     
    返回值;
    }


    //---------------------------


    .....

    //此代码调用read_temp_adc2()
    //请注意,当更改通道时,会有一个虚拟读取,然后使用READ_TEMP_ADC2(0);调用来收集数据



     read_temp_ADC2 (1); //<--虚拟读取
     对于(ii=0;ii<9;i++){
       dat1 = read_temp_ADC2 (0);
        test_arr[tc_inc+]=日期1;
     }
     
    // 转至另一个频道......
      read_temp_ADC2 (2);//<--虚拟读取
     对于(ii=0;ii<9;i++){
       dat1 = read_temp_ADC2 (0);
        test_arr[tc_inc+]=日期1;
     }


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    清除上一英寸值的代码是笨拙的。 只需使用ADC12MCTL0 &=~ADC12INCH_31;并一次清除该字段中的所有位。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    有时,显示单个操作更好,以便人们看到所需内容,但您是对的,同时执行所有操作更好,以实现代码紧凑。