본문 바로가기

Enginius/Firmware

PIC32 - ADC

 PIC32에는 16개의 10bit분해능을 갖는 ADC 포트가 있다. 

ADC Block Diagram

 이를 사용하기 위해서 초기화를 해주고, ADC변환이 완료 되었을 때 마다 인터럽트 루틴에서 그 값을 update해주는 방식을 사용했다.
 현재 로봇에는 6개의 ADC만을 필요로 하기 때문에 AN0-AN5를 사용하고 나머지는 사용하지 않는다. 인터럽트의 priority는 3으로 한다. (높을수록 우선순위)



 ADC Control Registers

ADCCON1: ADC Control Register1 
 bit31-16
     Reserved
 bit15
     ON
     1: ADC 를 킨다.
     0: ADC 를 끈다.
 bit14
     FRZ : Freeze in debug exeption Mode bit
     1: Debug Exception Mode에서 수행을 멈춘다.
     0: Debug Exception Mode에서도 수행을 계속한다. 
 bit13
     SIDL: Stop in IDLE Mode bit
     1: IDLE Mode에서 module의 동작을 멈춘다.
     0: IDLE Mode에서도 module을 계속 동작시킨다. 
 bit12-11
     Reserved
 bit10-8
     FORM<2:0>: Data Output Format bits
     000: Integer 16-bit
     etc: Datasheet 참조
 bit7-5
     SSRC<2:0>: Conversion Trigger Source Select bits
     111: 자동으로 ADC 변환. 
     etc: Datasheet 참조
 bit4
     CLRASAM: Stop Conversion Sequence bit (when the first A/D converter interrupt is generated)
     1: ADC Interrupt가 발생하고 나서 ASAM을 초기화한다. 즉 ADC 동작을 멈춘다. 
     0: 계속 ADC 동작을 수행, 값을 덮어쓴다. 
 bit3
     Reserverd
 bit12
     ASAM: ADC Sample Auto-Start bit
     1: 이전 Sample이 끝나면 곧바로 다음 Sampling을 수행한다.
     0: SAMP 가 set되면 수행한다.
 bit1
     SAMP: ADC Sample Enable bit ?
     1: ADC SHA Sampling 수행
     0: ADC sample/hold amplifier is Holding
 bit0
     DONE: ADC Status bit
     1: ADC 가 끝났다. 
     0: ADC 가 끝나지 않던가 시작하지 않았다.

ADCCON2: ADC Control Register 2
 bit31-16
     Reserved
 bit15-13
     VCFG<2:0>: Voltage Reference Configuration bits
     000: AVDD와 AVSS가 Vref
     etc: Datasheet 참조

 bit12
     OFFCAL: Input Offset Calibration Mode Selection bit
     1: Enable Offset Calibration (SHA의 Vinh와 Vinl이 Vr-에 연결되어 있어야 한다.)
     0: Offset Calibration을 끈다. (SHA의 input은 AD1CHS나 AD1CSSL에 의해 Control)
 bit11
     Reserved
 bit10
     CSCNA: Scan input Selections for CH0+ SHA Input for MUX A Input MUX Setting bit
     1: Input을 Scan한다.
     0: Scan하지 않는다. 
 bit9-8
     Reserved
 bit7
     BUFS: Buffer Fill Status bit
     BUFM이 1일 때만 Valid
 bit6
     Reserved
 bit5-2
     SMPI<3:0>: Samle/Convert Sequences Per Interrupt Selection bits
     1111: 매 16번째 sample/convert sequence에서 인터럽트 발생
     .....
     0000: 매번 sample/convert sequence에서 인터럽트 발생
 bit1
     BUFM: ADC Result Buffer Mode Select bit
     1: result 버퍼를 2개의 8-word 버퍼로 여긴다.  ADC1BUF(7....0), ADC1BUF(15....8)
     0: result 버퍼를 하나의 16-word 버퍼로 여긴다. ADC1BUF(15....0)
 bit0
     ALTS: Alternative Input Sample Mode Select bit
     1: 처음엔 MUX A를 사용하고, 다음은 다른 설정에 따라 다른 MUX를 사용한다.
     0: MUX A만을 사용한다.

ADCCON3: ADC Control Register 2
 bit31-16
     Reserved
 bit15
     ADRC: ADC Conversion Clock Source bit
     1: 내부 RC Clock
     0: PBClk를 사용
 bit14-13
     Reserved
 bit12-8
     SAMC<4:0>: Auto-Sample Time bits
     11111: 31 Tad
     10000: 16 Tad
     ......
     00001: 1 Tad
     00000: 0 Tad (불가)
 bit7-0
     ADCS<7:0>: ADC Conversion Clock Select bits
     11111111: Tpb*2*(ADCS<7:0> + 1) = 512 * Tpb = Tad
     .....
     00000001: Tpb*2*(ADCS<7:0> + 1) = 4 * Tpb = Tad
     00000000: Tpb*2*(ADCS<7:0> + 1) = 2 * Tpb = Tad
 
AD1CHS: ADC Input Select Register 
 bit31
     CH0NB: Negative Input Select bit for MUX B
     1: Channel0 negative input이 AN1이다. 
     0: Channel0 negative input이 Vr-이다. 

 bit30-28
     Reserved
 bit27-24
     CH0SB<3:0>: Positive Input Select bits for MUX B
     1111 : Channel 0 positive input is AN15
     .....
     0000 : Channel 0 positive input is AN0
 bit23
     CH0NA: Negative Input Select bit for MUX A Multiplex Setting
     1: Channel 0 negative input is AN1
     0: Channel 0 negaive intput is VR-
 bit22-20
     Reserved
 bit19-16
     CH0NA: Positive Input Select bits for MUX A Mutiplexer Setting 
     1111 : Channel 0 positive input is AN15
     .....
     0000 : Channel 0 positive input is AN0
 bit15-0
     Reserved

