打印
[活动]

【极海G32A1465测评】3、PWM点灯

[复制链接]
240|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 sujingliang 于 2024-12-14 21:54 编辑

一、板上资源
RGB灯对应LED1、LED2、LED3




对应引脚:PMD0、PMD15、PMD16

查了一下手册,引脚复用情况:



手册上写:PMD0对应CFGTMR2_CH2,但这里可能是笔误:实际应该是CFGTMR0_CH2
PMD15对应CFGTMR0_CH0,PMD15对应CFGTMR0_CH1


二、引脚配置
复用:PM_MUX_ALT2
PMD0:CFGTMR0_CH2
PMD15:CFGTMR0_CH0
PMD16:CFGTMR0_CH1
{
        .base            = PMD,
        .pinPmIdx        = 0U,                //LED1        CFGTMR0_CH2
        .pullCfg         = PM_INTERNAL_PULL_NOT_ENABLED,
        .drvSel          = PM_LOW_DRIVE_STRENGTH,
        .passiveFilt     = false,
        .mux             = PM_MUX_ALT2,//PM_MUX_AS_GPIO,
        .pinLk           = false,
        .intCfg          = PM_DMA_INT_DISABLED,
        .clrIntFlg       = false,
        .gpioBase        = NULL,
        .digitFilt       = false,        
    },
    {
        .base            = PMD,
        .pinPmIdx        = 15U,                //LED2        CFGTMR0_CH0
        .pullCfg         = PM_INTERNAL_PULL_NOT_ENABLED,
        .drvSel          = PM_LOW_DRIVE_STRENGTH,
        .passiveFilt     = false,
        .mux             = PM_MUX_ALT2,
        .pinLk           = false,
        .intCfg          = PM_DMA_INT_DISABLED,
        .clrIntFlg       = false,
        .gpioBase        = NULL,
        .digitFilt       = false,
    },
    {
        .base            = PMD,
        .pinPmIdx        = 16U,                        //LED3        CFGTMR0_CH1
        .pullCfg         = PM_INTERNAL_PULL_NOT_ENABLED,
        .drvSel          = PM_LOW_DRIVE_STRENGTH,
        .passiveFilt     = false,
        .mux             = PM_MUX_ALT2,
        .pinLk           = false,
        .intCfg          = PM_DMA_INT_DISABLED,
        .clrIntFlg       = false,
        .gpioBase        = NULL,
        .digitFilt       = false,
    },
三、TMR初始化


 CFGTMR_Init(CFGTMR0_INSTANCE, &g_cfgtmr0InitConfig, &cfgtmr0State);                
/* Initialize CFGTMR PWM */
    CFGTMR_InitPWM(CFGTMR0_INSTANCE, &g_cfgtmr0PWMInitConfig);
