9_PWM

                            PWM Expriment:

  Default:


   Carrier Waveform :  Triangular wave
   Carrier frequency : 1000HZ;
   Carrier Peak Value : ±1V
   Modulating Waveform :  Sine Wave
   Modulating Frequency : 200rad/s;
   Modulating Peak Value : 0.8V;

  We've already know that the PWM output is all unrectified Pulse Series. The output Frequency is identical as the Modulating Waveform does thus which is because PWM mostly used in the invertor. As for the carrier frequency, it determines the output pulse frequency, to say more specificly, is to determine the Period that matters the Inductor & Capacitor. So the output waveform fluctuation Value is about to change.
  And we can see clearly via next series of the expriment:

First Expriment ( Default Value ):

  According to the theory of the PWM, the two pulses are inverted simultanously while the Carrier & the Modulating Waveform intersect, and we can see this through the Scope.

Second Expriment ( Modulating Frequency 100rad/s; ) :

  The output Pulse' frequency changed while we changed the Modulating frequency, and because of the unchanged Carrier frequency, the output Pulse inverted less frequently. So this may creating problem if we lower the Modulating Frequency that the pulse gets so less that carry too much harmonics which may find difficult to filt.

Third Expriment ( Carrier frequency : 500HZ )

  Comparing with the defaut value, if we lower the Carrier frequency, the pulse gets inverted slower just like what we've mentioned above. So it can be important to choose the preferable Carrier frequency for which can reduce the harmonics in the output and reduce both the Inductor and Capacitor value since the interchange between the input and output is lower!

1_Layout:



2_SinFrenquency=200rad_Triangle_1000Hz:



3_SinFrenquency=100rad_Triangle_1000Hz:



4_SinFrenquency=200rad_Triangle_500Hz:





