找回密码
 立即注册

QQ登录

只需一步,快速开始

打印 上一主题 下一主题
开启左侧

[NUC] NUC131 PWM_DoubleBuffer波形问题

[复制链接]
跳转到指定楼层
楼主
匿名  发表于 5 天前 |只看大图 回帖奖励 |正序浏览 |阅读模式
使用en-us--NUC131_Series_BSP_CMSIS_V3.00.006\SampleCode\StdDriver\PWM_DoubleBuffer中的示例
我理解PWM 输出会在 1MHz(40% 占空比)和 250kHz(50% 占空比)之间切换。但是实际测试后波形看着跟我理解的不一致。


/*---------------------------------------------------------------------------------------------------------*/
/* Macro, type and constant definitions                                                                    */
/*---------------------------------------------------------------------------------------------------------*/

#define PLL_CLOCK           50000000


/*---------------------------------------------------------------------------------------------------------*/
/* Global variables                                                                                        */
/*---------------------------------------------------------------------------------------------------------*/

/**
* @brief       PWM0 IRQ Handler
*
* @param       None
*
* @return      None
*
* @details     ISR to handle PWM0 interrupt event
*/
void PWM1_IRQHandler(void)
{
    static int toggle = 0;

    // Update PWM0 channel 0 period and duty
    if(toggle == 0)
    {
        PWM_SET_CNR(PWM1, 0, 99);
        PWM_SET_CMR(PWM1, 0, 39);
    }
    else
    {
        PWM_SET_CNR(PWM1, 0, 399);
        PWM_SET_CMR(PWM1, 0, 199);
    }
    toggle ^= 1;
    // Clear channel 0 period interrupt flag
    PWM_ClearPeriodIntFlag(PWM1, 0);
}

void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Enable Internal RC clock */
    CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);

    /* Waiting for IRC22M clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);

    /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
    CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));

    /* Enable external 12MHz XTAL, internal 22.1184MHz */
    CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk | CLK_PWRCON_OSC22M_EN_Msk);

    /* Enable PLL and Set PLL frequency */
    CLK_SetCoreClock(PLL_CLOCK);

    /* Waiting for clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk | CLK_CLKSTATUS_XTL12M_STB_Msk | CLK_CLKSTATUS_OSC22M_STB_Msk);

    /* Switch HCLK clock source to PLL, STCLK to HCLK/2 */
    CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_PLL, CLK_CLKDIV_HCLK(2));

    /* Enable UART module clock */
    CLK_EnableModuleClock(UART0_MODULE);

    /* Select UART module clock source */
    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));

    /* Enable PWM0 module clock */
    CLK_EnableModuleClock(PWM1_MODULE);

    /* Select PWM module clock source */
    //CLK_SetModuleClock(PWM0_MODULE, CLK_CLKSEL3_PWM0_S_HClK, 0);
    CLK_SetModuleClock(PWM1_MODULE, CLK_CLKSEL3_PWM1_S_PLL, 0);

    /* Reset PWM0 */
    SYS_ResetModule(PWM1_RST);

    /* Update System Core Clock */
    /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CyclesPerUs automatically. */
    //SystemCoreClockUpdate();
    PllClock        = PLL_CLOCK;            // PLL
    SystemCoreClock = PLL_CLOCK / 1;        // HCLK
    CyclesPerUs     = PLL_CLOCK / 1000000;  // For CLK_SysTickDelay()

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Set GPB multi-function pins for UART0 RXD and TXD */
    SYS->GPB_MFP &= ~(SYS_GPB_MFP_PB0_Msk | SYS_GPB_MFP_PB1_Msk);
    SYS->GPB_MFP |= (SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD);
    /* Set GPA multi-function pins for PWM1 Channel 0 */
                SYS->GPA_MFP &= ~(SYS_GPA_MFP_PA2_Msk);
    SYS->GPA_MFP |= SYS_GPA_MFP_PA2_PWM1_CH0;
    SYS->ALT_MFP3 &= ~(SYS_ALT_MFP3_PA2_Msk);
    SYS->ALT_MFP3 |= SYS_ALT_MFP3_PA2_PWM1_CH0;
}