AD1PCFG: ADC Port Configuration Register 
 bit31-16
     Reserved
 bit15-0
     PCFG<15:0>: Analog Input Pin Configuration Control Bits
     1: Analog Input pin을 digital로 한다.  
     0: Analog Input pin을 analog로 한다. - digital로 포트를 읽으면 1로 읽힌다. 
     ~(0x003F) = ~(0b111111) (0-5번만 analog, 0-5번 빼고는 digital로)

AD1CSSL: ADC Input Scan Select Register 
 bit31-16
     Reserved
 bit15-0
     CSSL<15:0>: ADC Input Pin Scan Selection bits
     1: Scan 한다.  
     0: Scan 하지 않는다. 
     0x003F = 0b111111 (0-5번까지 scan)

IFS1: Interrupt Flag Status Register1
 bit1
     AD1IF: Analog-to-Digital Converter 1 Interrupt Request Flag bit
     1: 인터럽트가 발생했다. 
     0: 인터럽트가 발생하지 않았다.

IEC1: Interrupt Enable Control Register1
 bit1
     AD1IE: ADC1 Interrupt Enable bit
     1: 인터럽트를 사용한다.
     0: 인터럽트를 사용하지 않는다.

IPC6: Interrupt Priority Control Register 6
 bit28-26
     AD1IP<2:0>: ADC 1 Interrupt Priority bits
     111: 우선 순위가 7
     ....
     011: 우선 순위가 3
     000: 우선 순위가 0


PIC32 ADC 초기화 함수와 인터럽트 함수

//adc관련
unsigned int adc_value[ADC_NUM];
char adc_ready = 0;

void Init_adc()
{
//*	//ADC 초기화
	CloseADC10();
	// 				Turn module on | ouput in integer | trigger mode auto | enable autosample
	#define PARAM1	ADC_MODULE_ON | ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON
	// 				ADC ref external | disable offset test | enable scan mode | perform 16 samples
	#define PARAM2	ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_OFF| ADC_ALT_INPUT_OFF
	// use ADC internal clock | set sample time
	//#define PARAM3	ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15
	//#define PARAM4	ENABLE_ALL_ANA
	//#define PARAM5	SKIP_SCAN_ALL
	#define PARAM3	ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_16
	#define PARAM4	ENABLE_AN0_ANA | ENABLE_AN1_ANA | ENABLE_AN2_ANA | ENABLE_AN3_ANA | ENABLE_AN4_ANA | ENABLE_AN5_ANA
	#define PARAM5	SKIP_SCAN_AN6 | SKIP_SCAN_AN7 | SKIP_SCAN_AN8 | SKIP_SCAN_AN9 | SKIP_SCAN_AN10 | SKIP_SCAN_AN11 | SKIP_SCAN_AN12 | SKIP_SCAN_AN13 | SKIP_SCAN_AN14 | SKIP_SCAN_AN15 

	// use ground as neg ref for A
	SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF);
	OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using parameter define above
	ConfigIntADC10(ADC_INT_ON | ADC_INT_PRI_3);
	EnableADC10();			
}

//인터럽트 
void __ISR(_ADC_VECTOR, ipl3) ADC10Handler(void)
{
	char z = 0;
	for (z=0; z < ADC_NUM; z++)
	{
		adc_value[z] = ReadADC10(z);
	}
	adc_ready = 1;

	mAD1ClearIntFlag();
}
#2. 매크로 사용 안한 버젼
void Init_adc()
{

	//Initialization
	AD1CON1 = 0x0000;
	AD1CON2 = 0x0000;
	AD1CON3 = 0x0000;

	//ADC Input Channel Select Register
	AD1CHS = 0x0000;


	//TRIS bit가 1이면 input이다. 
	//PCFGn bit( AD1PCFG )이 0이면 analog input, 1이면 digital input
	//ADC가 PORTB에 있다. 그래서 TRISB를 1로 하고 AD1PCFG를 0으로 하면 Analog input. 
	TRISBSET		= 0b111111;
	AD1PCFGCLR	= 0b111111;	


	//ADC Input Scan Selection Register
	AD1CSSL		= 0b111111;
	

	//ADC Control Registers
	//AD1CON3		= 0b1001000000000000;	//12, 15 bit set
	AD1CON3bits.ADCS = 16;
	AD1CON3bits.SAMC = 0;
	AD1CON3bits.ADRC = 1;

	//AD1CON2		= 0b10000111100;		//2,3,4,5, 10 bit set
	AD1CON2bits.CSCNA = 1;
	AD1CON2bits.SMPI = 0b1111;

	//AD1CON1		= 0b1000000011100100;	//2, 5,6,7, 15 bit set
	AD1CON1bits.ON = 1;
	AD1CON1bits.SSRC = 0b111;
	AD1CON1bits.ASAM = 1;
	
	

	//Clear ADC Interrupt Flag
	IFS1bits.AD1IF = 0;
	
	//ADC Interrupt Priority
	IPC6bits.AD1IP = 3;
	
	//ADC Interrupt SubPriority
	IPC6bits.AD1IS = 3;

	//ADC Interrupt Enable
	IEC1bits.AD1IE = 1;

}


 

'Enginius > Firmware' 카테고리의 다른 글

PIC32 - GPIO  (0) 2010.02.17
PIC32 - Interrupt  (0) 2010.02.17
PIC32 - 기본 페리  (0) 2010.01.05
AVR - atmega128 pwm 쓰기  (0) 2010.01.01
AVR - LDM (Led DotMatrix)  (0) 2009.11.19