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.

[参考译文] MSP430FR2433:连续模式 PWM

Guru**** 2529560 points
Other Parts Discussed in Thread: MSP430FR2433

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1212277/msp430fr2433-continuous-mode-pwm

器件型号:MSP430FR2433

我正在使用示例 TIMER_A_ex2_ContinousModeOperationWithCCR0Interrupt 尝试在 P1.0上生成 PWM 信号。

每当我运行程序时、P1.0都会在一段时间后变为高电平、但从不会产生 PWM 信号。

我已经试着修改代码一些以获得 PWM 信号、但到目前为止没成功。

下面是代码:

/* --COPYRIGHT--,BSD
 * Copyright (c) 2017, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * --/COPYRIGHT--*/
//******************************************************************************
//!  TIMER_A, Toggle LED1, CCR0 Cont. Mode ISR, DCO SMCLK
//!
//!  Toggle LED1 using software and TA_0 ISR. Toggles every
//!  50000 SMCLK cycles. SMCLK provides clock source for TACLK.
//!  During the TA_0 ISR, LED1 is toggled and 50000 clock cycles are added to
//!  CCR0. TA_0 ISR is triggered every 50000 cycles. CPU is normally off and
//!  used only during TA_ISR.
//!  ACLK = n/a, MCLK = SMCLK = TACLK = default DCO ~1.048MHz
//!
//!           MSP430FR2xx_4xx Board
//!              ---------------
//!          /|\|               |
//!           | |               |
//!           --|RST            |
//!             |               |
//!             |               |-->LED1
//!
//! This example uses the following peripherals and I/O signals.  You must
//! review these and change as needed for your own board:
//! - TimerA peripheral
//! - GPIO peripheral
//!
//! This example uses the following interrupt handlers.  To use this example
//! in your own application you must add these interrupt handlers to your
//! vector table.
//! - Timer A0
//!
//*****************************************************************************
#include "driverlib.h"
#include "Board.h"

#define COMPARE_VALUE 50000

void main (void)
{
    //Stop Watchdog Timer
    WDT_A_hold(WDT_A_BASE);

    //Set LED1 as an output pin.
    GPIO_setAsOutputPin(
        GPIO_PORT_P1,
        GPIO_PIN0
        );

    /*
     * Disable the GPIO power-on default high-impedance mode to activate
     * previously configured port settings
     */
    PMM_unlockLPM5();

    //Start timer in continuous mode sourced by SMCLK
    Timer_A_initContinuousModeParam initContParam = {0};
    initContParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
    initContParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
    initContParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;
    initContParam.timerClear = TIMER_A_DO_CLEAR;
    initContParam.startTimer = false;
    Timer_A_initContinuousMode(TIMER_A1_BASE, &initContParam);

    //Initiaze compare mode
    Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE,
        TIMER_A_CAPTURECOMPARE_REGISTER_0
        );
		
    Timer_A_initCompareModeParam initCompParam = {0};
    initCompParam.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_0;
    initCompParam.compareInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;
    initCompParam.compareOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;
    initCompParam.compareValue = COMPARE_VALUE;
    Timer_A_initCompareMode(TIMER_A1_BASE, &initCompParam);


    Timer_A_startCounter( TIMER_A1_BASE,
            TIMER_A_CONTINUOUS_MODE
                );

    //Enter LPM0, enable interrupts
    //__bis_SR_register(LPM0_bits + GIE);

    //For debugger
    //__no_operation();
}

