PWM调整占空比失败

Viewed 62

一、描述你遇到的问题

在例程的基础上修改了一下,调用uapi_pwm_update_duty_ratio接口调整通道的占空比,没有任何反应。实际上SDK里的uapi_gpio_set_val、uapi_pwm_start、uapi_pwm_get_frequency、uapi_pwm_stop等接口都有这样的毛病,不过都能用相应方法实现同一功能,我也就不提了,占空比修改不了还是很致命的,我试图用:

uapi_pwm_stop_group(channel);
  if(duty == 0)
  {
      //不支持占空比为0,所以在此加个判断,直接把通道关闭掉后就不再做任何处理。
      return;
  }
  uapi_pwm_close(channel);
  uapi_pwm_clear_group(channel);
  uapi_pwm_unregister_interrupt(channel);
  pwm_config_t cfg_no_repeat = {
        TOTAL_TIME / 100 * (100 - duty),//低电平
        TOTAL_TIME / 100 * duty,//高电平。之所以先除再乘是因为防止数据溢出
        0,
        0,
        true
    };
    /* 设置可作为PWM IO的模式 */ 
    uapi_pin_set_mode(pin, PWM_PIN_MODE);
    uapi_pwm_deinit();
    uapi_pwm_init();
    /* 打开指定chanel的PWM */
    uapi_pwm_open(channel, &cfg_no_repeat);
    /* 注册回调函数 */ 
    uapi_pwm_unregister_interrupt(channel);
    uapi_pwm_register_interrupt(channel, pwm_sample_callback);
    /* 每个通道单独一组,分别指定 */
    uint8_t channel_id[1] = {channel};
    uapi_pwm_set_group(channel, channel_id, 1);

的方式重新初始化PWM,实现同样的功能,但是还是不行,所以想问一下怎么回事。是调用uapi_pwm_update_duty_ratio接口前要先关闭通道等做些更多操作吗?

二、你具体做的所有步骤结果截图

三、当前开发板状态全景照片

四、开发板串口所有日志

调用uapi_pwm_update_duty_ratio接口的实现方式中串口基本没输出什么东西,而如果用重新初始化的方法,日志是这样的:

1 Answers

虽然这个接口该不能用还是不能用,但是也可以用其他方法来实现同样的功能:先关闭通道,再用不同的参数打开,再重新开启分组。

/**

  • Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
  • Description: PWM Sample Source. \n
  • History: \n
  • 2023-06-27, Create file. \n
    */
    #include "pinctrl.h"
    #include "pwm.h"
    #include "osal_debug.h"
    #include "cmsis_os2.h"
    #include "app_init.h"
    #include "tcxo.h"

#define PWM_GPIO 2
#define PWM_PIN_MODE 1
#define PWM_CHANNEL 2
#define PWM_GROUP_ID 0
#define TEST_MAX_TIMES 5
#define DALAY_MS 100
#define TEST_TCXO_DELAY_1000MS 1000
#define PWM_TASK_STACK_SIZE 0x1000
#define PWM_TASK_PRIO (osPriority_t)(17)

static errcode_t pwm_sample_callback(uint8_t channel)
{
osal_printk("PWM %d, cycle done. \r\n", channel);
return ERRCODE_SUCC;
}

#define TOTAL_TIME 5000//为保证是同一频率而定义整体时间

static void *pwm_task(const char *arg)
{
UNUSED(arg);
pwm_config_t cfg_no_repeat = {
2500, //低电平
2500, //高电平
0,
0,
true
};

uapi_pin_set_mode(PWM_GPIO, PWM_PIN_MODE);
uapi_pwm_deinit();
uapi_pwm_init();
uapi_pwm_open(PWM_CHANNEL, &cfg_no_repeat);

uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS);
uapi_pwm_unregister_interrupt(PWM_CHANNEL);
uapi_pwm_register_interrupt(PWM_CHANNEL, pwm_sample_callback);

uint8_t channel_id = PWM_CHANNEL;
/* channel_id can also choose to configure multiple channels, and the third parameter also needs to be adjusted
    accordingly. */
uapi_pwm_set_group(PWM_GROUP_ID, &channel_id, 1);
/* Here you can also call the uapi_pwm_start interface to open each channel individually. */
uapi_pwm_start_group(PWM_GROUP_ID);

uint8_t duty = 55;
uint8_t flag = 1;
osal_printk("PWM start\r\n");
uapi_tcxo_delay_ms(5000);
while(1)
{
    uapi_pwm_close(PWM_GROUP_ID);
    if(flag)
    {
        duty += 5;
    }
    else
    {
        duty -= 5;
    }
    if(duty == 5)
    {
        flag = 1;
    }
    else if(duty == 95)
    {
        flag = 0;
    }
    osal_printk("now duty:%d\r\n", duty);
    cfg_no_repeat.low_time = TOTAL_TIME / 100 * (100 - duty);
    cfg_no_repeat.high_time = TOTAL_TIME / 100 * duty;
    uapi_pwm_open(PWM_CHANNEL, &cfg_no_repeat);
    uapi_pwm_start_group(PWM_GROUP_ID);
    uapi_tcxo_delay_ms(1000);
}
uapi_pwm_close(PWM_GROUP_ID);
uapi_pwm_deinit();
return NULL;

}

static void pwm_entry(void)
{
osThreadAttr_t attr;

attr.name = "PWMTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = PWM_TASK_STACK_SIZE;
attr.priority = PWM_TASK_PRIO;

if (osThreadNew((osThreadFunc_t)pwm_task, NULL, &attr) == NULL) {
    /* Create task fail. */
}

}

/* Run the pwm_entry. */
app_run(pwm_entry);
目前还有一个问题就是输出时间稍微长一点单片机就崩溃了,然后重启,不知道怎么搞的