全部文档
概述 硬件支持 快速开发指南 内核 驱动 通用组件 专业组件 常见问题

PWM设备用户开发


基础BSP配置--以STM32为例

工程及使用说明

如果在提供的OneOS源码中已经有适合的工程DEMO工程,则可以直接使用;如果没有请参照快速上手中的操作指南,新建一个合适的工程。 STM32的PWM硬件接口依赖于定时器实现,在配置时需要配置好定时器的PWM功能。定时器配置为PWM功能后,不再支持通用定时器功能。

使用STM32CubeMX配置硬件

  1. 打开oneos\projects\xxxxx(project文件夹)\board\CubeMX_Config下的CUBE工程文件;

  2. 在CUBE工程中进行PWM配置,如下图所示: pwm_cube

配置和生成工程

  1. 点击Clock Configuration检查时钟配置,然后点击GENARATE CODE生成STM32CubeMX工程代码;
  2. 在对应的oneos\projects\xxxxx(project文件夹)目录下打开OneOS-Cube工具,在命令行输入menuconfig打开可视化配置界面;
  3. 如下图示,通过空格或向右方向键选择(Top) → Drivers→ MISC下的Using PWM device drivers选项;
    (Top) → Drivers→ MISC
                                       OneOS Configuration
    [*] Using push button device drivers
    [*] Using led device drivers
    [ ] Using buzzer device drivers
    [ ] Using ADC device drivers
    [ ] Using DAC device drivers
    [*] Using PWM device drivers
    [ ] Using input capture device drivers
    [*] Using pulse encoder device drivers
    
  4. 通过Esc退出配置界面,退出时选择保存。
  5. 在命令行输入scons --ide=mdk5构建工程;

工程编译及实现

  1. 打开对应的oneos\projects\xxxxx(project文件夹) 目录下的project.uvprojx工程文件;
  2. 在工程中将原有或自己编写的pwm_test文件加入到application子文件夹中;
  3. 编译并下载工程,运行程序;
  4. 打开串口工具如xshell等,通信成功后,即可通过输入pwm_sample pwm0 0 10000000 5000000 19的测试指令;
  5. 如果将PWM通道对应引脚和使能中断触发的对应引脚pin 19相连,可以看到pin 19被pwm的变化触发中断,10000ms(毫秒)后停止触发;其他情况可以通过示波器观察。

PWM设备


API列表

函数 说明
os_device_find() 查找PWM设备
os_device_control() 控制PWM设备,可以设置周期、脉冲宽度、开关设备

os_device_find

该函数根据PWM设备名查找对应的PWM设备设备,函数原型如下:

os_device_t *os_device_find(const char *name);
参数 说明
name 设备名称
返回 说明
设备指针 查找到对应设备将返回相应的设备指针
OS_NULL 没有找到设备

os_device_control

该函数用于控制PWM设备参数,函数原型如下:

os_err_t os_device_control(os_device_t *dev, int cmd, void *arg);
参数 说明
dev 设备指针
cmd 命令控制字
arg 控制的参数
返回 说明
OS_EOK 函数执行成功
其他错误码 失败

脉冲编码器支持的命令控制字如下所示:

控制字 说明
OS_PWM_CMD_ENABLE 启动PWM设备
OS_PWM_CMD_DISABLE 停止PWM设备
OS_PWM_CMD_SET_PERIOD 设置PWM周期
OS_PWM_CMD_SET_PULSE 设置PWM脉冲宽度

注意事项

  1. PWM的输出频率由周期时间period决定,例如周期时间为0.5ms(毫秒),则period值为500000ns(纳秒),输出频率为2KHz,占空比为pulse/period(注意定时器频率带来的误差),pulse值不能超过period。
  2. pulse和period设置独立,如STM32的PWM设备在设置period时不需要通道信息,则通道信息直接给0;
  3. period设置具有特殊性,如STM32的PWM设备设置period将改变多个通道,因此在修改周期时将把所有的通道进行自动停止,重新设定确认无误后,请调用指令打开。

