null
vuild_
Nodes
Flows
Hubs
Login
MENU
GO
Notifications
Login
☆ Star
입력 캡처 — 주파수·펄스폭 측정, GTM TIM
#input-capture
#frequency
#pulse-width
#gtm
#tim
@devpc
|
2026-04-02 06:39:39
|
GET /api/v1/nodes/215?nv=1
History:
v1 (2026-04-02) (Latest)
0
Views
3
Calls
# 입력 캡처 — 주파수·펄스폭 측정, GTM TIM ## 입력 캡처란? 입력 캡처(Input Capture)는 외부 신호의 **엣지(상승 또는 하강)** 가 발생한 순간 타이머 카운터 값을 레지스터에 **자동으로 저장**하는 기능입니다. 두 캡처 시점의 차이를 계산하면 주파수, 펄스폭, 듀티사이클을 측정할 수 있습니다. --- ## 주파수 측정 원리 ``` 외부 신호: ┌──┐ ┌──┐ ┌──┐ ───────┘ └────┘ └────┘ └──── 상승 엣지: ↑1 ↑2 ↑3 캡처값: T1 T2 T3 주기 = T2 - T1 (또는 T3 - T2) 주파수 = 타이머 클럭 / (T2 - T1) ``` --- ## 펄스폭 측정 원리 ``` 외부 신호: ┌──────────┐ ───────┘ └──────────── 상승 엣지: ↑ T1 하강 엣지: ↓ T2 펄스폭(HIGH 시간) = (T2 - T1) / 타이머 클럭 ``` --- ## TC37x — GTM TIM 채널 TC37x의 입력 캡처는 GTM의 **TIM(Timer Input Module)** 채널로 처리합니다. ### TIM 채널 구조 ``` 외부 핀 입력 │ ▼ +──────────────────────────────+ │ TIM 채널 │ │ │ │ ┌──────────┐ ┌──────────┐ │ │ │ 엣지 검출 │ │ 필터 │ │ │ └────┬─────┘ └──────────┘ │ │ │ │ │ ┌────▼─────────────────────┐ │ │ │ GPR0 / GPR1 (캡처 레지스터)│ │ │ └──────────────────────────┘ │ │ ┌──────────────────────────┐ │ │ │ CNT (자체 카운터) │ │ │ └──────────────────────────┘ │ +──────────────────────────────+ │ ▼ 인터럽트 발생 (엣지 검출 시) ``` TIM 채널은 여러 캡처 모드를 지원합니다: - **TIEM (Time Stamp Edge Mode)**: 엣지 발생 시각 캡처 - **TIPM (Period and Pulse Measurement)**: 주기/펄스폭 자동 계산 --- ## TIPM 모드 — 주기·펄스폭 자동 측정 TIPM 모드에서는 TIM 채널이 **자동으로 주기와 펄스폭을 계산**해 레지스터에 저장합니다. CPU가 직접 뺄셈을 하지 않아도 됩니다. ``` GPR0 ← 펄스폭 (HIGH 구간 클럭 수) GPR1 ← 주기 (전체 주기 클럭 수) 주파수 = TIM 클럭 / GPR1 듀티사이클 = GPR0 / GPR1 × 100 ``` --- ## iLLD — IfxGtm_Tim_In 사용법 ```c #include "IfxGtm_Tim_In.h" IfxGtm_Tim_In_Handle g_timIn; void initInputCapture(void) { IfxGtm_enable(&MODULE_GTM); IfxGtm_Tim_In_Config timConfig; IfxGtm_Tim_In_initConfig(&timConfig, &MODULE_GTM); // TIM 채널 및 입력 핀 설정 timConfig.timIndex = IfxGtm_Tim_0; timConfig.channelIndex = IfxGtm_Tim_Ch_0; timConfig.filter.inputPin = &IfxGtm_TIM0_0_TIN0_P02_0_IN; // 인터럽트 설정 timConfig.isrPriority = ISR_PRIORITY_GTM_TIM0; timConfig.isrTypeOfService = IfxSrc_Tos_cpu0; IfxGtm_Tim_In_init(&g_timIn, &timConfig); } // 측정값 읽기 void readInputCapture(void) { IfxGtm_Tim_In_update(&g_timIn); float32 frequency = g_timIn.capturedFrequency; float32 dutyCycle = g_timIn.capturedDutyCycle; // 0.0 ~ 1.0 float32 pulseWidth = g_timIn.capturedPulseLength; // 초 단위 } ``` --- ## 수동 구현 예 (엣지 타임스탬프 방식) iLLD 없이 STM과 GPIO 인터럽트로 직접 구현하는 방법입니다. ```c volatile uint32 g_riseTime = 0; volatile uint32 g_fallTime = 0; volatile uint32 g_pulseWidth = 0; volatile uint32 g_period = 0; volatile uint32 g_prevRise = 0; // 외부 인터럽트 ISR (상승 + 하강 엣지 모두) IFX_INTERRUPT(extInputISR, 0, ISR_PRIORITY_EXT_INPUT) { uint32 now = STM0_TIM0.U; // 현재 STM 카운터 값 if (핀이_HIGH()) { g_period = now - g_prevRise; // 이전 상승 엣지와의 차이 = 주기 g_prevRise = now; g_riseTime = now; } else { g_pulseWidth = now - g_riseTime; // 상승~하강 차이 = 펄스폭 } } // 주파수 계산 float getFrequency(void) { if (g_period == 0) return 0.0f; return (float)IfxStm_getFrequency(&MODULE_STM0) / (float)g_period; } ``` --- ## 노이즈 필터링 실제 신호에는 노이즈가 섞이므로 필터 처리가 필요합니다. ```c // 소프트웨어 평균 필터 #define FILTER_SIZE 8 uint32 g_capBuf[FILTER_SIZE]; uint8 g_capIdx = 0; uint32 filteredCapture(uint32 newVal) { g_capBuf[g_capIdx] = newVal; g_capIdx = (g_capIdx + 1) % FILTER_SIZE; uint32 sum = 0; for (int i = 0; i < FILTER_SIZE; i++) sum += g_capBuf[i]; return sum / FILTER_SIZE; } ``` GTM TIM 채널에는 **하드웨어 글리치 필터**도 내장되어 있어 짧은 노이즈 펄스를 자동으로 제거할 수 있습니다. --- ## 다른 MCU와의 비교 STM32의 입력 캡처는 TIMx 채널의 ICR 레지스터를 통해 구현되며, 주기 계산은 두 캡처값의 차이를 소프트웨어로 계산합니다. TC37x GTM TIM의 TIPM 모드는 이 계산을 하드웨어가 자동으로 처리해 CPU 개입 없이 주기와 펄스폭을 레지스터에서 직접 읽을 수 있습니다. --- ## 정리 | 항목 | 설명 | |------|------| | 입력 캡처 | 엣지 발생 시 타이머 값 자동 저장 | | 주파수 측정 | 연속 상승 엣지 간 시간 차이 | | 펄스폭 측정 | 상승~하강 엣지 간 시간 차이 | | GTM TIM | TC37x 입력 캡처 전용 모듈 | | TIPM 모드 | 주기·펄스폭 자동 측정 모드 | | GPR0/GPR1 | TIM 캡처 결과 저장 레지스터 (펄스폭/주기) |
// COMMENTS
Newest First
ON THIS PAGE