mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-15 17:02:53 +08:00
296 lines
8.9 KiB
C
296 lines
8.9 KiB
C
#include "wm_pwm.h"
|
||
|
||
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD>Ƶ<EFBFBD>ʣ<EFBFBD> f = 40MHz / Prescaler / (Period + 1)<29><>
|
||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD>ռ<EFBFBD>ձȣ<D5B1>
|
||
* <20>ض<EFBFBD><D8B6><EFBFBD>ģʽ<C4A3><CABD><EFBFBD>ݼ<EFBFBD><DDBC><EFBFBD><EFBFBD><EFBFBD>(Pulse + 1) / (Period + 1)
|
||
* Pulse >= Period<6F><64>PWM<57><4D><EFBFBD><EFBFBD>һֱΪ<D6B1>ߵ<EFBFBD>ƽ
|
||
* Pulse < Period <20><>PWM<57><4D><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD>Ϊ(Pulse + 1)<29><><EFBFBD>͵<EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD>Ϊ(Period - Pulse)
|
||
* Pulse = 0 <20><>PWM<57><4D><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD>Ϊ(1)<29><><EFBFBD>͵<EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD>Ϊ(Period)
|
||
*
|
||
* <20>м<EFBFBD><D0BC><EFBFBD><EFBFBD><EFBFBD>ģʽ <20><>(2 * Pulse + 1) / (2 * (Period + 1))
|
||
* Pulse > Period <20><>PWM<57><4D><EFBFBD><EFBFBD>һֱΪ<D6B1>ߵ<EFBFBD>ƽ
|
||
* Pulse <= Period<6F><64>PWM<57><4D><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD>Ϊ(2 * Pulse + 1)<29><><EFBFBD>͵<EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD>Ϊ(2 * (Period - Pulse) + 1)
|
||
* Pulse = 0 <20><>PWM<57><4D><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD>Ϊ(1)<29><><EFBFBD>͵<EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD>Ϊ(2 * Period + 1)
|
||
*/
|
||
|
||
HAL_StatusTypeDef __PWM_OutMode_Config(PWM_HandleTypeDef *hpwm, uint32_t Channel, uint32_t OutMode)
|
||
{
|
||
if (PWM_OUT_MODE_BREAK == OutMode)
|
||
{
|
||
SET_BIT(hpwm->Instance->BKCR, (1 << (PWM_BKCR_EN_Pos + Channel)));
|
||
}
|
||
else if (PWM_OUT_MODE_5SYNC == OutMode)
|
||
{
|
||
assert_param(Channel == PWM_CHANNEL_0);
|
||
CLEAR_BIT(hpwm->Instance->BKCR, (PWM_CHANNEL_ALL << PWM_BKCR_EN_Pos));
|
||
SET_BIT(hpwm->Instance->CR, PWM_CR_ALLSYNCEN);
|
||
}
|
||
else if (PWM_OUT_MODE_2SYNC == OutMode)
|
||
{
|
||
assert_param((Channel == PWM_CHANNEL_0) || (Channel == PWM_CHANNEL_2));
|
||
CLEAR_BIT(hpwm->Instance->BKCR, (PWM_CHANNEL_ALL << PWM_BKCR_EN_Pos));
|
||
CLEAR_BIT(hpwm->Instance->CR, PWM_CR_ALLSYNCEN);
|
||
SET_BIT(hpwm->Instance->CR, (1 << (PWM_CR_TWOSYNCEN_Pos + Channel / 2)));
|
||
}
|
||
else if (PWM_OUT_MODE_2COMPLEMENTARY == OutMode)
|
||
{
|
||
assert_param((Channel == PWM_CHANNEL_0) || (Channel == PWM_CHANNEL_2));
|
||
CLEAR_BIT(hpwm->Instance->BKCR, (PWM_CHANNEL_ALL << PWM_BKCR_EN_Pos));
|
||
CLEAR_BIT(hpwm->Instance->CR, PWM_CR_ALLSYNCEN);
|
||
CLEAR_BIT(hpwm->Instance->CR, (1 << (PWM_CR_TWOSYNCEN_Pos + Channel / 2)));
|
||
SET_BIT(hpwm->Instance->CR, (1 << (PWM_CR_2COMPLEMENTARY_Pos + Channel / 2)));
|
||
if (Channel == PWM_CHANNEL_0)
|
||
{
|
||
MODIFY_REG(hpwm->Instance->DTCR, (PWM_DTCR_DTDIV | PWM_DTCR_DTCNT01), (PWM_DTCR_DTEN01 | hpwm->Init.Dtdiv | hpwm->Init.Dtcnt));
|
||
}
|
||
else if (Channel == PWM_CHANNEL_2)
|
||
{
|
||
MODIFY_REG(hpwm->Instance->DTCR, (PWM_DTCR_DTDIV | PWM_DTCR_DTCNT23), (PWM_DTCR_DTEN23 | hpwm->Init.Dtdiv | hpwm->Init.Dtcnt));
|
||
}
|
||
}
|
||
else if (PWM_OUT_MODE_INDEPENDENT == OutMode)
|
||
{
|
||
CLEAR_BIT(hpwm->Instance->BKCR, (PWM_CHANNEL_ALL << PWM_BKCR_EN_Pos));
|
||
CLEAR_BIT(hpwm->Instance->CR, PWM_CR_ALLSYNCEN);
|
||
if (Channel != PWM_CHANNEL_4)
|
||
{
|
||
CLEAR_BIT(hpwm->Instance->CR, (1 << (PWM_CR_TWOSYNCEN_Pos + Channel / 2)));
|
||
CLEAR_BIT(hpwm->Instance->CR, (1 << (PWM_CR_2COMPLEMENTARY_Pos + Channel / 2)));
|
||
}
|
||
}
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
HAL_StatusTypeDef __PWM_CountType_Config(PWM_HandleTypeDef *hpwm, uint32_t Channel, uint32_t CounterMode)
|
||
{
|
||
if (Channel == PWM_CHANNEL_4)
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CH4CR2, PWM_CH4CR2_CNTTYPE, (CounterMode << PWM_CH4CR2_CNTTYPE_Pos));
|
||
}
|
||
else
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CR, (0x0FF << (PWM_CR_CNTTYPE0_Pos + Channel * 2)),
|
||
(CounterMode << (PWM_CR_CNTTYPE0_Pos + Channel * 2)));
|
||
}
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
HAL_StatusTypeDef __PWM_Freq_Config(PWM_HandleTypeDef *hpwm, uint32_t Channel, uint32_t Prescaler, uint32_t Period)
|
||
{
|
||
if (hpwm->Channel == PWM_CHANNEL_0)
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CLKDIV01, PWM_CLKDIV01_CH0, hpwm->Init.Prescaler);
|
||
MODIFY_REG(hpwm->Instance->PERIOD, PWM_PERIOD_CH0, hpwm->Init.Period);
|
||
}
|
||
else if (hpwm->Channel == PWM_CHANNEL_1)
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CLKDIV01, PWM_CLKDIV01_CH1, (hpwm->Init.Prescaler << PWM_CLKDIV01_CH1_Pos));
|
||
MODIFY_REG(hpwm->Instance->PERIOD, PWM_PERIOD_CH1, (hpwm->Init.Period << PWM_PERIOD_CH1_Pos));
|
||
}
|
||
else if (hpwm->Channel == PWM_CHANNEL_2)
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CLKDIV23, PWM_CLKDIV23_CH2, hpwm->Init.Prescaler);
|
||
MODIFY_REG(hpwm->Instance->PERIOD, PWM_PERIOD_CH2, (hpwm->Init.Period << PWM_PERIOD_CH2_Pos));
|
||
}
|
||
else if (hpwm->Channel == PWM_CHANNEL_3)
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CLKDIV23, PWM_CLKDIV23_CH3, (hpwm->Init.Prescaler << PWM_CLKDIV23_CH3_Pos));
|
||
MODIFY_REG(hpwm->Instance->PERIOD, PWM_PERIOD_CH3, (hpwm->Init.Period << PWM_PERIOD_CH3_Pos));
|
||
}
|
||
else if (hpwm->Channel == PWM_CHANNEL_4)
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CH4CR1, (PWM_CH4CR1_DIV | PWM_CH4CR1_PRD),
|
||
((hpwm->Init.Prescaler << PWM_CH4CR1_DIV_Pos) | (hpwm->Init.Period << PWM_CH4CR1_PRD_Pos)));
|
||
}
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
HAL_StatusTypeDef __PWM_Duty_Config(PWM_HandleTypeDef *hpwm, uint32_t Channel, uint32_t Pulse)
|
||
{
|
||
if (Channel == PWM_CHANNEL_0)
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CMPDAT, PWM_CMPDAT_CH0, Pulse);
|
||
}
|
||
else if (Channel == PWM_CHANNEL_1)
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CMPDAT, PWM_CMPDAT_CH1, (Pulse << PWM_CMPDAT_CH1_Pos));
|
||
}
|
||
else if (Channel == PWM_CHANNEL_2)
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CMPDAT, PWM_CMPDAT_CH2, (Pulse << PWM_CMPDAT_CH2_Pos));
|
||
}
|
||
else if (Channel == PWM_CHANNEL_3)
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CMPDAT, PWM_CMPDAT_CH3, (Pulse << PWM_CMPDAT_CH3_Pos));
|
||
}
|
||
else if (Channel == PWM_CHANNEL_4)
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CH4CR2, PWM_CH4CR2_CMP, (Pulse << PWM_CH4CR2_CMP_Pos));
|
||
}
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
HAL_StatusTypeDef __PWM_AutoReload_Config(PWM_HandleTypeDef *hpwm, uint32_t Channel, uint32_t AutoReloadPreload)
|
||
{
|
||
if (Channel == PWM_CHANNEL_4)
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CH4CR2, PWM_CH4CR2_CNTMODE, (AutoReloadPreload << PWM_CH4CR2_CNTMODE_Pos));
|
||
}
|
||
else
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CR, (0x01 << (PWM_CR_CNTMODE_Pos + Channel)),
|
||
(AutoReloadPreload << (PWM_CR_CNTMODE_Pos + Channel)));
|
||
}
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
HAL_StatusTypeDef __PWM_OutInverse_Config(PWM_HandleTypeDef *hpwm, uint32_t Channel, uint32_t OutInverse)
|
||
{
|
||
if (Channel == PWM_CHANNEL_4)
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CH4CR2, PWM_CH4CR2_PINV, OutInverse);
|
||
}
|
||
else
|
||
{
|
||
MODIFY_REG(hpwm->Instance->CR, (0x01 << (PWM_CR_PINV_Pos + Channel)),
|
||
(OutInverse << (PWM_CR_PINV_Pos + Channel)));
|
||
}
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
HAL_StatusTypeDef __PWM_OutEn_Config(PWM_HandleTypeDef *hpwm, uint32_t Channel)
|
||
{
|
||
if (Channel == PWM_CHANNEL_0)
|
||
{
|
||
CLEAR_BIT(hpwm->Instance->CR, PWM_CR_POEN);
|
||
}
|
||
if (Channel == PWM_CHANNEL_4)
|
||
{
|
||
CLEAR_BIT(hpwm->Instance->CH4CR3, PWM_CH4CR3_POEN);
|
||
}
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
HAL_StatusTypeDef HAL_PWM_Init(PWM_HandleTypeDef *hpwm)
|
||
{
|
||
if (hpwm == NULL)
|
||
{
|
||
return HAL_ERROR;
|
||
}
|
||
|
||
assert_param(IS_PWM_INSTANCE(hpwm->Instance));
|
||
assert_param(IS_PWM_CHANNELS(hpwm->Channel));
|
||
assert_param(IS_PWM_PRESCALER(hpwm->Init.Prescaler));
|
||
assert_param(IS_PWM_COUNTER_MODE(hpwm->Init.CounterMode));
|
||
assert_param(IS_PWM_PERIOD(hpwm->Init.Period));
|
||
assert_param(IS_PWM_PULSE(hpwm->Init.Pulse));
|
||
assert_param(IS_PWM_AUTORELOADPRELOAD(hpwm->Init.AutoReloadPreload));
|
||
assert_param(IS_PWM_OUTMODE(hpwm->Init.OutMode));
|
||
assert_param(IS_PWM_OUTINVERSE(hpwm->Init.OutInverse));
|
||
if (hpwm->Init.OutMode == PWM_OUT_MODE_2COMPLEMENTARY)
|
||
{
|
||
assert_param(IS_PWM_DTDIV(hpwm->Init.Dtdiv));
|
||
assert_param(IS_PWM_DTCNT(hpwm->Init.Dtcnt));
|
||
}
|
||
|
||
HAL_PWM_MspInit(hpwm);
|
||
__PWM_OutMode_Config(hpwm, hpwm->Channel, hpwm->Init.OutMode);
|
||
__PWM_CountType_Config(hpwm, hpwm->Channel, hpwm->Init.CounterMode);
|
||
__PWM_Freq_Config(hpwm, hpwm->Channel, hpwm->Init.Prescaler, hpwm->Init.Period);
|
||
__PWM_Duty_Config(hpwm, hpwm->Channel, hpwm->Init.Pulse);
|
||
__PWM_AutoReload_Config(hpwm, hpwm->Channel, hpwm->Init.AutoReloadPreload);
|
||
__PWM_OutInverse_Config(hpwm, hpwm->Channel, hpwm->Init.OutInverse);
|
||
__PWM_OutEn_Config(hpwm, hpwm->Channel);
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
HAL_StatusTypeDef HAL_PWM_DeInit(PWM_HandleTypeDef *hpwm)
|
||
{
|
||
assert_param(IS_PWM_INSTANCE(hpwm->Instance));
|
||
|
||
HAL_PWM_MspDeInit(hpwm);
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
__attribute__((weak)) void HAL_PWM_MspInit(PWM_HandleTypeDef *hpwm)
|
||
{
|
||
UNUSED(hpwm);
|
||
}
|
||
|
||
__attribute__((weak)) void HAL_PWM_MspDeInit(PWM_HandleTypeDef *hpwm)
|
||
{
|
||
UNUSED(hpwm);
|
||
}
|
||
|
||
HAL_StatusTypeDef HAL_PWM_Start(PWM_HandleTypeDef *hpwm, uint32_t channel)
|
||
{
|
||
if (hpwm == NULL)
|
||
{
|
||
return HAL_ERROR;
|
||
}
|
||
|
||
assert_param(IS_PWM_INSTANCE(hpwm->Instance));
|
||
assert_param(IS_PWM_CHANNELS(channel));
|
||
|
||
SET_BIT(hpwm->Instance->CR, (0x01 << (PWM_CR_CNTEN_Pos + channel)));
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
HAL_StatusTypeDef HAL_PWM_Stop(PWM_HandleTypeDef *hpwm, uint32_t Channel)
|
||
{
|
||
if (hpwm == NULL)
|
||
{
|
||
return HAL_ERROR;
|
||
}
|
||
|
||
assert_param(IS_PWM_INSTANCE(hpwm->Instance));
|
||
assert_param(IS_PWM_CHANNELS(Channel));
|
||
|
||
CLEAR_BIT(hpwm->Instance->CR, (0x01 << (PWM_CR_CNTEN_Pos + Channel)));
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
HAL_StatusTypeDef HAL_PWM_Duty_Set(PWM_HandleTypeDef *hpwm, uint32_t Channel, uint32_t Duty)
|
||
{
|
||
if (hpwm == NULL)
|
||
{
|
||
return HAL_ERROR;
|
||
}
|
||
|
||
assert_param(IS_PWM_INSTANCE(hpwm->Instance));
|
||
assert_param(IS_PWM_CHANNELS(Channel));
|
||
assert_param(IS_PWM_PULSE(Duty));
|
||
|
||
__PWM_Duty_Config(hpwm, Channel, Duty);
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
HAL_StatusTypeDef HAL_PWM_Freq_Set(PWM_HandleTypeDef *hpwm, uint32_t Channel, uint32_t Prescaler, uint32_t Period)
|
||
{
|
||
if (hpwm == NULL)
|
||
{
|
||
return HAL_ERROR;
|
||
}
|
||
|
||
assert_param(IS_PWM_INSTANCE(hpwm->Instance));
|
||
assert_param(IS_PWM_CHANNELS(Channel));
|
||
assert_param(IS_PWM_PULSE(Period));
|
||
|
||
__PWM_Freq_Config(hpwm, Channel, Prescaler, Period);
|
||
|
||
return HAL_OK;
|
||
}
|
||
|