1. TMS320F28335 ADC 모듈 개요
TI의 TMS320F28335는 C2000 Delfino 시리즈의 32비트 마이크로컨트롤러로, 고속 아날로그-디지털 변환(ADC)을 지원하여 모터 제어, 센서 데이터 수집, 전력 관리 등 다양한 애플리케이션에 적합합니다. ADC 모듈은 고속 샘플링, 트리거 소스 선택, 다중 채널 변환 기능을 제공합니다. 이 문서에서는 TMS320F28335 ADC 모듈의 설정 방법, Bitfield 구조를 활용한 레지스터 설정, 그리고 실용적인 예제 코드를 제공하여 초보자와 숙련된 개발자 모두 쉽게 활용할 수 있도록 돕습니다.
주요 사양
- 해상도: 12비트
- 샘플링 속도: 최대 12.5 MSPS (메가 샘플 per 초)
- 입력 채널: 16개 아날로그 입력 채널 (ADCINA0
7, ADCINB07) - 변환 모드:
- 단일 변환
- 연속 변환
- 트리거 소스:
- 소프트웨어 트리거
- ePWM 트리거 (SOCA, SOCB)
- 외부 핀 트리거
- 인터럽트: 변환 완료 시 인터럽트 지원
- 샘플 앤 홀드: 80ns 샘플링 윈도우
- 레지스터: ADCCTL1, ADCCTL2, ADCSOCxCTL, ADCINT 등 Bitfield 구조로 설정
- 결과 저장: 16개 결과 레지스터 (ADCRESULT0~15)
- 모듈 수: 단일 ADC 모듈, 2개의 SOC(Start of Conversion) 그룹 (SEQA, SEQB)
2. ADC Bitfield 설정 상세
TMS320F28335의 ADC 레지스터는 Bitfield 구조로 정의되어 있으며, F2833x_adc.h 헤더 파일을 통해 접근합니다. 주요 레지스터는 다음과 같습니다:
2.1 ADCCTL1 (ADC 제어 레지스터 1)
- bit.RESET: ADC 소프트 리셋 (1: 리셋)
- bit.ADCENABLE: ADC 모듈 활성화 (1: 활성화)
- bit.ADCBGPWD: ADC 밴드갭 및 레퍼런스 전원 활성화 (1: 활성화)
- bit.ADCPWDN: ADC 아날로그 회로 전원 활성화 (1: 활성화)
2.2 ADCCTL2 (ADC 제어 레지스터 2)
- bit.CLKDIV2EN: ADC 클럭 분주비 (0: SYSCLK, 1: SYSCLK/2)
- bit.ADCNONOVERLAP: 비중첩 모드 (1: 활성화, SOC 간 충돌 방지)
- bit.INTMODEx: 인터럽트 모드 (x=1~8, 0: 변환 완료 시, 1: 연속)
2.3 ADCSOCxCTL (SOC 제어 레지스터, x=0~15)
- bit.CHSEL: 채널 선택 (0
15: ADCINA07, ADCINB0~7) - bit.ACQPS: 샘플링 윈도우 크기 (0~63, 단위: SYSCLK 사이클)
- bit.TRIGSEL: 트리거 소스 선택 (0: 소프트웨어, 5: ePWM SOCA 등)
2.4 ADCINT (인터럽트 제어 레지스터)
- bit.INTxEN: 인터럽트 활성화 (x=1~8, 1: 활성화)
- bit.INTxCONT: 연속 인터럽트 모드 (1: 연속)
- bit.INTxSEL: 인터럽트 트리거 SOC 선택
3. ADC 설정 절차
- 시스템 초기화:
- InitSysCtrl()로 시스템 클럭과 PLL 초기화
- 인터럽트 비활성화 및 PIE 초기화 (DINT, InitPieCtrl, InitPieVectTable)
- ADC 클럭 활성화:
- CpuSysRegs.PCLKCR0.bit.ADCENCLK = 1로 ADC 모듈 클럭 활성화
- 보호된 레지스터 접근을 위해 EALLOW와 EDIS 사용
- ADC 전원 활성화:
- AdcRegs.ADCCTL1.bit.ADCBGPWD = 1로 밴드갭 및 레퍼런스 활성화
- AdcRegs.ADCCTL1.bit.ADCPWDN = 1로 아날로그 회로 전원 활성화
- AdcRegs.ADCCTL1.bit.ADCENABLE = 1로 ADC 모듈 활성화
- 샘플링 설정:
- AdcRegs.ADCCTL2.bit.CLKDIV2EN으로 클럭 분주 설정
- AdcRegs.ADCSOCxCTL.bit.ACQPS로 샘플링 윈도우 설정
- 채널 및 트리거 설정:
- AdcRegs.ADCSOCxCTL.bit.CHSEL로 변환 채널 선택
- AdcRegs.ADCSOCxCTL.bit.TRIGSEL로 트리거 소스 설정
- 인터럽트 설정 (필요 시):
- AdcRegs.ADCINT.bit.INTxEN으로 인터럽트 활성화
- AdcRegs.ADCINTSOCSELx로 인터럽트 트리거 SOC 선택
- 시퀀서 설정:
- AdcRegs.ADCSOCPRIORITY로 시퀀서 우선순위 설정
- AdcRegs.ADCCTL1.bit.INTPULSEPOS로 인터럽트 펄스 위치 설정
- 변환 시작:
- 소프트웨어 트리거: AdcRegs.ADCSOCFRC1.bit.SOCx = 1
- ePWM 트리거: ePWM 모듈에서 SOCA/SOCB 설정
4. ADC 설정 고려사항
- 클럭 설정: SYSCLK(150MHz)에서 ADC 클럭 분주 설정
- 샘플링 윈도우: 최소 80ns (ACQPS ≥ 6 @ 150MHz)
- 트리거 소스: ePWM 트리거 사용 시 동기화 확인
- 인터럽트: 변환 완료 인터럽트로 데이터 처리 최적화
- 결과 처리: ADCRESULTx 레지스터에서 12비트 데이터 읽기
- 노이즈 방지: 아날로그 입력에 저역통과 필터 권장
5. 실용적인 ADC 예제 코드 (Bitfield 구조)
아래는 TMS320F28335 ADC 모듈을 Bitfield 구조로 설정한 5개의 예제 코드입니다. GPIO와 ADC 설정은 별도의 함수로 분리되었으며, 각 라인에 상세한 주석이 추가되었습니다. Code Composer Studio(CCS)와 C2000Ware 환경에서 실행 가능합니다.
5.1 예제 1: 기본 ADC 변환 (소프트웨어 트리거)
// File: adc_basic_software.c
// Description: TMS320F28335 ADC 기본 변환 (소프트웨어 트리거) 예제
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28335
#include "F28x_Project.h"
volatile Uint16 adcResult; // ADC 변환 결과 저장 변수
// GPIO 설정 함수
void ConfigureGPIO(void) {
EALLOW; // 보호된 레지스터 접근 허용
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // GPIO0을 일반 입력으로 설정 (ADCINA0)
GpioCtrlRegs.GPADIR.bit.GPIO0 = 0; // GPIO0을 입력으로 설정
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // GPIO34를 출력으로 설정 (LED용)
GpioDataRegs.GPBSET.bit.GPIO34 = 1; // GPIO34를 High로 설정하여 LED 켬
EDIS; // 보호된 레지스터 접근 비허용
}
// ADC 설정 함수
void ConfigureADC(void) {
EALLOW; // 보호된 레지스터 접근 허용
CpuSysRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC 모듈 클럭 활성화
EDIS; // 보호된 레지스터 접근 비허용
AdcRegs.ADCCTL1.bit.RESET = 1; // ADC 모듈 리셋
AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // 밴드갭 및 레퍼런스 전원 활성화
AdcRegs.ADCCTL1.bit.ADCPWDN = 1; // ADC 아날로그 회로 전원 활성화
AdcRegs.ADCCTL1.bit.ADCENABLE = 1; // ADC 모듈 활성화
AdcRegs.ADCCTL2.bit.CLKDIV2EN = 1; // ADC 클럭 분주비 SYSCLK/2 (75MHz)
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; // 인터럽트 펄스 위치: 변환 완료 시
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0; // SOC0: ADCINA0 채널 선택
AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; // 샘플링 윈도우: 6 SYSCLK (80ns @ 150MHz)
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 0; // 소프트웨어 트리거 선택
AdcRegs.ADCINTSOCSEL1.bit.SOC0 = 0; // SOC0에 인터럽트 연결 비활성화
}
void main(void) {
InitSysCtrl(); // 시스템 클럭(150MHz)과 PLL 초기화
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE 컨트롤러 초기화
IER = 0x0000; // CPU 인터럽트 레지스터 비활성화
IFR = 0x0000; // 인터럽트 플래그 레지스터 클리어
InitPieVectTable(); // PIE 인터럽트 벡터 테이블 초기화
ConfigureGPIO(); // GPIO 설정 함수 호출
ConfigureADC(); // ADC 설정 함수 호출
while(1) {
AdcRegs.ADCSOCFRC1.bit.SOC0 = 1; // SOC0 소프트웨어 트리거 시작
while(AdcRegs.ADCINTFLG.bit.ADCINT1 == 0); // 변환 완료 대기
adcResult = AdcRegs.ADCRESULT0; // 변환 결과 읽기
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // 인터럽트 플래그 클리어
DELAY_US(1000); // 1ms 대기 (샘플링 주기 조정)
}
}
설명:
- 기능: ADCINA0 채널에서 소프트웨어 트리거로 단일 변환 수행, 결과 저장
- 설정: ADC 클럭 75MHz, 샘플링 윈도우 80ns, ADCINA0 채널, 소프트웨어 트리거
- GPIO: GPIO0(ADCINA0), GPIO34(LED)
- 출력: adcResult에 12비트 ADC 값 저장, LED ON
5.2 예제 2: ePWM 트리거 ADC 변환
// File: adc_epwm_trigger.c
// Description: TMS320F28335 ADC ePWM 트리거 변환 예제
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28335
#include "F28x_Project.h"
volatile Uint16 adcResult; // ADC 변환 결과 저장 변수
// GPIO 설정 함수
void ConfigureGPIO(void) {
EALLOW; // 보호된 레지스터 접근 허용
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // GPIO0을 ADCINA0으로 설정
GpioCtrlRegs.GPADIR.bit.GPIO0 = 0; // GPIO0을 입력으로 설정
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // GPIO34를 출력으로 설정 (LED용)
GpioDataRegs.GPBSET.bit.GPIO34 = 1; // GPIO34를 High로 설정하여 LED 켬
EDIS; // 보호된 레지스터 접근 비허용
}
// ePWM1 설정 함수 (ADC 트리거용)
void ConfigureEPWM1(void) {
EALLOW; // 보호된 레지스터 접근 허용
CpuSysRegs.PCLKCR1.bit.EPWM1 = 1; // ePWM1 모듈 클럭 활성화
EDIS; // 보호된 레지스터 접근 비허용
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 타임-베이스 카운터를 업 카운트 모드로 설정
EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 클럭 분주비 1/1 (SYSCLK = 150MHz)
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 2; // 고속 클럭 분주비 1/2 (TBCLK = 75MHz)
EPwm1Regs.TBPRD = 750; // 주기 레지스터 설정: 750 TBCLK = 10us (100kHz)
EPwm1Regs.CMPA.bit.CMPA = 375; // 비교 레지스터 A 설정: 50% 듀티 사이클
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // TBCTR=0일 때 PWM_A 출력을 High로 설정
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // TBCTR=CMPA일 때 PWM_A 출력을 Low로 설정
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // SOCA 트리거 활성화
EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO; // TBCTR=0일 때 SOCA 트리거 발생
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // 첫 번째 이벤트에서 SOCA 트리거 발생
EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // Free run 모드
}
// ADC 설정 함수
void ConfigureADC(void) {
EALLOW; // 보호된 레지스터 접근 허용
CpuSysRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC 모듈 클럭 활성화
EDIS; // 보호된 레지스터 접근 비허용
AdcRegs.ADCCTL1.bit.RESET = 1; // ADC 모듈 리셋
AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // 밴드갭 및 레퍼런스 전원 활성화
AdcRegs.ADCCTL1.bit.ADCPWDN = 1; // ADC 아날로그 회로 전원 활성화
AdcRegs.ADCCTL1.bit.ADCENABLE = 1; // ADC 모듈 활성화
AdcRegs.ADCCTL2.bit.CLKDIV2EN = 1; // ADC 클럭 분주비 SYSCLK/2 (75MHz)
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; // 인터럽트 펄스 위치: 변환 완료 시
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0; // SOC0: ADCINA0 채널 선택
AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; // 샘플링 윈도우: 6 SYSCLK (80ns @ 150MHz)
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 5; // ePWM1 SOCA 트리거 선택
AdcRegs.ADCINTSOCSEL1.bit.SOC0 = 0; // SOC0에 인터럽트 연결 비활성화
}
void main(void) {
InitSysCtrl(); // 시스템 클럭(150MHz)과 PLL 초기화
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE 컨트롤러 초기화
IER = 0x0000; // CPU 인터럽트 레지스터 비활성화
IFR = 0x0000; // 인터럽트 플래그 레지스터 클리어
InitPieVectTable(); // PIE 인터럽트 벡터 테이블 초기화
ConfigureGPIO(); // GPIO 설정 함수 호출
ConfigureADC(); // ADC 설정 함수 호출
ConfigureEPWM1(); // ePWM1 설정 함수 호출
while(1) {
while(AdcRegs.ADCINTFLG.bit.ADCINT1 == 0); // 변환 완료 대기
adcResult = AdcRegs.ADCRESULT0; // 변환 결과 읽기
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // 인터럽트 플래그 클리어
}
}
설명:
- 기능: ePWM1 SOCA 트리거로 ADCINA0 채널에서 변환 수행, 결과 저장
- 설정: ADC 클럭 75MHz, 샘플링 윈도우 80ns, ADCINA0 채널, ePWM1 SOCA 트리거 (100kHz)
- GPIO: GPIO0(ADCINA0), GPIO34(LED)
- 출력: adcResult에 12비트 ADC 값 저장, LED ON
5.3 예제 3: ADC 인터럽트 기반 다중 채널 변환
// File: adc_interrupt_multi.c
// Description: TMS320F28335 ADC 인터럽트 기반 다중 채널 변환 예제
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28335
#include "F28x_Project.h"
volatile Uint16 adcResults[2]; // ADCINA0, ADCINA1 변환 결과 저장 배열
// ADC 인터럽트 서비스 루틴
__interrupt void adc_isr(void) {
adcResults[0] = AdcRegs.ADCRESULT0; // ADCINA0 결과 읽기
adcResults[1] = AdcRegs.ADCRESULT1; // ADCINA1 결과 읽기
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // 인터럽트 플래그 클리어
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // PIE 그룹 1 인터럽트 ACK
}
// GPIO 설정 함수
void ConfigureGPIO(void) {
EALLOW; // 보호된 레지스터 접근 허용
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // GPIO0을 ADCINA0으로 설정
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0; // GPIO1을 ADCINA1으로 설정
GpioCtrlRegs.GPADIR.bit.GPIO0 = 0; // GPIO0을 입력으로 설정
GpioCtrlRegs.GPADIR.bit.GPIO1 = 0; // GPIO1을 입력으로 설정
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // GPIO34를 출력으로 설정 (LED용)
GpioDataRegs.GPBSET.bit.GPIO34 = 1; // GPIO34를 High로 설정하여 LED 켬
EDIS; // 보호된 레지스터 접근 비허용
}
// ADC 설정 함수
void ConfigureADC(void) {
EALLOW; // 보호된 레지스터 접근 허용
CpuSysRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC 모듈 클럭 활성화
EDIS; // 보호된 레지스터 접근 비허용
AdcRegs.ADCCTL1.bit.RESET = 1; // ADC 모듈 리셋
AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // 밴드갭 및 레퍼런스 전원 활성화
AdcRegs.ADCCTL1.bit.ADCPWDN = 1; // ADC 아날로그 회로 전원 활성화
AdcRegs.ADCCTL1.bit.ADCENABLE = 1; // ADC 모듈 활성화
AdcRegs.ADCCTL2.bit.CLKDIV2EN = 1; // ADC 클럭 분주비 SYSCLK/2 (75MHz)
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; // 인터럽트 펄스 위치: 변환 완료 시
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0; // SOC0: ADCINA0 채널 선택
AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; // 샘플링 윈도우: 6 SYSCLK (80ns @ 150MHz)
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 0; // 소프트웨어 트리거 선택
AdcRegs.ADCSOC1CTL.bit.CHSEL = 1; // SOC1: ADCINA1 채널 선택
AdcRegs.ADCSOC1CTL.bit.ACQPS = 6; // 샘플링 윈도우: 6 SYSCLK
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 0; // 소프트웨어 트리거 선택
AdcRegs.ADCINT.bit.INT1EN = 1; // ADCINT1 인터럽트 활성화
AdcRegs.ADCINTSOCSEL1.bit.SOC1 = 1; // SOC1 완료 시 ADCINT1 트리거
}
void main(void) {
InitSysCtrl(); // 시스템 클럭(150MHz)과 PLL 초기화
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE 컨트롤러 초기화
IER = 0x0000; // CPU 인터럽트 레지스터 비활성화
IFR = 0x0000; // 인터럽트 플래그 레지스터 클리어
InitPieVectTable(); // PIE 인터럽트 벡터 테이블 초기화
EALLOW; // 보호된 레지스터 접근 허용
PieVectTable.ADCINT1 = &adc_isr; // ADCINT1 인터럽트 벡터를 ISR 함수에 연결
EDIS; // 보호된 레지스터 접근 비허용
ConfigureGPIO(); // GPIO 설정 함수 호출
ConfigureADC(); // ADC 설정 함수 호출
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // PIE 그룹 1에서 ADCINT1 인터럽트 활성화
IER |= M_INT1; // CPU 인터럽트 그룹 1 활성화
EINT; // 글로벌 인터럽트 활성화
ERTM; // 실시간 모드 활성화
while(1) {
AdcRegs.ADCSOCFRC1.bit.SOC0 = 1; // SOC0 소프트웨어 트리거 시작
AdcRegs.ADCSOCFRC1.bit.SOC1 = 1; // SOC1 소프트웨어 트리거 시작
}
}
설명:
- 기능: ADCINA0, ADCINA1 채널에서 소프트웨어 트리거로 다중 변환 수행, 인터럽트를 통해 결과 저장
- 설정: ADC 클럭 75MHz, 샘플링 윈도우 80ns, ADCINA0/ADCINA1 채널, 소프트웨어 트리거, ADCINT1 활성화
- GPIO: GPIO0(ADCINA0), GPIO1(ADCINA1), GPIO34(LED)
- 출력: adcResults 배열에 12비트 ADC 값 저장, LED ON
5.4 예제 4: 연속 변환 모드 (시퀀서 사용)
// File: adc_sequential_continuous.c
// Description: TMS320F28335 ADC 연속 변환 모드 예제
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28335
#include "F28x_Project.h"
volatile Uint16 adcResults[4]; // ADCINA0~3 변환 결과 저장 배열
// ADC 인터럽트 서비스 루틴
__interrupt void adc_isr(void) {
adcResults[0] = AdcRegs.ADCRESULT0; // ADCINA0 결과 읽기
adcResults[1] = AdcRegs.ADCRESULT1; // ADCINA1 결과 읽기
adcResults[2] = AdcRegs.ADCRESULT2; // ADCINA2 결과 읽기
adcResults[3] = AdcRegs.ADCRESULT3; // ADCINA3 결과 읽기
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // 인터럽트 플래그 클리어
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // PIE 그룹 1 인터럽트 ACK
}
// GPIO 설정 함수
void ConfigureGPIO(void) {
EALLOW; // 보호된 레지스터 접근 허용
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // GPIO0을 ADCINA0으로 설정
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0; // GPIO1을 ADCINA1으로 설정
GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 0; // GPIO2을 ADCINA2으로 설정
GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 0; // GPIO3을 ADCINA3으로 설정
GpioCtrlRegs.GPADIR.bit.GPIO0 = 0; // GPIO0을 입력으로 설정
GpioCtrlRegs.GPADIR.bit.GPIO1 = 0; // GPIO1을 입력으로 설정
GpioCtrlRegs.GPADIR.bit.GPIO2 = 0; // GPIO2을 입력으로 설정
GpioCtrlRegs.GPADIR.bit.GPIO3 = 0; // GPIO3을 입력으로 설정
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // GPIO34를 출력으로 설정 (LED용)
GpioDataRegs.GPBSET.bit.GPIO34 = 1; // GPIO34를 High로 설정하여 LED 켬
EDIS; // 보호된 레지스터 접근 비허용
}
// ADC 설정 함수
void ConfigureADC(void) {
EALLOW; // 보호된 레지스터 접근 허용
CpuSysRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC 모듈 클럭 활성화
EDIS; // 보호된 레지스터 접근 비허용
AdcRegs.ADCCTL1.bit.RESET = 1; // ADC 모듈 리셋
AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // 밴드갭 및 레퍼런스 전원 활성화
AdcRegs.ADCCTL1.bit.ADCPWDN = 1; // ADC 아날로그 회로 전원 활성화
AdcRegs.ADCCTL1.bit.ADCENABLE = 1; // ADC 모듈 활성화
AdcRegs.ADCCTL2.bit.CLKDIV2EN = 1; // ADC 클럭 분주비 SYSCLK/2 (75MHz)
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; // 인터럽트 펄스 위치: 변환 완료 시
AdcRegs.ADCCTL1.bit.SEQ1MODE = 1; // 시퀀서 1 연속 모드 활성화
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0; // SOC0: ADCINA0 채널 선택
AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; // 샘플링 윈도우: 6 SYSCLK (80ns @ 150MHz)
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 0; // 소프트웨어 트리거 선택
AdcRegs.ADCSOC1CTL.bit.CHSEL = 1; // SOC1: ADCINA1 채널 선택
AdcRegs.ADCSOC1CTL.bit.ACQPS = 6; // 샘플링 윈도우: 6 SYSCLK
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 0; // 소프트웨어 트리거 선택
AdcRegs.ADCSOC2CTL.bit.CHSEL = 2; // SOC2: ADCINA2 채널 선택
AdcRegs.ADCSOC2CTL.bit.ACQPS = 6; // 샘플링 윈도우: 6 SYSCLK
AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 0; // 소프트웨어 트리거 선택
AdcRegs.ADCSOC3CTL.bit.CHSEL = 3; // SOC3: ADCINA3 채널 선택
AdcRegs.ADCSOC3CTL.bit.ACQPS = 6; // 샘플링 윈도우: 6 SYSCLK
AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 0; // 소프트웨어 트리거 선택
AdcRegs.ADCINT.bit.INT1EN = 1; // ADCINT1 인터럽트 활성화
AdcRegs.ADCINTSOCSEL1.bit.SOC3 = 1; // SOC3 완료 시 ADCINT1 트리거
}
void main(void) {
InitSysCtrl(); // 시스템 클럭(150MHz)과 PLL 초기화
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE 컨트롤러 초기화
IER = 0x0000; // CPU 인터럽트 레지스터 비활성화
IFR = 0x0000; // 인터럽트 플래그 레지스터 클리어
InitPieVectTable(); // PIE 인터럽트 벡터 테이블 초기화
EALLOW; // 보호된 레지스터 접근 허용
PieVectTable.ADCINT1 = &adc_isr; // ADCINT1 인터럽트 벡터를 ISR 함수에 연결
EDIS; // 보호된 레지스터 접근 비허용
ConfigureGPIO(); // GPIO 설정 함수 호출
ConfigureADC(); // ADC 설정 함수 호출
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // PIE 그룹 1에서 ADCINT1 인터럽트 활성화
IER |= M_INT1; // CPU 인터럽트 그룹 1 활성화
EINT; // 글로벌 인터럽트 활성화
ERTM; // 실시간 모드 활성화
AdcRegs.ADCSOCFRC1.bit.SOC0 = 1; // SOC0 소프트웨어 트리거 시작 (연속 모드 시작)
}
설명:
- 기능: ADCINA0~3 채널에서 연속 변환 모드로 다중 변환 수행, 인터럽트를 통해 결과 저장
- 설정: ADC 클럭 75MHz, 샘플링 윈도우 80ns, ADCINA0~3 채널, 소프트웨어 트리거, 시퀀서 연속 모드, ADCINT1 활성화
- GPIO: GPIO0
3(ADCINA03), GPIO34(LED) - 출력: adcResults 배열에 12비트 ADC 값 저장, LED ON
5.5 예제 5: 외부 핀 트리거 ADC 변환
// File: adc_external_trigger.c
// Description: TMS320F28335 ADC 외부 핀 트리거 변환 예제
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28335
#include "F28x_Project.h"
volatile Uint16 adcResult; // ADC 변환 결과 저장 변수
// GPIO 설정 함수
void ConfigureGPIO(void) {
EALLOW; // 보호된 레지스터 접근 허용
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // GPIO0을 ADCINA0으로 설정
GpioCtrlRegs.GPADIR.bit.GPIO0 = 0; // GPIO0을 입력으로 설정
GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0; // GPIO12를 일반 입력으로 설정 (외부 트리거)
GpioCtrlRegs.GPADIR.bit.GPIO12 = 0; // GPIO12를 입력으로 설정
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // GPIO34를 출력으로 설정 (LED용)
GpioDataRegs.GPBSET.bit.GPIO34 = 1; // GPIO34를 High로 설정하여 LED 켬
EDIS; // 보호된 레지스터 접근 비허용
}
// ADC 설정 함수
void ConfigureADC(void) {
EALLOW; // 보호된 레지스터 접근 허용
CpuSysRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC 모듈 클럭 활성화
EDIS; // 보호된 레지스터 접근 비허용
AdcRegs.ADCCTL1.bit.RESET = 1; // ADC 모듈 리셋
AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // 밴드갭 및 레퍼런스 전원 활성화
AdcRegs.ADCCTL1.bit.ADCPWDN = 1; // ADC 아날로그 회로 전원 활성화
AdcRegs.ADCCTL1.bit.ADCENABLE = 1; // ADC 모듈 활성화
AdcRegs.ADCCTL2.bit.CLKDIV2EN = 1; // ADC 클럭 분주비 SYSCLK/2 (75MHz)
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; // 인터럽트 펄스 위치: 변환 완료 시
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0; // SOC0: ADCINA0 채널 선택
AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; // 샘플링 윈도우: 6 SYSCLK (80ns @ 150MHz)
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 1; // 외부 핀 트리거 (GPIO12, ADCTRIG1)
AdcRegs.ADCINTSOCSEL1.bit.SOC0 = 0; // SOC0에 인터럽트 연결 비활성화
}
void main(void) {
InitSysCtrl(); // 시스템 클럭(150MHz)과 PLL 초기화
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE 컨트롤러 초기화
IER = 0x0000; // CPU 인터럽트 레지스터 비활성화
IFR = 0x0000; // 인터럽트 플래그 레지스터 클리어
InitPieVectTable(); // PIE 인터럽트 벡터 테이블 초기화
ConfigureGPIO(); // GPIO 설정 함수 호출
ConfigureADC(); // ADC 설정 함수 호출
while(1) {
while(AdcRegs.ADCINTFLG.bit.ADCINT1 == 0); // 변환 완료 대기
adcResult = AdcRegs.ADCRESULT0; // 변환 결과 읽기
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // 인터럽트 플래그 클리어
}
}
설명:
- 기능: GPIO12(ADCTRIG1) 외부 핀 트리거로 ADCINA0 채널에서 변환 수행, 결과 저장
- 설정: ADC 클럭 75MHz, 샘플링 윈도우 80ns, ADCINA0 채널, 외부 핀 트리거
- GPIO: GPIO0(ADCINA0), GPIO12(ADCTRIG1), GPIO34(LED)
- 출력: adcResult에 12비트 ADC 값 저장, LED ON
6. 사용 방법
6.1 환경 설정
- C2000Ware 설치: C:\ti\c2000\C2000Ware_x_xx_xx_xx
- CCS 프로젝트: TMS320F28335 타겟으로 프로젝트 생성, F28x_Project.h 포함
- 링커 파일: device_support\f2833x 폴더에서 링커 파일 추가
6.2 코드 실행
- 각 예제를 별도의 .c 파일로 저장하거나, main.c에 복사
- 다른 예제 코드 주석 처리
6.3 하드웨어 준비
- ADC 입력: ADCINA0
3 핀에 아날로그 신호(03.3V) 연결 - LED: GPIO34에 LED 연결
- ePWM 트리거: 예제 2의 경우 ePWM1 SOCA 트리거 확인
- 외부 트리거: 예제 5의 경우 GPIO12에 트리거 신호 연결
6.4 디버깅
- CCS Expressions 창: AdcRegs.ADCRESULT0~`AdcRegs.ADCRESULT3` 확인
- 인터럽트 상태: AdcRegs.ADCINTFLG로 인터럽트 플래그 점검
- 샘플링 확인: 오실로스코프로 ADC 입력 신호와 트리거 동기화 확인
7. 추가 팁
- 캘리브레이션: ADC 사용 전 Device_cal() 호출 권장
- 노이즈 감소: 아날로그 입력에 저역통과 필터 사용
- C2000Ware 참고: C:\ti\c2000\C2000Ware_x_xx_xx_xx\device_support\f2833x\examples\cpu1\adc
- 문제 해결:
- ADC 출력 없음: ADCCTL1.bit.ADCENABLE, ADCSOCxCTL.bit.TRIGSEL 확인
- 인터럽트 실패: ADCINT.bit.INTxEN, PieCtrlRegs.PIEIER1 확인
- 부정확한 결과: ADCSOCxCTL.bit.ACQPS 값 및 아날로그 입력 범위(0~3.3V) 확인
- TI 리소스: TI E2E 포럼, C2000Ware 예제
8. 결론
이 문서는 TMS320F28335 ADC 모듈의 설정 방법과 Bitfield 구조를 활용한 예제 코드를 제공하여 다양한 애플리케이션에 적용 가능하도록 구성했습니다.
키워드: TMS320F28335, ADC, C2000, 아날로그-디지털 변환, 마이크로컨트롤러, Code Composer Studio, ePWM 트리거, 인터럽트, 다중 채널 변환, 연속 변환, 외부 트리거, 샘플링 윈도우
'MCU > C2000' 카테고리의 다른 글
[TMS320F28335] CAN, I2C, McBSP 사용법 : Bitfield 구조 활용 예제 코드 (0) | 2025.08.19 |
---|---|
[TMS320F28335] DMA 사용법 : Bitfield 구조 활용 예제 코드 (0) | 2025.08.19 |
[TMS320F28335] eQEP 및 eCAP 사용법 : Bitfield 구조 활용 예제 코드 (0) | 2025.08.19 |
[TMS320F28335] XINTF 사용법 : Bitfield 구조 활용 예제 코드 (0) | 2025.08.19 |
[TMS320F28335] ePWM 사용법 : Bitfield 구조 활용 예제 코드 (1) | 2025.08.18 |
[TMS320F28377D] DC-DC 변환 토포롤로지별 ePWM 생성 방법: Bitfield 구조 활용 예제 코드 (1) | 2025.08.18 |
[TI C2000]TMS320F28377D, TMS320F28379D, TMS320F28388D 비교 (2) | 2025.08.18 |
[TI C2000]CMD 파일: 상세 설명, 구조, 작성 방법 및 예제(C2000 CMD File: Detailed Explanation, Structure, Writing Methods, and Examples) (2) | 2025.08.18 |