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:MSP430F5325

Guru**** 2391415 points
Other Parts Discussed in Thread: MSP430F5325

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/727136/ccs-msp430f5325

主题中讨论的其他器件:MSP430F5325

工具/软件:Code Composer Studio

大家好、我在端口 P1.1上测量给定信号频率50Hz 方波的计时器节拍时遇到问题、我正在使用 MSP430F5325

我想在它的打开时间、即10毫秒内测量计时器节拍。 能不能有人告诉我如何操作、也可以有示例代码的人

我还有一个问题、假设我在10ms 内测量计时器节拍、然后借助计时器节拍值、我可以控制该信号的脉冲宽度或频率吗?

#include 

unsigned int rising_cap=0; 
unsigned int Falling_cap=0; volatile unsigned int Rising _count = 0;
unsigned int i=0; int main (void) { WDTCTL = WDTPW + WDTHOLD;//停止看门狗计时 器(i=0;i<20000;i++)//晶体稳定延迟 { } P1DIR &=~ BIT1; P1SEL |= BIT1; //将 P1.1设置为 TA0 TA0CCTL0 |= CM_1 + SCS + CCIS_0 + CAP + CCIE; //上升沿+ CCI0A (P1.1)+捕捉模式+中断 TA0CCTL1 |= CM_2 + SCS + CCIS_0 + CAP + CCIE; //下降沿、捕捉模式、中断 TA0CTL = tassel_2; // SMCLK _BIS_SR (GIE); // LPM0 +启用全局 INT } #pragma vector = TIMER0_A0_vector __interrupt void Timer0_A0_ISR (void) {
RISING_COUNT++; 

如果(RISING_COUNT== 2)
rising_cap = TA0CCR0; 
FALLING_CAP = TA0CCR1;

     }

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

    如果您只需要计算输入信号正在执行的脉冲数、那么您可以将其与计时器时钟输入绑定、它将在每个脉冲上前进。

    如果您需要计算上升沿和下降沿之间的时间并计算脉冲宽度、那么在捕获模式下应仅使用一个 CCR、并在下降沿和上升沿进行捕获。 您可以在每次捕获更新时从之前的捕获中减去电流捕获、以确定在实例之间传递了多少个计时器时钟周期。

    在上面的代码中、您需要单独的信号或将同一信号绑定到与 CCR1关联的任何引脚以及与 CCR0关联的引脚。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    #include 
    
    unsigned long int current_cap=0、timer_ticks = 0;
    unsigned int previous_cap=0;
    volatile unsigned long int caption_count = 0;
    unsigned int i=0;
    
    int main (void)
    {
    
    WDTCTL = WDTPW + WDTHOLD;//停止看门狗计时
    
    器(i=0;i<20000;i++)//晶体稳定延迟
    | 1PITSEL
    
    
    = 1~ 1
    ;BITS1 | 1 PITSEL //将 P1.1设置为 TA0
    
    TA0CCTL0 |= CM_3 + SCS + CCIS_0 + CAP + CCIE; //捕获模式、在上升沿和下降沿同时捕获、SYNC、捕获中断使能
    
    TA0CTL = tassel_2; //SMCLK、连续模式
    
    _BIS_SR (GIE); // LPM0 +启用全局 INT
    
    while (1)
    {
    
    TA0CTL |= MC_2; //定时器启动
    while (caption_count!= 2);
    if (caption_count== 2)
    {
    TA0CTL &=~ MC_2; //计时器停止
    TA0CCTL0 &=~ CCIE; //在此处使用断点并测量 timer_ticks
    TA0CCR0 = 0;
    }
    }
    
    
    
    #pragma vector = TIMER0_A0_vector
    _interrupt void Timer0_A0_ISR (void)
    {
    CAPTURE_COUNT++;
    Timer_ticks = TA0CCR0;
    }
    

    感谢您的宝贵答复、我按照 you.no上的建议对代码进行了更改、但问题是它变化很大、即(12042、17482、16782、17151、18834、 12465、12447、15831、10674)

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

    您的 SMCLK 速度是多少? 您很可能需要对其进行分频、因为您的计时速度可能太快、并且会翻转计时器。 如果 SMLCK 是默认值、则1MHz 对于50Hz 信号来说太快。 考虑您的脉宽测量可接受的分辨率、然后重新计算运行计时器以实现该多个步骤所需的速度。 在大多数情况下、更少(速度)就更好了。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这种变异源于这样一个事实:您不知道您的计划在第一个阶段开始倾听的位置。 由于您等待两个边沿、您始终会看到超过半个周期、但由于您在两个边沿之后停止、您将不会看到整个周期。

    尝试保存前两个捕获、然后减去它们。 我怀疑这种差异将是一致的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    #include 
    
    unsigned long int first_edge=0、second_edge=0;
    volatile unsigned int caption_count = 0、period=0;
    
    int main (void)
    {
    WDTCTL = WDTPW + WDTHOLD;//停止看门狗计时器
    
    P1DIR &=~ BIT1;
    P1SEL |= BIT1; //将 P1.1设置为 TA0
    
    TA0CCTL0 |= CM_1 + SCS + CCIS_0 + CAP + COV + CCIE; //捕获模式、在上升沿和下降沿同时捕获、SYNC、捕获中断使能
    
    TA0CTL = tassel_1 + MC_2; //ACLK、连续模式
    
    _BIS_SR (GIE);
    while (1)
    {
    if (second_edge > first_edge)
    {
    周期=(second_edge - first_edge);
    }
    否则、如果(second_edge <first_edge)           )
    {
    周期=(first_edge - second_edge);
    }
    }
    
    #pragma vector = TIMER0_A0_vector
    _interrupt void Timer0_A0_ISR (void)
    {
    CAPTURE_COUNT++;
    
    如果(CAPTURE_COUNT==1)
    {
    first_edge = TA0CCR0;
    }
    否则、如果(caption_count==2)
    {
    second_edge = TA0CCR0;
    CAPTURE_COUNT=0;
    TA0CCR0=0;
    }
    }
    

    你好 Jace H、

    我的控制器速度默认为1MHz,这意味着我在50Hz 的一个周期内得到大约20,000个时钟脉冲,我是指在20ms 内得到20,000个时钟脉冲。

    现在、我将控制器速度更改为 ACLK (32768Hz)。 但这并没有解决我的问题。 同样、我会得到一个较大的变化、因此我在代码中做了更多的更改。 请看。

    在我的新代码中、我现在面临另一个问题、两个连续上升沿之间的变化较小、因此计算了周期。 根据 ACLK、如果频率为50Hz、在20ms 周期内、我得到~ 655或656个时钟。

    我的问题是、当计时器溢出时、我得到了不需要的结果、为了克服这一问题、我将 TA0CCR0值复位为零、但不幸的是、它不起作用、并且仍然得到不需要的结果(变化)。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    #include 
    
    unsigned long int first_edge=0、second_edge=0;
    volatile unsigned int caption_count = 0、period=0;
    
    int main (void)
    {
    WDTCTL = WDTPW + WDTHOLD;//停止看门狗计时器
    
    P1DIR &=~ BIT1;
    P1SEL |= BIT1; //将 P1.1设置为 TA0
    
    TA0CCTL0 |= CM_1 + SCS + CCIS_0 + CAP + COV + CCIE; //捕获模式、在上升沿和下降沿同时捕获、SYNC、捕获中断使能
    
    TA0CTL = tassel_1 + MC_2; //ACLK、连续模式
    
    _BIS_SR (GIE);
    while (1)
    {
    if (second_edge > first_edge)
    {
    周期=(second_edge - first_edge);
    }
    否则、如果(second_edge <first_edge)           )
    {
    周期=(first_edge - second_edge);
    }
    }
    
    #pragma vector = TIMER0_A0_vector
    _interrupt void Timer0_A0_ISR (void)
    {
    CAPTURE_COUNT++;
    
    如果(CAPTURE_COUNT==1)
    {
    first_edge = TA0CCR0;
    }
    否则、如果(caption_count==2)
    {
    second_edge = TA0CCR0;
    CAPTURE_COUNT=0;
    TA0CCR0=0;
    }
    }
    

    大家好、感谢您的建议。 我已经在我的代码中实现了您的想法。 但在我的新代码中、现在我面临另一个问题、两个连续上升沿之间的变化较小、因此计算了周期。 根据 ACLK、如果频率为50Hz、在20ms 周期内、我得到~ 655或656个时钟。

    我的问题是、当计时器溢出时、我得到了不需要的结果、为了克服这一问题、我将 TA0CCR0值复位为零、但不幸的是、它不起作用、并且仍然得到不需要的结果(变化)。 请帮助我了解嵌入式产品的最新动态。 您能不能输入一行代码来克服这一问题。

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

    > unsigned long int first_edge=0、second_edge=0;
    将这些设置为16位、因此算术有效(根据定义、差异不能大于16位):
    > unsigned int first_edge = 0、second_edge = 0;
    --------
    > if (second_edge> first_edge){
    >周期=(second_edge - first_edge);
    >}
    >否则 IF (second_edgele <first_edge){)
    >周期=(FIRST_EDGE - second_EDGE);
    >}
    根据定义、second_edge 比 first_edge "大"、因此只需减去它们。 16位无符号下溢的"魔法"将处理回绕。 您只需要:
    >周期=(second_edge - first_edge);
    --------
    正确、务必确保您的计时器起搏处于输入信号的合理范围内。 对于50Hz、SMCLK (1MHz)或 ACLK (32kHz)均正常、但 SMCLK 将为您提供更多的精度。
    --------
    我注意到您已从 CM_3 (双边沿)切换到 CM_1 (上升沿)。 这很好、请记住、您现在正在测量脉冲周期(1/频率)、时间(我认为吗?) 您刚才提到了脉冲宽度。 就本练习而言、两者都是可以的。

    [编辑:修正了一些模糊的措辞。]

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    此外:我刚刚注意到、您在 main 中的循环会尽可能快(实际上快于)获取结果、因此很可能会看到部分结果。 我建议在该循环和 ISR 之间进行互锁。

    可以通过多种方法来实现这一点。 也许最简单的办法是:
    > LPM0; //休眠,直到 ISR 提示唤醒
    while (1)循环的第一行、然后添加
    > LPM0_EXIT; //唤醒 main()
    到 ISR 中的"caption_count = 2"块。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    #include 
    
    unsigned int first_edge=0、second_edge=0、i=0、first_diff=0、secnd_diff=0、third_edge=0、third_diff=0;
    volatile unsigned int caption_count=0;
    
    
    int main (void)
    {
    WDTCTL = WDTPW + WDTHOLD;//停止看门狗计时器
    
    用于稳定(I
    
    
    
    = 1P400+~);I = 1 WDITBIT+ 1 + 1 + 1 + 1 + WDITBIT= 1;I = 1 + 1 + WDITBITS1 + 1 +
    //将 P1.1设置为 TA0
    
    TA0CCTL0 |= CM_3 + SCS + CCIS_0 + CAP + CCIE + SCCI;//捕获模式、在上升沿和下降沿进行捕获、SYNC、捕获中断使能
    
    TA0CTL |= tassel_1 + MC_2 + TACLR; //ACLK、连续模式、清除定时器
    
    _BIS_SR (GIE);
    while (1)
    {
    FIRST_DIFF =(second_EDE-FIRST_EDGE);
    
    secnd_diff =(third_edge-second_edge);
    
    third_diff =(nour_edge-third_edge);
    }
    }
    #pragma vector = TIMER0_A0_VECTOR
    __INTERRUPT void Timer0_A0_ISR (void)
    {
    CAPTURE_COUNT++;
    如果(CAPTURE_COUNT==1)
    {
    first_edge = TA0CCR0;
    }
    否则、如果(caption_count==2)
    {
    second_edge = TA0CCR0;
    }
    否则、如果(caption_count=3)
    {
    third_edge = TA0CCR0;
    }
    否则、如果(caption_count==4)
    {
    Four_EDGE = TA0CCR0;
    TA0R = 0;
    CAPTURE_COUNT=0;
    }
    }
    

    您好!

    当我在捕获模式下启动定时器时,它将根据 CAP 模式在下降沿或上升沿或双边沿(右)上提供中断。

    我的第一个问题是,我测量的计时器时钟是在方波的哪个部分,即 在它的导通时间或关断时间?

    第二个问题我如何在它的准时内找出计时器节拍? 我有50%的占空比。

    第三个问题如果我想找出关断时间上的计时器节拍、我该怎么办?

    我之前问过的第四个问题是,在计时器节拍时间(关断或接通)的帮助下,我可以控制脉冲宽度并执行 PWM 吗?? (“是”还是“否”)??

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您仍在不断获取读数、因此在任何时候(至少)、您的其中一个差异都是毫无意义的。 我在上面建议了一个互锁方案。

    我不建议将 TA0R 复位回0、因为这会使结果偏斜。 这在这个有限功能程序中可能无关紧要、但稍后会这样做。

    >当我在捕获模式下启动计时器时,它将根据 CAP 模式在下降沿或上升沿或双边沿(右)上产生中断?
    根据 CM 设置、是。

    >我的第一个问题是,我测量的计时器时钟是在方波的哪个部分,即在它的导通时间或关断时间?
    导通时间是上升沿和下降沿之间的差值。 计时器不会告诉您它检测到了哪个边沿、因此您必须查看、例如通过(P1IN&BIT1)。 这里有一场比赛、但使用50Hz 信号时、您几乎总是会赢。

    >第二个问题如何确定计时器的导通时间? 我有50%的占空比。
    导通时间是上升沿和下降沿之间的差值。 如果占空比为50%、则导通时间为(total_period/2)、其中 total_period 是两个上升(或两个下降)边沿之间的差值。

    >第三个问题如果我想找出关断时间的计时器节拍、我该怎么办?
    关断时间是下降沿和上升沿之间的差值。 或者、它是(total_period-on-time)。

    >我以前问过的第四个问题是,在计时器节拍时间(关闭或打开)的帮助下,我是否可以控制脉冲宽度和 PWM?? (“是”还是“否”)?
    我没有回答、因为问题不完整。 您要控制什么信号? 读取输入信号不会隐式地使您能够控制输入信号。 如果您有另一个计时器、生成输出并使用相同的时钟(TASSEL/ID)、则捕获差异中的单位适合为该另一个计时器放入 CCR。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我上次查看(一段时间前)、TI 没有关于此主题的应用手册。 但是、我熟悉[其他人]介绍的 AppNote AVR135。 它用于不同的器件、但原理是通用的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我执行了你的操作、我在代码中执行了这些操作、但我的问题没有得到解决、也没有得到计时器节拍("周期读数为0")、所以我只需将其删除、并通过设置 TA0R =0来清除计时器计数器、 然后我检查结果、因为我的计时器 CCR0没有溢出、所以我得到了清晰的结果。

    > 导通时间是上升沿和下降沿之间的差值。 如果占空比为50%、则导通时间为(total_period/2)、其中 total_period 是两个上升(或两个下降)边沿之间的差值。

    是导通时间是上升沿和下降沿之间的差值、但计时器不知道首先捕获哪个沿(上升沿或下降沿)、因此 (TOTAL_PERIODE/2) 提供导通时间值或关断时间值?  (total_period/2)位于时间段的哪个部分(开或关)?

    根据 MSP430的用户指南、CM_3捕获下降和上升。 这意味着在首次发生的情况下、它在两个边沿上都发生中断、这种情况是下降或上升。

    根据代码、我非常希望确保我在其导通时间内测量计时器节拍、得到的值介于上升和下降之间

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    >导通时间是上升沿和下降沿之间的差异。 计时器不会告诉您它检测到了哪个边沿、因此您必须查看、例如通过(P1IN&BIT1)。 这里有一场比赛、但使用50Hz 信号时、您几乎总是会赢。

    我在代码中执行此操作(P1IN 和 BIT1)、但遗憾的是、我们只能在低侧读取、而不是在高侧读取、因为我尝试了这两种操作
    首先、我通过设置(P1IN & BIT1)=0....读取到低电平 我得到了结果并进行了大量迭代、但有些结果是好的、大多数结果是无用的

    现在我第二次读取 P1.1高电平(P1IN & BIT1)==1。这次我没有得到很长的结果时间、因为它没有在高电平条件下读取我的引脚。

    我只能通过在一个新程序上设置 LED 上的高低电平条件来交叉检查这个问题、最后我发现、无论上拉高电平还是上拉低电平、我只能在低电平条件下读取我的引脚。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    >(P1IN & BIT1)==1
    此条件从不为真--&的结果为0或 BIT1 (=2)。 尝试:
    >(P1IN 和 BIT1)!= 0