RT-Thread系列07——PWM设备

文章目录

  • 1. PWM测试
  • 2. 配置分析

====>>> 文章汇总(有代码汇总) <<<====

目标:使用PWM实现呼吸灯。

  • RT-Thread studio,版本: 2.2.6,不一样其实区别也不大
  • RT-Thread:标准版,4.0.3版本
  • 芯片包版本:0.1.9
  • 开发板:正点原子战舰开发板,主控STM32F103ZET6。

1. PWM测试

第一步:在 RT-Thread Settings 中 -> 组件 -> 设备驱动程序 -> 使用 PWM 设备驱动程序,勾选上。
在这里插入图片描述

第二步:在board.h中打开#define BSP_USING_PWM3宏定义,并添加使用的通道宏定义#define BSP_USING_PWM3_CH2

这里测试使用的引脚为PB5(TIM3的通道2)。根据自己使用的定时器和通道进行修改上述宏定义。
注意:通道宏定义board.h默认里面没写,要自己添加上。

RT-Thread系列07——PWM设备_第1张图片
第三步:从左侧窗口打开cubemx,勾选上TIM3的CH2,选择PWM输出模式,确认一下引脚是不是对的,参数配置可以不用管,然后关闭cubemx界面,生成代码后刷新左侧目录界面。即可在cubemx文件夹中的stm32f1xx_hal_msp.c文件中看到TIM的引脚初始化代码,一共有两个函数。

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)

第四步:修改drv_pwm.c

drv_pwm.c文件中的static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device)函数中,添加定时器的初始化。
RT-Thread系列07——PWM设备_第2张图片
添加之后如下:

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;
#endif

    // 以下是自己添加的
    // 注意这里是定时器的初始化 别看混了!!!
    if (HAL_TIM_Base_Init(tim) != HAL_OK)
    {
        LOG_E("%s tim 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;
    }
    ...
}

第五步:添加测试例程

/*
 * 程序清单:这是一个 PWM 设备使用例程
 * 例程导出了 pwm_thread_test 命令到控制终端
 * 命令调用格式:pwm_thread_test
 * 程序功能:通过 PWM 设备控制 LED 灯的亮度,可以看到LED不停的由暗变到亮,然后又从亮变到暗。
*/

#include 
#include 

#define PWM_DEV_NAME        "pwm3"  /* PWM设备名称 */
#define PWM_DEV_CHANNEL     2       /* PWM通道 */

struct rt_device_pwm *pwm_dev;      /* PWM设备句柄 */

static rt_thread_t pwm_thread = NULL;

// 线程相关参数
#define THREAD_PRIORITY         25
#define THREAD_STACK_SIZE       512
#define THREAD_TIMESLICE        5

static void pwm_led_thread_entry(void *parameter)
{
    rt_uint32_t period, pulse, dir;

    period = 500000;    /* 周期为0.5ms,单位为纳秒ns */
    dir = 1;            /* PWM脉冲宽度值的增减方向 */
    pulse = 0;          /* PWM脉冲宽度值,单位为纳秒ns */

    /* 查找设备 */
    pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME);
    if (pwm_dev == RT_NULL)
    {
        rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME);
    }

    /* 设置PWM周期和脉冲宽度默认值 */
    rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
    /* 使能设备 */
    rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);

    while (1)
    {
        rt_thread_mdelay(50);
        if (dir)
        {
            pulse += 5000;      /* 从0值开始每次增加5000ns */
        }
        else
        {
            pulse -= 5000;      /* 从最大值开始每次减少5000ns */
        }
        if (pulse >= period)
        {
            dir = 0;
        }
        if (0 == pulse)
        {
            dir = 1;
        }

        /* 设置PWM周期和脉冲宽度 */
        rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
    }
}


static int pwm_thread_test(void)
{
    pwm_thread = rt_thread_create("pwm_th",                        // name
                                    pwm_led_thread_entry,           // 函数体入口
                                    RT_NULL,                        // 函数体 参数
                                    THREAD_STACK_SIZE,              // 分配内存大小
                                    THREAD_PRIORITY,                // 优先级
                                    THREAD_TIMESLICE);              // 时间片大小
    /* 如果获得线程控制块,启动这个线程 */
    if (pwm_thread != RT_NULL)
        rt_thread_startup(pwm_thread);    // 启动线程
    else
    {
        // 输出错误码
        rt_kprintf("pwm led thread is failed...the error code is %ld \r\n", pwm_thread->error);
    }

    return RT_EOK;
}

/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(pwm_thread_test, pwm thread test);

2. 配置分析

这里简单分析一下,定义这两个东西之后都改变了什么东西。

#define BSP_USING_PWM3
#define BSP_USING_PWM3_CH2

第一个:声明了BSP_USING_PWM3之后,在drivers 文件夹中,会打开如下内容的声明。即声明了PWM3_CONFIG、PWM3_INDEX
RT-Thread系列07——PWM设备_第3张图片
RT-Thread系列07——PWM设备_第4张图片

PWM3_CONFIG的内容如下,即定义了定时器3。

RT-Thread系列07——PWM设备_第5张图片

而我们定义的 BSP_USING_PWM3_CH2 通道,在pwm_get_channel函数中。

RT-Thread系列07——PWM设备_第6张图片

你可能感兴趣的:(RTOS,#,RT-Thread,单片机,stm32,RT-Thread)