STM32_PWM_Interrupt_MODE
STM32_PWM_MODE
STM32에 사용하는 PWM을 interrupt로 사용하는 방법을 정리.
1. PWM 초기 설정
- 아래와 같이 사용하는 Timer의 channel을 PWM Generation으로 설정
- 관련 Configuration을 설정
- Counter Settings
- TIM Clock = Datasheet를 참고하여 어떤 clock를 사용하는지(APB1,APB2 등)을 체크할 것.
- Prescaler : 1
- Period Count : 35999
- TIM Tick = (1 / TIM Clock) * (Prescaler + 1) * (Period Count + 1)
- PWM Frequency = (1 / TIM Tick)
- PWM Generation Channel
- mode
- mode 1 : PWM Duty Level이 High
- mode 2 : PWM Duty Level이 Low
- Pulse : PWM Duty를 설정할 수 있음.
- Fast mode : PWM Fast mode 여부
- mode
- interrupt mode를 사용하여 callback이 호출되도록 함.
2. PWM code Example
2.1 init
- 아래의 코드를 사용하여 PWM interrupt mode를 init함.
/*...*/ HAL_TIM_PWM_Start_IT(&htim2,TIM_CHANNEL_3); /*...*/
2.2 start
- PWM Duty를 조절할 수 있는 별도의 함수를 구현
FUNC_StatusTypeDef PWM_SetValue(uint32_t cp_channel, uint8_t persent) { TIM_OC_InitTypeDef sConfigOC = {0}; uint16_t value = 0; //uint16_t maxvalue = 35999; //double unitvalue = 359.99; uint16_t maxvalue = 36000; double unitvalue = 360.00; if((persent < 0) || (persent > 100)) { return FUNC_ERROR; } if((cp_channel != TIM_CHANNEL_3) && (cp_channel != TIM_CHANNEL_4)) { return FUNC_ERROR; } value = (uint16_t)(maxvalue - (uint16_t)(unitvalue * persent)); //__disable_irq(); HAL_TIM_PWM_Stop(&htim2, cp_channel); sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = value; if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, cp_channel) != HAL_OK) { //Error_Handler(); __enable_irq(); return FUNC_ERROR; } if(HAL_TIM_PWM_Start(&htim2, cp_channel) != HAL_OK) { //Error_Handler(); __enable_irq(); return FUNC_ERROR; } //__enable_irq(); return FUNC_OK; }
2.3 callback
- 아래의 코드와 같이 callback 함수를 사용하여 PWM Pulse 출력의 1cycle이 끝나면
PWM Duty를 변경하도록 구현
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
sCP *pCP;
uint32_t bCh;
if(htim == &htim2)
{
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
{
pCP = &CP_B;
bCh = TIM_CHANNEL_3;
}
else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)
{
pCP = &CP_C;
bCh = TIM_CHANNEL_4;
}
else
{
return;
}
if(pCP->PWM_Duty != pCP->PWM_DutyBK)
{
if(FUNC_OK != PWM_SetValue(bCh, pCP->PWM_Duty))
{
printf("PWM_SetValue ERROR \r\n");
}
else
{
pCP->PWM_DutyBK = pCP->PWM_Duty;
}
}
}
}
댓글남기기