当前位置:网站首页>GD32 RT-Thread PWM驱动函数
GD32 RT-Thread PWM驱动函数
2022-06-30 09:37:00 【Sky_Lannister】
GD32 PWM驱动函数
驱动函数包含三个文件,drv_pwm.c、drv_pwm.h、pwm_config.h,使用RT_USING_PWM进行开启关闭,移植注意事项参见 移植完整版RT-Thread到GD32F4XX(详细) 中关于pwm移植相关内容,移植完成后使用及验证方法同stm32
drv_pwm.c
/** ****************************************************************************** * @file drv_pwm.c * @author yangFei * @brief 按照GD32库实现pwm驱动 * * @version V1.0.0 * @date 2022.05.30 * @verbatim * * @endverbatim ****************************************************************************** * @note * @attention * * Change Logs: * Date Author Notes * 2022.05.30 yangFei 适用芯片为GD32f4xx,使用官方提供标准库,例程移植自https://github.com/RT-Thread/rt- thread/tree/master/bsp/gd32/gd32407v-start * ****************************************************************************** */
#ifdef RT_USING_PWM
#include <drivers/hwtimer.h>
#include "drv_pwm.h"
#include "pwm_config.h"
//#define DRV_DEBUG
#define LOG_TAG "drv.pwm"
#include <drv_log.h>
#define MAX_PERIOD 65535
#define MIN_PERIOD 3
#define MIN_PULSE 2
timer_oc_parameter_struct timer_ocintpara;
enum
{
#ifdef BSP_USING_PWM1
PWM1_INDEX,
#endif
#ifdef BSP_USING_PWM2
PWM2_INDEX,
#endif
#ifdef BSP_USING_PWM3
PWM3_INDEX,
#endif
#ifdef BSP_USING_PWM4
PWM4_INDEX,
#endif
#ifdef BSP_USING_PWM5
PWM5_INDEX,
#endif
#ifdef BSP_USING_PWM6
PWM6_INDEX,
#endif
#ifdef BSP_USING_PWM7
PWM7_INDEX,
#endif
#ifdef BSP_USING_PWM8
PWM8_INDEX,
#endif
#ifdef BSP_USING_PWM9
PWM9_INDEX,
#endif
#ifdef BSP_USING_PWM10
PWM10_INDEX,
#endif
#ifdef BSP_USING_PWM11
PWM11_INDEX,
#endif
#ifdef BSP_USING_PWM12
PWM12_INDEX,
#endif
#ifdef BSP_USING_PWM13
PWM13_INDEX,
#endif
#ifdef BSP_USING_PWM14
PWM14_INDEX,
#endif
#ifdef BSP_USING_PWM15
PWM15_INDEX,
#endif
#ifdef BSP_USING_PWM16
PWM16_INDEX,
#endif
#ifdef BSP_USING_PWM17
PWM17_INDEX,
#endif
};
struct gd32_pwm
{
struct rt_device_pwm pwm_device;
TIM_HandleTypeDef tim_handle;
rt_uint8_t channel;
char *name;
};
static struct gd32_pwm gd32_pwm_obj[] =
{
#ifdef BSP_USING_PWM1
PWM1_CONFIG,
#endif
#ifdef BSP_USING_PWM2
PWM2_CONFIG,
#endif
#ifdef BSP_USING_PWM3
PWM3_CONFIG,
#endif
#ifdef BSP_USING_PWM4
PWM4_CONFIG,
#endif
#ifdef BSP_USING_PWM5
PWM5_CONFIG,
#endif
#ifdef BSP_USING_PWM6
PWM6_CONFIG,
#endif
#ifdef BSP_USING_PWM7
PWM7_CONFIG,
#endif
#ifdef BSP_USING_PWM8
PWM8_CONFIG,
#endif
#ifdef BSP_USING_PWM9
PWM9_CONFIG,
#endif
#ifdef BSP_USING_PWM10
PWM10_CONFIG,
#endif
#ifdef BSP_USING_PWM11
PWM11_CONFIG,
#endif
#ifdef BSP_USING_PWM12
PWM12_CONFIG,
#endif
#ifdef BSP_USING_PWM13
PWM13_CONFIG,
#endif
#ifdef BSP_USING_PWM14
PWM14_CONFIG,
#endif
#ifdef BSP_USING_PWM15
PWM15_CONFIG,
#endif
#ifdef BSP_USING_PWM16
PWM16_CONFIG,
#endif
#ifdef BSP_USING_PWM17
PWM17_CONFIG,
#endif
};
void GD32_TIM_MspPostInit(TIM_HandleTypeDef* htim)
{
if(htim->Instance == TIMER2)
{
/* USER CODE END TIM2_MspPostInit 0 */
rcu_periph_clock_enable(RCU_GPIOC);
/**TIM2 GPIO Configuration PC6 ------> TIM2_CH0 PC7 ------> TIM2_CH1 PC8 ------> TIM2_CH2 PC9 ------> TIM2_CH3 */
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
gpio_af_set(GPIOC, GPIO_AF_2, GPIO_PIN_6);
gpio_af_set(GPIOC, GPIO_AF_2, GPIO_PIN_7);
gpio_af_set(GPIOC, GPIO_AF_2, GPIO_PIN_8);
gpio_af_set(GPIOC, GPIO_AF_2, GPIO_PIN_9);
}
else if(htim->Instance == TIMER3)
{
/* USER CODE BEGIN TIM3_MspPostInit 0 */
__HAL_RCC_GPIOB_CLK_ENABLE();
/**TIM3 GPIO Configuration PB9 ------> TIM3_CH3 */
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_9);
}
else
{
LOG_E("%d timer-pwm pin config failed", htim->Instance);
}
}
static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg);
static struct rt_pwm_ops drv_ops =
{
drv_pwm_control
};
static rt_err_t drv_pwm_enable(TIM_HandleTypeDef *htim, struct rt_pwm_configuration *configuration, rt_bool_t enable)
{
uint32_t timer_periph = htim->Instance;
uint16_t channel = htim->Channel;
if (!enable)
{
timer_ocintpara.outputstate = TIMER_CCX_DISABLE;
timer_channel_output_config(timer_periph, channel, &timer_ocintpara);
}
else
{
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_channel_output_config(timer_periph, channel, &timer_ocintpara);
}
return RT_EOK;
}
static rt_err_t drv_pwm_get(TIM_HandleTypeDef *htim, struct rt_pwm_configuration *configuration)
{
uint32_t channel = htim->Channel;
rt_uint64_t tim_clock;
uint32_t timer_periph = htim->Instance;
uint32_t pulse = 0;
if((timer_periph == TIMER0) || (timer_periph == TIMER7) || (timer_periph == TIMER8) || (timer_periph == TIMER9) || (timer_periph == TIMER10))
{
tim_clock = rcu_clock_freq_get(CK_APB2);
}
else
{
tim_clock = rcu_clock_freq_get(CK_APB1);
}
if (((uint16_t)TIMER_CTL0(timer_periph) & TIMER_CKDIV_DIV2) == CTL0_CKDIV(3))
{
tim_clock = tim_clock / 2;
}
else if (((uint16_t)TIMER_CTL0(timer_periph) & TIMER_CKDIV_DIV4) == CTL0_CKDIV(3))
{
tim_clock = tim_clock / 4;
}
/* Convert nanosecond to frequency and duty cycle. 1s = 1 * 1000 * 1000 * 1000 ns */
tim_clock /= 1000000UL;
configuration->period = ((uint32_t)TIMER_CAR(timer_periph) + 1) * ((uint16_t)TIMER_PSC(timer_periph) + 1) * 1000UL / tim_clock;
switch(channel){
/* configure TIMER_CH_0 */
case TIMER_CH_0:
pulse = (uint32_t)TIMER_CH0CV(timer_periph);
break;
/* configure TIMER_CH_1 */
case TIMER_CH_1:
pulse = (uint32_t)TIMER_CH1CV(timer_periph);
break;
/* configure TIMER_CH_2 */
case TIMER_CH_2:
pulse = (uint32_t)TIMER_CH2CV(timer_periph);
break;
/* configure TIMER_CH_3 */
case TIMER_CH_3:
pulse = (uint32_t)TIMER_CH3CV(timer_periph);
break;
default:
break;
}
configuration->pulse = (pulse + 1) * ((uint16_t)TIMER_PSC(timer_periph) + 1) * 1000UL / tim_clock;
return RT_EOK;
}
static rt_err_t drv_pwm_set(TIM_HandleTypeDef *htim, struct rt_pwm_configuration *configuration)
{
rt_uint32_t period, pulse;
rt_uint64_t tim_clock, psc;
rt_uint32_t channel = configuration->channel;
uint32_t timer_periph = htim->Instance;
timer_disable(timer_periph);
if((timer_periph == TIMER0) || (timer_periph == TIMER7) || (timer_periph == TIMER8) || (timer_periph == TIMER9) || (timer_periph == TIMER10))
{
tim_clock = rcu_clock_freq_get(CK_APB2);
}
else
{
tim_clock = rcu_clock_freq_get(CK_APB1);
}
/* Convert nanosecond to frequency and duty cycle. 1s = 1 * 1000 * 1000 * 1000 ns */
tim_clock /= 1000000UL;
period = (unsigned long long)configuration->period * tim_clock / 1000ULL ;
psc = period / MAX_PERIOD + 1;
period = period / psc;
if (period < MIN_PERIOD)
{
period = MIN_PERIOD;
}
htim->Init.prescaler = (psc*4 - 1);
htim->Init.period = (period - 1);
timer_init(timer_periph, &htim->Init);
pulse = (unsigned long long)configuration->pulse * tim_clock / psc / 1000ULL;
if (pulse < MIN_PULSE)
{
pulse = MIN_PULSE;
}
else if (pulse > period)
{
pulse = period;
}
timer_channel_output_pulse_value_config(timer_periph, channel, (pulse - 1));
timer_channel_output_mode_config(timer_periph, channel, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(timer_periph, channel, TIMER_OC_SHADOW_DISABLE);
timer_counter_value_config(timer_periph, 0);
/* Update frequency value */
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(timer_periph);
/* auto-reload preload enable */
timer_enable(timer_periph);
return RT_EOK;
}
static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
{
struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)device->parent.user_data;
switch (cmd)
{
case PWM_CMD_ENABLE:
return drv_pwm_enable(htim, configuration, RT_TRUE);
case PWM_CMD_DISABLE:
return drv_pwm_enable(htim, configuration, RT_FALSE);
case PWM_CMD_SET:
return drv_pwm_set(htim, configuration);
case PWM_CMD_GET:
return drv_pwm_get(htim, configuration);
default:
return RT_EINVAL;
}
}
static rt_err_t gd32_hw_pwm_init(struct gd32_pwm *device)
{
rt_err_t result = RT_EOK;
TIM_HandleTypeDef *tim = RT_NULL;
RT_ASSERT(device != RT_NULL);
tim = (TIM_HandleTypeDef *)&device->tim_handle;
/* pwm pin configuration */
GD32_TIM_MspPostInit(tim);
switch(tim->Instance){
case TIMER0:
rcu_periph_clock_enable(RCU_TIMER0);
break;
case TIMER1:
rcu_periph_clock_enable(RCU_TIMER1);
break;
case TIMER2:
rcu_periph_clock_enable(RCU_TIMER2);
break;
case TIMER3:
rcu_periph_clock_enable(RCU_TIMER3);
break;
case TIMER4:
rcu_periph_clock_enable(RCU_TIMER4);
break;
case TIMER5:
rcu_periph_clock_enable(RCU_TIMER5);
break;
case TIMER6:
rcu_periph_clock_enable(RCU_TIMER6);
break;
case TIMER7:
rcu_periph_clock_enable(RCU_TIMER7);
break;
case TIMER8:
rcu_periph_clock_enable(RCU_TIMER8);
break;
case TIMER9:
rcu_periph_clock_enable(RCU_TIMER9);
break;
case TIMER10:
rcu_periph_clock_enable(RCU_TIMER10);
break;
case TIMER11:
rcu_periph_clock_enable(RCU_TIMER11);
break;
case TIMER12:
rcu_periph_clock_enable(RCU_TIMER12);
break;
case TIMER13:
rcu_periph_clock_enable(RCU_TIMER13);
break;
default:
break;
}
rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
timer_deinit(tim->Instance);
/* configure the timer to pwm mode */
tim->Init.prescaler = 0;
tim->Init.counterdirection = TIMER_COUNTER_UP;
tim->Init.period = 0;
tim->Init.clockdivision = TIMER_CKDIV_DIV4;
tim->Init.repetitioncounter = 0;
tim->Init.alignedmode = TIMER_COUNTER_EDGE;
timer_init(tim->Instance, &tim->Init);
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
/* config pwm channel */
if (device->channel & 0x01)
{
timer_channel_output_config(tim->Instance, TIMER_CH_0, &timer_ocintpara);
}
if (device->channel & 0x02)
{
timer_channel_output_config(tim->Instance, TIMER_CH_1, &timer_ocintpara);
}
if (device->channel & 0x04)
{
timer_channel_output_config(tim->Instance, TIMER_CH_2, &timer_ocintpara);
}
if (device->channel & 0x08)
{
timer_channel_output_config(tim->Instance, TIMER_CH_3, &timer_ocintpara);
}
// timer_channel_output_pulse_value_config(TIMER3,TIMER_CH_3,3999);
timer_channel_output_mode_config(tim->Instance, device->channel, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(tim->Instance, device->channel, TIMER_OC_SHADOW_DISABLE);
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(tim->Instance);
/* auto-reload preload enable */
timer_enable(tim->Instance);
__exit:
return result;
}
static void pwm_get_channel(void)
{
#ifdef BSP_USING_PWM0_CH0
gd32_pwm_obj[PWM0_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM0_CH1
gd32_pwm_obj[PWM0_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM0_CH2
gd32_pwm_obj[PWM0_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM0_CH3
gd32_pwm_obj[PWM0_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM1_CH0
gd32_pwm_obj[PWM1_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM1_CH1
gd32_pwm_obj[PWM1_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM1_CH2
gd32_pwm_obj[PWM1_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM1_CH3
gd32_pwm_obj[PWM1_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM2_CH0
gd32_pwm_obj[PWM2_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM2_CH1
gd32_pwm_obj[PWM2_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM2_CH2
gd32_pwm_obj[PWM2_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM2_CH3
gd32_pwm_obj[PWM2_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM3_CH0
gd32_pwm_obj[PWM3_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM3_CH1
gd32_pwm_obj[PWM3_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM3_CH2
gd32_pwm_obj[PWM3_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM3_CH3
gd32_pwm_obj[PWM3_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM4_CH0
gd32_pwm_obj[PWM4_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM4_CH1
gd32_pwm_obj[PWM4_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM4_CH2
gd32_pwm_obj[PWM4_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM4_CH3
gd32_pwm_obj[PWM4_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM5_CH0
gd32_pwm_obj[PWM5_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM5_CH1
gd32_pwm_obj[PWM5_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM5_CH2
gd32_pwm_obj[PWM5_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM5_CH3
gd32_pwm_obj[PWM5_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM6_CH0
gd32_pwm_obj[PWM6_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM6_CH1
gd32_pwm_obj[PWM6_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM6_CH2
gd32_pwm_obj[PWM6_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM6_CH3
gd32_pwm_obj[PWM6_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM7_CH0
gd32_pwm_obj[PWM7_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM7_CH1
gd32_pwm_obj[PWM7_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM7_CH2
gd32_pwm_obj[PWM7_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM7_CH3
gd32_pwm_obj[PWM7_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM8_CH0
gd32_pwm_obj[PWM8_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM8_CH1
gd32_pwm_obj[PWM8_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM8_CH2
gd32_pwm_obj[PWM8_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM8_CH3
gd32_pwm_obj[PWM8_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM9_CH0
gd32_pwm_obj[PWM9_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM9_CH1
gd32_pwm_obj[PWM9_INDEX].channel |= 1 << 1;
#endif
#ifdef BSP_USING_PWM9_CH2
gd32_pwm_obj[PWM9_INDEX].channel |= 1 << 2;
#endif
#ifdef BSP_USING_PWM9_CH3
gd32_pwm_obj[PWM9_INDEX].channel |= 1 << 3;
#endif
#ifdef BSP_USING_PWM12_CH0
gd32_pwm_obj[PWM12_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM12_CH1
gd32_pwm_obj[PWM12_INDEX].channel |= 1 << 1;
#endif
}
static int gd32_pwm_init(void)
{
int i = 0;
int result = RT_EOK;
pwm_get_channel();
for (i = 0; i < sizeof(gd32_pwm_obj) / sizeof(gd32_pwm_obj[0]); i++)
{
/* pwm init */
if (gd32_hw_pwm_init(&gd32_pwm_obj[i]) != RT_EOK)
{
LOG_E("%s init failed", gd32_pwm_obj[i].name);
result = -RT_ERROR;
goto __exit;
}
else
{
LOG_D("%s init success", gd32_pwm_obj[i].name);
/* register pwm device */
if (rt_device_pwm_register(&gd32_pwm_obj[i].pwm_device, gd32_pwm_obj[i].name, &drv_ops, &gd32_pwm_obj[i].tim_handle) == RT_EOK)
{
LOG_D("%s register success", gd32_pwm_obj[i].name);
}
else
{
LOG_E("%s register failed", gd32_pwm_obj[i].name);
result = -RT_ERROR;
}
}
}
__exit:
return result;
}
INIT_DEVICE_EXPORT(gd32_pwm_init);
#endif /* RT_USING_PWM */
/************************ (C) COPYRIGHT *****END OF FILE****/
drv_pwm.h
/** ****************************************************************************** * @file drv_pwm.h * @author yangFei * @brief 存放hal库中关于pwm相关的定义 * * @version V1.0.0 * @date 2022.05.30 * @verbatim * * @endverbatim ****************************************************************************** * @note * @attention * * Change Logs: * Date Author Notes * 2022.05.30 yangFei * ****************************************************************************** */
#ifndef _DRV_PWM_H
#define _DRV_PWM_H
#include "gd32f4xx_timer.h"
/** * @brief HAL State structures definition */
typedef enum
{
HAL_TIM_STATE_RESET = 0x00U, /*!< Peripheral not yet initialized or disabled */
HAL_TIM_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */
HAL_TIM_STATE_BUSY = 0x02U, /*!< An internal process is ongoing */
HAL_TIM_STATE_TIMEOUT = 0x03U, /*!< Timeout state */
HAL_TIM_STATE_ERROR = 0x04U /*!< Reception process is ongoing */
} HAL_TIM_StateTypeDef;
/** * @brief HAL Active channel structures definition */
typedef enum
{
HAL_TIM_ACTIVE_CHANNEL_0 = TIMER_CH_0, /*!< The active channel is 0 */
HAL_TIM_ACTIVE_CHANNEL_1 = TIMER_CH_1, /*!< The active channel is 1 */
HAL_TIM_ACTIVE_CHANNEL_2 = TIMER_CH_2, /*!< The active channel is 2 */
HAL_TIM_ACTIVE_CHANNEL_3 = TIMER_CH_3 /*!< The active channel is 3 */
} HAL_TIM_ActiveChannel;
/** * @brief TIM Time Base Handle Structure definition */
typedef struct
{
uint32_t Instance; /*!< Register base address */
timer_parameter_struct Init; /*!< TIM Time Base required parameters */
HAL_TIM_ActiveChannel Channel; /*!< Active channel */
// DMA_HandleTypeDef *hdma[7]; /*!< DMA Handlers array
// This array is accessed by a @ref DMA_Handle_index */
HAL_LockTypeDef Lock; /*!< Locking object */
__IO HAL_TIM_StateTypeDef State; /*!< TIM operation state */
} TIM_HandleTypeDef;
#endif /* _DRV_PWM_H */
/************************ (C) COPYRIGHT *****END OF FILE****/
pwm_config.h
/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-12-13 zylx first version */
#ifndef __PWM_CONFIG_H__
#define __PWM_CONFIG_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BSP_USING_PWM0
#ifndef PWM0_CONFIG
#define PWM0_CONFIG \ {
\ .tim_handle.Instance = TIMER0, \ .name = "pwm0", \ .channel = 0 \ }
#endif /* PWM1_CONFIG */
#endif /* BSP_USING_PWM1 */
#ifdef BSP_USING_PWM1
#ifndef PWM1_CONFIG
#define PWM1_CONFIG \ {
\ .tim_handle.Instance = TIMER1, \ .name = "pwm1", \ .channel = 0 \ }
#endif /* PWM1_CONFIG */
#endif /* BSP_USING_PWM1 */
#ifdef BSP_USING_PWM2
#ifndef PWM2_CONFIG
#define PWM2_CONFIG \ {
\ .tim_handle.Instance = TIMER2, \ .name = "pwm2", \ .channel = 0 \ }
#endif /* PWM2_CONFIG */
#endif /* BSP_USING_PWM2 */
#ifdef BSP_USING_PWM3
#ifndef PWM3_CONFIG
#define PWM3_CONFIG \ {
\ .tim_handle.Instance = TIMER3, \ .name = "pwm3", \ .channel = 0 \ }
#endif /* PWM3_CONFIG */
#endif /* BSP_USING_PWM3 */
#ifdef BSP_USING_PWM4
#ifndef PWM4_CONFIG
#define PWM4_CONFIG \ {
\ .tim_handle.Instance = TIMER4, \ .name = "pwm4", \ .channel = 0 \ }
#endif /* PWM4_CONFIG */
#endif /* BSP_USING_PWM4 */
#ifdef BSP_USING_PWM5
#ifndef PWM5_CONFIG
#define PWM5_CONFIG \ {
\ .tim_handle.Instance = TIMER5, \ .name = "pwm5", \ .channel = 0 \ }
#endif /* PWM5_CONFIG */
#endif /* BSP_USING_PWM5 */
#ifdef __cplusplus
}
#endif
#endif /* __PWM_CONFIG_H__ */
边栏推荐
- 【JVM】G1垃圾回收器簡述
- Magnetic levitation 3D lamp
- Splendid China: public welfare tourism for the middle-aged and the elderly - entering Foshan nursing home
- train_de.py: error: argument --save_steps: invalid int value: ‘$[$[889580/128/4]*10/2]‘
- 孙安民作品《莲花净心》数字藏品上线长城数艺
- 调试方法和技巧详解
- Installation and use
- Some domestic image sources
- MySQL index, transaction and storage engine of database (2)
- Questions about cookies and sessions
猜你喜欢
随机推荐
Setting up the d2lbook environment for Li Mu's "hands on learning and deep learning"
ModuleNotFoundError: No module named ‘_swigfaiss‘
train_ de.py: error: argument --save_ steps: invalid int value: ‘$[$[889580/128/4]*10/2]‘
Deployment of efficient and versatile clusters lvs+kept highly available clusters
G-Code 详解
Splendid China: public welfare tourism for the middle-aged and the elderly - entering Foshan nursing home
Network based BGP
JS obtient la chaîne spécifiée spécifiant la position du caractère & sous - chaîne spécifiant la plage de position du caractère 【 détails simples 】
Tooltips in the era of touch
7. development of mobile login function
MySQL log management, backup and recovery of databases (1)
无人机项目跟踪记录八十三---pcb图完成
UAV project tracking record 83 -- PCB diagram completion
MySQL log management, backup and recovery of databases (2)
SolidWorks质量特性详解(惯性张量、转动惯量、惯性主轴)
About the split and join operations of strings
KOREANO ESSENTIAL打造气质职场范
C語言實現掃雷遊戲,附詳解及完整代碼
Harvester ch1 of CKB and HNS, connection tutorial analysis
Shell script functions