/* * 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 */ #include <board.h> #include<rtthread.h> #include<rtdevice.h> #ifdef RT_USING_PWM #include "drv_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 extern void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); 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 stm32_pwm { struct rt_device_pwm pwm_device; TIM_HandleTypeDef tim_handle; rt_uint8_t channel; char *name; }; static struct stm32_pwm stm32_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 }; 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) { /* Converts the channel number to the channel number of Hal library */ rt_uint32_t channel = 0x04 * (configuration->channel - 1); if (!enable) { HAL_TIM_PWM_Stop(htim, channel); } else { HAL_TIM_PWM_Start(htim, channel); } return RT_EOK; } static rt_err_t drv_pwm_get(TIM_HandleTypeDef *htim, struct rt_pwm_configuration *configuration) { /* Converts the channel number to the channel number of Hal library */ rt_uint32_t channel = 0x04 * (configuration->channel - 1); rt_uint64_t tim_clock; #if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) if (htim->Instance == TIM9 || htim->Instance == TIM10 || htim->Instance == TIM11) #elif defined(SOC_SERIES_STM32L4) if (htim->Instance == TIM15 || htim->Instance == TIM16 || htim->Instance == TIM17) #elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) if (0) #endif { #if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0) tim_clock = HAL_RCC_GetPCLK2Freq() * 2; #endif } else { #if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) tim_clock = HAL_RCC_GetPCLK1Freq(); #else tim_clock = HAL_RCC_GetPCLK1Freq() * 2; #endif } if (__HAL_TIM_GET_CLOCKDIVISION(htim) == TIM_CLOCKDIVISION_DIV2) { tim_clock = tim_clock / 2; } else if (__HAL_TIM_GET_CLOCKDIVISION(htim) == TIM_CLOCKDIVISION_DIV4) { tim_clock = tim_clock / 4; } /* Convert nanosecond to frequency and duty cycle. 1s = 1 * 1000 * 1000 * 1000 ns */ tim_clock /= 1000000UL; configuration->period = (__HAL_TIM_GET_AUTORELOAD(htim) + 1) * (htim->Instance->PSC + 1) * 1000UL / tim_clock; configuration->pulse = (__HAL_TIM_GET_COMPARE(htim, channel) + 1) * (htim->Instance->PSC + 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; /* Converts the channel number to the channel number of Hal library */ rt_uint32_t channel = 0x04 * (configuration->channel - 1); #if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) if (htim->Instance == TIM9 || htim->Instance == TIM10 || htim->Instance == TIM11) #elif defined(SOC_SERIES_STM32L4) if (htim->Instance == TIM15 || htim->Instance == TIM16 || htim->Instance == TIM17) #elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) if (0) #endif { #if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0) tim_clock = HAL_RCC_GetPCLK2Freq() * 2; #endif } else { #if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) tim_clock = HAL_RCC_GetPCLK1Freq(); #else tim_clock = HAL_RCC_GetPCLK1Freq() * 2; #endif } /* 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; __HAL_TIM_SET_PRESCALER(htim, psc - 1); if (period < MIN_PERIOD) { period = MIN_PERIOD; } __HAL_TIM_SET_AUTORELOAD(htim, period - 1); pulse = (unsigned long long)configuration->pulse * tim_clock / psc / 1000ULL; if (pulse < MIN_PULSE) { pulse = MIN_PULSE; } else if (pulse > period) { pulse = period; } __HAL_TIM_SET_COMPARE(htim, channel, pulse - 1); __HAL_TIM_SET_COUNTER(htim, 0); /* Update frequency value */ HAL_TIM_GenerateEvent(htim, TIM_EVENTSOURCE_UPDATE); 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 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; #endif 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.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; } static void pwm_get_channel(void) { #ifdef BSP_USING_PWM1_CH1 stm32_pwm_obj[PWM1_INDEX].channel |= 1 << 0; #endif #ifdef BSP_USING_PWM1_CH2 stm32_pwm_obj[PWM1_INDEX].channel |= 1 << 1; #endif #ifdef BSP_USING_PWM1_CH3 stm32_pwm_obj[PWM1_INDEX].channel |= 1 << 2; #endif #ifdef BSP_USING_PWM1_CH4 stm32_pwm_obj[PWM1_INDEX].channel |= 1 << 3; #endif #ifdef BSP_USING_PWM2_CH1 stm32_pwm_obj[PWM2_INDEX].channel |= 1 << 0; #endif #ifdef BSP_USING_PWM2_CH2 stm32_pwm_obj[PWM2_INDEX].channel |= 1 << 1; #endif #ifdef BSP_USING_PWM2_CH3 stm32_pwm_obj[PWM2_INDEX].channel |= 1 << 2; #endif #ifdef BSP_USING_PWM2_CH4 stm32_pwm_obj[PWM2_INDEX].channel |= 1 << 3; #endif #ifdef BSP_USING_PWM3_CH1 stm32_pwm_obj[PWM3_INDEX].channel |= 1 << 0; #endif #ifdef BSP_USING_PWM3_CH2 stm32_pwm_obj[PWM3_INDEX].channel |= 1 << 1; #endif #ifdef BSP_USING_PWM3_CH3 stm32_pwm_obj[PWM3_INDEX].channel |= 1 << 2; #endif #ifdef BSP_USING_PWM3_CH4 stm32_pwm_obj[PWM3_INDEX].channel |= 1 << 3; #endif #ifdef BSP_USING_PWM4_CH1 stm32_pwm_obj[PWM4_INDEX].channel |= 1 << 0; #endif #ifdef BSP_USING_PWM4_CH2 stm32_pwm_obj[PWM4_INDEX].channel |= 1 << 1; #endif #ifdef BSP_USING_PWM4_CH3 stm32_pwm_obj[PWM4_INDEX].channel |= 1 << 2; #endif #ifdef BSP_USING_PWM4_CH4 stm32_pwm_obj[PWM4_INDEX].channel |= 1 << 3; #endif #ifdef BSP_USING_PWM5_CH1 stm32_pwm_obj[PWM5_INDEX].channel |= 1 << 0; #endif #ifdef BSP_USING_PWM5_CH2 stm32_pwm_obj[PWM5_INDEX].channel |= 1 << 1; #endif #ifdef BSP_USING_PWM5_CH3 stm32_pwm_obj[PWM5_INDEX].channel |= 1 << 2; #endif #ifdef BSP_USING_PWM5_CH4 stm32_pwm_obj[PWM5_INDEX].channel |= 1 << 3; #endif #ifdef BSP_USING_PWM6_CH1 stm32_pwm_obj[PWM6_INDEX].channel |= 1 << 0; #endif #ifdef BSP_USING_PWM6_CH2 stm32_pwm_obj[PWM6_INDEX].channel |= 1 << 1; #endif #ifdef BSP_USING_PWM6_CH3 stm32_pwm_obj[PWM6_INDEX].channel |= 1 << 2; #endif #ifdef BSP_USING_PWM6_CH4 stm32_pwm_obj[PWM6_INDEX].channel |= 1 << 3; #endif #ifdef BSP_USING_PWM7_CH1 stm32_pwm_obj[PWM7_INDEX].channel |= 1 << 0; #endif #ifdef BSP_USING_PWM7_CH2 stm32_pwm_obj[PWM7_INDEX].channel |= 1 << 1; #endif #ifdef BSP_USING_PWM7_CH3 stm32_pwm_obj[PWM7_INDEX].channel |= 1 << 2; #endif #ifdef BSP_USING_PWM7_CH4 stm32_pwm_obj[PWM7_INDEX].channel |= 1 << 3; #endif #ifdef BSP_USING_PWM8_CH1 stm32_pwm_obj[PWM8_INDEX].channel |= 1 << 0; #endif #ifdef BSP_USING_PWM8_CH2 stm32_pwm_obj[PWM8_INDEX].channel |= 1 << 1; #endif #ifdef BSP_USING_PWM8_CH3 stm32_pwm_obj[PWM8_INDEX].channel |= 1 << 2; #endif #ifdef BSP_USING_PWM8_CH4 stm32_pwm_obj[PWM8_INDEX].channel |= 1 << 3; #endif #ifdef BSP_USING_PWM9_CH1 stm32_pwm_obj[PWM9_INDEX].channel |= 1 << 0; #endif #ifdef BSP_USING_PWM9_CH2 stm32_pwm_obj[PWM9_INDEX].channel |= 1 << 1; #endif #ifdef BSP_USING_PWM9_CH3 stm32_pwm_obj[PWM9_INDEX].channel |= 1 << 2; #endif #ifdef BSP_USING_PWM9_CH4 stm32_pwm_obj[PWM9_INDEX].channel |= 1 << 3; #endif #ifdef BSP_USING_PWM12_CH1 stm32_pwm_obj[PWM12_INDEX].channel |= 1 << 0; #endif #ifdef BSP_USING_PWM12_CH2 stm32_pwm_obj[PWM12_INDEX].channel |= 1 << 1; #endif } static int stm32_pwm_init(void) { int i = 0; int result = RT_EOK; pwm_get_channel(); for (i = 0; i < sizeof(stm32_pwm_obj) / sizeof(stm32_pwm_obj[0]); i++) { /* pwm init */ if (stm32_hw_pwm_init(&stm32_pwm_obj[i]) != RT_EOK) { LOG_E("%s init failed", stm32_pwm_obj[i].name); result = -RT_ERROR; goto __exit; } else { LOG_D("%s init success", stm32_pwm_obj[i].name); /* register pwm device */ if (rt_device_pwm_register(&stm32_pwm_obj[i].pwm_device, stm32_pwm_obj[i].name, &drv_ops, &stm32_pwm_obj[i].tim_handle) == RT_EOK) { LOG_D("%s register success", stm32_pwm_obj[i].name); } else { LOG_E("%s register failed", stm32_pwm_obj[i].name); result = -RT_ERROR; } } } __exit: return result; } INIT_DEVICE_EXPORT(stm32_pwm_init); #endif /* RT_USING_PWM */ 这段出现很多报错是什么原因
最新发布
08-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值