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.

[参考译文] CCS/MSP430G2553:我无法使用计时器触发 ADC?

Guru**** 2538960 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/964239/ccs-msp430g2553-i-cannot-trigger-the-adc-with-timer

器件型号:MSP430G2553

工具/软件:Code Composer Studio

我将使用微控制器的内部温度传感器制作温度计。 它将由 ADC 计时器触发并每10秒测量一次。 然后温度值将出现在显示屏上。 问题是:
1) 1)我无法使用计时器触发 ADC。 SHC_3或 SHC_2或 SHC_1未执行此任务? 如何使用计时器触发 ADC? 我的错在哪里?
2) 2)如果可以使用计时器触发 ADC、是否有其他方法可以每10秒进行一次测量、而不使用我在计时器中断中编写的代码?

e2e.ti.com/.../WhatsApp-Video-2020_2D00_12_2D00_14-at-15.21.55.mp4

#include 
const int dizi[]={0x7E、0xC、0xB6、0x9E、0xCC、 0xDA、0xFA、0xE、0xFE、0xDE、0xC6、0x72};
长 ADC_mem_value;
长度;
int TENS_digit;
int one_digit;
int counter=0; //对于10_second
int x=0;
int main (void)
{
WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器


BCSCTL1 |= DIV_0; // 32kHz 低温
BCSCTL3 |= XCAP_3 + LFXT1S_0;

/* PİN SETTİNG */
P2DIR |= BIT0+BIT1+BIT2+BIT3;// 7段显示摄像机捕捉能量引脚组 D1-D2-D3-D4
P2OUT |=(BIT0+BIT1+BIT2+BIT3);// 7段显示 D1-D2-D3-D4能量引脚优先为低电平
P1DIR |= 0xFF; //7段显示 LED 套件
P1OUT=0x00; //前7段显示 LED 低电平


/* TİMER SETTİNG */

TA0CTL = MC_1 + TASSEL_1 +TAIE;//UP 至 CCR0--
TA0CCR0 =32767;//1秒;



/*ADC SETTİNG */

ADC10CTL0 |= ADC10ON +REFON+SREF_1 + ADC10SHT_3;// ADC akative-- REFON (1、5V)-采样时间64 x ADC10CLKs -中断使能
ADC10CTL0&=~ REF2_5V; //REF 1、5V 感应电压
ADC10CTL1 |=SHS_3+INCH_10+ADC10SSEL_0 + CONSEQ_0;//带有定时器的 ADC 触发器(TA3 OUT1)。我不知道有工作
//温度选择通道10 -选择 ADC 振荡器5MHZ -单通道单次转换
ADC10CTL0 |= ENC+ADC10SC; //启用转换并开始覆盖

_bis_SR_register (GIE);

while (1)
{


/*显示7段*/

P2OUT |=(BIT2+BIT1 + BIT0);
P1OUT=0x72;
P2OUT &=~(BIT3);
_DELAY_CYCLES (1000);


P2OUT |=(BIT0+BIT1 + BIT3);
P1OUT=0xC6;
P2OUT &=~(BIT2);
_DELAY_CYCLES (1000);


P2OUT |=(BIT0+BIT3+BIT2);
P1OUT=DIZI[ONS_DIGENT];
P1OUT|=BIT0;
P2OUT &=~(BIT1);
_DELAY_CYCLES (1000);

P2OUT |=(BIT1 + BIT3 + BIT2);
P1OUT=DIZI[TENS_DIGENT];
P2OUT &=~(BIT0);
__DELAY_CYCLES (1000);

}

}