参数g_cfgtmr0InitConfig:
/* CFGTMR user initialize config */
CFGTMR_USER_CONFIG_T g_cfgtmr0InitConfig =
{
    {
        .softSync     = true,              /* Software trigger state */
        .hwSync0      = false,             /* Hardware trigger 1 state */
        .hwSync1      = false,             /* Hardware trigger 2 state */
        .hwSync2      = false,             /* Hardware trigger 3 state */
        .maxLoadingPoint  = false,             /* Max loading point state */
        .minLoadingPoint  = false,             /* Min loading point state */
        .inverterSync     = CFGTMR_PWM_SYNC,     /* Update mode for ICTRL register */
        .outRegSync       = CFGTMR_PWM_SYNC,     /* Update mode for SWOCTRL register */
        .maskRegSync      = CFGTMR_PWM_SYNC,     /* Update mode for OMASK register */
        .initCounterSync  = CFGTMR_PWM_SYNC,     /* Update mode for INITV register */
        .autoClrTrigger   = true,              /* Automatic clear of the trigger */
        .syncPoint        = CFGTMR_UPDATE_NOW,   /* Synchronization point */
    },
    .cfgtmrMode        = CFGTMR_MODE_EDGE_ALIGNED_PWM,  /* Mode of operation for CFGTMR */
    .BDMMode         = CFGTMR_BDM_MODE_11,            /* CFGTMR debug mode */
    .cfgtmrPsc         = CFGTMR_CLOCK_DIV_1,            /* CFGTMR clock prescaler */
    .cfgtmrClkSrc      = CFGTMR_CLOCK_SRC_SYSTEMCLK,    /* CFGTMR clock source */
    .isEnableInitTrg = false,                       /* Initialization trigger */
    .isEnableInterrupt = false,                     /* Interrupt state */
};
softSync:软件触发状态,设置为true表示启用软件触发。
hwSync0、hwSync1、hwSync2:硬件触发状态,分别对应硬件触发1、2、3,这里都设置为false表示禁用。
maxLoadingPoint、minLoadingPoint:最大和最小加载点状态,这里都设置为false表示禁用。
inverterSync、outRegSync、maskRegSync、initCounterSync:这些参数定义了不同寄存器的更新模式,这里都设置为CFGTMR_PWM_SYNC,表示使用PWM同步模式更新。
autoClrTrigger:自动清除触发状态,设置为true表示启用自动清除触发。
syncPoint:同步点,设置为CFGTMR_UPDATE_NOW表示立即更新。
cfgtmrMode:CFGTMR的工作模式,设置为CFGTMR_MODE_EDGE_ALIGNED_PWM表示边缘对齐PWM模式。
BDMMode:CFGTMR的调试模式,设置为CFGTMR_BDM_MODE_11。
cfgtmrPsc:CFGTMR的时钟预分频器,设置为CFGTMR_CLOCK_DIV_1表示不分频。
cfgtmrClkSrc:CFGTMR的时钟源,设置为CFGTMR_CLOCK_SRC_SYSTEMCLK表示使用系统时钟。
isEnableInitTrg:初始化触发状态,设置为false表示禁用初始化触发。
isEnableInterrupt:中断状态,设置为false表示禁用中断。


参数g_cfgtmr0PWMInitConfig:
/* CFGTMR PWM initialize config */
CFGTMR_PWM_PARAM_T g_cfgtmr0PWMInitConfig =
{
    .numOfIndependentPwmChns  = 3U,                         /* Independent PWM channels number */
    .numOfCombinedPwmChns     = 0U,                         /* cCombined PWM channels number */
    .mode                     = CFGTMR_MODE_EDGE_ALIGNED_PWM, /* CFGTMR operation mode, Configured as PWM mode */
    .uFreqHZ                  = 10000U,                     /* PWM frequency in HZ */
    .deadTimeVal              = 0U,                         /* Dead time value */
    .deadTimePsc              = CFGTMR_DEADTIME_DIV_1,        /* Dead time prescale */
    .pwmIndependentChnCfg     = g_cfgtmr0PWMIndependentChannelsConfig, /* Configuration for independent PWM channels */
    .pwmCombinedChnCfg        = NULL,                               /* Configuration for combined PWM channels */
    .pwmFaultCfg              = &g_cfgtmr0PWMFaultConfig               /* Configuration for PWM fault */
};
numOfIndependentPwmChns:独立PWM通道的数量。
numOfCombinedPwmChns:组合PWM通道的数量(在这个例子中为0n,表示没有使用组合通道)。
mode:CFGTMR的操作模式,这里配置为CFGTMR_MODE_EDGE_ALIGNED_PWM,即边缘对齐PWM模式。
uFreqHZ:PWM信号的频率,以赫兹为单位。
deadTimeVal:死区时间的值。注意,如果enableDeadTime为false,则这个值将被忽略。
deadTimePsc:死区时间预分频器。它决定了死区时间的分辨率。
pwmIndependentChnCfg:指向独立PWM通道配置数组的指针。在这个例子中,它指向了一个包含单个元素的数组。
pwmCombinedChnCfg:指向组合PWM通道配置数组的指针。在这个例子中,它被设置为NULL,因为没有使用组合通道。
pwmFaultCfg:指向PWM故障配置的指针。它允许配置在检测到故障时PWM应该如何响应。