void UART0_Init()
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Reset IP */
    SYS_ResetModule(UART0_RST);

    /* Configure UART0 and set UART0 Baudrate */
    UART_Open(UART0, 115200);
}

/*---------------------------------------------------------------------------------------------------------*/
/*  Main Function                                                                                          */
/*---------------------------------------------------------------------------------------------------------*/
int32_t main(void)
{
    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, IP clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART to 115200-8n1 for print message */
    UART0_Init();
    printf("+------------------------------------------------------------------------+\n");
    printf("|                          PWM Driver Sample Code                        |\n");
    printf("|                                                                        |\n");
    printf("+------------------------------------------------------------------------+\n");
    printf("  This sample code will use PWM0 channel 0 to output waveform\n");
    printf("  I/O configuration:\n");
    printf("    waveform output pin: PWM0 channel 0(PA.12)\n");
    printf("\nUse double buffer feature.\n");

    /*
        PWM0 channel 0 waveform of this sample shown below:

        |<-        CNR + 1  clk     ->|  CNR + 1 = 399 + 1 CLKs
                       |<-CMR+1 clk ->|  CMR + 1 = 199 + 1 CLKs
                                      |<-   CNR + 1  ->|  CNR + 1 = 99 + 1 CLKs
                                               |<CMR+1>|  CMR + 1 = 39 + 1 CLKs
      __                ______________          _______
        |______200_____|     200      |____60__|   40  |_____PWM waveform

    */


    /*
      Configure PWM0 channel 0 init period and duty.
      Period is __HXT / (prescaler * clock divider * (CNR + 1))
      Duty ratio = (CMR + 1) / (CNR + 1)
      Period = 12 MHz / (2 * 1 * (199 + 1)) =  30000 Hz
      Duty ratio = (99 + 1) / (199 + 1) = 50%
    */
    // PWM0 channel 0 frequency is 100Hz, duty 30%,
    PWM_ConfigOutputChannel(PWM1, 0, 30000, 30);

    // Enable output of PWM0 channel 0
    PWM_EnableOutput(PWM1, PWM_CH_0_MASK);

    // Enable PWM0 channel 0 period interrupt, use channel 0 to measure time.
    PWM_EnablePeriodInt(PWM1, 0, 0);
    NVIC_EnableIRQ(PWM1_IRQn);

    // Start
    PWM_Start(PWM1, PWM_CH_0_MASK);

    while(1);

}

微信图片_20251222151257.jpg (171.81 KB, 下载次数: 12)

PWM波形

PWM波形
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 顶 踩
回复

使用道具

6#
匿名  发表于 3 天前
我对新上传的图片描述有问题,因为我匿名发的帖子,好像没法修改,我重新开个帖子吧,谢谢。
回复 支持 反对

使用道具

5#
匿名  发表于 3 天前
修改PWM周期为4us和2us后,波形正常。之前有问题的周期是4us和1us。感觉PWM的周期拉长就能正常,周期超过1us左右就不行。
新上传的图片是正常的PWM周期为4us和2us的切换。

微信图片_20251224174813.jpg (153.51 KB, 下载次数: 7)

增大PWM周期

增大PWM周期
回复 支持 反对

使用道具

地板
匿名  发表于 3 天前
C:\Users\book\Desktop\微信图片_20251224174813.jpg
回复 支持 反对

使用道具

板凳
chrishu 发表于 3 天前 | 只看该作者
游客 61.185.196.x 发表于 2025-12-23 09:12
代码中把示例中PWM0改为PWM1,波形中有一段既不是1MHz(40% 占空比)也不是 250kHz(50% 占空比) ...

直接改 CNR和CMR是能改周期和占空比。周期根据当前的分频系数和CMR算
回复 支持 反对

使用道具 举报

沙发
匿名  发表于 4 天前
代码中把示例中PWM0改为PWM1,波形中有一段既不是1MHz(40% 占空比)也不是 250kHz(50% 占空比)
回复 支持 反对

使用道具

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则

新唐MCU