Github

整个RTT学习过程中对工程的完善和开发都记录在Github上的一个项目中,项目还会随着学习的深入进行更新
项目URL:https://github.com/HITLIVING/-RT-Thread-.git
读者可以通过Pull下来整个项目进一步了解
对PWM驱动的实现需要格外关注
steering_app.c
steering_app.h
两个文件

外设配置

STM32F1RCT6芯片
野火MINI开发板自带显示屏(240*320)(仅用来显示信息,与PWM自身无关)
显示屏控制芯片ILI9341(仅用来显示信息,与PWM自身无关)

Cube

配置Tim定时器引脚,绑定通道
image.png

  • 在选定引脚上开启定时器(PA15,TIM2,通用定时器,Channel1)
  • 选择时钟源内部时钟
  • 配置通道1PWM通用输出功能

Kconfig

添加Env配置选项
image.png

menu "On-chip Peripheral Drivers" 下添加代码段

  1. menuconfig BSP_USING_PWM
  2. bool "Enable pwm"
  3. default n
  4. select RT_USING_PWM
  5. if BSP_USING_PWM
  6. menuconfig BSP_USING_PWM1
  7. bool "Enable timer2 output pwm"
  8. default n
  9. if BSP_USING_PWM1
  10. config BSP_USING_PWN2_CH1
  11. bool "Enable PWM1 channel1"
  12. default n
  13. endif
  14. endif

使得可以通过Env开启PWM驱动的配置

Env

开启PWM外设
image.png
image.png
image.png
image.png
image.png

使用 scons 指令生成MDK5工程,完成配置

MDK

image.png

在驱动文件夹下看到 drv_pwm 即配置成功
此时点击编译会报错
image.png

需要手动在
pwm_config.h 文件下添加对PWM1的定义
pwm_config.h可通过drv_pwm.c->drv_config.h->pwm_config.h找到

  1. #ifdef BSP_USING_PWM1
  2. #ifndef PWM1_CONFIG
  3. #define PWM1_CONFIG \
  4. { \
  5. .tim_handle.Instance = TIM2, \
  6. .name = "pwm1", \
  7. .channel = 1 \
  8. }
  9. #endif /* PWM1_CONFIG */
  10. #endif /* BSP_USING_PWM1 */

再次编译,无错误时,PWM的驱动配置已经完成

接口函数

查找 PWM 设备

应用程序根据 PWM 设备名称获取设备句柄,进而可以操作 PWM 设备,查找设备函数如下所示:

  1. rt_device_t rt_device_find(const char* name);
参数 描述
name 设备名称
返回 ——
设备句柄 查找到对应设备将返回相应的设备句柄
RT_NULL 没有找到设备

设备名称即为在pwm_config.h中定义的设备名称
设备句柄需要用RT-Thread定义的PWM设备描述结构体接收

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

设置 PWM 周期和脉冲宽度

通过如下函数设置 PWM 周期和占空比:

  1. rt_err_t rt_pwm_set(struct rt_device_pwm *device,
  2. int channel,
  3. rt_uint32_t period,
  4. rt_uint32_t pulse);
参数 描述
device PWM 设备句柄
channel PWM 通道
period PWM 周期时间 (单位纳秒 ns)
pulse PWM 脉冲宽度时间 (单位纳秒 ns)
返回 ——
RT_EOK 成功
-RT_EIO device 为空
-RT_ENOSYS 设备操作方法为空
其他错误码 执行失败

使能 PWM 设备

设置好 PWM 周期和脉冲宽度后就可以通过如下函数使能 PWM 设备:

  1. rt_err_t rt_pwm_enable(struct rt_device_pwm *device, int channel);
参数 描述
device PWM 设备句柄
channel PWM 通道
返回 ——
RT_EOK 设备使能成功
-RT_ENOSYS 设备操作方法为空
其他错误码 设备使能失败

关闭 PWM 设备通道

通过如下函数关闭 PWM 设备对应通道。

  1. rt_err_t rt_pwm_disable(struct rt_device_pwm *device, int channel);
参数 描述
device PWM 设备句柄
channel PWM 通道
返回 ——
RT_EOK 设备关闭成功
-RT_EIO 设备句柄为空
其他错误码 设备关闭失败

上机实验

  1. #include <rtthread.h>
  2. #include <rtdevice.h>
  3. #include <stdio.h>
  4. #include "steering_app.h"
  5. #include "drv_ili9341_lcd.h"
  6. rt_uint32_t PWM1_freq = 2000;
  7. rt_uint32_t PWM1_duty = 20;
  8. rt_err_t Steering_PWM_init(void)
  9. {
  10. rt_uint32_t PWM1_period = 1000000000/PWM1_freq;
  11. rt_uint32_t PWM1_pulse = PWM1_period/100*PWM1_duty;
  12. /* PWM device handle */
  13. struct rt_device_pwm *pwm_dev;
  14. /* find device */
  15. pwm_dev = (struct rt_device_pwm *)rt_device_find("pwm1");
  16. if (pwm_dev == RT_NULL)
  17. {
  18. rt_kprintf("pwm sample run failed! can't find pwm1 device!\n");
  19. return RT_ERROR;
  20. }
  21. /* set PWM period and pulse*/
  22. rt_pwm_set(pwm_dev, 1, PWM1_period, PWM1_pulse);
  23. /* enable PWM device */
  24. rt_pwm_enable(pwm_dev, 1);u
  25. ILI9341_DispStringLine_EN (LINE(4), "PWM Signal Frequence:");
  26. ILI9341_DispStringLine_EN (LINE(6), "PWM Signal Duty:");
  27. return RT_EOK;
  28. }
  29. void Steering_PWM_Condition(void)
  30. {
  31. char str_freq[] = {0};
  32. char str_duty[] = {0};
  33. sprintf(str_freq, "%d", PWM1_freq);
  34. sprintf(str_duty, "%d", PWM1_duty);
  35. ILI9341_DispStringLine_EN (LINE(5), str_freq);
  36. ILI9341_DispStringLine_EN (LINE(7), str_duty);
  37. }
  38. void Steering_PWM_Disable(void)
  39. {
  40. /* PWM device handle */
  41. struct rt_device_pwm *pwm_dev;
  42. /* find device */
  43. pwm_dev = (struct rt_device_pwm *)rt_device_find("pwm1");
  44. /* disable PWM device */
  45. rt_pwm_disable(pwm_dev, 1);
  46. }

因为PWM在使用时更常用频率和占空比,这里设置了频率为2kHz,占空比为20%的PWM信号,转换成周期和脉宽后写入pwm1设备

结合前面控制界面的配置,将PWM设备定义成steering舵机的一个功能块并添加在了菜单中,可以通过选择调用,并将配置信息显示在显示屏上

万用表上有测量电信号的频率和占空比的功能,将表上显示的数据与屏幕显示对比即可得知PWM信号正常与否

实验效果

  • 开机界面

IMG_5612.JPG

  • 菜单界面,选择第三个选项,舵机控制

IMG_5613.JPG

  • 测量输出信号频率

IMG_5614.JPG

  • 测量输出信号占空比

IMG_5615.JPG