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.

[参考译文] MSP430FR6043:输出 PWM

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1312126/msp430fr6043-output-pwm

器件型号:MSP430FR6043

我正在尝试输出与 ToF 相对应的 PWM 信号。 立即使用50%占空比进行测试、以验证我是否可以在引脚上获得预期的信号。

在 system_pre_int.c 内、我添加了以下代码。

/*在此处插入低级初始化*/

/*禁用看门狗计时器以防止在*/期间复位
/* int32_t 变量初始化序列。 */
//停止 WDT
WDTCTL = WDTPW + WDTHOLD;

P1DIR |= BIT2;
P1SEL0 |= BIT2;
TA0CCR0 = 1000;
TA0CCTL1 = OUTMOD_7;
TA0CCR1 = 500;
TA0CTL = TASSEL_2 + MC_1;

一旦我将此代码加载到、映射到该代码的引脚上的电压从0V 变为3.3V。 想知道我错了什么、没有获得50%的占空比。

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

    根据数据表(SLASEF5B)表9-26、您已为 UCA1TXD (PSEL=01)设置了 P1.2、这通常会产生高(1)水平。 针对 P1.2 (PSEL=10)的另外一个函数是 TA1.0、它是(a)定时器 TA1、而不是 TA0、并且(b)并不十分适合("实际") PWM。

    PWM 在其他引脚上可用。 您的目标是使用特定的引脚还是使用特定的计时器?

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

    您好、Bruce -感谢您的回复。 这是我第一次尝试编程这样的内容、所以有点失落。 我的最终目标是将来自超声波传感器的飞行时间信号编码到 PWM 中。 首先验证我可以从电路板输出50%。 您会为此建议哪个引脚?

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

    您提供了哪些引脚? 我提问、因为(例如)在 EVM 上、似乎大多数引脚都已被使用。

    P1.3可将 TA1的 PWM 输出为 TA1.1 [再次参考表9-26]。 您可以使用以下工具:

    P1DIR |= BIT3;            // P1.3 as TA1.1 per
    P1SEL1 |= BIT3;           //  SLASEF5B Table 9-26
    TA1CCR0 = 1000-1;         // 1ms period (SMCLK=1MHz)
    TA1CCTL1 = OUTMOD_7;      // On at CCR0, Off at CCR1
    TA1CCR1 = 500;            // 0.5ms on for 50% duty
    TA1CTL = TASSEL_2 + MC_1; // SMCLK, Up 

    [编辑:在 CCR0上忘记了-1。]

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

    我将进行处理、确保以正确的方式将代码加载到板上。 我还没有运气。 仅读取为0V。 J10列为 GPIO。 TxSel J10-5连接到 P2.3和 TA0.0。 我会不断尝试、看看我是否能从这些内容中读取任何内容。

     

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

    您的代码将 TA0.1配置为 PWM 的输出模式。 这就是您应该与该代码一起使用的引脚。 在 P6.7中出现的数据表中搜索

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

    你把我设置在了正确的路径-我找到了一个使用 Code Composer Studio 中的计时器 B 的示例。 它在 P3.1和 P3.7上创建两个 PWM。 我修改后仅使用 P3.1、可以在 EVM 板上的 J13-1上访问该 P3.1。 我现在遇到的问题是更新 TB0CCR1。

    下面是代码-我  使用 PWM 示例合并了另一个线程的解决方案以对其进行测试。 现在、占空比是静态的、与我初始设置的一样。

    #include <msp430.h>
    
    int main(void)
    {
        static int counter   = 110;                      // Cycle counter
        static int  direction = 1;                      // 1: up, 0: down
    
        WDTCTL = WDTPW | WDTHOLD;               // Stop WDT
    
        // Configure GPIO
        P3DIR |= BIT1                  // Select output
        P3SEL0 &= ~BIT1               // Select functions
        P3SEL1 |= BIT1
    
        // Disable the GPIO power-on default high-impedance mode to activate
        // previously configured port settings
        PM5CTL0 &= ~LOCKLPM5;
    
        TB0CCR0 = 1000-1;                       // PWM Period
        TB0CCTL1 = OUTMOD_7;                    // CCR1 reset/set
        TB0CCR1 = 500;                          // CCR1 PWM duty cycle
        TB0CTL = TBSSEL__SMCLK | MC__UP | TBCLR | TBIE;// SMCLK, up mode, clear TBR
    
        __bis_SR_register(GIE);
        __bis_SR_register(LPM0_bits);           // Enter LPM0
        //__no_operation();                       // For debugger
        while( 1 )                                         // Endless loop
        {
    
    
        // Timer0 A1 interrupt service routine
        #pragma vector = TIMER0_A1_VECTOR
        __interrupt void Timer0_A1_ISR( void );
    
    
    
        TB0CTL &= ~TBIFG;                                // Clear interrupt flag
    
            if( ++counter >= 50000 )                            // 5s
            {
              if( direction )                                   // Direction is up
              {
                  TB0CCR1 += 10;                                  // Add 5% to existing value
    
                if( TB0CCR1 == 900 )                            // Reached 50% duty cycle
                {
                  direction = 0;                                // Next time down
                }
              }
              else                                              // Direction is down
              {
                  TB0CCR1 -= 100;                                  // Subtract 5% from existing value
    
                if( TB0CCR1 == 100 )                             // Reached 5% duty cycle
                {
                  direction = 1;                                // Next time up
                }
              }
    
              counter = 0;                                      // Reset counter
            }
        }
    }

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

    它看起来基本上是正确的、除了以下几点:

    1)您似乎在 main ()的 while (1)循环的中间对 ISR 进行了编码。 实际上、这会(某种程度上是意外的)做一些事情、但不同的是、

    2)在 while (1)循环之前,您将 CPU 放入 LPM0,没有唤醒机制。

    最简单的解决方法是将以"#pragma "开头的行向下移动到文件底部,根据需要调整右括号("}"),因此 Timer0_A1_ISR()是一个单独的函数,而 main()中的 while (1)是空的(这很好,因为由于 LPM0,你永远不会到达那里)。

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

    尝试了解最终如何在 USS 应用中实现这一点。 有一个名为 system_pre_init.c 的文件、我在其中设置计时器以输出 PWM、然后在 main.c 中有一个 while (1)循环用于执行超声波捕获。 我希望从该捕获中提取结果、并在每次该循环运行时通过 PWM 将其发送出去。 我是否必须禁用 LPM 才能更改 PWM 占空比?

    我会不会这样做?

    while (1)

    {

    //发生 USS 捕获

    //从 LPM 唤醒

    //中断

    //更改 PWM 占空比

    //返回 LPM

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

    我不知道我在这里错了什么。 我一直在阅读示例并尝试了解如何使用计时器 B 中断。 我有这些。 连接了一个示波器、试图查看我可以更改占空比、但它与我在 main 中初始化的值保持固定。 提前感谢您的帮助。

    #include <msp430.h>
    static int IncDec_PWM   = 1;
    
    int main(void)
    {
    
        WDTCTL = WDTPW | WDTHOLD;               // Stop WDT
    
        // Configure GPIO
        P3DIR |= BIT1;                  // Select output
        P3SEL0 &= ~BIT1 ;              // Select functions
        P3SEL1 |= BIT1;
    
        // Disable the GPIO power-on default high-impedance mode to activate
        // previously configured port settings
        PM5CTL0 &= ~LOCKLPM5;
    
        TB0CCR0 = 1000-1;                       // PWM Period
        TB0CCTL1 = OUTMOD_7;                    // CCR1 reset/set
        TB0CCR1 = 10;                          // CCR1 PWM duty cycle
        TB0CTL = TBSSEL__SMCLK | MC__UP | TBCLR | TBIE;// SMCLK, up mode, clear TBR
    
        __bis_SR_register(LPM0_bits + GIE);
    
        while(1){}
    }
    
    #pragma vector = TIMER0_B1_VECTOR
    __interrupt void Timer0_B1_ISR( void ){
    
        TA0CCR1 += IncDec_PWM;
        if( TA0CCR1 > 990 || TA0CCR1 < 10 )
               IncDec_PWM = -IncDec_PWM;
    }

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

    想出来-我复制了一个计时器 A 示例。 如果我在 Timer0_B1_ISR 中将 TA 更改为 TB、它会为 ME 更改占空比。

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

    当我从 main.c 中的超声波算法获得飞行时间信号时、建议如何触发此更改? 我是否会创建一个像 Timer0_B1_ISR 这样的函数并调用它?

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

    我不知道你的目标 main ()循环看起来是什么样子,但我想它是以整体动态思维构建的。 你不应更改这个值;特别是、不要添加 LPM 或启用/禁用中断。

    我想您对环路的贡献将是两行代码:(a) 根据最近的捕获计算适当的占空比(b)将该值存储到 TB0CCR1中。 你不需要一个 ISR (它不用做任何事情)、所以不要设置 TBIE。

    其他[1]:由于您正在使用 TimerB,我建议您设置 CLLD=2以避免出现干扰。 这可能看起来像:

    > TB0CCTL1 = OUTMOD_7|CLLD_2;           // CCR1复位/置位,更新 TB0R==0处的影子。

    其他[2]:到目前为止,放入_sys_pre_init 的代码没有问题。 但请记住、此函数是在 C 初始化之前调用的、因此不要添加依赖于初始化变量(包括=0)的代码。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    其他[1]:由于您使用的是 TimerB,因此建议您设置 CLLD=2以避免出现故障。 这可能看起来像:

    只是一个路过的人;这让我在上一个项目上浪费了几天时间。 同步 CCR 加载实际上并不适用于 FR6043。 请参阅 勘误表TB25。

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

    没有、我没有注意到这一点。 感谢您指出。 看起来也适用于其他 FR5/FR6器件。

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

    非常感谢 Bruce -非常感谢您的帮助! 它现在似乎在工作。 我必须在 while 环路中的特定位置插入占空比计算、才能使其正常工作。 然后将其缩放到100到900之间。  

       while(1)
        {
    
            code = USS_startLowPowerUltrasonicCapture(&gUssSWConfig);
            checkCode(code, USS_message_code_no_error);
    
            code = USS_runAlgorithms(&gUssSWConfig,&algResults);
            checkCode(code, USS_message_code_valid_results);
    
            TB0CCR1 = (int)(algResults.totalTOF_UPS * 50571428.57 - 10900);
    #if (APPLICATION_ENABLE_CHANNEL_SWAP == true)