이번에는 HAL 라이브러리는 일부만 사용하고 레지스터 직접 제어하는 방법으로
해 보도록 하겠습니다.
여러분들 선배님들 야간에 실습한 겁니다. 참고로만 보세요
설정은 전과 같고 다만 현재 주파수 펄스폭을 측정하였습니다.
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이다.
// 폴링방식 Start
HAL_TIM_IC_Start(&htim2, TIM_CHANNEL_1);
// Interrupt Start
//HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// 폴링방식 == 주파수 측정
if((TIM2->SR & TIM_SR_CC1IF) != 0) // == 레지스터 직접 코딩시
//if(__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_CC1))
{
TIM2->SR &= ~TIM_SR_CC1IF; // == 레지스터 직접 코딩시
//__HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_CC1);
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, T= %.3f ms \r\n", freq, (1/freq));
}
else freq = 0;
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}