RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)

基于 RT-Thread Studio 1.1.2 版本开发,目前最新版本。

RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第1张图片

1、配置PWM设备驱动相关宏定义

1.1 配置PWM和TIM设备驱动

 在RT-Thread Settings 配置界面中,在设备驱动程序目录下勾选 HWTIMER 和 PWM设备驱动程序,如下图所示:

RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第2张图片

 配置完后在 rtconfig.h 中可以查看刚刚配置的 RT_USING_HWTIMER 和 RT_USING_PWM 的设备驱动宏定义。

RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第3张图片

1.2  stm32f1xx_hal_conf.h 头文件查看是否已宏定义HAL_TIM_MODULE_ENABLED 和 HAL_PWR_MODULE_ENABLED,如果没有自动配置则手动取消相关注释打开

 RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第4张图片

1.3 在board.h 增加 #define BSP_USING_PWM4 和  #define BSP_USING_PWM4_CH1 宏定义

RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第5张图片

1.4 在board.h 增加 #define BSP_USING_TIM4 宏定义

RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第6张图片

1.5 需要用户自己添加配置的TIM设备硬件驱动代码   

extern void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);

RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第7张图片

在这个函数static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device) 中调用了 HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim) 这个函数。

RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第8张图片

那么就需要通过STM32CubeIDE配置自动生成相关驱动代码。

2. STM32CubeIDE 生成 TIM 和 PWM驱动代码

2.1 使用STM32官方STM32CubeIDE配置TIM4 PWM CH1通道(即PB6) 

RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第9张图片

RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第10张图片

RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第11张图片

RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第12张图片

 2.2 打开tim.c查看TIM和PWM代码

RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第13张图片

 代码如下:

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle)
{

  if(tim_pwmHandle->Instance==TIM4)
  {
  /* USER CODE BEGIN TIM4_MspInit 0 */

  /* USER CODE END TIM4_MspInit 0 */
    /* TIM4 clock enable */
    __HAL_RCC_TIM4_CLK_ENABLE();
  /* USER CODE BEGIN TIM4_MspInit 1 */

  /* USER CODE END TIM4_MspInit 1 */
  }
}
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(timHandle->Instance==TIM4)
  {
  /* USER CODE BEGIN TIM4_MspPostInit 0 */

  /* USER CODE END TIM4_MspPostInit 0 */

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**TIM4 GPIO Configuration
    PB6     ------> TIM4_CH1
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* USER CODE BEGIN TIM4_MspPostInit 1 */

  /* USER CODE END TIM4_MspPostInit 1 */
  }

}

void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef* tim_pwmHandle)
{

  if(tim_pwmHandle->Instance==TIM4)
  {
  /* USER CODE BEGIN TIM4_MspDeInit 0 */

  /* USER CODE END TIM4_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_TIM4_CLK_DISABLE();
  /* USER CODE BEGIN TIM4_MspDeInit 1 */

  /* USER CODE END TIM4_MspDeInit 1 */
  }
}

 3、移植复制相关驱动代码到 drv_pwm.c 源文件

RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第14张图片

 RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第15张图片

4、创建线程 PWM 驱动 LED 灯验证

4.1 具体线程测试代码如下

#include 
#include 
#define PWM_DEV_NAME        "pwm4" /* PWM设 备 名 称 */
#define PWM_DEV_CHANNEL     1 << 0/* PWM通 道 */

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

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);
        return RT_ERROR;
    }
    rt_kprintf("pwm sample run ! 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_led_init(void)
{
    static rt_thread_t tid_pwmled = RT_NULL;

    rt_err_t ret = RT_EOK;

/* 创建 serial 线程 */
    tid_pwmled = rt_thread_create("t_pwmled",pwm_led_thread_entry, RT_NULL, 512, 24, 10);
   /* 创建成功则启动线程 */
   if (tid_pwmled != RT_NULL)
   {
       rt_thread_startup(tid_pwmled);
   }
   else
   {
       ret = RT_ERROR;
   }

   return ret;

}

INIT_APP_EXPORT(pwm_led_init);

4.2 验证串口效果截图

RT-Thread 之 PWM 设备驱动详细配置过程(血泪经验)_第16张图片

实际效果也是pwm驱动led灯不断由暗变亮、由亮变暗,实现led灯呼吸灯效果。

你可能感兴趣的:(RT_Thread,物联网,嵌入式)