一通道pwm参考
https://blog.csdn.net/yangshengwei230612/article/details/128738351?spm=1001.2014.3001.5501
以下主要是多通道与一通道的区别
芯片
stm32f407rgt6
1、配置PWM设备驱动相关宏定义
添加PWM宏定义
#define BSP_USING_PWM8
#define BSP_USING_PWM8_CH1
#define BSP_USING_PWM8_CH2
2.添加配置的TIM和PWM设备硬件驱动代码
使用STM32CubeIDE 生成 TIM 和 PWM驱动代码
2.1 使用STM32官方STM32CubeIDE配置TIM8 PWM CH1通道(即PI5)
定时器8:TIM8_CH1复用PI5
定时器8:TIM8_CH2复用PI6
使用外部高速时钟
配置时钟频率
设置生生成项目名称
将红框内的相关驱动代码拷贝到rt-thread pwm测试项目中的 drivers/drv_pwm.c 源文件
2.3复制驱动代码
将上面keil中红框内的相关驱动代码拷贝到rt-thread pwm测试项目中的 drivers/drv_pwm.c 源文件
修改pwm_config.h文件
如果没有对应pwm配置则添加
#ifdef BSP_USING_PWM8
#ifndef PWM8_CONFIG
#define PWM8_CONFIG \
{ \
.tim_handle.Instance = TIM8, \
.name = "pwm8", \
.channel = 0 \
}
#endif /* PWM5_CONFIG */
#endif /* BSP_USING_PWM8 */
4、创建线程 PWM 驱动
4.1 具体线程测试代码如下
/*
* 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 1/* PWM通 道 */
#define PWM_DEV_CHANNEL_2 2 /* PWM通 道 */
struct rt_device_pwm *pwm_dev; /* PWM设 备 句 柄 */
static void pwm_led_thread_entry(void *parameter)
{
rt_uint32_t period, pulse, dir, max_period;
period = 250000; /* 周 期 为0.5ms, 单 位 为 纳 秒ns */
dir = 1; /* PWM脉 冲 宽 度 值 的 增 减 方 向 */
pulse = period/2; /* PWM脉 冲 宽 度 值, 单 位 为 纳秒ns */
max_period = 500000;
/* 查 找 设 备 */
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_1, period, pulse);
/* 使 能 设 备 */
rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL_1);
while (0)
{
rt_thread_mdelay(50);
if (dir)
{
period += 500; /* 从0值 开 始 每 次 增加5000ns */
}
else
{
period -= 500; /* 从 最 大 值 开 始 每 次减 少5000ns */
}
if (period >= max_period )
{
dir = 0;
// period = 500000;
}
if (period <= 250000)
{
dir = 1;
// period = 250000;
}
pulse = period/2;
/* 设 置PWM周 期 和 脉 冲 宽 度 */
rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL_1, 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;
}
//ch2
static void pwm_ch2_thread_entry(void *parameter)
{
rt_uint32_t period, pulse, dir, max_period;
period = 250000; /* 周 期 为0.5ms, 单 位 为 纳 秒ns */
dir = 1; /* PWM脉 冲 宽 度 值 的 增 减 方 向 */
pulse = period/2; /* PWM脉 冲 宽 度 值, 单 位 为 纳秒ns */
max_period = 500000;
/* 查 找 设 备 */
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_2, period, pulse);
/* 使 能 设 备 */
rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL_2);
while (0)
{
rt_thread_mdelay(50);
if (dir)
{
period += 500; /* 从0值 开 始 每 次 增加5000ns */
}
else
{
period -= 500; /* 从 最 大 值 开 始 每 次减 少5000ns */
}
if (period >= max_period )
{
dir = 0;
// period = 500000;
}
if (period <= 250000)
{
dir = 1;
// period = 250000;
}
pulse = period/2;
/* 设 置PWM周 期 和 脉 冲 宽 度 */
rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL_2, period, pulse);
}
}
static int pwm_ch2_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_ch2_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();
pwm_ch2_init();
while (count++)
{
LOG_D("Hello RT-Thread!");
rt_thread_mdelay(1000);
}
return RT_EOK;
}