board.h中打开如下定义,并新增要使用的通道
#define BSP_USING_PWM1 /*#define BSP_USING_PWM2*/ /*#define BSP_USING_PWM3*/ #define BSP_USING_PWM1_CH1
drv_pwm.c中的函数 static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device)
多了一个初始化操作HAL_TIM_Base_Init(tim),这个是多余的,需要删除,然后就正常了
但是使用tim16时就又需要这个初始化,因此需要根据cubemx初始化代码灵活调整
static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device) { rt_err_t result = RT_EOK; TIM_HandleTypeDef *tim = RT_NULL; TIM_OC_InitTypeDef oc_config = {0}; TIM_MasterConfigTypeDef master_config = {0}; TIM_ClockConfigTypeDef clock_config = {0}; RT_ASSERT(device != RT_NULL); tim = (TIM_HandleTypeDef *)&device->tim_handle; /* configure the timer to pwm mode */ tim->Init.Prescaler = 0; tim->Init.CounterMode = TIM_COUNTERMODE_UP; tim->Init.Period = 0; tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; #if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; tim->Init.RepetitionCounter = 0; #endif // if (HAL_TIM_Base_Init(tim) != HAL_OK) // { // LOG_E("%s pwm base init failed", device->name); // result = -RT_ERROR; // goto __exit; // } if (HAL_TIM_PWM_Init(tim) != HAL_OK) { LOG_E("%s pwm init failed", device->name); result = -RT_ERROR; goto __exit; } clock_config.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(tim, &clock_config) != HAL_OK) { LOG_E("%s clock init failed", device->name); result = -RT_ERROR; goto __exit; } master_config.MasterOutputTrigger = TIM_TRGO_RESET; master_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(tim, &master_config) != HAL_OK) { LOG_E("%s master config failed", device->name); result = -RT_ERROR; goto __exit; } oc_config.OCMode = TIM_OCMODE_PWM1; oc_config.Pulse = 0; oc_config.OCPolarity = TIM_OCPOLARITY_HIGH; oc_config.OCNPolarity = TIM_OCNPOLARITY_HIGH; oc_config.OCFastMode = TIM_OCFAST_DISABLE; oc_config.OCNIdleState = TIM_OCNIDLESTATE_RESET; oc_config.OCIdleState = TIM_OCIDLESTATE_RESET; /* config pwm channel */ if (device->channel & 0x01) { if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_1) != HAL_OK) { LOG_E("%s channel1 config failed", device->name); result = -RT_ERROR; goto __exit; } } if (device->channel & 0x02) { if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_2) != HAL_OK) { LOG_E("%s channel2 config failed", device->name); result = -RT_ERROR; goto __exit; } } if (device->channel & 0x04) { if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_3) != HAL_OK) { LOG_E("%s channel3 config failed", device->name); result = -RT_ERROR; goto __exit; } } if (device->channel & 0x08) { if (HAL_TIM_PWM_ConfigChannel(tim, &oc_config, TIM_CHANNEL_4) != HAL_OK) { LOG_E("%s channel4 config failed", device->name); result = -RT_ERROR; goto __exit; } } /* pwm pin configuration */ HAL_TIM_MspPostInit(tim); /* enable update request source */ __HAL_TIM_URS_ENABLE(tim); __exit: return result; }
使用方式如下
#define PWM_DEV_NAME "pwm1" /* PWM设备名称*/ #define PWM_DEV_CHANNEL 1 /* PWM通道*/ struct rt_device_pwm *pwm_dev; /* PWM设备句柄*/ static int pwm_test(int argc, char *argv[]) { rt_uint32_t freq, duty; if (argc < 2) { LOG_E("Usage:pwm_test [freq] [duty]"); return RT_ERROR; } freq = 1000000000 / atoi(argv[1]); /* 频率 */ duty = atoi(argv[2]) * freq / 100; /* PWM脉冲宽度值, 单位为纳秒ns */ /* 查找设备*/ pwm_dev = (struct rt_device_pwm *) rt_device_find(PWM_DEV_NAME); if (pwm_dev == RT_NULL) { LOG_E("can't find %s device!", PWM_DEV_NAME); return RT_ERROR; } else { LOG_I("find %s device!", PWM_DEV_NAME); } /* 设置PWM周期和脉冲宽度默认值*/ LOG_I("set %s ,freq=%d,duty=%d", PWM_DEV_NAME, freq, duty); rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, freq, duty); /* 使能设备*/ LOG_I("enable %s device", PWM_DEV_NAME); rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL); // delay(1000); // /* 关闭设备*/ // LOG_I("disable %s device", PWM_DEV_NAME); // rt_pwm_disable(pwm_dev, PWM_DEV_CHANNEL); return RT_EOK; } /* 导出到msh 命令列表中*/ MSH_CMD_EXPORT_ALIAS(pwm_test, pwm, pwm_test);
标签:rt,PWM,stm32L431,thread,tim,TIM,device,pwm,config From: https://www.cnblogs.com/arthurly/p/17035672.html