参数g_cfgtmr0PWMIndependentChannelsConfig:
/* CFGTMR the PWM of the independent channels config */
CFGTMR_INDEPENDENT_CHAN_PARAM_T g_cfgtmr0PWMIndependentChannelsConfig[3] =
{
    {
        .hwChannelId = 0,                        /* Hardware channel ID */
        .dutyCycle   = 0x2000U,                  /* Duty cycle percent 0-0x8000 */
        .polarity    = CFGTMR_POLARITY_HIGH,       /* Polarity of the PWM signal generated on MCU pin. */
        .safeState   = CFGTMR_LOW_STATE,           /* Safe state of the PWM channel when faults are detected */
        .enableSecondChnOutput = false,          /* Enabled/disabled the channel (n+1) output */
        .secondChnPolarity = CFGTMR_MAIN_INVERTED, /* Select channel (n+1) output relative to channel (n) */
        .enableDeadTime = false,                 /* Enable/disable dead time */
        .isExternalTrigger = false,              /* Enable/disable external Trigger */
    },
                {
        .hwChannelId = 1,                        /* Hardware channel ID */
        .dutyCycle   = 0x2000U,                  /* Duty cycle percent 0-0x8000 */
        .polarity    = CFGTMR_POLARITY_HIGH,       /* Polarity of the PWM signal generated on MCU pin. */
        .safeState   = CFGTMR_LOW_STATE,           /* Safe state of the PWM channel when faults are detected */
        .enableSecondChnOutput = false,          /* Enabled/disabled the channel (n+1) output */
        .secondChnPolarity = CFGTMR_MAIN_INVERTED, /* Select channel (n+1) output relative to channel (n) */
        .enableDeadTime = false,                 /* Enable/disable dead time */
        .isExternalTrigger = false,              /* Enable/disable external Trigger */
    },
                {
        .hwChannelId = 2,                        /* Hardware channel ID */
        .dutyCycle   = 0x2000U,                  /* Duty cycle percent 0-0x8000 */
        .polarity    = CFGTMR_POLARITY_HIGH,       /* Polarity of the PWM signal generated on MCU pin. */
        .safeState   = CFGTMR_LOW_STATE,           /* Safe state of the PWM channel when faults are detected */
        .enableSecondChnOutput = false,          /* Enabled/disabled the channel (n+1) output */
        .secondChnPolarity = CFGTMR_MAIN_INVERTED, /* Select channel (n+1) output relative to channel (n) */
        .enableDeadTime = false,                 /* Enable/disable dead time */
        .isExternalTrigger = false,              /* Enable/disable external Trigger */
    }
};
hwChannelId:硬件通道ID,指定了哪个硬件通道将被配置为PWM输出。
dutyCycle:占空比,以十六进制表示,范围从0到0x8000,对应0%到100%的占空比。
polarity:PWM信号的极性,CFGTMR_POLARITY_HIGH 表示高电平有效,CFGTMR_POLARITY_LOW 表示低电平有效。
safeState:当检测到故障时,PWM通道的安全状态,CFGTMR_LOW_STATE 表示低电平,CFGTMR_HIGH_STATE 表示高电平。
enableSecondChnOutput:是否启用第二个通道(n+1)的输出。在某些硬件中,一个PWM通道可能伴随着一个附加的、相关的通道。
secondChnPolarity:第二个通道(n+1)相对于第一个通道(n)的极性。CFGTMR_MAIN_INVERTED 表示第二个通道的极性与第一个通道相反。
enableDeadTime:是否启用死区时间。死区时间用于防止两个互补的PWM信号同时处于高电平或低电平,从而避免短路。
isExternalTrigger:是否启用外部触发。外部触发允许PWM信号的生成由外部事件控制。


四、调节PWM周期及占空比


