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.

[参考译文] MSP430FR2355:尝试在 A/D 上使用单个序列--不进入 ADCIR?

Guru**** 2538960 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/967534/msp430fr2355-attempt-at-using-single-sequence-on-a-d----not-getting-into-adcisr

器件型号:MSP430FR2355

您好...

我正在尝试执行单次转换序列、并且必须在设置方面缺少一些内容...我正在使用用户指南中的流程图、MSC 位= 1且 SHP 位= 1 ...

我使用 P5.1 (TB2.2)作为启动序列的选通脉冲。 采样通道(A4-A0)。  请注意、我没有将 A0转换为模拟通道、因为它当前用于调试。

我配置硬件(I/O、AD、Timer2)。  然后我等待...我似乎从未进入 AD ISR。  有人能告诉我我我缺少了什么吗?  (我认为我不需要做 ADCSC、因为我认为 TB2.2会这样做)

设置代码:

void configMultiTimer (unsigned int p)
{
TB2R = 0;
TB2CTL |= TBSSEL_ACLK;
TB2CCR0 = p;
TB2CCR1 = p - 6;
TB2CCR2 = p - 2;//每个数据表需要100us
/*
*用于无线电发射周期
*
TB2CCTL0 &=~CCIFG;
TB2CCTL0 |= CCIE;
/*
*用于 a/d 和参考设置
*
TB2CCTL1 &=~CCIFG;
TB2CCTL1 |= CCIE;
TB2CTL |= MC__UP;
}

void configAD (void)
{
P1SEL0 |= BIT1 | BIT2 | BIT3 | BIT4;P1SEL1 |= BIT1 | BIT2 | BIT3 | BIT4;
P5SEL0 |= BIT1;//设置 TB2.2在 A/D 的单通道序列上采样
ADCCTL0 |= ADCMSC;
ADCCTL1 |= ADCSHP | ADCCONSEQ1 | ADCSHS_3;
ADCCTL2 &=~ADCRES;//设置为12位
ADCCTL2 |= ADCRES_2;
ADCMCTL0 |= ADCSREF_1 | ADCINCH_4;
ADCIFG &=~ADCIFG0;
ADCIE |= ADCIE0;
}

void turnOffAD (void)
{
ADCIFG &=~ADCIFG0;
PMMCTL0_H = PMMPW_H;
PMMCTL2 &=~INTREFEN;
ADCCTL0 &=~ADCON;
}

void turnOnAD (void)
{
PMMCTL0_H = PMMPW_H;
PMMCTL2 |= INTREFEN | REFVSEL_2;
ADCCTL0 |= ADCON;
while (!(PMMCTL2 & REFGENRDY));
}

ISR 代码:

#pragma vector=TIMER2_B1_VECTOR
__INTERRUPT void T2_ADSetup_ISR (void)
{
开关(__evo_in_range (TB2IV、TBIV_TBCCR1))
{
案例 TBIV_none:
中断;
案例 TBIV_TBCCR1://power A/D -参考
if (!flags.joinSwitchFlag)
{
TurnOnAD();
ADCCTL0 |= ADCENC;
}
中断;
默认值:
中断;
}
LPM3_EXIT;
}

#pragma vector=ADC_vector
__interrupt void 热电偶(void)
{
switch (__evo_in_range (ADCIV、ADCIV_ADCIFG))
{
ADCIV_ADCIFG 案例:
*pResult = ADCMEM0;//读取清除 IFG
pResult++;
如果(pResult >(AD + 4))
{
flags.adFlag = T;
LPM3_EXIT;
}
中断;
默认值:
中断;
}
}

我进入 TB1.1 IRQ 以启用基准和 A/D

谢谢

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

    >    ADCCTL1 |=  ADCSHP | ADCCONSEQ1 | ADCSHS_3;

    1)根据数据表(SLASEC4D)表6-22、SHS=3来自比较器(eComp0.COUT)。 SHS=2是唯一使用 TB1而不是 TB2的 TimerB 触发器。

    2) ADCCONSEQ1是位名称、而不是字段值、因此实际上会设置 CONSEQ=2。 要使 CONSEQ=1、请使用 ADCCONSEQ_1。

    >    TB2CCTL0 |= CCIE;

    This requests TIMER2_B0_VECTOR, but I don't see one of those, so you'll soon end up in ISR_Trap.

    更常见的情况是:要生成计时器触发器、您可以从计时器生成信号(PWM-ISH -- OUTMOD=7通常工作正常);您无需将其路由到引脚、ADC (SHS)将会找出它。 每个周期的上升沿都会触发 ADC。 在用户指南(SLAU445H)图21-6中、您将生成 SHI。  

    [编辑:忘记提及 OUTMOD]

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

    我猜您也不必为 TB1.1安装 ISR (正如我在参考代码中看到的)?。。。 另外,如果你想使用 TB1.1,我觉得使用 OUTMOD=7是很奇怪的,除非你当然使用 SHI 反转....看起来 OUTMOD =3是怎么走的?...

    无论如何,我都没有看到表6-22……看了表6-17,发现这很混乱,尽管我看到 TB1.1是“ADC 触发器”,开始假设我不会从 TB2到达那里,但却故意希望…

    我想我必须重新思考一下,因为我的 TB1连接在一起了…

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

    OUTMOD=3也正常。 在这种情况下、虽然(在一个你可以从 TB2.1触发的时间内) OUTMOD=3时、上升边沿已经过你设定 ADCON=1的时间、所以你将看到一个完整周期的延迟。

    更一般地说:看起来您使用 joinSwitchFlag 作为计时器触发器的闸门。 您可以在计时器 ISR 中直接启动序列(SHS=0的 ADCSC)、而不是先打开 ADC。 这也可以避免您与 TB1发生冲突。

    未经请求:注意用户指南图21-21/22/23中的蓝色框--这些是在 ENC=1时不能更改的字段。 具体而言、在设置 ADCENC=0之前、不能设置 ADCON=0。

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

    我能够移动到 TB1.1。  joinSwitchFlag 是一个无线电标志。  我只想在客户端和主机链接之后执行 A/D 转换。  是的、在 ADCON = 1且 ENC = 0之后、在 ADCON = 0之前、我遵循 ENC = 1。  我遇到 OUTMOD=3的问题、我不知道原因。  我已经设置了 TB1CCR2 = p - 20和 TB1CCR1 = p - 16、所以所有这些应该都是好的。  我发现、如果我使用 OUTMOD = 7、我的 adflag 会被置位、但如果我使用 OUTMOD=3、则永远不会被置位。   

    当使用 TB1.1作为源时、它会在正边沿或负边沿触发来采样 A/D 吗?  如果 OUTMOD7正常工作的话,就会出现这种情况。。。

    您是否看到会阻止 OUTMOD=3工作的钝化情况?

    下面是清理代码:

    ISR 代码:

    #pragma vector = Timer1_B0_vector
    __interrupt void hostrate (void)
    {
    flags.wakeUpFlag = T;
    LPM3_EXIT;
    }
    
    #pragma vector=Timer1_B1_vector
    __interrupt void T1_ADSetup_ISR (void)
    {
    switch (__evo_in_range (TB1IV、TBIV_TBCCR2))
    {
    案例 TBIV_none:
    中断;
    案例 TBIV_TBCCR2://power A/D -参考
    if (!flags.joinSwitchFlag)
    {
    TurnOnAD();
    ADCCTL0 |= ADCENC;
    }
    中断;
    默认值:
    中断;
    }
    LPM3_EXIT;
    }
    
    #pragma vector=ADC_vector
    __interrupt void 热电偶(void)
    {
    switch (__evo_in_range (ADCIV、ADCIV_ADCIFG))
    {
    ADCIV_ADCIFG 案例:
    *pResult = ADCMEM0;//读取清除 IFG
    pResult++;
    如果(pResult >(AD + 4))
    {
    flags.adFlag = T;
    LPM3_EXIT;
    }
    中断;
    默认值:
    中断;
    }
    }
    

    功能代码:

    void configMultiTimer (unsigned int p)
    {
    TB1R = 0;
    TB1CTL |= TBSSEL_ACLK;
    TB1CCR0 = p;
    TB1CCR2 = p - 20;
    TB1CCR1 = p - 16;//每个数据表需要100us
    /*
    *用于无线电发射周期
    *
    TB1CCTL0 &=~CCIFG;
    TB1CCTL0 |= CCIE;
    /*
    *用于 a/d 和参考设置
    *
    TB1CCTL2 &=~CCIFG;
    TB1CCTL2 |= CCIE;
    TB1CCTL1 = OUTMOD_7;
    P2SEL0 |= BIT0;//测试以监控 OUTMOD
    
    TB1CTL |= MC__UP;
    }
    
    void configAD (void)
    {
    P1SEL0 |= BIT1 | BIT2 | BIT3 | BIT4;P1SEL1 |= BIT1 | BIT2 | BIT3 | BIT4;
    ADCCTL0 |= ADCMSC;
    ADCCTL1 |= ADCSHP | ADCCONSEQ_1 | ADCSHS_2;
    ADCCTL2 &=~ADCRES;//设置为12位
    ADCCTL2 |= ADCRES_2;
    ADCMCTL0 |= ADCSREF_1 | ADCINCH_4;
    ADCIFG &=~ADCIFG0;
    ADCIE |= ADCIE0;
    }
    
    void turnOffAD (void)
    {
    ADCIFG &=~ADCIFG0;
    PMMCTL0_H = PMMPW_H;
    PMMCTL2 &=~INTREFEN;
    ADCCTL0 &=~ADCON;
    }
    
    void turnOnAD (void)
    {
    PMMCTL0_H = PMMPW_H;
    PMMCTL2 |= INTREFEN | REFVSEL_2;
    ADCCTL0 |= ADCON;
    while (!(PMMCTL2 & REFGENRDY));
    }
    

    带有 flag 的主代码: 正如您看到的、我首先关闭 ENC

    if (flags.adFlag)
    {
    flags.adFlag = F;
    ADCCTL0 &=~ADCENC;
    TurnOffAD();
    pResult = AD;
    中间体 Tc =((float)* pResult / 4096.0)* 2.5 * 1000;
    热输入电压=((中间值 TC -偏移量)/AMPBIN);//mV
    ThermostTemc = VtoT (ThermoVin);
    }
    

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

    如果 OUTMOD=7成功、但不是=3成功、我的第一个猜测是 TurnOnAD 花费的时间过长、并且(=7)您实际上是在 CCR0上升沿触发的。 在这种情况下、如果使用=3、则必须等待一个"p"周期(通过另一个 CCR2事件)、然后才能触发。 "从不"是指"从不"还是仅仅是"不在周期内"?

    一个快速实验是增加 CCR2->CCR1的间隙、例如设置 CCR2=p-40或其他内容。

    它在上升沿触发、除非您设置 ADCISSH=1。

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

    我试过 CC2 =p-60但没有任何用处...我认为它与定序有关的事情比任何事情都要多(不知道为什么 OUTMOD7起作用)...我说这是因为如果我在 AD ISR 内中断、在那里你读取了 MEM0、 我的 TB1R 计数器与 TB1CCR0....it 匹配看起来我得到了第一个测量 AD4,但我再也不会回到 ISR 中来得到3-0.....

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

    事实证明,问题的关键在于:

    ADDCTL0 |= ADCSHT_2

    出于某种原因、默认 ADCSHT_1无效。  我现在有 OUTMOD3、CCR2 = p-6、CCR1 = p-2、 使用32kHz 晶振似乎是有效的...不确定为什么 S/H 时间会使方程式混乱...传感器板始终通电、因此无需担心真正的趋稳...而且考虑到温度、它不会改变这么快

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

    不知怎么说、我的脑海中看到您使用的是 ADCSSEL=1 (ACLK)、但回看我显然是错了。 省略后、您将使用 ADCSSEL=0 (MODCLK)、它的速度非常快(~5MHz)。  

    在此速度下、ADC 结果很可能太快、无法检索、并且溢出、因此您只能看到一个 ISR 调用。 这就是我在另一个线程中提到的内容。

    设置 ADCSSEL=1 (ACLK)或 ADCSHT=2将降低 ADC 的速度、并且您将达到一个可以及时采集样本的点。 您应该小心,因为小的定时错误可能会导致偶尔的超限--这通常是您无法检测到的。

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

    是的,我同意我可能需要查看溢出标志(必须查看...no,以确定 A/D 是否有这些标志)。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。  已知4个采样/保持和13-14个转换在5mhz 时会产生18个时钟....即使进入 AD ISR 需要5个时钟(16MHz)、11个时钟输出、30个时钟执行增量、 复制寄存器+如果在运行速度快3倍的系统时钟上进行比较...我认为我应该能够处理这个问题

    简短的回答从逻辑上说,我看不出这是什么问题,实际上我看到了它,所以它必须是真的。。。

    谢谢