//******************************************************************************
//
//This is the TIMER1_A0 interrupt vector service routine.
//
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=TIMER1_A0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(TIMER1_A0_VECTOR)))
#endif
void TIMER1_A0_ISR (void)
{
    uint16_t compVal = Timer_A_getCaptureCompareCount(TIMER_A1_BASE,
            TIMER_A_CAPTURECOMPARE_REGISTER_0)
            + COMPARE_VALUE;

    //Toggle LED1
    GPIO_toggleOutputOnPin(
        GPIO_PORT_P1,
        GPIO_PIN0
        );

    //Add Offset to CCR0
    //Timer_A_setCompareValue(TIMER_A1_BASE,
    //    TIMER_A_CAPTURECOMPARE_REGISTER_0,
    //    compVal
    //    );
    // Reset timer
    //Timer_A_clear(TIMER_A1_BASE);
    //Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0);
    Timer_A_clearTimerInterrupt(TIMER_A1_BASE);
}

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

    您已经删除启用中断(GIE)的代码行、所以我不知道您是如何获得任何信号的。 该示例旨在以1MHz/50000/2=10Hz 的频率生成方波。 为了获得"真实"PWM、请尝试每次通过 ISR 修改 compare_value 的值。

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

    我曾尝试取消注释   __ bis_SR_register (LPM0_bits + GIE);(第110行)、但没有对输出进行任何更改。 我还尝试了改变 compare_value 的值、但这没有起到任何作用。

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

    您是如何判断它不起作用的?  ISR 中的断点? 示波器跟踪? LED?

    我手头没有材料、但当我阅读这些材料时、我会预期有8Hz 方波。 或许可以列出 TA1寄存器。

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

    我同时使用示波器观察 LED (LED1)。 观察计时器寄存器、似乎它们都没有发生改变。

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

    此时、我将在 Build Settings -> General 中查看 MCU 规范。 某些 FR2设备没有 TA1、可能会安静地忽略调用。

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

    没错、我更改了 FR2433的构建设置、现在 TA0寄存器将得到修改。 但是、我在 P1.0上仍然没有获得 PWM 输出

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    但是,我仍然没有在 P1.0上获得 PWM 输出

    你永远不会。

    所示代码使用 OUT (TAxCCTLn)值控制输出的设置。 您永远不会更改它。

    唯一可切换与 CCR0相关输出的另一种模式是模式4、切换。 它始终提供50%的占空比。 要执行 PWM、您需要使用 CCR0以外的代码。

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

    那么、在连续模式下使用计时器生成 PWM 输出的步骤有哪些?

    我有:

    步骤1:在连续模式下初始化计时器

    第2步:做一些事情(也许使用比较捕获寄存器?) 触发中断或直接控制输出

    是这样吗?

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

    最简单的方法是不使用连续模式。 使用向上计数模式。 CCR0控制周期(频率)、而 CCRn (n 不是0)控制 OUTn 上的占空比。

    用户指南会告诉您如何操作、当然 TI 提供的一组代码示例中也包含这些示例。

    要在连续模式下实现它、您必须使用 CCR0配置中断。 然后 ISR 必须切换输出并更改 CCR0、以便为下一个边沿生成中断。 很多工作,你最好有一个非常好的理由来做这种方式,因为计时器可以自行完成任务。

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

    好的、

    我的初始原因是想在不同的 GPIO 上生成多个 PWM、我需要将附加的 CCR0寄存器用作周期控制、而不是另一个寄存器来触发 GPIO 脉冲。

    如果这真是麻烦、我认为只使用向上计数模式和 CCRn 寄存器是没问题的。

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

    您好!

    如果您只是尝试获取 PWM 输出、那么是的、向上计数模式和 CCRn 寄存器要容易得多。 不过、我们提供了一个使用2个计时器在不同 GPIO 上生成多个 PWM 的示例( 此处已链接)。 希望这些内容对您的特定应用有所帮助。

    谢谢!

    苏珊  

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

    那么、如果我需要生成8个不同的 PWM、MSP430FR2433是可行的选项还是需要使用不同的微控制器?

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

    您好!

    遗憾的是、MSP430FR2433器件一次最多只能生成4个 PWM。  

    有关替代产品、您可以查看 MSP430FR2476 或我们全新的 MSPM0L1306 器件。 您还可以查看我们的器件目录、以了解是否有更适合您的应用的器件。  

    要计算 MSP430器件上可获得的 PWM 输出数量、应取每个器件的 CC 总数、并减去一个计时器。 对于 MSPM0器件、每个器件的 CC 数量是可以实现的 PWM 输出数量。  

    谢谢!

    苏珊