TIM2 Ch1 폴링방식 주파수 측정 캡처기능입니다.
주파수 측정을 폴링방식으로 구현했습니다.
타이머 7로 100hz(10ms)마다 GPIO Pin을 토글시켰 출력했습니다.
실제 출력 주파수는 전체주기는 20ms로 주파수는 50HZ입니다.
참고로 TIM2는 고급타이머로 32Bit 입니다.(TIM5도 32Bit 고급타이머임)
// TIM2 입력 클럭 = 90 MHz
// PSC = 89
// CNT 클럭 = 1 MHz
// CH1 Rising Edge Capture
// 1 Count = 1 us
.
계산식
입력신호 : F = 100 Hz
주기 : T = 10 ms
캡처결과
첫 번째 Rising Edge == CCR1 = 10000 == A
두 번째 Rising Edge == CCR1 = 20000 == B
계산 : period_cnt = 10000 == B - A
CNT 클럭: : F = 1MHZ
측정 주기 : 1u sec X 10000 == 10000u sec == 10ms
측정주파수 : 100HZ
실제 출력은 H / L 비트반전하여 출력되므로 전체 주기는 20m sec 이며
실제 측정 주파수는 50HZ이다.
주파수 계산식 =
volatile uint32_t cap_new = 0;
volatile uint32_t cap_old = 0;
volatile uint32_t period_cnt = 0;
volatile float freq = 0.0f;
HAL_TIM_IC_Start(&htim2, TIM_CHANNEL_1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
//if(TIM2->SR & TIM_SR_CC1IF) == 레지스터 직접 코딩시
if(__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_CC1))
{
// FLAG CLR
// TIM2->SR &= ~TIM_SR_CC1IF; // == 레지스터 직접 코딩시
__HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_CC1);
// data Read
// cap_new = TIM2->CCR1; // == 레지스터 직접 코딩시
cap_new = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);
if(cap_new >= cap_old)
{
period_cnt = cap_new - cap_old;
}
else
{ //// 32비트 타이머 기준 오버플로우 보정
period_cnt = (0xFFFFFFFF - cap_old) + cap_new + 1;
}
cap_old = cap_new;
if(period_cnt != 0)
{
freq = 1000000.0f / (float)period_cnt;
}
printf("Freq = %.2f Hz\r\n", freq);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM7)
{
Out_Bit_Tg(Pulse_OUT_GPIO_Port, Pulse_OUT_Pin);
}
}