【MSP432E401Y学习笔记】PWM输出之改例程

该博客展示了如何在MSP432E4微控制器上配置两个PWM信号,分别在PF0和PF1上产生25%和75%的占空比。通过修改原始例程,作者成功地将PWM扩展到PF2,并介绍了如何配置PWM时钟、周期和占空比。此外,还详细解释了中断设置,以便在计数器达到特定值时触发中断。
摘要由CSDN通过智能技术生成

在例程pwm_gen0_basic_interrupt里面一开始是这样的(主函数)

/* --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--*/
/******************************************************************************
 * MSP432E4 PWM with basic interrupt
 *
 * Description: This project creates two PWMs from PWM Generator 3.  Each PWM
 *              period is 128K clock cycles(64K up and 64K down); ~250Hz.  PWMA
 *              has a 25% positive duty cycle while PWMB has 75%.  The PWM
 *              interrupt sources for Generator 0 are the PWMA comparator value
 *              in both the up and down directions and the Load and Zero count
 *              values.
 *
 *                MSP432E401Y
 *             ------------------
 *         /|\|                  |
 *          | |                  |
 *          --|RST               |
 *            |               PA0|<--- UART RX
 *            |               PA1|---> UART TX
 *            |                  |
 *            |               PF0|---> PWMA 25% Duty Cycle
 *            |               PF1|---> PWMB 75% Duty Cycle
 *            |                  |
 *
 * Author: C. Sterzik
 *
*******************************************************************************/
/* DriverLib Includes */
#include <ti/devices/msp432e4/driverlib/driverlib.h>

/* Standard Includes */
#include <stdint.h>
#include <stdbool.h>

/* Include for serial console */
#include "uartstdio.h"

/* Global variable for system clock */
uint32_t getSystemClock;

/* PWM ISR */
void PWM0_0_IRQHandler(void)
{
    uint32_t getIntStatus;

    getIntStatus = MAP_PWMGenIntStatus(PWM0_BASE, PWM_GEN_0, true);

    MAP_PWMGenIntClear(PWM0_BASE, PWM_GEN_0, getIntStatus);

}

/* Function to setup the serial console */
void InitConsole(void)
{
    /* Enable the clock to GPIO port A and UART 0 */
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    /* Configure the GPIO Port A for UART 0 */
    MAP_GPIOPinConfigure(GPIO_PA0_U0RX);
    MAP_GPIOPinConfigure(GPIO_PA1_U0TX);
    MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    /* Configure the UART for 115200 bps 8-N-1 format with internal 16 MHz
     * oscillator as the UART clock source */
    MAP_UARTClockSourceSet(UART0_BASE, UART_CLOCK_ALTCLK);

    UARTStdioConfig(0, 115200, 16000000);
}

/* Prints out 5x "." with a second delay after each print.  This function will
 * then backspace, clearing the previously printed dots, and then backspace
 * again so you can continuously printout on the same line.  The purpose of
 * this function is to indicate to the user that the program is running. */
void
PrintRunningDots(void)
{
    UARTprintf(". ");

    MAP_SysCtlDelay(getSystemClock / 3);
    UARTprintf(". ");
    MAP_SysCtlDelay(getSystemClock / 3);
    UARTprintf(". ");
    MAP_SysCtlDelay(getSystemClock / 3);

    UARTprintf(". ");
    MAP_SysCtlDelay(getSystemClock / 3);
    UARTprintf(". ");
    MAP_SysCtlDelay(getSystemClock / 3);
    UARTprintf("\b\b\b\b\b\b\b\b\b\b");
    UARTprintf("          ");
    UARTprintf("\b\b\b\b\b\b\b\b\b\b");
    MAP_SysCtlDelay(getSystemClock / 3);
}

