首页 > 其他分享 >rt-thread 中pwm组件不起作用的问题 stm32L431

rt-thread 中pwm组件不起作用的问题 stm32L431

时间:2023-01-08 23:12:46浏览次数:42  
标签:rt PWM stm32L431 thread tim TIM device pwm config

board.h中打开如下定义,并新增要使用的通道

#define BSP_USING_PWM1
/*#define BSP_USING_PWM2*/
/*#define BSP_USING_PWM3*/
#define BSP_USING_PWM1_CH1

drv_pwm.c中的函数 static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device)

多了一个初始化操作HAL_TIM_Base_Init(tim),这个是多余的,需要删除,然后就正常了

但是使用tim16时就又需要这个初始化,因此需要根据cubemx初始化代码灵活调整

static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device)
{
    rt_err_t result = RT_EOK;
    TIM_HandleTypeDef *tim = RT_NULL;
    TIM_OC_InitTypeDef oc_config = {0};
    TIM_MasterConfigTypeDef master_config = {0};
    TIM_ClockConfigTypeDef clock_config = {0};

    RT_ASSERT(device != RT_NULL);

    tim = (TIM_HandleTypeDef *)&device->tim_handle;

    /* configure the timer to pwm mode */
    tim->Init.Prescaler = 0;
    tim->Init.CounterMode = TIM_COUNTERMODE_UP;
    tim->Init.Period = 0;
    tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4)
    tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    tim->Init.RepetitionCounter = 0;
#endif

//    if (HAL_TIM_Base_Init(tim) != HAL_OK)
//    {
//        LOG_E("%s pwm base init failed", device->name);
//        result = -RT_ERROR;
//        goto __exit;
//    }
    if (HAL_TIM_PWM_Init(tim) != HAL_OK)
    {
        LOG_E("%s pwm init failed", device->name);
        result = -RT_ERROR;
        goto __exit;
    }

    clock_config.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    if (HAL_TIM_ConfigClockSource(tim, &clock_config) != HAL_OK)
    {
        LOG_E("%s clock init failed", device->name);
        result = -RT_ERROR;
        goto __exit;
    }

    master_config.MasterOutputTrigger = TIM_TRGO_RESET;
    master_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(tim, &master_config) != HAL_OK)
    {
        LOG_E("%s master config failed", device->name);
        result = -RT_ERROR;
        goto __exit;
    }

    oc_config.OCMode = TIM_OCMODE_PWM1;
    oc_config.Pulse = 0;
    oc_config.OCPolarity = TIM_OCPOLARITY_HIGH;
    oc_config.OCNPolarity = TIM_OCNPOLARITY_HIGH;
    oc_config.OCFastMode = TIM_OCFAST_DISABLE;
    oc_config.OCNIdleState = TIM_OCNIDLESTATE_RESET;
    oc_config.OCIdleState  = TIM_OCIDLESTATE_RESET;

    /* config pwm channel */
    if (device->channel & 0x01)
    {
        if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_1) != HAL_OK)
        {
            LOG_E("%s channel1 config failed", device->name);
            result = -RT_ERROR;
            goto __exit;
        }
    }

    if (device->channel & 0x02)
    {
        if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_2) != HAL_OK)
        {
            LOG_E("%s channel2 config failed", device->name);
            result = -RT_ERROR;
            goto __exit;
        }
    }

    if (device->channel & 0x04)
    {
        if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_3) != HAL_OK)
        {
            LOG_E("%s channel3 config failed", device->name);
            result = -RT_ERROR;
            goto __exit;
        }
    }

    if (device->channel & 0x08)
    {
        if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_4) != HAL_OK)
        {
            LOG_E("%s channel4 config failed", device->name);
            result = -RT_ERROR;
            goto __exit;
        }
    }

    /* pwm pin configuration */
    HAL_TIM_MspPostInit(tim);

    /* enable update request source */
    __HAL_TIM_URS_ENABLE(tim);

__exit:
    return result;
}

 

使用方式如下

#define PWM_DEV_NAME "pwm1" /* PWM设备名称*/
#define PWM_DEV_CHANNEL 1 /* PWM通道*/
struct rt_device_pwm *pwm_dev; /* PWM设备句柄*/
static int pwm_test(int argc, char *argv[])
{
    rt_uint32_t freq, duty;
    if (argc < 2)
    {
        LOG_E("Usage:pwm_test [freq] [duty]");
        return RT_ERROR;
    }
    freq = 1000000000 / atoi(argv[1]); /* 频率 */
    duty = atoi(argv[2]) * freq / 100; /* PWM脉冲宽度值, 单位为纳秒ns */
    /* 查找设备*/
    pwm_dev = (struct rt_device_pwm *) rt_device_find(PWM_DEV_NAME);
    if (pwm_dev == RT_NULL)
    {
        LOG_E("can't find %s device!", PWM_DEV_NAME);
        return RT_ERROR;
    }
    else
    {
        LOG_I("find %s device!", PWM_DEV_NAME);
    }
    /* 设置PWM周期和脉冲宽度默认值*/
    LOG_I("set %s ,freq=%d,duty=%d", PWM_DEV_NAME, freq, duty);
    rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, freq, duty);
    /* 使能设备*/
    LOG_I("enable %s device", PWM_DEV_NAME);
    rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);
//    delay(1000);
//    /* 关闭设备*/
//    LOG_I("disable %s device", PWM_DEV_NAME);
//    rt_pwm_disable(pwm_dev, PWM_DEV_CHANNEL);
    return RT_EOK;
}
/* 导出到msh 命令列表中*/
MSH_CMD_EXPORT_ALIAS(pwm_test, pwm, pwm_test);

 

标签:rt,PWM,stm32L431,thread,tim,TIM,device,pwm,config
From: https://www.cnblogs.com/arthurly/p/17035672.html

相关文章