打印
[技术问答]

hc32m120-timer4输出2路4通道互补死区可调pwm-例程

[复制链接]
9562|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 mao13226675618 于 2021-8-28 13:55 编辑

hc32m120-timer4输出2路4通道带死区可调互补pwm。/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32_ddl.h"

/**
* @addtogroup HC32M120_DDL_Examples
* @{
*/

/**
* @addtogroup TIMER4_PWM_Dead_Timer_Filter_Mode
* @{
*/

/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/

/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/* TIM4 PWM Port/Pin definition */
#define TIM4_1_OXH_PORT                 (GPIO_PORT_6)
#define TIM4_1_OXH_PIN                  (GPIO_PIN_1)
#define TIM4_1_OXH_GPIO_FUNC            (GPIO_FUNC_4_TIM4)

#define TIM4_1_OXL_PORT                 (GPIO_PORT_6)
#define TIM4_1_OXL_PIN                  (GPIO_PIN_0)
#define TIM4_1_OXL_GPIO_FUNC            (GPIO_FUNC_2_TIM4)

#define TIM4_1_OVH_PORT                 (GPIO_PORT_3)
#define TIM4_1_OVH_PIN                  (GPIO_PIN_1)
#define TIM4_1_OVH_GPIO_FUNC            (GPIO_FUNC_2_TIM4)

#define TIM4_1_OVL_PORT                 (GPIO_PORT_6)
#define TIM4_1_OVL_PIN                  (GPIO_PIN_2)
#define TIM4_1_OVL_GPIO_FUNC            (GPIO_FUNC_4_TIM4)

/* Function clock gate definition */
#define FUNCTION_CLK_GATE               (CLK_FCG_TIM4)

/* Timer4 Counter period value && interrupt number definition */
#define TIMER4_CNT_CYCLE_VAL            ((uint16_t)(400))    /* 500 ms */

/* Timer4 OCO Channel definition */
//#define TIMER4_OCO_LOW_CH               (TIMER4_OCO_UL)    /* only TIMER4_OCO_UL  TIMER4_OCO_VL  TIMER4_OCO_WL */
//#define TIMER4_OCO_LOW_CH               (TIMER4_OCO_VL)
#define TIMER4_OCO_OCCR_BUF_SIZE        (4u)

/* Timer4 OCO get interrupt source number definition */
#define TIMER4_OCO_INT_SRC(x)           ((en_int_src_t)((uint32_t)INT_TMR4_GCMUH + ((uint32_t)((x) - TIMER4_OCO_UH))))

/* Timer4 PWM get channel by OCO low channel */
#define TIMER4_PWM_CH(x)                (((x) == TIMER4_OCO_UL) ? TIMER4_PWM_U : \
                                         (((x) == TIMER4_OCO_VL) ? TIMER4_PWM_V : TIMER4_PWM_W))

/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/

/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
static void SystemClockConfig(void);
static void Timer4OcoMatchIrqCb(void);

/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
static uint16_t m_au16OccrVal[TIMER4_OCO_OCCR_BUF_SIZE];

/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/

/**
* @brief  Configure system clock.
* @param  None
* @retval None
*/
static void SystemClockConfig(void)
{
    /* Configure the system clock to HRC8MHz. */
    CLK_HRCInit(CLK_HRC_ON, CLK_HRCFREQ_48);
}

/**
* @brief  TIMER4 OCO match interrupt handler callback.
* @param  None
* @retval None
*/
static void Timer4OcoMatchIrqCb(void)
{
    static uint8_t u8CntOcoMatchIrq = 0u;

    if (++u8CntOcoMatchIrq >= TIMER4_OCO_OCCR_BUF_SIZE)
    {
        u8CntOcoMatchIrq = 0u;
    }

    TIMER4_OCO_ClearFlag(TIMER4_OCO_UL);
    TIMER4_OCO_SetOccrVal(TIMER4_OCO_UL, m_au16OccrVal[u8CntOcoMatchIrq]);
                TIMER4_OCO_ClearFlag(TIMER4_OCO_VL);
    TIMER4_OCO_SetOccrVal(TIMER4_OCO_VL, m_au16OccrVal[u8CntOcoMatchIrq]);
}

