OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 952|回复: 3

STM32G474三通道PWM互补输出,TIM1_CH3N无互补波形问题

[复制链接]

3

主题

8

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2020-8-3
在线时间
7 小时
发表于 2024-3-4 00:22:16 | 显示全部楼层 |阅读模式
12金钱
求助大佬帮忙看看,6组PWM只有PB15的TIM1_CH3N互补波形没输出
PWM c文件如下

TIM_HandleTypeDef g_atimx_cplm_pwm_handle;                              /* 定时器x句柄 */

/**
* @brief       高级定时器TIMX 互补输出 初始化函数(使用PWM模式1)
* @note
*              配置高级定时器TIMX 互补输出, 一路OCy 一路OCyN, 并且可以设置死区时间
*
*              高级定时器的时钟来自APB2, 而PCLK2 = 170Mhz, 我们设置PPRE2不分频, 因此
*              高级定时器时钟 = 170Mhz
*              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
*              Ft=定时器工作频率, 单位 : Mhz
*
* @param       arr: 自动重装值
* @param       psc: 时钟预分频数
* @retval      无
*/

void atim_timx_cplm_pwm_init(uint16_t arr, uint16_t psc)
{
    TIM_OC_InitTypeDef tim_oc_cplm_pwm = {0};
    TIM_BreakDeadTimeConfigTypeDef sbreak_dead_time_config = {0};

    g_atimx_cplm_pwm_handle.Instance = ATIM_TIMX_CPLM;                                  /* 定时器x */
    g_atimx_cplm_pwm_handle.Init.Prescaler = psc;                                       /* 定时器预分频系数 */
    g_atimx_cplm_pwm_handle.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;          /* 向上计数模式 */
    g_atimx_cplm_pwm_handle.Init.Period = arr;                                          /* 自动重装载值 */
    g_atimx_cplm_pwm_handle.Init.RepetitionCounter = 0;                                 /* 重复计数器寄存器为0 */
    g_atimx_cplm_pwm_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;     /* 使能影子寄存器TIMx_ARR */
    HAL_TIM_PWM_Init(&g_atimx_cplm_pwm_handle) ;

    /* 设置PWM输出 */
    tim_oc_cplm_pwm.OCMode = TIM_OCMODE_PWM1;                                           /* PWM模式1 */
    tim_oc_cplm_pwm.Pulse = 0;                                                          /* 比较值为0 */
    tim_oc_cplm_pwm.OCPolarity = TIM_OCPOLARITY_LOW;                                    /* OCy 低电平有效 */
    tim_oc_cplm_pwm.OCNPolarity = TIM_OCNPOLARITY_LOW;                                  /* OCyN 低电平有效 */
    tim_oc_cplm_pwm.OCFastMode = TIM_OCFAST_ENABLE;                                     /* 使用快速模式 */
    tim_oc_cplm_pwm.OCIdleState = TIM_OCIDLESTATE_RESET;                                /* 主通道的空闲状态 */
    tim_oc_cplm_pwm.OCNIdleState = TIM_OCNIDLESTATE_RESET;                              /* 互补通道的空闲状态 */
    HAL_TIM_PWM_ConfigChannel(&g_atimx_cplm_pwm_handle, &tim_oc_cplm_pwm, TIM_CHANNEL_1);    /* 配置后默认清CCER的互补输出位 */   

最佳答案

查看完整内容[请看2#楼]

已解决,GPIO_PIN_15端口复用应配成GPIO_AF4_TIM1
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

8

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2020-8-3
在线时间
7 小时
 楼主| 发表于 2024-3-4 00:22:17 | 显示全部楼层
已解决,GPIO_PIN_15端口复用应配成GPIO_AF4_TIM1
回复

使用道具 举报

3

主题

8

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2020-8-3
在线时间
7 小时
 楼主| 发表于 2024-3-4 00:24:50 | 显示全部楼层
PWM c文件如下
IM_HandleTypeDef g_atimx_cplm_pwm_handle;                              /* 定时器x句柄 */


void atim_timx_cplm_pwm_init(uint16_t arr, uint16_t psc)
{
    TIM_OC_InitTypeDef tim_oc_cplm_pwm = {0};
    TIM_BreakDeadTimeConfigTypeDef sbreak_dead_time_config = {0};

    g_atimx_cplm_pwm_handle.Instance = ATIM_TIMX_CPLM;                                  /* 定时器x */
    g_atimx_cplm_pwm_handle.Init.Prescaler = psc;                                       /* 定时器预分频系数 */
    g_atimx_cplm_pwm_handle.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;          /* 向上计数模式 */
    g_atimx_cplm_pwm_handle.Init.Period = arr;                                          /* 自动重装载值 */
    g_atimx_cplm_pwm_handle.Init.RepetitionCounter = 0;                                 /* 重复计数器寄存器为0 */
    g_atimx_cplm_pwm_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;     /* 使能影子寄存器TIMx_ARR */
    HAL_TIM_PWM_Init(&g_atimx_cplm_pwm_handle) ;

    /* 设置PWM输出 */
    tim_oc_cplm_pwm.OCMode = TIM_OCMODE_PWM1;                                           /* PWM模式1 */
    tim_oc_cplm_pwm.Pulse = 0;                                                          /* 比较值为0 */
    tim_oc_cplm_pwm.OCPolarity = TIM_OCPOLARITY_LOW;                                    /* OCy 低电平有效 */
    tim_oc_cplm_pwm.OCNPolarity = TIM_OCNPOLARITY_LOW;                                  /* OCyN 低电平有效 */
    tim_oc_cplm_pwm.OCFastMode = TIM_OCFAST_ENABLE;                                     /* 使用快速模式 */
    tim_oc_cplm_pwm.OCIdleState = TIM_OCIDLESTATE_RESET;                                /* 主通道的空闲状态 */
    tim_oc_cplm_pwm.OCNIdleState = TIM_OCNIDLESTATE_RESET;                              /* 互补通道的空闲状态 */
    HAL_TIM_PWM_ConfigChannel(&g_atimx_cplm_pwm_handle, &tim_oc_cplm_pwm, TIM_CHANNEL_1);    /* 配置后默认清CCER的互补输出位 */   
                HAL_TIM_PWM_ConfigChannel(&g_atimx_cplm_pwm_handle, &tim_oc_cplm_pwm, TIM_CHANNEL_2);
                HAL_TIM_PWM_ConfigChannel(&g_atimx_cplm_pwm_handle, &tim_oc_cplm_pwm, TIM_CHANNEL_3);
               
    /* 设置死区参数,开启死区中断 */
    sbreak_dead_time_config.OffStateRunMode = TIM_OSSR_ENABLE;                          /* OSSR设置为1 */
    sbreak_dead_time_config.OffStateIDLEMode = TIM_OSSI_DISABLE;                        /* OSSI设置为0 */
    sbreak_dead_time_config.LockLevel = TIM_LOCKLEVEL_OFF;                              /* 上电只能写一次,需要更新死区时间时只能用此值 */
    sbreak_dead_time_config.DeadTime = 0X04;                                            /* 死区时间 */
    sbreak_dead_time_config.BreakState = TIM_BREAK_DISABLE;                             /* BKE = 0, 关闭BKIN检测 */
    sbreak_dead_time_config.BreakPolarity = TIM_BREAKPOLARITY_LOW;                      /* BKP = 1, BKIN低电平有效 */
    sbreak_dead_time_config.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;              /* 使能AOE位,允许刹车后自动恢复输出 */
    HAL_TIMEx_ConfigBreakDeadTime(&g_atimx_cplm_pwm_handle, &sbreak_dead_time_config);  /* 设置BDTR寄存器 */
               
                HAL_TIM_PWM_Start(&g_atimx_cplm_pwm_handle, TIM_CHANNEL_1);     /* 开启主通道输出 */
                HAL_TIMEx_PWMN_Start(&g_atimx_cplm_pwm_handle, TIM_CHANNEL_1);  /* 开启互补通道输出 */
                 __HAL_TIM_SetCompare(&g_atimx_cplm_pwm_handle, TIM_CHANNEL_1, 1000);
                 
                HAL_TIM_PWM_Start(&g_atimx_cplm_pwm_handle, TIM_CHANNEL_2);     /* 开启主通道输出 */
                HAL_TIMEx_PWMN_Start(&g_atimx_cplm_pwm_handle, TIM_CHANNEL_2);  /* 开启互补通道输出 */
                 __HAL_TIM_SetCompare(&g_atimx_cplm_pwm_handle, TIM_CHANNEL_2, 3000);

                HAL_TIM_PWM_Start(&g_atimx_cplm_pwm_handle, TIM_CHANNEL_3);     /* 开启主通道输出 */
                HAL_TIMEx_PWMN_Start(&g_atimx_cplm_pwm_handle, TIM_CHANNEL_3);  /* 开启互补通道输出 */
                 __HAL_TIM_SetCompare(&g_atimx_cplm_pwm_handle, TIM_CHANNEL_3, 2000);


}

/**
* @brief       定时器底层驱动,时钟使能,引脚配置
                此函数会被HAL_TIM_PWM_Init()调用
* @param       htim:定时器句柄
* @retval      无
*/
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == ATIM_TIMX_CPLM)
    {
        GPIO_InitTypeDef gpio_init_struct;
        
        ATIM_TIMX_CPLM_CHY_GPIO_CLK_ENABLE();                                   /* 通道y对应IO口时钟使能 */
        ATIM_TIMX_CPLM_CHYN_GPIO_CLK_ENABLE();                                  /* 互补通道对应IO口时钟使能 */
        ATIM_TIMX_CPLM_CLK_ENABLE();                                            /* 定时器x时钟使能 */

        /* 配置PWM主通道引脚 */
        gpio_init_struct.Pin = ATIM_TIMX_CPLM_CHY_GPIO_PIN|ATIM_TIMX_CPLM_CHY_GPIO_PIN_B|GPIO_PIN_10;
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;
        gpio_init_struct.Pull = GPIO_NOPULL;
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH ;
        gpio_init_struct.Alternate = ATIM_TIMX_CPLM_CHY_GPIO_AF;                /* 端口复用 */
        HAL_GPIO_Init(ATIM_TIMX_CPLM_CHY_GPIO_PORT, &gpio_init_struct);

        /* 配置PWM互补通道引脚 */
        gpio_init_struct.Pin = ATIM_TIMX_CPLM_CHYN_GPIO_PIN|ATIM_TIMX_CPLM_CHYN_GPIO_PIN_B|GPIO_PIN_15;
        HAL_GPIO_Init(ATIM_TIMX_CPLM_CHYN_GPIO_PORT, &gpio_init_struct);
    }
}
回复

