一、流程步骤
1、CubeMX配置:
这里使用stm32f407zgt6开发板,配置TIM4 PWM CH1通道。(RCC、SYS配置省略啦~)
2、 rtconfig.h中使能宏定义RT_USING_HWTIMER和RT_USING_PWM
3、stm32f1xx_hal_conf.h头文件使能宏定义HAL_TIM_MODULE_ENABLED 和HAL_PWR_MODULE_ENABLED
4、 rtconfig.h中增加以下宏定义
5、将源码drv_pwm.c加入keil工程,查看配置的TIM设备驱动代码
6、将tim.c中的TIM和PWM代码复制到drv_pwm.c源文件,代码:
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->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_GPIOD_CLK_ENABLE();
/**TIM4 GPIO Configuration
PD12 ------> TIM4_CH1
*/
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* USER CODE BEGIN TIM4_MspPostInit 1 */
/* USER CODE END TIM4_MspPostInit 1 */
}
}
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->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 */
}
}
//extern void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
注:源文件drv_pwm.c中的这三个函数注释掉
7、测试代码 (pwm_led_sample.c) :
在官网文档中的示例代码中,添加了一些验证程序进度的输出语句,用于理解程序使用。
程序功能:通过PWM设备控制LED灯的亮度,可以看到LED不停的由暗变到亮,然后又从亮变到暗。
#include <rtthread.h>
#include <rtdevice.h>
#include <rt_drv_pwm.h>
#define PWM_DEV_NAME "pwm4" /* PWM设备名称 */
#define PWM_DEV_CHANNEL 1 /* PWM通道 */
struct rt_device_pwm *pwm_dev; /* PWM设备句柄 */
static int pwm_led_sample(int argc, char *argv[])
{
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;
}
else
rt_kprintf("pwm sample run succeeded! can find %s device!\n", PWM_DEV_NAME);
rt_kprintf("1 hello this is rt_kprintf!!!!!\n");
/* 设置PWM周期和脉冲宽度默认值 */
rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
rt_kprintf("2 hello this is rt_kprintf!!!!!\n");
/* 使能设备 */
rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);
rt_kprintf("3 hello this is rt_kprintf!!!!!\n");
while (1)
{
rt_thread_mdelay(50);
if (dir)
{
pulse += 5000; /* 从0值开始每次增加5000ns */
rt_kprintf("4 hello this is rt_kprintf!!!!!\n");
rt_kprintf("pulse+:%d\n", pulse);
}
else
{
pulse -= 5000; /* 从最大值开始每次减少5000ns */
rt_kprintf("pulse-:%d\n", pulse);
}
if (pulse >= period)
{
dir = 0;
}
if (0 == pulse)
{
dir = 1;
}
rt_kprintf("dir:%d\n", dir);
rt_kprintf("5 hello this is rt_kprintf!!!!!\n");
/* 设置PWM周期和脉冲宽度 */
rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
rt_kprintf("6 hello this is rt_kprintf!!!!!\n");
}
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(pwm_led_sample, pwm sample);
二、效果验证
1、串口助手(MobaX)log日志:
2、pwm驱动led灯不断由暗变亮、由亮变暗,实现呼吸灯效果
开发板引脚:芯片IS62WV51216的A17脚,对应TIM4_CH1
将A17引脚连到LED的一端,即可实现呼吸灯效果
3、逻辑分析仪测波形:
从暗到亮再到暗
循环进行