/**
* @brief  Main function of TIMER4 PWM dead timer filter mode
* @param  None
* @retval int32_t return value, if needed
*/
int32_t main(void)
{
    uint32_t u32PwmChU;
          uint32_t u32PwmChV;
    stc_irq_regi_config_t stcIrqRegiConf;
    stc_timer4_cnt_init_t stcTimer4CntInit;
    stc_timer4_oco_init_t stcTimer4OcoInit;
    stc_timer4_pwm_init_t stcTimer4PwmInit;
    stc_oco_low_ch_compare_mode_t stcLowChCmpMode;

    /* Configure system clock. */
    SystemClockConfig();

    /* Enable peripheral clock */
    CLK_FcgPeriphClockCmd(FUNCTION_CLK_GATE, Enable);

    /* Initialize TIMER4 Counter */
    TIMER4_CNT_StructInit(&stcTimer4CntInit);
    stcTimer4CntInit.u16ClkDiv = TIMER4_CNT_CLK_DIV1;
    /* Period_Value(500ms) = SystemClock(SystemCoreClock) / TIMER4_CNT_Clock_Division(128) / Frequency(2) */
    stcTimer4CntInit.u16CycleVal = TIMER4_CNT_CYCLE_VAL;
    TIMER4_CNT_Init(&stcTimer4CntInit);

    /* Initialize TIMER4 OCO high&&low channel */
    m_au16OccrVal[0] = (TIMER4_CNT_CYCLE_VAL / 2u);
    m_au16OccrVal[1] = (TIMER4_CNT_CYCLE_VAL / 2u);
    m_au16OccrVal[2] = (TIMER4_CNT_CYCLE_VAL / 2u);
    m_au16OccrVal[3] = (TIMER4_CNT_CYCLE_VAL / 2u);
    TIMER4_OCO_StructInit(&stcTimer4OcoInit);
    stcTimer4OcoInit.enOcoCmd = Enable;
    stcTimer4OcoInit.enOcoIntCmd = Enable;
    stcTimer4OcoInit.u16OccrVal = m_au16OccrVal[0];
    TIMER4_OCO_Init(TIMER4_OCO_UL, &stcTimer4OcoInit);
    TIMER4_OCO_Init(TIMER4_OCO_VL, &stcTimer4OcoInit);
   // if (TIMER4_OCO_LOW_CH % 2ul)
  //  {
        /* OCMR[31:0] 0x0FF0 0FFF = b 0000 1111 1111 0000   0000 1111 1111 1111 */
        stcLowChCmpMode.OCMRx_f.OCFDCL = TIMER4_OCO_OCF_SET;    /* bit[0] 1 */
        stcLowChCmpMode.OCMRx_f.OCFPKL = TIMER4_OCO_OCF_SET;    /* bit[1] 1 */
        stcLowChCmpMode.OCMRx_f.OCFUCL = TIMER4_OCO_OCF_SET;    /* bit[2] 1 */
        stcLowChCmpMode.OCMRx_f.OCFZRL = TIMER4_OCO_OCF_SET;    /* bit[3] 1 */

        stcLowChCmpMode.OCMRx_f.OPDCL = TIMER4_OCO_OP_INVERT;   /* bit[5:4]    11 */
        stcLowChCmpMode.OCMRx_f.OPPKL = TIMER4_OCO_OP_INVERT;   /* bit[7:6]    11 */
        stcLowChCmpMode.OCMRx_f.OPUCL = TIMER4_OCO_OP_INVERT;   /* bit[9:8]    11 */
        stcLowChCmpMode.OCMRx_f.OPZRL = TIMER4_OCO_OP_INVERT;   /* bit[11:10]  11 */
        stcLowChCmpMode.OCMRx_f.OPNPKL = TIMER4_OCO_OP_HOLD;    /* bit[13:12]  00 */
        stcLowChCmpMode.OCMRx_f.OPNZRL = TIMER4_OCO_OP_HOLD;    /* bit[15:14]  00 */
        stcLowChCmpMode.OCMRx_f.EOPNDCL = TIMER4_OCO_OP_HOLD;   /* bit[17:16]  00 */
        stcLowChCmpMode.OCMRx_f.EOPNUCL = TIMER4_OCO_OP_HOLD;   /* bit[19:18]  00 */
        stcLowChCmpMode.OCMRx_f.EOPDCL = TIMER4_OCO_OP_INVERT;  /* bit[21:20]  11 */
        stcLowChCmpMode.OCMRx_f.EOPPKL = TIMER4_OCO_OP_INVERT;  /* bit[23:22]  11 */
        stcLowChCmpMode.OCMRx_f.EOPUCL = TIMER4_OCO_OP_INVERT;  /* bit[25:24]  11 */
        stcLowChCmpMode.OCMRx_f.EOPZRL = TIMER4_OCO_OP_INVERT;  /* bit[27:26]  11 */
        stcLowChCmpMode.OCMRx_f.EOPNPKL = TIMER4_OCO_OP_HOLD;   /* bit[29:28]  00 */
        stcLowChCmpMode.OCMRx_f.EOPNZRL = TIMER4_OCO_OP_HOLD;   /* bit[31:30]  00 */

        stcLowChCmpMode.enExtendMatchCondCmd =Enable; //Disable;//Enable;

        TIMER4_OCO_SetLowChCompareMode(TIMER4_OCO_UL, &stcLowChCmpMode);  /* Set OCO low channel compare mode */
                                TIMER4_OCO_SetLowChCompareMode(TIMER4_OCO_VL, &stcLowChCmpMode);
  //  }

    /* Register IRQ handler && configure NVIC. */
    stcIrqRegiConf.enIRQn = Int013_IRQn;
    stcIrqRegiConf.enIntSrc =TIMER4_OCO_INT_SRC(TIMER4_OCO_UL);
                stcIrqRegiConf.enIntSrc =TIMER4_OCO_INT_SRC(TIMER4_OCO_VL);
    stcIrqRegiConf.pfnCallback = &Timer4OcoMatchIrqCb;
    INTC_IrqRegistration(&stcIrqRegiConf);
    NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);
    NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_03);
    NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);

    /* Initialize PWM I/O */
    GPIO_SetFunc(TIM4_1_OXH_PORT, TIM4_1_OXH_PIN, TIM4_1_OXH_GPIO_FUNC);
    GPIO_SetFunc(TIM4_1_OXL_PORT, TIM4_1_OXL_PIN, TIM4_1_OXL_GPIO_FUNC);
               
    GPIO_SetFunc(TIM4_1_OVH_PORT, TIM4_1_OVH_PIN, TIM4_1_OVH_GPIO_FUNC);
    GPIO_SetFunc(TIM4_1_OVL_PORT, TIM4_1_OVL_PIN, TIM4_1_OVL_GPIO_FUNC);
    /* Timer4 PWM: Get pwm couple channel */
    u32PwmChU = TIMER4_PWM_CH(TIMER4_OCO_UL);
    u32PwmChV = TIMER4_PWM_CH(TIMER4_OCO_VL);
    /* Initialize Timer4 PWM */
    TIMER4_PWM_StructInit(&stcTimer4PwmInit);
    stcTimer4PwmInit.enRtIntMaskCmd = Enable;
    stcTimer4PwmInit.u16ClkDiv = TIMER4_PWM_CLK_DIV1;
    stcTimer4PwmInit.u16Mode = TIMER4_PWM_DEAD_TIMER_FILTER_MODE;
    TIMER4_PWM_Init(u32PwmChU, &stcTimer4PwmInit);
    TIMER4_PWM_SetDeadRegionValue(u32PwmChU, 10u, 10u);
    TIMER4_PWM_SetFilterCountValue(u32PwmChU, (200u));
               
                TIMER4_PWM_StructInit(&stcTimer4PwmInit);
    stcTimer4PwmInit.enRtIntMaskCmd = Enable;
    stcTimer4PwmInit.u16ClkDiv = TIMER4_PWM_CLK_DIV1;
    stcTimer4PwmInit.u16Mode = TIMER4_PWM_DEAD_TIMER_FILTER_MODE;
    TIMER4_PWM_Init(u32PwmChV, &stcTimer4PwmInit);
    TIMER4_PWM_SetDeadRegionValue(u32PwmChV, 10u, 10u);
    TIMER4_PWM_SetFilterCountValue(u32PwmChV, (200u));
               
               

    /* Start TIMER4 counter. */
    TIMER4_CNT_Start();

    while (1)
    {
    }
}