int main(void)
{
    /* Configure the system clock for 16 MHz internal oscillator */
    getSystemClock = MAP_SysCtlClockFreqSet((SYSCTL_OSC_INT |
                                             SYSCTL_USE_OSC), 16000000);

    /* Initialize serial console */
    InitConsole();

    /* Display the setup on the console. */
    UARTprintf("PWM ->\n");
    UARTprintf("  Module: PWM0 Generator 0\n");
    UARTprintf("  Pin(s): PF0 and PF1\n");
    UARTprintf("  Duty Cycle: 25%% on PF0 and 75%% on PF1\n");
    UARTprintf("Generating PWM on PWM0 (PF0,PF1) -> ");

    /* The PWM peripheral must be enabled for use. */
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    while(!(MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_PWM0)));

    /* Set the PWM clock to the system clock. */
    MAP_PWMClockSet(PWM0_BASE,PWM_SYSCLK_DIV_1);

    /* Enable the clock to the GPIO Port F for PWM pins */
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF));

    MAP_GPIOPinConfigure(GPIO_PF0_M0PWM0);
    MAP_GPIOPinConfigure(GPIO_PF1_M0PWM1);

    MAP_GPIOPinTypePWM(GPIO_PORTF_BASE, (GPIO_PIN_0 | GPIO_PIN_1|));

    /* Configure the PWM0 to count up/down without synchronization. */
    MAP_PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_UP_DOWN |
                        PWM_GEN_MODE_NO_SYNC);

    /* Set the PWM period to 250Hz.  To calculate the appropriate parameter
     * use the following equation: N = (1 / f) * SysClk.  Where N is the
     * function parameter, f is the desired frequency, and SysClk is the
     * system clock frequency.
     * In this case you get: (1 / 250Hz) * 16MHz = 64000 cycles.  Note that
     * the maximum period you can set is 2^16 - 1. */
    MAP_PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, 64000);
    /* Set PWM0 PF0 to a duty cycle of 25%.  You set the duty cycle as a
     * function of the period.  Since the period was set above, you can use the
     * PWMGenPeriodGet() function.  For this example the PWM will be high for
     * 25% of the time or 16000 clock cycles (64000 / 4). */
    MAP_PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0,
                     MAP_PWMGenPeriodGet(PWM0_BASE, PWM_GEN_0) / 4);

    /* Set PWM0 PF1 to a duty cycle of 75%.  You set the duty cycle as a
     * function of the period.  Since the period was set above, you can use the
     * PWMGenPeriodGet() function.  For this example the PWM will be high for
     * 7% of the time or 16000 clock cycles 3*(64000 / 4). */
    MAP_PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1,
                     3*MAP_PWMGenPeriodGet(PWM0_BASE, PWM_GEN_0) / 4);


    MAP_IntMasterEnable();

    /* This timer is in up-down mode.  Interrupts will occur when the
     * counter for this PWM counts to the load value (64000), when the
     * counter counts up to 64000/4 (PWM A Up), counts down to 64000/4
     * (PWM A Down), and counts to 0. */
    MAP_PWMGenIntTrigEnable(PWM0_BASE, PWM_GEN_0,
                            PWM_INT_CNT_ZERO | PWM_INT_CNT_LOAD |
                            PWM_INT_CNT_AU | PWM_INT_CNT_AD);
    MAP_IntEnable(INT_PWM0_0);

    MAP_PWMIntEnable(PWM0_BASE, PWM_INT_GEN_0);

    /* Enable the PWM0 Bit 0 (PF0) and Bit 1 (PF1) output signals. */
    MAP_PWMOutputState(PWM0_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT), true);

    /* Enables the counter for a PWM generator block. */
    MAP_PWMGenEnable(PWM0_BASE, PWM_GEN_0);
    /* Loop forever while the PWM signals are generated. */
    while(1)
    {
        /* Print out indication on the console that the program is running. */
        PrintRunningDots();
    }
}

尝试添加其他管脚,直接在有F0/F1的地方加上F2无果。查阅其他例程,在pwm_genx里面找到了

/* Generator 0 Pins */
    MAP_GPIOPinConfigure(GPIO_PF1_M0PWM1);

    /* Generator 1 Pins */
    MAP_GPIOPinConfigure(GPIO_PF2_M0PWM2);
    MAP_GPIOPinConfigure(GPIO_PF3_M0PWM3);

    /* Generator 2 Pins */
    MAP_GPIOPinConfigure(GPIO_PG0_M0PWM4);
    MAP_GPIOPinConfigure(GPIO_PG1_M0PWM5);

    /* Generator 3 Pins */
    MAP_GPIOPinConfigure(GPIO_PK4_M0PWM6);
    MAP_GPIOPinConfigure(GPIO_PK5_M0PWM7);

在有gen0的地方加上gen1,成功√

/* DriverLib Includes */
#include <ti/devices/msp432e4/driverlib/driverlib.h>

/* Standard Includes */
#include <stdint.h>
#include <stdbool.h>