#pragma vector=TIMER0_A1_vector
__interrupt void TA0_kesme_func (void)
{

switch (TAIV){
case 2:





中断; // CCR1未使用
情况4:



中断; // CCR2未使用

案例10:

COUNTER++;
X++;

if (counter =10)// if counter10 =10秒

{
ADC10CTL0 |= ENC+ ADC10SC;

/*计算温度*/
ADC_MEM_VALUE = ADC10MEM;
度=((adc_mem_value - 672)* 423)/ 1024;
TENS_Digitity=degre/10;
ons_digits=degre% 10;

计数器=0;



}


中断;

}



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

    1) 1)要使用计时器触发器、可使用 OUTMOD 在通道上生成实际波形。 该波形的上升沿是触发器。  [参考用户指南(SLAU144J)图22-3 -您生成 SHI。]

    如果 SHS=3、则为 TA0.2。 您无需将该通道连接到引脚、ADC 会将该部分输出出来。 因此、您需要添加如下内容:

    > TA0CCR2 = 10;  //脉宽> 0 (10相当任意)

    > TA0CCTL2 = OUTMOD_7;//复位/置位、因此脉冲位于周期的开始位置

    在10秒周期内、您可能需要调整这些值以避免长时间等待。

    2)使用 TA0CTL:ID 字段、您可以将输入时钟除以高达/8;使用32kHz ACLK (我认为您有一个晶振)、该值大约为16秒。对于您的情况、我建议 ID=3 (/8)和 CCR0=10*32768U/8-1。

    3)这并不明显、但如果您按照用户指南图22-5中的箭头操作、您会发现、当 SH>0和 CONSEQ=0时、您需要在转换之间切换(低电平、然后高电平) ENC。 这通常在完成 ISR 中完成。 这有点麻烦;我建议您改用 CONSEQ=2和 MSC=0 [Ref 用户指南图22-7]、这不是该要求。

    4) 4)您实际上不会在任何地方检查 ADC 完成情况。 您可以轮询 ADC10IFG、但在10秒周期内、我建议使用中断(ADC10_Vector)和 LPM。

    [编辑:CCR0忘记-1 ]

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

    非常感谢您首先为我提供帮助。 我不能理解一些配件、因为我的英语不好。 我根据您的评论对代码进行了更改、但问题未得到解决。 ADCMEM 值似乎再次为零。
    这就是我想要的;在计时器计数10秒后、让 ADC 运行并计算角度。









    #include 
    const int dizi[]={0x7E、0xC、0xB6、0x9E、0xCC、 0xDA、0xFA、0xE、0xFE、0xDE、0xC6、0x72};
    长 ADC_mem_value;
    长度;
    int TENS_digit;
    int one_digit;
    int counter=0; //对于10_second
    int x=0;
    int main (void)
    {
    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
    
    
    BCSCTL1 |= DIV_0; // 32kHz 低温
    BCSCTL3 |= XCAP_3 + LFXT1S_0;
    
    /* PİN SETTİNG */
    P2DIR |= BIT0+BIT1+BIT2+BIT3;// 7段显示摄像机捕捉能量引脚组 D1-D2-D3-D4
    P2OUT |=(BIT0+BIT1+BIT2+BIT3);// 7段显示 D1-D2-D3-D4能量引脚优先为低电平
    P1DIR |= 0xFF; //7段显示 LED 套件
    P1OUT=0x00; //前7段显示 LED 低电平
    
    
    /* TİMER SETTİNG */
    
    TA0CTL = MC_1 + TASSEL_1 +TAIE+ID_3;//UP 至 CCR0-- CLK/8
    TA0CCR0 =40959;//(10 * 32768U / 8)-1 = 10秒;
    TACCTL0|=OUTMOD_7;
    
    
    /*ADC SETTİNG */
    
    ADC10CTL0 |= ADC10ON +REFON+SREF_1 + ADC10SHT_3;// ADC akative-- REFON (1、5V)-采样时间64 x ADC10CLKs -中断使能
    ADC10CTL0&=~ REF2_5V; //REF 1、5V 感应电压
    ADC10CTL1 |=SHS_3+INCH_10+ADC10SSEL_0 + CONSEQ_2;//带有定时器的 ADC 触发器(TA3 OUT1)。我不知道有工作
    // tempeture 选择通道10-选择 ADC 振荡器5MHZ -重复单通道
    ADC10CTL0 |= ENC+ADC10SC; //启用转换并开始覆盖
    
    _bis_SR_register (GIE);
    
    while (1)
    {
    
    
    /*显示7段*/
    
    P2OUT |=(BIT2+BIT1 + BIT0);
    P1OUT=0x72;
    P2OUT &=~(BIT3);
    _DELAY_CYCLES (1000);
    
    
    P2OUT |=(BIT0+BIT1 + BIT3);
    P1OUT=0xC6;
    P2OUT &=~(BIT2);
    _DELAY_CYCLES (1000);
    
    
    P2OUT |=(BIT0+BIT3+BIT2);
    P1OUT=DIZI[ONS_DIGENT];
    P1OUT|=BIT0;
    P2OUT &=~(BIT1);
    _DELAY_CYCLES (1000);
    
    P2OUT |=(BIT1 + BIT3 + BIT2);
    P1OUT=DIZI[TENS_DIGENT];
    P2OUT &=~(BIT0);
    __DELAY_CYCLES (1000);
    
    }
    
    }
    
    
    #pragma vector=TIMER0_A1_vector
    __interrupt void TA0_kesme_func (void)
    {
    
    switch (TAIV){
    case 2:
    
    
    
    
    
    中断; // CCR1未使用
    情况4:
    
    
    
    中断; // CCR2未使用
    
    案例10:
    
    //计数器++;
    //x++;
    
    // if (counter =10)// if counter10 =10秒
    
    
    ADC10CTL0 |= ENC+ ADC10SC;
    
    /*计算温度*/
    ADC_MEM_VALUE = ADC10MEM;
    度=((adc_mem_value - 672)* 423)/ 1024;
    TENS_Digitity=degre/10;
    ons_digits=degre% 10;
    
    //counter=0;
    
    
    
    
    
    
    中断;
    
    }
    
    
    
    

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

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

    1) 1)如果 SHS=3、则使用 CCR2 (TA0.2)生成波形。 如下所示:

    > TA0CCR2 = 10;  //脉宽> 0 (10相当任意)

    > TA0CCTL2 = OUTMOD_7;//复位/置位、因此脉冲位于周期的开始位置

    2)当 SHS > 0时、您无需设置 ADC10SC (永远)。 您确实需要设置 ENC (一次)。

    3) 3)对于计时器触发器、您根本不需要该计时器 ISR。 我建议您将该算术移动到 ADC10 ISR (vector=ADC10_vector)、以便您知道转换已完成。 [编辑:要执行此操作、请不要设置 TAIE、并且要设置 ADC10IE。]

    4)由于 CONSEQ=2、ADC10BUSY=1一直为1、所以您应该改为使用 ADC10IFG (可能使用(3)中提到的 ISR)。

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

    我添加了一个 ADC 中断并删除了计时器中断。 它每10秒进行一次测量、并且工作正常。 但有一些我不理解的问题。 当我启用 SHS_2时、它会进行测量、代码正常工作。 当我激活 SHS_1或 SHS_3时、它不起作用。 为什么? 我无法理解逻辑。

    以下是 video.it的工作成果。谢谢

    e2e.ti.com/.../run.mp4

    #include 
    const int dizi[]={0x7E、0xC、0xB6、0x9E、0xCC、 0xDA、0xFA、0xE、0xFE、0xDE、0xC6、0x72};
    长 ADC_mem_value;
    长度;
    int TENS_digit;
    int one_digit;
    int counter=0; //对于10_second
    
    int main (void)
    {
    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
    
    
    BCSCTL1 |= DIV_0; // 32kHz 低温
    BCSCTL3 |= XCAP_3 + LFXT1S_0;
    
    /* PİN SETTİNG */
    P2DIR |= BIT0+BIT1+BIT2+BIT3;// 7段显示摄像机捕捉能量引脚组 D1-D2-D3-D4
    P2OUT |=(BIT0+BIT1+BIT2+BIT3);// 7段显示 D1-D2-D3-D4能量引脚优先为低电平
    P1DIR |= 0xFF; //7段显示 LED 套件
    P1OUT=0x00; //前7段显示 LED 低电平
    
    
    
    
    
    /*ADC SETTİNG */
    
    ADC10CTL0 |= ADC10ON +REFON+SREF_1 + ADC10SHT_3+ADC10IE;// ADC akative-- REFON (1、5V)-采样时间64 x ADC10CLK -中断使能
    ADC10CTL0&=~ REF2_5V; //REF 1、5V 感应电压
    ADC10CTL1 |=SHS_2+INCH_10+ADC10SSEL_0 + CONSEQ_2;//带有定时器的 ADC 触发器(TA3 OUT1)。我不知道有工作
    // tempeture 选择通道10-选择 ADC 振荡器5MHZ -重复单通道
    ADC10CTL0 |= ENC+ADC10SC; //启用转换并开始覆盖
    
    
    
    
    /* TİMER SETTİNG */
    
    TA0CTL = MC_1 + TASSEL_1 +ID_3;//UP 至 CCR0-- CLK/8
    TA0CCR0 =40959;//(10 * 32768U / 8)-1 = 10秒;
    TA0CCR1 =10;
    TACCTL0|=OUTMOD_7;
    
    
    _bis_SR_register (GIE);
    
    while (1)
    {
    
    
    /*显示7段*/
    
    P2OUT |=(BIT2+BIT1 + BIT0);
    P1OUT=0x72;
    P2OUT &=~(BIT3);
    _DELAY_CYCLES (1000);
    
    
    P2OUT |=(BIT0+BIT1 + BIT3);
    P1OUT=0xC6;
    P2OUT &=~(BIT2);
    _DELAY_CYCLES (1000);
    
    
    P2OUT |=(BIT0+BIT3+BIT2);
    P1OUT=DIZI[ONS_DIGENT];
    P1OUT|=BIT0;
    P2OUT &=~(BIT1);
    _DELAY_CYCLES (1000);
    
    P2OUT |=(BIT1 + BIT3 + BIT2);
    P1OUT=DIZI[TENS_DIGENT];
    P2OUT &=~(BIT0);
    __DELAY_CYCLES (1000);
    
    }
    
    }
    
    
    #pragma vector=ADC10_vector
    __interrupt void ADC10_ISR (void)
    
    {
    
    /*计算温度*/
    ADC_MEM_VALUE = ADC10MEM;
    度=((adc_mem_value - 672)* 423)/ 1024;
    TENS_Digitity=degre/10;
    ons_digits=degre% 10;
    
    }
    
    
    
    
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    SHS=2使用 CCR0 (TA0.0)、该代码使用 CCR0生成波形。  

    之前、当您使用 SHS=3时、您需要使用 CCR2。 如果您使用 SHS=1、则需要使用 CCR1 (TA0.1)。 [参考用户指南(SLAU144J)第22.3.2节。]

    但听起来好像您现在拥有了所需的功能。

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

    [引用用户="Bruce McKenney47378"]

    SHS=2使用 CCR0 (TA0.0)、该代码使用 CCR0生成波形。  

    之前、当您使用 SHS=3时、您需要使用 CCR2。 如果您使用 SHS=1、则需要使用 CCR1 (TA0.1)。 [参考用户指南(SLAU144J)第22.3.2节。]

    但听起来好像您现在拥有了所需的功能。

    [/报价]

    我已经阅读过很多次用户手册、但我不理解。 但是、感谢您、我现在明白了。 现在我有几个问题。 我想通过编号来提出我的问题。
    1) 1)如果我们没有使用 outmod、我们会创建一个计时器中断来设置-复位计时器? outmods 无需执行此功能。 我理解正确吗?
    2)我在 ADC 控制1设置中使用了 SHS_1
    ADC10CTL1 |=SHS_1+INCH_10+ADC10SSEL_0 + CONSEQ_2;。
    然后我配置计时器。
    TA0CCR0 =40959;
    TA0CCR1 =32767
    TACCTL1|=OUTMOD_7;
    然后,我运行该程序。
    但 ADC 每10秒启动一次转换、就像之前的配置一样。 但它是否应该每1秒进行一次转换? 因为 TA0CCR1 = 32767 (1 secont)且 TACCTL1 |= OUTMOD_7;
    为什么测量时间没有改变? 我错过了哪里?

    3)我使用外部晶体振荡器、因为它精确地产生了1秒。
    在我上面写的代码中、我注意到在配置 TA0CTL 时、我选择 ACLK (tassel_1)作为时钟源。(TA0CTL = MC_1 + tassel_1 +ID_3;)
    我使用晶体、因为我无法使用 ACLK 创建精确的"1秒"。 但现在没有问题。 它精确地形成了1秒。我想知道当我在计时器配置中选择 TASSEL_1时会发生什么情况。 我的主时钟源是32kHz 晶体振荡器、计时器的时钟源是 ACLK。 它是如何精确地发生在"1sec"?
    你给我提供了很多帮助。 我再次感谢你。

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

    1) 1)您的程序不能直接访问 CCR 通道波形、因此如果您使用计时器中断、您可能会使用 ADC10SC (SHS=0)。 [您也可以使用 OUTMOD=0并调出位、但这是一个相当回旋的地方。]

    2) 2)我建议您查看用户指南(SLAU144J)图12-12。 这里显示了生成 SHI 的计时器通道输出的选项。 ADC 只关心上升沿、并且(只有)每个向上计数模式周期有一个上升沿;因此 CCR0决定 ADC 采样周期、CCR1决定周期中的位置。 通常,CCR1几乎可以是>0和<CCR0, though with a 10-second cycle you might notice a difference. [将 OUTMOD=7与 CCR0搭配使用有点不寻常[请参阅用户指南第12.2.5.1节]。 显然、它在 G2553上工作、但它可能是实施过程中发生的事故。 我仍然建议 SHS=3和我给您的这两行代码。]

    3) 3)我不太确定问题是什么。 32.768kHz 晶振的32768个周期恰好为1秒。 您的晶体可能精确到大约20ppm (0.002%)。 在 F2系列中、您唯一的选择是 VLOCLK、它是+/-50%。 在另一个系列中、有内部32kHz 时钟、但即使只有大约1-3%的时钟效果。 晶体是一个很好的计时人员、尽管设计时有点麻烦。