TMS320F28388D는 Texas Instruments의 C2000 시리즈 마이크로컨트롤러로, 실시간 제어 애플리케이션에 최적화된 32비트 CPU 타이머를 제공합니다. 이 가이드에서는 TMS320F28388D의 CPU 타이머 구조, 모든 DriverLib API의 상세 설명, 그리고 상세 주석이 포함된 예제 코드를 제공합니다. 초보자부터 숙련된 개발자까지 활용 가능한 실용적인 정보를 제공하며, C2000Ware의 DriverLib를 기반으로 한 예제를 포함합니다.
TMS320F28388D CPU 타이머란
TMS320F28388D는 CPU1과 CPU2 각각에 3개의 32비트 타이머(Timer0, Timer1, Timer2)를 제공하여 총 6개의 타이머를 지원합니다. 이 타이머들은 주기적 인터럽트, 시간 측정, 이벤트 트리거 등에 사용됩니다. 주요 특징은 다음과 같습니다:
- 32비트 카운터: TIM 레지스터로 시스템 클럭(SYSCLK)을 기반으로 동작.
- 프리스케일러: TDDR 레지스터로 클럭 분주 조정 가능.
- 인터럽트: Timer0(PIE 그룹 1, INT7), Timer1(INT13), Timer2(INT14)로 고유 인터럽트 제공.
- 제어 레지스터: TIF(오버플로우 플래그), TRB(리로드), TSS(시작/정지) 등.
DriverLib API: TMS320F28388D CPU 타이머 제어
TI의 DriverLib는 하드웨어 추상화 계층(HAL)을 제공하여 CPU 타이머 설정을 간소화합니다. driverlib/cputimer.h에 정의된 모든 API는 다음과 같습니다:
1. initCPUTimer(void) -TI 제공 예제 함수
- 기능: 지정된 타이머를 초기화하여 레지스터를 기본값으로 설정하고 인터럽트를 비활성화.
- 매개변수: 타이머 베이스 주소(CPUTIMER0_BASE, CPUTIMER1_BASE, CPUTIMER2_BASE).
- 반환값: 없음.
- 예시: CPUTimer_initTimer(); // Timer0 초기화.
2. configCPUTimer(uint32_t timer, uint32_t sysclkHz, uint32_t period) - TI 제공 예제 함수
- 기능: 시스템 클럭 주파수와 주기(마이크로초 단위)를 기반으로 타이머를 설정.
- 매개변수:
- timer: 타이머 베이스 주소.
- sysclkHz: 시스템 클럭 주파수(Hz, 예: DEVICE_SYSCLK_FREQ).
- period: 타이머 주기(마이크로초).
- 반환값: 없음.
- 예시: CPUTimer_configTimer(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 1000000); // 1초 주기.
3. CPUTimer_startTimer(uint32_t timer)
- 기능: 타이머를 시작하여 카운터 동작 활성화(TSS 비트를 0으로 설정, TIM을 PRD로 리로드).
- 매개변수: 타이머 베이스 주소.
- 반환값: 없음.
- 예시: CPUTimer_startTimer(CPUTIMER0_BASE); // Timer0 시작.
4. CPUTimer_stopTimer(uint32_t timer)
- 기능: 타이머를 정지(TSS 비트를 1로 설정).
- 매개변수: 타이머 베이스 주소.
- 반환값: 없음.
- 예시: CPUTimer_stopTimer(CPUTIMER0_BASE); // Timer0 정지.
5. CPUTimer_reloadTimerCounter(uint32_t timer)
- 기능: 타이머 카운터(TIM)를 주기 레지스터(PRD) 값으로 리로드(TRB 비트 설정).
- 매개변수: 타이머 베이스 주소.
- 반환값: 없음.
- 예시: CPUTimer_reloadTimer(CPUTIMER0_BASE); // Timer0 리로드.
6. CPUTimer_getTimerCount(uint32_t timer)
- 기능: 현재 타이머 카운터(TIM) 값을 반환(인라인 함수로 빠른 실행).
- 매개변수: 타이머 베이스 주소.
- 반환값: uint32_t 타입의 카운터 값.
- 예시: uint32_t count = CPUTimer_getTimerCount(CPUTIMER1_BASE); // 현재 카운터 값 읽기.
7. CPUTimer_enableInterrupt(uint32_t timer)
- 기능: 타이머 인터럽트를 활성화(TIE 비트 설정).
- 매개변수: 타이머 베이스 주소.
- 반환값: 없음.
- 예시: CPUTimer_enableInterrupt(CPUTIMER0_BASE); // Timer0 인터럽트 활성화.
8. CPUTimer_disableInterrupt(uint32_t timer)
- 기능: 타이머 인터럽트를 비활성화(TIE 비트 클리어).
- 매개변수: 타이머 베이스 주소.
- 반환값: 없음.
- 예시: CPUTimer_disableInterrupt(CPUTIMER0_BASE); // Timer0 인터럽트 비활성화.
9. CPUTimer_setPeriod(uint32_t timer, uint32_t period)
- 기능: 타이머의 주기 레지스터(PRD) 값을 설정(클럭 사이클 단위).
- 매개변수:
- timer: 타이머 베이스 주소.
- period: 주기 값(클럭 사이클 단위).
- 반환값: 없음.
- 예시: CPUTimer_setPeriod(CPUTIMER1_BASE, 1000000); // 주기 설정.
10. CPUTimer_setPreScaler(uint32_t timer, uint16_t prescaler)
- 기능: 타이머의 프리스케일러(TDDR)를 설정하여 SYSCLK을 분주.
- 매개변수:
- timer: 타이머 베이스 주소.
- prescaler: 프리스케일러 값(0~255, 실제 분주비는 prescaler+1).
- 반환값: 없음.
- 예시: CPUTimer_setPreScaler(CPUTIMER2_BASE, 1); // 분주비 2.
11. CPUTimer_getTimerOverflowStatus(uint32_t timer)
- 기능: 타이머 오버플로우 플래그(TIF) 상태를 반환(TIM이 0에 도달 시 1).
- 매개변수: 타이머 베이스 주소.
- 반환값: bool 타입(true: 오버플로우 발생, false: 발생 안 함).
- 예시: bool status = CPUTimer_getTimerOverflowStatus(CPUTIMER0_BASE); // 오버플로우 확인.
12. CPUTimer_clearOverflowFlag(uint32_t timer)
- 기능: 타이머 오버플로우 플래그(TIF)를 클리어.
- 매개변수: 타이머 베이스 주소.
- 반환값: 없음.
- 예시: CPUTimer_clearOverflowFlag(CPUTIMER0_BASE); // 오버플로우 플래그 클리어.
예제 1: 1초 주기 LED 토글
이 예제는 Timer0를 사용하여 1초마다 LED를 토글합니다. 상세 주석으로 각 단계 설명.
//#############################################################################
// FILE: main.c
// TITLE: TMS320F28388D CPU Timer0 LED Toggle Example
// DESCRIPTION: Uses CPU Timer0 to toggle an LED every 1 second
// with DriverLib and C2000Ware, incorporating emulation mode.
// C2000Ware Version: v6.00.00.00
// Copyright (C) 2025 Texas Instruments Incorporated
//#############################################################################
#include "driverlib.h" // TI DriverLib 기본 헤더 파일 포함
#include "device.h" // 디바이스별 설정(device.h) 포함
#include "cputimer.h" // CPU 타이머 관련 API 포함
#include "interrupt.h" // 인터럽트 관련 API 포함
// Timer0 인터럽트 서비스 루틴(ISR) 선언
__interrupt void timer0ISR(void);
// LED 상태를 저장하는 전역 변수 (volatile로 인터럽트에서 안전하게 사용)
volatile bool ledState = false;
void main(void)
{
// 디바이스 클럭 및 주변 장치 초기화 (PLL, Watchdog 등 설정)
// Watchdog은 기본적으로 비활성화됨
Device_init();
// GPIO 초기화
Device_initGPIO();
// LED 핀 설정 (GPIO31, LAUNCHXL-F28388D의 LED D9 사용)
// 주의: 사용 중인 보드의 schematics에 따라 GPIO 번호 확인 (예: GPIO34로 변경 가능)
GPIO_setPadConfig(31, GPIO_PIN_TYPE_STD); // GPIO31을 표준 GPIO로 설정
GPIO_setDirectionMode(31, GPIO_DIR_MODE_OUT); // GPIO31을 출력 모드로 설정
// PIE(Peripheral Interrupt Expansion) 모듈 초기화
Interrupt_initModule();
// 인터럽트 벡터 테이블 초기화
Interrupt_initVectorTable();
// Timer0 인터럽트를 ISR에 등록 (INT_TIMER0은 Timer0의 인터럽트 벡터, PIE 그룹 1, INT7)
Interrupt_register(INT_TIMER0, &timer0ISR);
// Timer0 인터럽트 활성화
Interrupt_enable(INT_TIMER0);
// Timer0 초기화: 레지스터를 수동으로 설정
// 1. 타이머 정지 (TSS 비트를 1로 설정)
CPUTimer_stopTimer(CPUTIMER0_BASE);
// 2. 인터럽트 비활성화 (TIE 비트 클리어, 초기화 안전성 보장)
CPUTimer_disableInterrupt(CPUTIMER0_BASE);
// 3. 주기 설정: 1초 주기, 시스템 클럭 200MHz 기준 200,000,000 사이클
CPUTimer_setPeriod(CPUTIMER0_BASE, 200000000U); // PRD에 200,000,000 설정
// 4. 프리스케일러 설정: TDDR=0 (분주비 1)
CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);
// 주의: Timer0는 SYSCLK(CPUTIMER_CLOCK_SOURCE_SYS)만 사용 가능
// CPUTimer_selectClockSource는 Timer2 전용
// 에뮬레이션 모드 설정: 디버깅 시 타이머가 자유 실행되도록 설정
// CPUTIMER_EMULATIONMODE_RUNFREE: 디버깅 중에도 타이머 계속 실행
CPUTimer_setEmulationMode(CPUTIMER0_BASE, CPUTIMER_EMULATIONMODE_RUNFREE);
// Timer0 인터럽트 활성화 (TIE 비트 설정)
CPUTimer_enableInterrupt(CPUTIMER0_BASE);
// 전역 인터럽트 활성화 (CPU 수준에서 인터럽트 허용)
Interrupt_enableMaster();
// Timer0 시작 (TIM을 PRD로 리로드하고 TSS 비트를 0으로 설정하여 카운터 동작 시작)
CPUTimer_startTimer(CPUTIMER0_BASE);
// 무한 루프: 인터럽트가 LED 토글 작업 처리
for(;;)
{
// 추가 작업이 필요 없는 경우 대기
// 디버깅 시 ledState 또는 CPUTimer_getTimerCount(CPUTIMER0_BASE) 확인 가능
}
}
// Timer0 인터럽트 서비스 루틴: 1초마다 호출
__interrupt void timer0ISR(void)
{
// LED 상태 토글 (true/false 전환)
ledState = !ledState;
// LED 핀에 상태 쓰기 (1: 켜짐, 0: 꺼짐)
GPIO_writePin(31, ledState ? 1 : 0);
// 타이머 오버플로우 플래그(TIF) 클리어
CPUTimer_clearOverflowFlag(CPUTIMER0_BASE);
// 인터럽트 확인: PIE 그룹 1 클리어 (Timer0는 그룹 1, INT7에 속함)
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}
설명: Timer0를 1초 주기로 설정하고, 인터럽트를 통해 LED를 토글합니다. 주석은 초기화, 설정, 인터럽트 처리 단계를 명확히 설명합니다.
예제 2: 타이머 카운터 모니터링 (SCI 출력)
Timer1의 카운터 값을 SCI를 통해 출력합니다. 상세 주석 포함.
//#############################################################################
// FILE: main.c
// TITLE: TMS320F28388D CPU Timer1 SCI Output Example
// DESCRIPTION: Uses CPU Timer1 to monitor counter value every 500ms
// and outputs via SCIA at 115200 baudrate with DriverLib.
// C2000Ware Version: v6.00.00.00
// Copyright (C) 2025 Texas Instruments Incorporated
//#############################################################################
#include "driverlib.h" // TI DriverLib 기본 헤더 파일 포함
#include "device.h" // 디바이스별 설정(device.h) 포함
#include "cputimer.h" // CPU 타이머 관련 API 포함
#include "sci.h" // SCI 관련 API 포함
#include <stdio.h> // sprintf를 위한 표준 라이브러리 포함
#include <string.h> // strlen을 위한 표준 라이브러리 포함
// SCI를 통해 문자열을 전송하는 함수
void SCI_print(const char *msg)
{
// SCI 모듈을 통해 문자열 전송 (uint16_t로 캐스팅하여 전송)
SCI_writeCharArray(SCIA_BASE, (uint16_t *)msg, strlen(msg));
}
void main(void)
{
// 디바이스 클럭 및 주변 장치 초기화 (PLL, Watchdog 등 설정)
// Watchdog은 기본적으로 비활성화됨
Device_init();
// GPIO 초기화
Device_initGPIO();
// SCI TX/RX 핀 설정 (LAUNCHXL-F28388D: GPIO28=SCIA_RX, GPIO29=SCIA_TX)
// pin_map.h: GPIO_28_SCIA_RX (0x00081801U), GPIO_29_SCIA_TX (0x00081A01U)
GPIO_setPinConfig(GPIO_28_SCIA_RX); // GPIO28을 SCIA RX로 설정
GPIO_setPinConfig(GPIO_29_SCIA_TX); // GPIO29를 SCIA TX로 설정
// SCI 설정: 115200 baudrate, 8비트 데이터, 1 스톱 비트, 패리티 없음
// LSPCLK: DEVICE_LSPCLK_FREQ (예: 50MHz) 기준
SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 115200,
(SCI_CONFIG_WLEN_8 | SCI_CONFIG_STOP_ONE | SCI_CONFIG_PAR_NONE));
// SCI FIFO 활성화 (전송 안정성 향상)
SCI_enableFIFO(SCIA_BASE);
// SCI 모듈 활성화
SCI_enableModule(SCIA_BASE);
// Timer1 초기화: 레지스터를 수동으로 설정
// 1. 타이머 정지 (TSS 비트를 1로 설정)
CPUTimer_stopTimer(CPUTIMER1_BASE);
// 2. 인터럽트 비활성화 (TIE 비트 클리어, 이 예제에서는 인터럽트 사용 안 함)
CPUTimer_disableInterrupt(CPUTIMER1_BASE);
// 3. 주기 설정: 500ms 주기, 시스템 클럭 200MHz 기준 100,000,000 사이클
CPUTimer_setPeriod(CPUTIMER1_BASE, 100000000U); // PRD에 100,000,000 설정
// 4. 프리스케일러 설정: TDDR=0 (분주비 1)
CPUTimer_setPreScaler(CPUTIMER1_BASE, 0);
// 주의: Timer1은 SYSCLK(CPUTIMER_CLOCK_SOURCE_SYS)만 사용 가능
// CPUTimer_selectClockSource는 Timer2 전용
// 에뮬레이션 모드 설정: 디버깅 시 타이머가 자유 실행되도록 설정
// CPUTIMER_EMULATIONMODE_RUNFREE: 디버깅 중에도 타이머 계속 실행
CPUTimer_setEmulationMode(CPUTIMER1_BASE, CPUTIMER_EMULATIONMODE_RUNFREE);
// Timer1 시작 (TIM을 PRD로 리로드하고 TSS 비트를 0으로 설정하여 카운터 동작 시작)
CPUTimer_startTimer(CPUTIMER1_BASE);
// 카운터 값을 저장할 문자열 버퍼
char msg[50];
// 메인 루프: 타이머 값 모니터링 및 SCI 출력
for(;;)
{
// 현재 Timer1의 카운터 값 읽기 (TIM 레지스터 값 반환)
uint32_t count = CPUTimer_getTimerCount(CPUTIMER1_BASE);
// 카운터 값을 문자열로 변환 (포맷: "Timer1 Count: <값>")
sprintf(msg, "Timer1 Count: %lu\r\n", count);
// SCI로 문자열 전송
SCI_print(msg);
// 100ms 대기하여 과도한 SCI 전송 방지 (100,000us)
DEVICE_DELAY_US(100000);
}
}
설명: Timer1의 카운터 값을 100ms마다 읽어 SCI로 전송합니다. 주석은 SCI 설정, 타이머 설정, 데이터 전송 과정을 상세히 설명합니다.
예제 3: 다중 타이머 동기화
Timer0, Timer1, Timer2를 각각 1초, 2초, 4초 주기로 동기화합니다. 상세 주석 포함.
//
// 포함된 파일들
//
#include "driverlib.h" // TI DriverLib 헤더 파일 포함: C2000 마이크로컨트롤러의 주변 장치 드라이버 라이브러리를 제공합니다.
#include "device.h" // 디바이스별 설정(device.h) 포함: 특정 디바이스(예: TMS320F2837xD)의 설정과 매크로를 정의합니다.
//
// 전역 변수들: 각 타이머의 인터럽트 발생 횟수를 저장하는 변수들. volatile 키워드로 컴파일러 최적화 방지하여 ISR에서 안전하게 접근 가능.
//
volatile uint32_t timer0Count = 0; // Timer0 인터럽트 카운터: 1초마다 증가
volatile uint32_t timer1Count = 0; // Timer1 인터럽트 카운터: 2초마다 증가
volatile uint32_t timer2Count = 0; // Timer2 인터럽트 카운터: 4초마다 증가
//
// 함수 프로토타입 선언: 컴파일러가 함수를 미리 인식하도록 함.
//
__interrupt void timer0ISR(void); // Timer0 인터럽트 서비스 루틴(ISR) 선언: 인터럽트 발생 시 호출됨.
__interrupt void timer1ISR(void); // Timer1 인터럽트 서비스 루틴(ISR) 선언.
__interrupt void timer2ISR(void); // Timer2 인터럽트 서비스 루틴(ISR) 선언.
void initCPUTimers(void); // 모든 CPU 타이머를 초기화하는 함수 선언.
void configCPUTimer(uint32_t, float, float); // 특정 타이머를 설정하는 함수 선언: 베이스 주소, 시스템 클럭 주파수, 주기(usec) 전달.
//
// Main 함수: 프로그램의 진입점. 디바이스 초기화, 인터럽트 설정, 타이머 시작 후 무한 루프 실행.
//
void main(void)
{
//
// 디바이스 클럭 및 주변 장치 초기화: 시스템 클럭(SYSCLK), PLL, 주변 클럭 등을 설정합니다. Device_init()는 C2000Ware의 표준 초기화 함수입니다.
//
Device_init();
//
// PIE(Peripheral Interrupt Expansion) 모듈 초기화: PIE 레지스터를 초기화하고 CPU 인터럽트를 비활성화합니다. 인터럽트 벡터를 관리합니다.
//
Interrupt_initModule();
//
// 인터럽트 벡터 테이블 초기화: 기본 ISR을 쉘 ISR로 설정합니다. 이 테이블은 인터럽트 발생 시 호출될 함수 포인터를 저장합니다.
//
Interrupt_initVectorTable();
//
// 각 CPU 타이머 인터럽트에 대한 ISR 등록: INT_TIMER0은 PIE Group 1.7, INT_TIMER1은 CPU INT13, INT_TIMER2은 CPU INT14에 매핑됩니다.
//
Interrupt_register(INT_TIMER0, &timer0ISR); // Timer0 ISR 등록: PIE를 통해 라우팅됨.
Interrupt_register(INT_TIMER1, &timer1ISR); // Timer1 ISR 등록: 직접 CPU 인터럽트.
Interrupt_register(INT_TIMER2, &timer2ISR); // Timer2 ISR 등록: 직접 CPU 인터럽트.
//
// CPU 타이머 주변 장치 초기화: 이 예제에서는 CPU 타이머만 초기화합니다. 다른 주변 장치는 필요 시 추가.
//
initCPUTimers();
//
// CPU-Timer 0, 1, 2를 각각 1초, 2초, 4초 주기로 인터럽트 발생하도록 설정: 주기(usec 단위)로 전달. DEVICE_SYSCLK_FREQ는 시스템 클럭(Hz)입니다.
//
configCPUTimer(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 1000000.0f); // Timer0: 1초 주기 (1,000,000 usec)
configCPUTimer(CPUTIMER1_BASE, DEVICE_SYSCLK_FREQ, 2000000.0f); // Timer1: 2초 주기 (2,000,000 usec)
configCPUTimer(CPUTIMER2_BASE, DEVICE_SYSCLK_FREQ, 4000000.0f); // Timer2: 4초 주기 (4,000,000 usec)
//
// Timer2의 프리스케일러 설정: 분주비 2 (TDDR = 1)로 설정하여 클럭을 1/2로 분주. 이는 주기 계산에 영향을 줌 (효과적인 주파수 감소).
//
CPUTimer_setPreScaler(CPUTIMER2_BASE, 1);
//
// 타이밍 정확성을 위해 전체 레지스터에 write-only 명령 사용: configCPUTimer나 initCPUTimers에서 변경된 설정을 업데이트. 인터럽트 활성화.
//
CPUTimer_enableInterrupt(CPUTIMER0_BASE); // Timer0 인터럽트 활성화: TIE 비트 설정.
CPUTimer_enableInterrupt(CPUTIMER1_BASE); // Timer1 인터럽트 활성화.
CPUTimer_enableInterrupt(CPUTIMER2_BASE); // Timer2 인터럽트 활성화.
//
// CPU 인터럽트 활성화: INT_TIMER0 (PIE Group 1.7), INT_TIMER1 (CPU INT13), INT_TIMER2 (CPU INT14) 활성화. PIE에서 TINT0 활성화.
//
Interrupt_enable(INT_TIMER0);
Interrupt_enable(INT_TIMER1);
Interrupt_enable(INT_TIMER2);
//
// CPU-Timer 0, 1, 2 시작: 타이머 카운터가 감소 시작. 주기 도달 시 인터럽트 발생.
//
CPUTimer_startTimer(CPUTIMER0_BASE);
CPUTimer_startTimer(CPUTIMER1_BASE);
CPUTimer_startTimer(CPUTIMER2_BASE);
//
// 전역 인터럽트(INTM) 및 실시간 인터럽트(DBGM) 활성화: Interrupt_enableMaster()는 EINT와 유사하게 INTM 비트 클리어.
//
Interrupt_enableMaster();
//
// 무한 루프: 인터럽트가 백그라운드에서 작업 처리. 디버깅 시 Expressions 창에서 timer0Count 등 확인 가능. 필요 시 여기에 코드 추가 (예: GPIO 토글).
//
for(;;)
{
// NOP; 또는 asm(" NOP;")으로 CPU IDLE 유지 가능.
}
}
//
// initCPUTimers - 이 함수는 모든 세 CPU 타이머를 알려진 상태로 초기화합니다. 최대 주기, 기본 프리스케일러, 정지 상태 등 설정.
//
void
initCPUTimers(void)
{
//
// 타이머 주기 최대값으로 초기화: 32비트 카운터의 최대값(0xFFFFFFFF)으로 설정하여 오버플로우 방지 초기 상태.
//
CPUTimer_setPeriod(CPUTIMER0_BASE, 0xFFFFFFFF); // Timer0 주기 최대 설정.
CPUTimer_setPeriod(CPUTIMER1_BASE, 0xFFFFFFFF); // Timer1 주기 최대 설정.
CPUTimer_setPeriod(CPUTIMER2_BASE, 0xFFFFFFFF); // Timer2 주기 최대 설정.
//
// 프리스케일러를 SYSCLKOUT으로 분주 1로 초기화: 분주비 1 (Prescaler = 0)로 클럭 그대로 사용.
//
CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);
CPUTimer_setPreScaler(CPUTIMER1_BASE, 0);
CPUTimer_setPreScaler(CPUTIMER2_BASE, 0);
//
// 타이머 정지 확인: 카운터 동작 중지.
//
CPUTimer_stopTimer(CPUTIMER0_BASE);
CPUTimer_stopTimer(CPUTIMER1_BASE);
CPUTimer_stopTimer(CPUTIMER2_BASE);
//
// 모든 카운터 레지스터를 주기 값으로 리로드: TMR 카운터를 PRD 값으로 초기화.
//
CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);
CPUTimer_reloadTimerCounter(CPUTIMER1_BASE);
CPUTimer_reloadTimerCounter(CPUTIMER2_BASE);
//
// 인터럽트 카운터 초기화: 각 타이머의 발생 횟수를 0으로 리셋.
//
timer0Count = 0;
timer1Count = 0;
timer2Count = 0;
}
//
// configCPUTimer - 이 함수는 선택된 타이머를 "freq"와 "period" 매개변수로 지정된 주기로 초기화합니다. "freq"는 Hz 단위, "period"는 uSeconds 단위. 설정 후 타이머는 정지 상태로 유지됩니다.
//
void
configCPUTimer(uint32_t cpuTimer, float freq, float period)
{
uint32_t temp; // 임시 변수: 주기 계산 결과를 저장.
//
// 타이머 주기 초기화: 공식 = (freq / 1e6) * period - 1. freq는 SYSCLK(Hz), period는 usec이므로 초당 카운트 계산.
//
temp = (uint32_t)((freq / 1000000.0f) * period); // 주기 값 계산: (SYSCLK / 1e6) * usec.
CPUTimer_setPeriod(cpuTimer, temp - 1); // 계산된 값 -1로 PRD 레지스터 설정 (타이머는 0에서 PRD까지 카운트).
//
// 프리스케일러를 SYSCLKOUT으로 분주 1로 설정: 기본 분주비 1 (Prescaler = 0).
//
CPUTimer_setPreScaler(cpuTimer, 0);
//
// 타이머 제어 레지스터 초기화: 타이머 정지, 카운터 리로드, 자유 실행 비활성화, 인터럽트 활성화. 또한 free 및 soft 비트 설정.
//
CPUTimer_stopTimer(cpuTimer); // 타이머 정지.
CPUTimer_reloadTimerCounter(cpuTimer); // 카운터 리로드.
CPUTimer_setEmulationMode(cpuTimer, CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT); // 에뮬레이션 모드: 디버깅 시 다음 감소 후 정지.
CPUTimer_enableInterrupt(cpuTimer); // 인터럽트 활성화.
//
// 세 CPU 타이머의 인터럽트 카운터 리셋: 해당 타이머에 따라 카운터 초기화.
//
if (cpuTimer == CPUTIMER0_BASE)
{
timer0Count = 0; // Timer0 카운터 리셋.
}
else if(cpuTimer == CPUTIMER1_BASE)
{
timer1Count = 0; // Timer1 카운터 리셋.
}
else if(cpuTimer == CPUTIMER2_BASE)
{
timer2Count = 0; // Timer2 카운터 리셋.
}
}
//
// timer0ISR - CpuTimer0에 대한 카운터: 1초마다 호출됨. PIE Group 1을 통해 처리.
//
__interrupt void
timer0ISR(void)
{
timer0Count++; // Timer0 인터럽트 횟수 증가: 1초마다 1씩 증가.
//
// 오버플로우 플래그 클리어: TIFR.INT 비트 클리어하여 다음 인터럽트 준비.
//
CPUTimer_clearOverflowFlag(CPUTIMER0_BASE);
//
// 이 인터럽트를 확인하여 Group 1에서 더 많은 인터럽트 수신: PIE ACK로 Group 1 클리어 (Timer0만 PIE 사용).
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}
//
// timer1ISR - CpuTimer1에 대한 카운터: 2초마다 호출됨. 직접 CPU INT13 처리.
//
__interrupt void
timer1ISR(void)
{
timer1Count++; // Timer1 인터럽트 횟수 증가: 2초마다 1씩 증가.
//
// 오버플로우 플래그 클리어: TIFR.INT 비트 클리어.
//
CPUTimer_clearOverflowFlag(CPUTIMER1_BASE);
// PIE ACK 불필요: 직접 CPU 인터럽트.
}
//
// timer2ISR - CpuTimer2에 대한 카운터: 4초마다 호출됨. 직접 CPU INT14 처리.
//
__interrupt void
timer2ISR(void)
{
timer2Count++; // Timer2 인터럽트 횟수 증가: 4초마다 1씩 증가.
//
// 오버플로우 플래그 클리어: TIFR.INT 비트 클리어.
//
CPUTimer_clearOverflowFlag(CPUTIMER2_BASE);
// PIE ACK 불필요: 직접 CPU 인터럽트.
}
//
// End of File
//
설명: 세 타이머를 각각 다른 주기로 설정하고, 프리스케일러를 적용해 동기화합니다. 주석은 각 타이머의 초기화, 설정, 인터럽트 처리 과정을 상세히 설명합니다.
'MCU > C2000' 카테고리의 다른 글
TMS320F28388D DSP eQEP 사용법: DriverLib API로 eQEP 설정 및 코드(수정) (0) | 2025.08.17 |
---|---|
TMS320F28388D DSP eCAP 사용법: DriverLib API로 eCAP 설정 및 코드(수정) (3) | 2025.08.17 |
TMS320F28388D DSP ePWM 사용법: DriverLib API로 ePWM 설정 및 코드(수정본) (0) | 2025.08.16 |
TMS320F28388D DSP ADC 사용법: DriverLib API로 ADC 설정 및 코드(수정) (0) | 2025.08.08 |
TMS320F28388D DSP SCI 사용법: Driverlib API로 UART 설정 및 예제(수정본) (0) | 2025.08.08 |
TMS320F28388D DSP Driverlib 기반 프로젝트 설정 및 기본 프로그램 작성 절차 (0) | 2025.08.08 |
TMS320F28335 DSP ePWM SPWM 생성 (0) | 2025.08.07 |
TMS320F28335 DSP ePWM Half-Bridge 상보 출력 설정 방법 (0) | 2025.08.07 |