使用道具 举报

3

主题

8

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2020-8-3
在线时间
7 小时
 楼主| 发表于 2024-3-4 00:25:26 | 显示全部楼层
h文件如下
/* TIMX 互补输出模式 定义 */

/* 主输出通道引脚 */
#define ATIM_TIMX_CPLM_CHY_GPIO_PORT            GPIOA
#define ATIM_TIMX_CPLM_CHY_GPIO_PIN             GPIO_PIN_8
#define ATIM_TIMX_CPLM_CHY_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PA口时钟使能 */

/* 互补输出通道引脚 */
#define ATIM_TIMX_CPLM_CHYN_GPIO_PORT           GPIOB
#define ATIM_TIMX_CPLM_CHYN_GPIO_PIN            GPIO_PIN_13
#define ATIM_TIMX_CPLM_CHYN_GPIO_CLK_ENABLE()   do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)   /* PB口时钟使能 */


/* 主输出B通道引脚 */
#define ATIM_TIMX_CPLM_CHY_GPIO_PORT_B            GPIOA
#define ATIM_TIMX_CPLM_CHY_GPIO_PIN_B             GPIO_PIN_9
#define ATIM_TIMX_CPLM_CHY_GPIO_CLK_ENABLE_B()    do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PA口时钟使能 */