/* Include for serial console */
#include "uartstdio.h"

/* Global variable for system clock */
uint32_t getSystemClock;

/* PWM ISR */
void PWM0_0_IRQHandler(void)
{
    uint32_t getIntStatus;

    getIntStatus = MAP_PWMGenIntStatus(PWM0_BASE, PWM_GEN_0, true);

    MAP_PWMGenIntClear(PWM0_BASE, PWM_GEN_0, getIntStatus);

}

/* Function to setup the serial console */
void InitConsole(void)
{
    /* Enable the clock to GPIO port A and UART 0 */
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    /* Configure the GPIO Port A for UART 0 */
    MAP_GPIOPinConfigure(GPIO_PA0_U0RX);
    MAP_GPIOPinConfigure(GPIO_PA1_U0TX);
    MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    /* Configure the UART for 115200 bps 8-N-1 format with internal 16 MHz
     * oscillator as the UART clock source */
    MAP_UARTClockSourceSet(UART0_BASE, UART_CLOCK_ALTCLK);

    UARTStdioConfig(0, 115200, 16000000);
}

/* Prints out 5x "." with a second delay after each print.  This function will
 * then backspace, clearing the previously printed dots, and then backspace
 * again so you can continuously printout on the same line.  The purpose of
 * this function is to indicate to the user that the program is running. */
void
PrintRunningDots(void)
{
    UARTprintf(". ");

    MAP_SysCtlDelay(getSystemClock / 3);
    UARTprintf(". ");
    MAP_SysCtlDelay(getSystemClock / 3);
    UARTprintf(". ");
    MAP_SysCtlDelay(getSystemClock / 3);

    UARTprintf(". ");
    MAP_SysCtlDelay(getSystemClock / 3);
    UARTprintf(". ");
    MAP_SysCtlDelay(getSystemClock / 3);
    UARTprintf("\b\b\b\b\b\b\b\b\b\b");
    UARTprintf("          ");
    UARTprintf("\b\b\b\b\b\b\b\b\b\b");
    MAP_SysCtlDelay(getSystemClock / 3);
}

