SOURCE TR28335_P2200.h
/*==============================================================
*
* FILE : TR28335_P2200.h .2017
* TITLE : TR28335 Potentiometer ADC Interrupt Service Routine
* SENSOR : Potentiometer(P2200)
*
*==============================================================*/
#ifndef __TR28335_P2200_H__
#define __TR28335_P2200_H__
#ifdef _cplusplus
extern "C" {
#endif
#include <main.h>
#define ADC_CORE_12_BIT 4095
#define SINGLE_16_STATE_SEQ(ADC_DATA) ((ADC_DATA) >> 4)
#define VOLTAGE(ADC_DATA) ((ADC_DATA) * (3.3f / ADC_CORE_12_BIT))
void initP2200Adc(void);
#ifdef _cplusplus
}
#endif /* extern "C" */
#endif /* __TR28335_P2200_H__ */
SOURCE TR28335_P2200.c
/*==============================================================
*
* FILE : TR28335_P2200.c .2017
* TITLE : TR28335 Potentiometer ADC Interrupt Service Routine
* SENSOR : Potentiometer(P2200)
*
*==============================================================*/
#include <TR28335_P2200.h>
interrupt void p2200_adc_isr(void);
float32 gVoltage;
/*=======================================
*
* Name : initP2200Adc
* Type : Fucntion
* Description : P2200 ADC Initialization
*
=========================================*/
void initP2200Adc(void)
{
gVoltage= 0.0f;
EALLOW;
PieVectTable.ADCINT = &p2200_adc_isr;
EDIS;
/* ADC 초기화 */
InitAdc();
/* ADC 설정 */
AdcRegs.ADCTRL3.bit.ADCCLKPS = 3; /* ADCCLK = HSPCLK/(ADCCLKPS*2)/(CPS+1) */
AdcRegs.ADCTRL1.bit.CPS = 1; /* ADCCLK = 75MHz/(3*2)/(1+1) = 6.2MHz */
AdcRegs.ADCTRL1.bit.ACQ_PS = 3; /* 샘플/홀드 사이클 = ADQ_PS + 1 = 4 (ADCCLK 기준) */
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; /* 시퀀스 모드 설정 : 직렬 시퀀스 모드 (0: 병렬 모드, 1: 직렬 모드) */
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0; /* ADC 채널수 설정 : 1개 (=MAX_CONV+1) 채널을 ADC */
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0; /* ADC 순서 설정 : 첫번째로 ADCINA0 채널을 ADC */
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ = 1; /* ePWM_SOCB로 ADC 시퀀스 시동 */
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; /* ADC 시퀀스 완료시 인터럽트 발생 설정 */
/* ePWM_SOCB 이벤트 트리거 설정 */
EPwm3Regs.ETSEL.bit.SOCBEN = 1; /* SOCB 이벤트 트리거 Enable */
EPwm3Regs.ETSEL.bit.SOCBSEL = 2; /* SCCB 트리거 조건 : 카운터 주기 일치 시 */
EPwm3Regs.ETPS.bit.SOCBPRD = 1; /* SOCB 이벤트 분주 설정 : 트리거 조건 한번 마다 */
EPwm3Regs.TBCTL.bit.CTRMODE = 0; /* 카운트 모드 설정 : UP-count 모드 */
EPwm3Regs.TBCTL.bit.HSPCLKDIV = 1; /* TBCLK = [SYSCLKOUT / ((HSPCLKDIV * 2) * 2^(CLKDIV))] */
EPwm3Regs.TBCTL.bit.CLKDIV = 1; /* TBCLK = [150MHz / (2*2)] = 37.5MHz */
EPwm3Regs.TBPRD = 1874; /* TB주기 = (TBPRD + 1)/TBCLK = 1875/37.5MHz = 50us(20KHz) */
EPwm3Regs.TBCTR = 0x0000; /* TB 카운터 초기화 */
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1;
return;
}
/*==================================================
*
* Name : p2200_adc_isr
* Type : Interrupt
* Description : P2200 ADC Interrupt Service Routine
*
====================================================*/
interrupt void p2200_adc_isr(void)
{
gVoltage= VOLTAGE(SINGLE_16_STATE_SEQ(AdcRegs.ADCRESULT0));
/* Reinitialize for next ADC sequence */
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
코드 분석
📌 Step .1 ADCINT : PIE Group 1 Vectors Table 에 Interrupt Service Routine 등록한다.
📌 Step .2 InitAdc : 이 함수는 TI에서 기술하여 제공하는 DSP2833x_Adc.c 라는 파일에서 찾을 수 있다. 사용자가 ADC 회로를 이용하여 어떠한 데이터를 변환할 수 있도록 ADC 회로를 초기화 하는 과정을 담고있다. 이 과정에서는 ADC 회로의 정상적인 기동을 위한 Power-up Sequence 가 포함된다.
📌 Step .3 : ADC 구동에 필요한 클럭 공급 과정
📌 Step .4 ADCTRL1 - ACQ_PS : ADC Sample & Hold 회로의 Acquisition window size 를 설정하는 항목이다. TM320F28X에 탑재된 ADC 회로는 일종의 비교형의 형태를 띠고 있으므로 취득한 외부 신호를 비교가 완료될 때까지 유지할 필요성이 있다. S/H 회로가 값을 취듯해 가지고 있는 시간이 결정 된다.
📌 Step.5 ADCTRL1 - SEQ_CASC : 시퀀서의 운용방법을 결정하는 비트다. 두 개의 시퀀서를 직렬로 연결하여 마치 하나의 시퀀서인 것 처럼 사용할 수 있는 직렬시퀀서모드(Cascaded mode)와 독립된 두 개로 운용하는 독립시퀀서모드(Dual-sequencer mode)로 구분된다.
📌 Step .6 ADCMAXCONV - MAX_CONV1 : ADC 채널수를 설정 한다.
📌 Step .7 ADCCHSELSEQ - CONV00 : P2200 은 ADCINA0 에 연결되어 있으므로 ADC 순서 설정 CONV00 비트에 ADCINA0 를 설정한다.
📌 Step .8 ADCTRL2 - EPWM_SOCB_SEQ : 직렬 시퀀스에서만 유효 하며 ePWM_SOCB 신호를 변환시작.
📌 Step .9 ADCTRL2 - INT_ENA_SEQ1 : 시퀀스 1에 의한 인터럽트를 활성화.
📌 Step .10 ETSEL - SOCBEN : EPWMxSOCB 는 ADC 인터럽트를 위해 제작되었다는 것을 알 수 있다.
📌 Step .11 ETSEL - SOCBSEL : 주기에 대한 트리거(인터럽트) 발생 옵션 부분이다. Enable event time-base counter equal to period(TBCTR = TBPRD) 는 초기값으로 설정하는 TBPRD 비트와 카운팅되서 증가하는 TBCTR비트값이 동일할 경우에 트리거가 발생하게 해준다. PRD 값이 고정되고 증가 클럭 속도를 설정을 통해서 정할 수 있으므로 원하는 시간을 계산할 수 있다.
📌 Step .12 ETPS - SOCBPRD : 이벤트 주기에서의 변환시작 선택 설정.
📌 Step .13 TBCTL - CTRMODE : 카운터 모드 설정.
📌 Step .14 TBCTL - HSPCLKDIV, CLKDIV : TBLCK 는 Time Base clock를 의미하며 pwm의 clock으로 사용된다. 이는 SYSCLK에서 분배하여 그 값을 정하며 수식적으로는 위에 표시해 놓았듯이 TBCLK = SYSCLK / (HSPCLKDIV * CLKDIV) 이다.
관련 그림은 아래와 같다.
📌 Step .15 TBPRD : ePWM 주기를 설정하는 카운터로 카운팅되는 TBCTR 이 TBPRD와 같으면 인터럽트가 발생된다.
📌 Step .16 ADCRESULT0 : ADCRESULT0 으로 ADC 결과를 받을때 주의할점은 첫 0~3bit 가 Reserved 이므로 4bit 만큼 시프트하여 사용하여야 한다.
결과
gVoltage 변수를 그래프로 관찰하면 아래와같이 0V~32V로 가변하는 그래프 결과를 확인할 수 있다.
ADC Clock 클럭 계산 Excel
TR28335 개발 KIT eCAP (Enhanced Capture Module) (0) | 2017.07.03 |
---|---|
TR28335 개발 KIT IC2(Inter integrated circuit) 통신 (2) | 2017.06.27 |
TR28335 개발 KIT Switch GPIO Input (0) | 2017.06.23 |
TR28335 개발 KIT CPU Timer 인터럽트 사용 (0) | 2017.06.23 |
TR28335 개발 KIT GPIO LED 제어 (0) | 2017.06.23 |