본문 바로가기
학부 자료/DSP(MCU)

[ADC] Analog to Digital Converter, 싱크웍스 예제 인터럽트(Interrupt) 방식으로 ADC 하기

by jackMK 2024. 2. 4.

ADC란

: Analog to Digital Converter, 말 그대로 아날로그 신호를 디지털 신호로 변환해 주는 역할을 하는 IC입니다.

간단한 예시로 마이크에서 들은 소리나 카메라에서 촬영한 빛을 디지털 데이터로 전환시키기 위한 부품을 칭합니다.

사실상 현대의 센서라고 부를만한 제품엔 모두 달려있는 필수요소입니다.

기본적으로 외부의 신호는 아날로그 신호이기 때문에 ADC가 없으면 읽어낼 수가 없다고 볼 수 있습니다.

 

 

Part 1. 예제 실습의 목적

: Delfino EVM의 Potentiometer의 DC 출력 신호를 ADC하고, 결과를 CCS의 Expressions 창에서 확인하는 예제입니다. ePWM 모듈의 타이머를 사용해서 정확한 주기로 ADC-B 모듈의 SOC0 을 트리거 하여 ADC를 진행하고, ADC 변환 종료 후에 인터럽트를 발생시켜서 ADC 결과를 저장하는 예제입니다.

 

*EVM이란 평가 모듈을 뜻하는 것으로 엔지니어와 개발자가 특정 마이크로컨트롤러의 기능을 실험하고 테스트할 수 있는 개발 및 평가 보드입니다.

 

원래 실습에서 사용할 보드입니다.

 

위 사진의 보드가 실습에서 요구하는 준비물로, 레버를 돌려 DC 조절을 해야합니다.

 

 

Digilent Analog Discovery 2™

 

하지만 저희 연구실에 해당 연습용 보드가 없어 위에 보이는 Digilent Analog Discovery 2™를 사용하였습니다. WaveForm 프로그램과 함께 사용하여 DC인가(Supplies)를 해주었습니다.

 

Digilent Analog Discovery 2™  Pinout Diagram

 

 

 

Part 2. 실습 진행 순서

  1.  WaveForm 실행 후 DC인가(Supplies) 준비
  2. CCS 실행 후 실행 작업(Launch→Build→Load) 후 Realtime으로 실행
  3. 변수 값 변화 확인

초기 세팅

 

 

 

Part 3. TEST(Code)

 

아래 코드는 싱크웍스의 Delfino 개발보드 F28377D 예제 2번의 CCS 코드입니다.

실습예제 사이트 바로가기

 

// 선행처리 지시

#include "F28x_Project.h" // Device Headerfile and Examples Include File

 

// 함수 선언

interrupt void adcb1_isr(void);

 

// 시스템에서 사용할 전역 변수 선언

Uint16 ADC_value;

Uint16 Loop_cnt, ADC_cnt;

 

// 메인 함수 - 시작

void main(void)

{

// Step 1. 전역 인터럽트 해제

DINT;

 

// Step 2. 시스템 클럭 초기화:

InitSysCtrl();

EALLOW; // PWM 모듈에 공급되는 시스템 클럭 분주

ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 0; // 0: 1분주, 1: 1/2분주

EDIS;

 

// Step 3. 인터럽트 초기화:

InitPieCtrl();

IER = 0x0000;

IFR = 0x0000;

InitPieVectTable();

 

// Vector Remapping

EALLOW;

PieVectTable.ADCB1_INT = &adcb1_isr;

EDIS;

 

// 외부 인터터트 포합된 백터 활성화

PieCtrlRegs.PIEIER1.bit.INTx2 = 1; // PIE 인터럽트(ADCA1INT) 활성화

IER |= M_INT1; // CPU 인터럽트(INT1) 활성화

 

// Step 4. ADC 초기화

// ADC 모드 설정 및 Power-up

 

EALLOW;

AdcbRegs.ADCCTL2.bit.PRESCALE = 6; // ADCCLK = SYSCLK / 4, SYSCLK = 200MHz

 

AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);

 

AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1; // ADC Interrupt Pulse Position: 변환종료 후 발생

AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1; // ADC 시동(Power-up)

DELAY_US(1000); // ADC가 시동되는 동안 1ms 지연

EDIS;

 

// ADC SOC(채널, S/H시간, 트리거소스) 및 인터럽트 설정

EALLOW;

AdcbRegs.ADCSOC0CTL.bit.CHSEL = 0; // SOC0 : ADCINB0 채널 변환

AdcbRegs.ADCSOC0CTL.bit.ACQPS = 14; // (S/H 시간) 설정 75ns = (ACQPS+1)/SYSCLK

AdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 7; // SOC0: ePWM2 SOCA/C로 트리거

AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 0; // EOC0ADCINT1를 발생

AdcbRegs.ADCINTSEL1N2.bit.INT1E = 1; // ADCINT1 활성화

AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // ADCINT1 flag 클리어 확인

EDIS;

 

//ADC SOC 트리거를 위한 ePWM2 설정

EALLOW;

EPwm2Regs.ETSEL.bit.SOCAEN = 1; // SOCA 이벤트 트리거 Enable

EPwm2Regs.ETSEL.bit.SOCASEL = 2; // SCCA 트리거 조건 : 카운터 주기 일치 시

EPwm2Regs.ETPS.bit.SOCAPRD = 1; // SOCA 이벤트 분주 설정 : 트리거 조건 한번 마다

EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // count up and start

EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; // TBCLK = [SYSCLKOUT / ((HSPCLKDIV*2) * 2^(CLKDIV))]

EPwm2Regs.TBCTL.bit.CLKDIV = 0; // TBCLK = [200MHz / (1*1)] = 200MHz

EPwm2Regs.TBPRD = 10000 - 1; // TBCLK/(TBPRD+1) = 200MHz/10,000 = 20KHz

EPwm2Regs.TBCTR = 0x0000; // TB 카운터 초기화

EDIS;

 

// Step 6. 변수 초기화

ADC_value = 0;

Loop_cnt = 0;

 

// 전역 인터럽트 활성화 및 and 리얼타임 디버깅 이벤트 활성화

EINT; // Enable Global interrupt INTM

ERTM; // Enable Global realtime interrupt DBGM

 

// IDLE loop. Just sit and loop forever :

for(;;)

{

Loop_cnt++;

}

 

}

// 메인 함수 -

 

// ADC 인터럽트 서비스 루틴

interrupt void adcb1_isr(void)

{

ADC_value= AdcbResultRegs.ADCRESULT0;

 

AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag

PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

}


코드 출력 후 공부한 사진입니다.

 

Part 4. 코드 간략 설명

SOC(Start of Conversion) : ADC를 시작하는 신호(트리거)

0~15 중 하나를 선택하여 아래 동작을 조작한다.

TRIGSEL(트리거 선택), CHSEL(입력 채널 선택), ACQPS(샘플 시간 결정)

ADCRESULTx 에 저장한다.

 

AdcxRegs :

ADC x핀의 결과값이 가상의 포트인 

AdcResultREGs.ADCRESULTx에 저장된다.

 

왼쪽부터 DataSheet p332, p102, p174
왼쪽부터 DataSheet p1591~1593 
왼쪽부터 DataSheet p1978~1980
DataSheet p1731

 

 

 

Part 5. 실습 결과

0V 일 때 ADC_value

 

 

1.5V 일 때 ADC_value

 

 

3V 일 때 ADC_value

 

 

 

DC값을 0~3V까지 바꿔주면서 ADC_value값이 변화하는 것을 관찰할 수 있습니다.

 

DataSheet에 기반하여 작성한 글이며 해당 파일이 용량이 큰 관계로 필요하신 분은 댓글로 이메일 남겨주시면 보내드리겠습니다.

 

이상으로 글을 마치겠습니다. 감사합니다.


loading