使用示例

PWM设备使用示例

PWM设备的具体使用方式可以参考如下示例代码,示例代码的主要步骤如下:

  1. 使能指定引脚的中断
  2. 查找PWM设备获取设备指针。
  3. 设置PWM周期和脉冲宽度。
  4. 使能PWM设备。
  5. 如果将PWM通道对应引脚和使能中断触发的对应引脚pin 19相连,可以看到pin 19被pwm的变化触发中断;其他情况可以通过示波器观察。
  6. 10000ms(毫秒)后关闭pwm设备。
#include <drv_cfg.h>
#include <device.h>
#include <os_clock.h>
#include <os_memory.h>
#include <stdlib.h>
#include <shell.h>
#include <timer/clocksource.h>

static void pwm_pin_callback(void *args)
{
    int pin = (int)(unsigned long)args;

    os_kprintf("<%d>   <%d>----------------------pin:%d value:%d\r\n", (int)os_tick_get(), (int)(os_clocksource_gettime() & 0x7fffffff), pin,  os_pin_read(pin));
}

int pwm_sample(int argc, char **argv)
{
    os_uint32_t pin;

    char *dev_name;

    os_device_t *pwm_dev = OS_NULL;

    struct os_pwm_configuration *config;

    config = os_calloc(1, sizeof(struct os_pwm_configuration));
    if (argc < 3)
    {
        os_kprintf("usage: pwm_sample <dev> <channel> [period(ns)] [duty(ns) def 1000000] [pin]\r\n");
        os_kprintf("       pwm_sample pwm_tim1 1 default: 5000000, 1000000\r\n");
        os_kprintf("       pwm_sample pwm_tim1 1 5000000 1000000 0x3e\r\n");
        os_kprintf("       pwm_sample pwm_tim1 1 1000000000 1000000000 0x3e\r\n");
        os_kprintf("       pwm_sample pwm_tim1 1 1000000000 0 0x3e\r\n");
        return -1;
    }

    dev_name = argv[1];
    config->channel  = strtol(argv[2], OS_NULL, 0);

    if (argc > 3)
    {
        config->period = strtol(argv[3], OS_NULL, 0);
    }

    if (argc > 4)
    {
        config->pulse = strtol(argv[4], OS_NULL, 0);
    }

    if (argc > 5)
    {
        pin = strtol(argv[5], OS_NULL, 0);

        os_pin_mode(pin, PIN_MODE_INPUT_PULLUP);
        os_pin_attach_irq(pin, PIN_IRQ_MODE_RISING_FALLING, pwm_pin_callback, (void *)pin);
        os_pin_irq_enable(pin, PIN_IRQ_ENABLE);
    }

    pwm_dev = os_device_find(dev_name);
    if (pwm_dev == OS_NULL)
    {
        os_kprintf("pwm sample run failed! can't find %s device!\r\n", dev_name);
        return OS_ERROR;
    }

    os_device_control(pwm_dev, OS_PWM_CMD_SET_PERIOD, config);

    os_device_control(pwm_dev, OS_PWM_CMD_SET_PULSE, config);

    os_device_control(pwm_dev, OS_PWM_CMD_ENABLE, config);

    os_task_msleep(10000);

    os_device_control(pwm_dev, OS_PWM_CMD_DISABLE, config);

    return 0;
}

SH_CMD_EXPORT(pwm_sample, pwm_sample, "test_pwm_sample!");

运行结果如下:

sh />pwm_sample pwm0 0 10000000 5000000 19
<2810> <182712576>----------------------pin:19 value:0
<2860> <682712576>----------------------pin:19 value:1
<3510> <740261632>----------------------pin:19 value:0
<3560> <1240261632>----------------------pin:19 value:1
<4210> <1297810688>----------------------pin:19 value:0

results matching ""

    No results matching ""