/* 互补输出通道B引脚 */
#define ATIM_TIMX_CPLM_CHYN_GPIO_PORT_B           GPIOB
#define ATIM_TIMX_CPLM_CHYN_GPIO_PIN_B            GPIO_PIN_14
#define ATIM_TIMX_CPLM_CHYN_GPIO_CLK_ENABLE_B()   do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)   /* PB口时钟使能 */



/* 主输出C通道引脚 */
#define ATIM_TIMX_CPLM_CHY_GPIO_PORT_C            GPIOA
#define ATIM_TIMX_CPLM_CHY_GPIO_PIN_C             GPIO_PIN_10
#define ATIM_TIMX_CPLM_CHY_GPIO_CLK_ENABLE_C()    do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PA口时钟使能 */

/* 互补输出通道C引脚 */
#define ATIM_TIMX_CPLM_CHYN_GPIO_PORT_C           GPIOB
#define ATIM_TIMX_CPLM_CHYN_GPIO_PIN_C            GPIO_PIN_15
#define ATIM_TIMX_CPLM_CHYN_GPIO_CLK_ENABLE_C()   do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)   /* PB口时钟使能 */

/* TIMX 引脚复用设置
* 因为PA8/PB13, 默认并不是TIM1的功能脚, 必须开启复用,PA8/PB13才能用作TIM1的功能
*/
#define ATIM_TIMX_CPLM_CHY_GPIO_AF              GPIO_AF6_TIM1

/* 互补输出使用的定时器 */
#define ATIM_TIMX_CPLM                          TIM1
#define ATIM_TIMX_CPLM_CHY                      TIM_CHANNEL_1
#define ATIM_TIMX_CPLM_CLK_ENABLE()             do{ __HAL_RCC_TIM1_CLK_ENABLE(); }while(0)    /* TIM1 时钟使能 */

/******************************************************************************************/

void atim_timx_cplm_pwm_init(uint16_t arr, uint16_t psc);   /* 高级定时器 互补输出 初始化函数 */

#endif
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 21:22

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表