296 lines
8.9 KiB
C
Raw Normal View History

2022-03-28 17:19:25 +08:00
#include "wm_pwm.h"
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD>Ƶ<EFBFBD>ʣ<EFBFBD> f = 40MHz / Prescaler / (Period + 1)<29><>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD>ռ<EFBFBD>ձȣ<EFBFBD>
* <EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD>ģʽ<EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(Pulse + 1) / (Period + 1)
* Pulse >= Period<EFBFBD><EFBFBD>PWM<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һֱΪ<EFBFBD>ߵ<EFBFBD>ƽ
* Pulse < Period <EFBFBD><EFBFBD>PWM<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ(Pulse + 1)<EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ(Period - Pulse)
* Pulse = 0 <EFBFBD><EFBFBD>PWM<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ(1)<EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ(Period)
*
* <EFBFBD>м<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ <EFBFBD><EFBFBD>(2 * Pulse + 1) / (2 * (Period + 1))
* Pulse > Period <EFBFBD><EFBFBD>PWM<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һֱΪ<EFBFBD>ߵ<EFBFBD>ƽ
* Pulse <= Period<EFBFBD><EFBFBD>PWM<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ(2 * Pulse + 1)<EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ(2 * (Period - Pulse) + 1)
* Pulse = 0 <EFBFBD><EFBFBD>PWM<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ(1)<EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>ƽ<EFBFBD><EFBFBD><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;
}