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.

[参考译文] MSP430FR2533:MSP430FR2X/4X ADC 通道序列问题

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/649350/msp430fr2533-msp430fr2x-4x-adc-sequence-of-channel-issue

器件型号:MSP430FR2533

您好,TI 员工  

我   ,的是 FR2533‘s ADC,、我希望使用具有计时器 B 触发器的单序列通道模式

但 问题是:

1) 1) FR2X/4X 系列 MCU 仅具有一个 ADC 转换结果存储器,、 不支持 DMA、

   这意味着 μ,在  通道模式序列中,ADC 转换完成后,每次 ADCIFG 被置位时都将进入 ADC ISR

2),Timer B 触发 ADC 时、根据 UG、ADCENC 必须在序列 μ s 之间切换、因此何时应切换 ADCENC。

  我的代码如下所示:

例程执行后,结果似乎是错误的,数组中 ADC 结果的顺序不正确,我该怎么做?

/*
@由 SS 供电
@Author kissn Liu
@date 2017-12-8
@fution:ADC 多通道样本使用 TA1触发器;
*/
#include "msp430fr2533.h"
/*
A7-ADC_Result [7]
。
。
。
A0-ADC_Result[0]

*
/ unsigned char ADC_Result[8]={0};
void init_ADC_Using_TA1_TRIGGER ()
{
//配置 ADC A0~7引脚
SYSCFG2 = ADCPCTL0 | ADCPCTL1 | ADCPCTL2 | ADCPCTL3 | ADCPCTL4 | ADCPCTL6 | ADCPCTL5 | ADCPCTL5


//配置 ADC
//更改 ADCSHTx 位以更改采样时间
ADCCTL0 |= ADCSHT_2 | ADCMSC | ADCON; //
ADCCTL1上的16ADCclks、MSC、ADC |= ADCSHS_2 | ADCSHP | ADCCONSEQ_1 | ADCSSEL_0; // ADC 时钟 MODCLK、采样计时器、TA1 TRIG、单序列
ADCCTL2 &=~ADCRES; // 8位转换结果
ADCMCTL0 |= ADCINCH_7 | ADCSREF_0; // A0~7 (EOS);Vref=Vcc
ADCIE |= ADCIE0; //启用 ADC 转换完成中断
ADCCTL0 |= ADCENC; // ADC 使能

TA1CCR0 = 33;
TA1CCR1 = 16;
//TA1CCTL0 =(CCIE);//启用 CCIFG
TA1CCTL1 = OUTMOD_7;//PWM 输出模式:7 -复位/设置
TA1CTL =(tassel_ACLK | MC_UP);

_bis_SR_register (GIE); //输入带中断

的 LPM3 }
void main()
{
WDTCTL = WDTPW | WDTHOLD; //停止 WDT
//禁用 GPIO 上电默认高阻抗模式以激活
//先前配置的端口设置
PM5CTL0 &=~LOCKLPM5;
init_adc_using_TA1_TRIGGER ();

while (1)
{

}

}
// ADC 中断服务例程

#pragma vector=ADC_vector
__interrupt void ADC_ISR (void)
{
static char i = 7;
switch (__even_in_range (ADCIV、ADCIV_ADCIFG)
){
case ADCIV_none:
中断;
ADCIV_ADCOVIFG 案例:
中断;
案例 ADCIV_ADCTOVIFG:
中断;
ADCIV_ADCHIIFG 案例:
中断;
ADCIV_ADCLOIFG 案例:
中断;
ADCIV_ADCINIFG 案例:
中断;
ADCIV_ADCIFG 案例:
/*
当 ADCSC 触发一个序列时、连续的序列可由 ADCSC 位触发。
当使用任何其他触发源时、必须在每个序列之间切换 ADCENC。
!!!ADC12ENC 必须在序列之间切换
*
ADCCTL0 &=~ADCENC;
ADC_RESULSE[i]= ADCMEM0;
if (i ==0)
{
I = 7;
__no_operation();
}
其他
{
i--;
}
ADCCTL0 |= ADCENC;
中断;
默认值:
break;
}


#pragma vector=Timer1_A0_vector
__interrupt void Timer1_A0 (void)
{
__no_operation ();

} 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果 MSC=1、则需要在突发之间切换 ENC、即当您(重新)设置 I=7时。 [另请参见 SLAU45G 图20-10]

    你在这里几乎肯定遇到的是一场比赛。 突发本身(有效)由 ADC 时钟驱动、因为它在前一个采样/转换完成后立即启动下一个采样/转换。 MODCLK 非常快;转换序列中的(16+11) MODCLK 只有大约27/5=6个 MCLK --只有足够的时间到达 ISR;整个突发可能会在您从 ISR 中退出时完成。 在重新填充 MEM0之前、您没有时间捕获它、并且阵列计数器[i](更不用说您的数据)将关闭。 我看到的选项:

    1) 1)使用 ACLK 而不是 MODCLK。 这将减慢转换速度(大约30.5*5=~150x),使您有更多时间进入/退出 ISR。 这也会延长采样/保持时间、因此您可能希望将 SHT"设置得非常低。
    2) 2)设置 MSC=0并以8倍的速度运行计时器。 这将意味着您的突发并不是真正的"同步"、而是在标称采样周期内均匀间隔、但您将有一个已知/可设置的 CPU 时钟数、以便在 MEM0被覆盖之前获取它。 我只需添加:完成所有这些操作后、您可能还需要设置 CONSEQ=3、然后您就不必切换 ENC。 (这就是我最终所做的。)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这条建议听起来不错!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    回复很好、Bruce。 感谢您的支持。

    此致、
    Ryan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢、您的建议解决了我的问题 

    /* @由 SS 供电 @Author kissn Liu @date 2017-12-8 @fution:ADC 多通道样本使用 TA1触发器; @ ADC 以重复通道模式序列工作 */ #include "msp430fr2533.h" /* A7-ADC_Result [7] 。 。 。 A0-ADC_Result[0] * / unsigned char ADC_Result[8]={0}; void init_ADC_Using_TA1_TRIGGER () { //配置 ADC A0~7引脚 SYSCFG2 = ADCPCTL0 | ADCPCTL1 | ADCPCTL2 | ADCPCTL3 | ADCPCTL4 | ADCPCTL6 | ADCPCTL5 | ADCPCTL5 //配置 ADC //@\! 更改 ADCSHTx 位来改变采样时间来获得预先设定的 ADC 结果 ADCCTL0 |= ADCSHT_2 | ADCON; // 16ADCclks, 、ADCCTL1上的 ADC |= ADCSHS_2 | ADCSHP | ADCCONSEQ_3 | ADCSSEL_0; // ADC 时钟 MODCLK、采样计时器、TA1 TRIG、重复序列通道 ADCCTL2 &=~ADCRES; // 8位转换结果 ADCMCTL0 |= ADCINCH_7 | ADCSREF_0; // A7~0 (EOS);Vref=Vcc ADCIE |= ADCIE0; //启用 ADC 转换完成中断 ADCCTL0 |= ADCENC; // ADC 使能 TA1CCR0 =250;//2000/8触发 ADC 每125us,采样周期为125us * 8 = 1000US TA1CCR1 = 125; //TA1CCTL0 =(CCIE);//启用 CCIFG TA1CCTL1 = OUTMOD_7;// PWM 输出模式:7 -重置/设置 TA1MC_CLK_=(tCLK_);//选择 TSM2MC_UP) _bis_SR_register (GIE); //输入带中断 的 LPM3 } void main() { WDTCTL = WDTPW | WDTHOLD; //停止 WDT //禁用 GPIO 上电默认高阻抗模式以激活 //先前配置的端口设置 PM5CTL0 &=~LOCKLPM5; init_adc_using_TA1_TRIGGER (); //P2DIR |= BIT0;用于调试。 while (1) { } } // ADC 中断服务例程 #pragma vector=ADC_vector __interrupt void ADC_ISR (void) { static char i = 7; switch (__even_in_range (ADCIV、ADCIV_ADCIFG) ){ case ADCIV_none: 中断; ADCIV_ADCOVIFG 案例: 中断; 案例 ADCIV_ADCTOVIFG: 中断; ADCIV_ADCHIIFG 案例: 中断; ADCIV_ADCLOIFG 案例: 中断; ADCIV_ADCINIFG 案例: 中断; ADCIV_ADCIFG 案例: ADC_RESULSE[i]= ADCMEM0; // 如果 i = 0、则表示: (1)序列 ADC 通道采样已完成、 (2)您可以在此处停止 ADC 转换以忽略对 ADC 结果数组的数据过写 * if (i ==0) { I = 7; //P2OUT ^= BIT0;//切换 P2.0以查看 ADC 采样的周期是否正确 __no_operation(); } 其他 { i--; } 中断; 默认值: break; } #pragma vector=Timer1_A0_vector __interrupt void Timer1_A0 (void) { __no_operation (); }
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    未经请求:读取 ADCINCH 字段会反映序列中的下一个通道、因此您可以从中得出"i"。 (这是 SLAU45G 中的"x"、图20-14、因此出于您的目的、它始终关闭1。) 计算的工作量稍大、但不能脱离同步。