1、配置PWM设备驱动相关宏定义
1.1 配置PWM和TIM设备驱动
在RT-Thread Settings 配置界面中,在设备驱动程序目录下勾选 HWTIMER 和 PWM设备驱动程序,如下图所示:
配置完后在 rtconfig.h 中可以查看刚刚配置的 RT_USING_HWTIMER 和 RT_USING_PWM 的设备驱动宏定义。
#define RT_USING_HWTIMER
#define RT_USING_PWM
修改 stm32f1xx_hal_conf.h
1.2 drivers/stm32f1xx_hal_conf.h 头文件查看是否已宏定义HAL_TIM_MODULE_ENABLED 和 HAL_PWR_MODULE_ENABLED,如果没有自动配置则手动取消相关注释打开
#define HAL_TIM_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
1.3修改board.h文件
在dervers/board.h 增加 #define BSP_USING_PWM4 和 #define BSP_USING_PWM4_CH1 宏定义
添加时钟宏定义
#define BSP_USING_TIM8
添加PWM宏定义
//使用的第几个时钟就是BSP_USING_PWM几, 我这里使用的是TIM8
#define BSP_USING_PWM8
#define BSP_USING_PWM8_CH1
2添加配置的TIM和PWM设备硬件驱动代码
使用STM32CubeIDE 生成 TIM 和 PWM驱动代码
2.1 使用STM32官方STM32CubeIDE配置TIM8 PWM CH1通道(即PI5)
定时器8:TIM8_CH1复用PI5
使用外部高速时钟
配置时钟频率
设置生生成项目名称
2.2 keil mdk5中打开tim.c查看TIM和PWM代码
2.3复制驱动代码
将红框内的相关驱动代码拷贝到rt-thread pwm测试项目中的 drivers/drv_pwm.c 源文件
修改pwm_config.h文件
如果没有对应pwm配置则添加
4、创建线程 PWM 驱动
4.1 具体线程测试代码如下
main.c
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-01-19 RT-Thread first version
*/
#include <rtthread.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include <rtdevice.h>
#define PWM_DEV_NAME "pwm8" /* 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;
}
int main(void)
{
int count = 1;
//初始化pwm
pwm_led_init();
while (count++)
{
LOG_D("Hello RT-Thread!");
rt_thread_mdelay(1000);
}
return RT_EOK;
}
使用示波器查看
因为main代码中修改的是占空比,使用万用笔测量PI5 也会发现电压在循环从小到大变化
#常见错误
…/drivers/drv_pwm.c:182:5: error: ‘PWM8_CONFIG’ undeclared here (not in a function)