int main(void)
{
    /* Configure the system clock for 16 MHz internal oscillator */
    getSystemClock = MAP_SysCtlClockFreqSet((SYSCTL_OSC_INT |
                                             SYSCTL_USE_OSC), 16000000);

    /* Initialize serial console */
    InitConsole();

    /* Display the setup on the console. */
    UARTprintf("PWM ->\n");
    UARTprintf("  Module: PWM0 Generator 0\n");
    UARTprintf("  Pin(s): PF0 and PF1\n");
    UARTprintf("  Duty Cycle: 25%% on PF0 and 75%% on PF1\n");
    UARTprintf("Generating PWM on PWM0 (PF0,PF1) -> ");

    /* The PWM peripheral must be enabled for use. */
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    while(!(MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_PWM0)));

    /* Set the PWM clock to the system clock. */
    MAP_PWMClockSet(PWM0_BASE,PWM_SYSCLK_DIV_1);

    /* Enable the clock to the GPIO Port F for PWM pins */
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF));

    MAP_GPIOPinConfigure(GPIO_PF0_M0PWM0);
    MAP_GPIOPinConfigure(GPIO_PF1_M0PWM1);
    MAP_GPIOPinConfigure(GPIO_PF2_M0PWM2);
    MAP_GPIOPinTypePWM(GPIO_PORTF_BASE, (GPIO_PIN_0 | GPIO_PIN_1| GPIO_PIN_2));

    /* Configure the PWM0 to count up/down without synchronization. */
    MAP_PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_UP_DOWN |
                        PWM_GEN_MODE_NO_SYNC);
    MAP_PWMGenConfigure(PWM0_BASE, PWM_GEN_1, PWM_GEN_MODE_UP_DOWN |
                        PWM_GEN_MODE_GEN_SYNC_LOCAL);
    /* Set the PWM period to 250Hz.  To calculate the appropriate parameter
     * use the following equation: N = (1 / f) * SysClk.  Where N is the
     * function parameter, f is the desired frequency, and SysClk is the
     * system clock frequency.
     * In this case you get: (1 / 250Hz) * 16MHz = 64000 cycles.  Note that
     * the maximum period you can set is 2^16 - 1. */
    MAP_PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, 64000);
    MAP_PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, 64000);
    /* Set PWM0 PF0 to a duty cycle of 25%.  You set the duty cycle as a
     * function of the period.  Since the period was set above, you can use the
     * PWMGenPeriodGet() function.  For this example the PWM will be high for
     * 25% of the time or 16000 clock cycles (64000 / 4). */
    MAP_PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0,
                     MAP_PWMGenPeriodGet(PWM0_BASE, PWM_GEN_0) / 4);

    /* Set PWM0 PF1 to a duty cycle of 75%.  You set the duty cycle as a
     * function of the period.  Since the period was set above, you can use the
     * PWMGenPeriodGet() function.  For this example the PWM will be high for
     * 7% of the time or 16000 clock cycles 3*(64000 / 4). */
    MAP_PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1,
                     3*MAP_PWMGenPeriodGet(PWM0_BASE, PWM_GEN_0) / 4);
    /* Set PWM0 PF2 to a duty cycle of 50%.  You set the duty cycle as a
     * function of the period.  Since the period was set above, you can use the
     * PWMGenPeriodGet() function.  For this example the PWM will be high for
     * 7% of the time or 16000 clock cycles 3*(64000 / 4). */
    MAP_PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2,
                     MAP_PWMGenPeriodGet(PWM0_BASE, PWM_GEN_0) / 4);

    MAP_IntMasterEnable();

    /* This timer is in up-down mode.  Interrupts will occur when the
     * counter for this PWM counts to the load value (64000), when the
     * counter counts up to 64000/4 (PWM A Up), counts down to 64000/4
     * (PWM A Down), and counts to 0. */
    MAP_PWMGenIntTrigEnable(PWM0_BASE, PWM_GEN_0,
                            PWM_INT_CNT_ZERO | PWM_INT_CNT_LOAD |
                            PWM_INT_CNT_AU | PWM_INT_CNT_AD);
    MAP_IntEnable(INT_PWM0_0);
    MAP_IntEnable(INT_PWM0_1);

    MAP_PWMIntEnable(PWM0_BASE, PWM_INT_GEN_0);
    MAP_PWMIntEnable(PWM0_BASE, PWM_INT_GEN_1);

    /* Enable the PWM0 Bit 0 (PF0) and Bit 1 (PF1) output signals. */
    MAP_PWMOutputState(PWM0_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT| PWM_OUT_2_BIT), true);

    /* Enables the counter for a PWM generator block. */
    MAP_PWMGenEnable(PWM0_BASE, PWM_GEN_0);
    MAP_PWMGenEnable(PWM0_BASE, PWM_GEN_1);
    /* Loop forever while the PWM signals are generated. */
    while(1)
    {
        /* Print out indication on the console that the program is running. */
        PrintRunningDots();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MSP432E401Y是一款低功耗的微控制器,它由德州仪器(Texas Instruments)所生产。这款微控制器集成了ARM Cortex-M4F内核,可以实现高性能的实时控制和低功耗的应用。 对于MSP432E401Y例程,可以选择使用Code Composer Studio(CCS)或者Energia开发环境进行开发和编程。 使用CCS进行开发时,可以利用TI-RTOS(实时操作系统)和HalCoGen(硬件配置生成器)来加快开发流程。通过HalCoGen,可以快速初始化外设和引脚,并生成对应的初始化代码。TI-RTOS提供了一系列的实时操作系统功能,例如任务调度、事件驱动和资源管理。开发者可以使用TI-RTOS的API来实现任务和中断处理程序,从而实现特定功能。 而使用Energia进行开发时,可以像使用Arduino一样使用简单的代码和函数库来控制MSP432E401Y。开发者可以使用Energia提供的库函数来初始化引脚、配置外设和编写程序。Energia还支持使用C和C++扩展库进行高级开发。另外,Energia还提供了丰富的例程和示例代码,帮助开发者快速入门和实现功能。 对于MSP432E401Y例程,可以根据实际需要进行开发。可以通过GPIO控制LED灯的亮灭,使用定时器实现精确的计时功能,通过串口与其他设备进行通信,或者使用ADC采集模拟信号等。这些例程可以通过CCS或Energia的开发环境进行编程和调试。 总之,MSP432E401Y例程可以根据需求进行开发,利用CCS或Energia的开发环境和API函数库来实现特定的功能。通过合理的代码编写和调试,可以充分发挥MSP432E401Y微控制器的性能,并实现低功耗的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值