/**
* @}
*/

/**
* @}
*/


此部分内容已被设置为付费内容,您可以在支付 9.9 元 人民币后浏览本楼层全部付费内容点击购买


  

死区可调.jpg (236.74 KB )

死区可调pwm

死区可调pwm

pwm波形2.jpg (268.61 KB )

互补2路4通道pwm

互补2路4通道pwm

使用特权

评论回复
沙发
mao13226675618|  楼主 | 2021-8-20 22:38 | 只看该作者
本帖最后由 mao13226675618 于 2021-8-26 20:38 编辑

波形运行稳定,开始信赖华大了,支撑国产技术发展壮大!

使用特权

评论回复
板凳
mao13226675618|  楼主 | 2021-8-21 08:12 | 只看该作者
本帖最后由 mao13226675618 于 2021-8-26 20:40 编辑

感觉比st更方便了,哈哈哈

使用特权

评论回复
地板
mao13226675618|  楼主 | 2021-8-23 06:57 | 只看该作者
本帖最后由 mao13226675618 于 2021-8-26 20:39 编辑

支持华大做强做大

使用特权

评论回复
5
tpgf| | 2021-9-10 17:57 | 只看该作者
死区的范围是多少啊

使用特权

评论回复
评论
martinhu 2021-9-14 13:56 回复TA
如果是死区定时器模式,好像是16bit的寄存器。 
6
martinhu| | 2021-9-14 13:59 | 只看该作者
这里的输出比较匹配电平逻辑设定,用翻转虽然也能出想要的波形,
但是在有些情况下可能会出错。
最好使用输出高或者输出低电平的设定。不过逻辑得重新整理。

使用特权

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

本版积分规则

1

主题

4

帖子

0

粉丝