diff --git a/chip/chip.hpp b/chip/chip.hpp index 2707b5d..1f4f3af 100644 --- a/chip/chip.hpp +++ b/chip/chip.hpp @@ -4,9 +4,9 @@ #include "zcan_irq_dispatcher.hpp" #include "zgpio.hpp" #include "zirq_dispatcher.hpp" +#include "zpwm_generator.hpp" #include "ztim.hpp" #include "zuart.hpp" - extern "C" { typedef struct { diff --git a/chip/zpwm_generator.cpp b/chip/zpwm_generator.cpp new file mode 100644 index 0000000..8704090 --- /dev/null +++ b/chip/zpwm_generator.cpp @@ -0,0 +1,56 @@ +#include "zpwm_generator.hpp" + +#include "zirq_dispatcher.hpp" +using namespace iflytop; + +void ZPWMGenerator::initialize(zchip_tim_t *htim, uint32_t channel, float freq, bool polarity) { + m_htim = htim; + m_polarity = polarity; + m_channel = channel; + m_freq = freq; + + ZASSERT(m_htim->Init.AutoReloadPreload == TIM_AUTORELOAD_PRELOAD_ENABLE); + ZASSERT(m_htim->Init.CounterMode == TIM_COUNTERMODE_UP); +} + +/****************************************************** + * kTimMode_timer * + ******************************************************/ +void ZPWMGenerator::startPWM(float duty) { startPWM(m_freq, duty); } + +void ZPWMGenerator::startPWM(float freq, float duty) { + if (!m_polarity) { + duty = 100.0 - duty; + } + + m_freq = freq; + + uint32_t prescaler = 0; + uint32_t autoreload = 0; + + uint32_t timClkFreq = chip_get_timer_clock_sorce_freq(m_htim); + ZASSERT(chip_calculate_prescaler_and_autoreload_by_expect_freq(timClkFreq, freq, &prescaler, &autoreload)); + __HAL_TIM_SET_AUTORELOAD(m_htim, autoreload); + __HAL_TIM_SET_PRESCALER(m_htim, prescaler); + + /** + * @brief + */ + TIM_OC_InitTypeDef sConfigOC = {0}; + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = duty / 100.0 * __HAL_TIM_GET_AUTORELOAD(m_htim); + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; + sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; + + if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, m_channel) != HAL_OK) { + Error_Handler(); + } + // HAL_TIM_PWM_Start(m_htim, Channel); + HAL_TIM_PWM_Start(m_htim, m_channel); +} +void ZPWMGenerator::stopPWM() { + // HAL_TIM_PWM_Stop(m_htim, m_channel); + startPWM(0); +} diff --git a/chip/zpwm_generator.hpp b/chip/zpwm_generator.hpp new file mode 100644 index 0000000..9d4bbb0 --- /dev/null +++ b/chip/zpwm_generator.hpp @@ -0,0 +1,41 @@ + +#pragma once +#include + +#include "basic/base.hpp" + +#ifdef HAL_TIM_MODULE_ENABLED + +namespace iflytop { +using namespace iflytop; +class ZPWMGenerator { + public: + typedef function ontimirq_t; + + private: + zchip_tim_t *m_htim; + bool m_polarity; + uint32_t m_channel; + float m_freq; + + public: + ZPWMGenerator() {} + + /** + * @brief + * + * @param Channel PWM通道 TIM_CHANNEL_1 TIM_CHANNEL_2 TIM_CHANNEL_3 TIM_CHANNEL_4 + * @param Polarity 1:高为有效电平,0:低为有效电平 + */ + void initialize(zchip_tim_t *htim, uint32_t channel, float freq, bool polarity); + /******************************************************************************* + * PWM_MODE * + *******************************************************************************/ + void startPWM(float freq, float duty); + void startPWM(float duty); + void stopPWM(); +}; + +} // namespace iflytop + +#endif \ No newline at end of file diff --git a/chip/ztim.cpp b/chip/ztim.cpp index 45fa07b..b99accc 100644 --- a/chip/ztim.cpp +++ b/chip/ztim.cpp @@ -6,6 +6,12 @@ using namespace iflytop; void ZTIM::initialize(zchip_tim_t *htim, mode_t mode) { m_htim = htim; m_mode = mode; + + if (m_mode == ktm_pwm) { + ZASSERT(m_htim->Init.AutoReloadPreload == TIM_AUTORELOAD_PRELOAD_ENABLE); + ZASSERT(m_htim->Init.CounterMode == TIM_COUNTERMODE_UP); + ZASSERT(m_htim->Channel) + } } ZTIM::mode_t ZTIM::getMode() { return m_mode; } @@ -46,3 +52,33 @@ void ZTIM::simpleTimer_stop() { m_timer_start = false; HAL_TIM_Base_Stop(m_htim); } + +void ZTIM::setPWMFreq(float freq) { + uint32_t prescaler = 0; + uint32_t autoreload = 0; + + uint32_t timClkFreq = chip_get_timer_clock_sorce_freq(m_htim); + ZASSERT(chip_calculate_prescaler_and_autoreload_by_expect_freq(timClkFreq, freq, &prescaler, &autoreload)); + __HAL_TIM_SET_AUTORELOAD(m_htim, autoreload); + __HAL_TIM_SET_PRESCALER(m_htim, prescaler); +} +void ZTIM::setPWMPolarity(uint32_t Channel, uint32_t Polarity) { m_timpwmPolarity[Channel] = Polarity; } + +void ZTIM::startPWM(uint32_t Channel, float duty) { + /** + * @brief + */ + TIM_OC_InitTypeDef sConfigOC = {0}; + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = duty / 100.0 * __HAL_TIM_GET_AUTORELOAD(m_htim); + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; + sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; + + if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) { + Error_Handler(); + } + HAL_TIM_PWM_Start(m_htim, Channel); +} +void ZTIM::stopPWM(uint32_t Channel) { startPWM(Channel, 100); } diff --git a/chip/ztim.hpp b/chip/ztim.hpp index f96cf90..fe68365 100644 --- a/chip/ztim.hpp +++ b/chip/ztim.hpp @@ -26,6 +26,8 @@ class ZTIM { ontimirq_t m_simpleTimer_cb; + bool m_timpwmPolarity[4]; + public: ZTIM() {} @@ -51,10 +53,17 @@ class ZTIM { /******************************************************************************* * PWM_MODE * *******************************************************************************/ + + /** + * @brief + * + * @param Channel PWM通道 TIM_CHANNEL_1 TIM_CHANNEL_2 TIM_CHANNEL_3 TIM_CHANNEL_4 + * @param Polarity 1:高为有效电平,0:低为有效电平 + */ + void setPWMPolarity(uint32_t Channel, uint32_t Polarity); void setPWMFreq(float freq); void startPWM(uint32_t Channel, float duty); void stopPWM(uint32_t Channel); - }; } // namespace iflytop