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. CPUTimer_initTimer(uint32_t timer)
- 기능: 지정된 타이머를 초기화하여 레지스터를 기본값으로 설정하고 인터럽트를 비활성화.
- 매개변수: 타이머 베이스 주소(CPUTIMER0_BASE, CPUTIMER1_BASE, CPUTIMER2_BASE).
- 반환값: 없음.
- 예시: CPUTimer_initTimer(CPUTIMER0_BASE); // Timer0 초기화.
2. CPUTimer_configTimer(uint32_t timer, uint32_t sysclkHz, uint32_t period)
- 기능: 시스템 클럭 주파수와 주기(마이크로초 단위)를 기반으로 타이머를 설정.
- 매개변수:
- 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_reloadTimer(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를 토글합니다. 상세 주석으로 각 단계 설명.
#include "driverlib.h" // TI DriverLib 헤더 파일 포함
#include "device.h" // 디바이스별 설정(device.h) 포함
// Timer0 인터럽트 서비스 루틴(ISR) 선언
__interrupt void timer0ISR(void);
// LED 상태를 저장하는 전역 변수 (volatile로 인터럽트에서 안전하게 사용)
volatile bool ledState = false;
void main(void)
{
// 디바이스 클럭 및 주변 장치 초기화 (PLL, Watchdog 등 설정)
Device_init();
// GPIO 초기화 및 LED 핀 설정 (예: GPIO0을 LED로 사용)
Device_initGPIO();
GPIO_setPadConfig(DEVICE_GPIO_PIN_LED1, GPIO_PIN_TYPE_STD); // 표준 GPIO 설정
GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED1, GPIO_DIR_MODE_OUT); // 출력 모드 설정
// PIE(Peripheral Interrupt Expansion) 모듈 초기화
Interrupt_initModule();
// 인터럽트 벡터 테이블 초기화
Interrupt_initVectorTable();
// Timer0 인터럽트를 ISR에 등록 (INT_TINT0은 Timer0의 인터럽트 벡터)
Interrupt_register(INT_TINT0, &timer0ISR);
// Timer0 인터럽트 활성화
Interrupt_enable(INT_TINT0);
// Timer0 초기화 (레지스터를 기본값으로 리셋)
CPUTimer_initTimer(CPUTIMER0_BASE);
// Timer0 설정: 시스템 클럭(예: 200MHz), 1초(1000000us) 주기로 설정
CPUTimer_configTimer(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 1000000);
// Timer0 인터럽트 활성화 (TIE 비트 설정)
CPUTimer_enableInterrupt(CPUTIMER0_BASE);
// 전역 인터럽트 활성화 (CPU 수준에서 인터럽트 허용)
Interrupt_enableMaster();
// Timer0 시작 (TSS 비트를 0으로 설정하여 카운터 동작 시작)
CPUTimer_startTimer(CPUTIMER0_BASE);
// 무한 루프: 인터럽트가 작업 처리
for(;;)
{
// 추가 작업이 필요 없는 경우 대기
}
}
// Timer0 인터럽트 서비스 루틴: 1초마다 호출
__interrupt void timer0ISR(void)
{
// LED 상태 토글 (true/false 전환)
ledState = !ledState;
// LED 핀에 상태 쓰기 (1: 켜짐, 0: 꺼짐)
GPIO_writePin(DEVICE_GPIO_PIN_LED1, ledState ? 1 : 0);
// 타이머 오버플로우 플래그(TIF) 클리어
CPUTimer_clearOverflowFlag(CPUTIMER0_BASE);
// 인터럽트 확인 (PIE 그룹 1 클리어)
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}
설명: Timer0를 1초 주기로 설정하고, 인터럽트를 통해 LED를 토글합니다. 주석은 초기화, 설정, 인터럽트 처리 단계를 명확히 설명합니다.
예제 2: 타이머 카운터 모니터링 (SCI 출력)
Timer1의 카운터 값을 SCI를 통해 출력합니다. 상세 주석 포함.
#include "driverlib.h" // TI DriverLib 헤더 파일 포함
#include "device.h" // 디바이스별 설정(device.h) 포함
#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 등 설정)
Device_init();
// GPIO 초기화
Device_initGPIO();
// SCI TX/RX 핀 설정 (예: SCIA 모듈 사용)
GPIO_setPinConfig(DEVICE_GPIO_CFG_SCIA_TX); // SCI 전송 핀 설정
GPIO_setPinConfig(DEVICE_GPIO_CFG_SCIA_RX); // SCI 수신 핀 설정
// SCI 설정: 115200 baudrate, 8비트 데이터, 1 스톱 비트, 패리티 없음
SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 115200,
(SCI_CONFIG_WLEN_8 | SCI_CONFIG_STOP_ONE | SCI_CONFIG_PAR_NONE));
// SCI 모듈 활성화
SCI_enableModule(SCIA_BASE);
// Timer1 초기화 (레지스터를 기본값으로 리셋)
CPUTimer_initTimer(CPUTIMER1_BASE);
// Timer1 설정: 시스템 클럭, 500ms(500000us) 주기로 설정
CPUTimer_configTimer(CPUTIMER1_BASE, DEVICE_SYSCLK_FREQ, 500000);
// Timer1 시작 (카운터 동작 시작)
CPUTimer_startTimer(CPUTIMER1_BASE);
// 카운터 값을 저장할 문자열 버퍼
char msg[50];
// 메인 루프: 타이머 값 모니터링
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 전송 방지
DEVICE_DELAY_US(100000);
}
}
설명: Timer1의 카운터 값을 100ms마다 읽어 SCI로 전송합니다. 주석은 SCI 설정, 타이머 설정, 데이터 전송 과정을 상세히 설명합니다.
예제 3: 다중 타이머 동기화
Timer0, Timer1, Timer2를 각각 1초, 2초, 4초 주기로 동기화합니다. 상세 주석 포함.
#include "driverlib.h" // TI DriverLib 헤더 파일 포함
#include "device.h" // 디바이스별 설정(device.h) 포함
// 인터럽트 서비스 루틴 선언
__interrupt void timer0ISR(void);
__interrupt void timer1ISR(void);
__interrupt void timer2ISR(void);
// 각 타이머의 인터럽트 발생 횟수를 저장하는 전역 변수
volatile uint32_t timer0Count = 0, timer1Count = 0, timer2Count = 0;
void main(void)
{
// 디바이스 클럭 및 주변 장치 초기화
Device_init();
// GPIO 초기화 (이 예제에서는 GPIO 사용 없음, 필요 시 추가)
Device_initGPIO();
// PIE 모듈 초기화
Interrupt_initModule();
// 인터럽트 벡터 테이블 초기화
Interrupt_initVectorTable();
// 각 타이머 인터럽트를 ISR에 등록
Interrupt_register(INT_TINT0, &timer0ISR); // Timer0 인터럽트
Interrupt_register(INT_TINT1, &timer1ISR); // Timer1 인터럽트
Interrupt_register(INT_TINT2, &timer2ISR); // Timer2 인터럽트
// 각 타이머 인터럽트 활성화
Interrupt_enable(INT_TINT0);
Interrupt_enable(INT_TINT1);
Interrupt_enable(INT_TINT2);
// 모든 CPU 타이머 초기화
CPUTimer_initTimer(CPUTIMER0_BASE); // Timer0 초기화
CPUTimer_initTimer(CPUTIMER1_BASE); // Timer1 초기화
CPUTimer_initTimer(CPUTIMER2_BASE); // Timer2 초기화
// 타이머 설정: 각각 1초, 2초, 4초 주기
CPUTimer_configTimer(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 1000000); // 1초
CPUTimer_configTimer(CPUTIMER1_BASE, DEVICE_SYSCLK_FREQ, 2000000); // 2초
CPUTimer_configTimer(CPUTIMER2_BASE, DEVICE_SYSCLK_FREQ, 4000000); // 4초
// Timer2의 프리스케일러 설정: 분주비 2 (TDDR = 1)
CPUTimer_setPreScaler(CPUTIMER2_BASE, 1);
// 각 타이머의 인터럽트 활성화
CPUTimer_enableInterrupt(CPUTIMER0_BASE);
CPUTimer_enableInterrupt(CPUTIMER1_BASE);
CPUTimer_enableInterrupt(CPUTIMER2_BASE);
// 전역 인터럽트 활성화
Interrupt_enableMaster();
// 모든 타이머 시작
CPUTimer_startTimer(CPUTIMER0_BASE);
CPUTimer_startTimer(CPUTIMER1_BASE);
CPUTimer_startTimer(CPUTIMER2_BASE);
// 무한 루프: 인터럽트가 작업 처리
for(;;)
{
// 디버깅 시 timer0Count, timer1Count, timer2Count 확인 가능
}
}
// Timer0 ISR: 1초마다 호출
__interrupt void timer0ISR(void)
{
// Timer0 인터럽트 카운터 증가
timer0Count++;
// 오버플로우 플래그 클리어
CPUTimer_clearOverflowFlag(CPUTIMER0_BASE);
// PIE 그룹 1 인터럽트 확인
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}
// Timer1 ISR: 2초마다 호출
__interrupt void timer1ISR(void)
{
// Timer1 인터럽트 카운터 증가
timer1Count++;
// 오버플로우 플래그 클리어
CPUTimer_clearOverflowFlag(CPUTIMER1_BASE);
// PIE 그룹 13 인터럽트 확인
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP13);
}
// Timer2 ISR: 4초마다 호출
__interrupt void timer2ISR(void)
{
// Timer2 인터럽트 카운터 증가
timer2Count++;
// 오버플로우 플래그 클리어
CPUTimer_clearOverflowFlag(CPUTIMER2_BASE);
// PIE 그룹 14 인터럽트 확인
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP14);
}
설명: 세 타이머를 각각 다른 주기로 설정하고, 프리스케일러를 적용해 동기화합니다. 주석은 각 타이머의 초기화, 설정, 인터럽트 처리 과정을 상세히 설명합니다.
'MCU > C2000' 카테고리의 다른 글
[TMS320F28388D] ePWM 사용법: DriverLib API로 ePWM 설정 및 코드 (0) | 2025.08.16 |
---|---|
[TMS320F28335] 기반 PSFB 컨버터 설계 및 위상 천이 PWM 제어 코드 (PSFB Converter Design and TMS320F28335-Based Phase-Shift PWM Control Code) (0) | 2025.08.10 |
[TMS320F28335] LLC 공진 컨버터 설계 및 제어 코드 가이드 (0) | 2025.08.09 |
[TMS320F28388D] ADC 사용법: DriverLib API로 ADC 설정 및 코드 (0) | 2025.08.08 |
[TMS320F28388D] SCI 사용법: Driverlib API로 UART 설정 및 예제 (0) | 2025.08.08 |
[TMS320F28388D] 프로젝트 설정 및 기본 프로그램 작성 절차 (0) | 2025.08.08 |
[TMS320F28335 ]ePWM SPWM 생성 (0) | 2025.08.07 |
[TMS320F28335] ePWM 하프 브리지 상보 출력 설정 (0) | 2025.08.07 |