CFGTMR_UpdatePwmPeriod(CFGTMR0_INSTANCE, CFGTMR_PWM_UPDATE_IN_DUTY_CYCLE, frequencyHZ, true);
 CFGTMR_UpdatePwmChannel(
                                  CFGTMR0_INSTANCE,
                                  g_cfgtmr0PWMIndependentChannelsConfig[0].hwChannelId,
                                  CFGTMR_PWM_UPDATE_IN_DUTY_CYCLE,
                                  dutyCycle,
                                  0U,
                                  true);



五、while(1)
while (1)
    {
        /* Change PWM output frequency */
        if (BTN_GetState(BUTTON_KEY1) == 0U)
        {
            frequencyHZ += 10000U;
            if (frequencyHZ > 100000)
            {
                frequencyHZ = 10000U;
            }
            
            CFGTMR_UpdatePwmPeriod(CFGTMR0_INSTANCE, CFGTMR_PWM_UPDATE_IN_DUTY_CYCLE, frequencyHZ, true);

            CFGTMR_UpdatePwmChannel(
                                  CFGTMR0_INSTANCE,
                                  g_cfgtmr0PWMIndependentChannelsConfig[0].hwChannelId,
                                  CFGTMR_PWM_UPDATE_IN_DUTY_CYCLE,
                                  dutyCycle,
                                  0U,
                                  true);
                                                
                                                CFGTMR_UpdatePwmChannel(
                                  CFGTMR0_INSTANCE,
                                  g_cfgtmr0PWMIndependentChannelsConfig[1].hwChannelId,
                                  CFGTMR_PWM_UPDATE_IN_DUTY_CYCLE,
                                  dutyCycle,
                                  0U,
                                  true);
                        
                                                CFGTMR_UpdatePwmChannel(
                                  CFGTMR0_INSTANCE,
                                  g_cfgtmr0PWMIndependentChannelsConfig[2].hwChannelId,
                                  CFGTMR_PWM_UPDATE_IN_DUTY_CYCLE,
                                  dutyCycle,
                                  0U,
                                  true);
         
            printf("CFGTMR PWM output frequency %dKHz.\r\n", frequencyHZ / 1000);
            while (BTN_GetState(BUTTON_KEY1) == 0U);
        }
        
        /* Change PWM output duty cycle */
        if (BTN_GetState(BUTTON_KEY2) == 0U)
        {
             dutyCycle += 0x1000U;
            if (dutyCycle > CFGTMR_MAX_DUTY_CYCLE)
            {
                dutyCycle = 0x2000U;
            }

            CFGTMR_UpdatePwmChannel(
                                  CFGTMR0_INSTANCE,
                                  g_cfgtmr0PWMIndependentChannelsConfig[0].hwChannelId,
                                  CFGTMR_PWM_UPDATE_IN_DUTY_CYCLE,
                                  dutyCycle,
                                  0U,
                                  true);
             CFGTMR_UpdatePwmChannel(
                                  CFGTMR0_INSTANCE,
                                  g_cfgtmr0PWMIndependentChannelsConfig[1].hwChannelId,
                                  CFGTMR_PWM_UPDATE_IN_DUTY_CYCLE,
                                  dutyCycle,
                                  0U,
                                  true);

                                                CFGTMR_UpdatePwmChannel(
                                  CFGTMR0_INSTANCE,
                                  g_cfgtmr0PWMIndependentChannelsConfig[2].hwChannelId,
                                  CFGTMR_PWM_UPDATE_IN_DUTY_CYCLE,
                                  dutyCycle,
                                  0U,
                                  true);
                                                                                                                        
            printf("CFGTMR PWM output duty cycle %0.2f%%.\r\n", ((float)dutyCycle / CFGTMR_MAX_DUTY_CYCLE) * 100);
            while (BTN_GetState(BUTTON_KEY2) == 0U);
        }
    }
按下B1调节PWM周期按下B2调节PWM空比

六、运行效果






使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

38

主题

79

帖子

0

粉丝