들어가며
이 글에서는 Texas Instruments사의 Cortex-M4칩인 TM4C123GH6PM의 ADC 초기화 설정 방법을 설명합니다. 예제 코드는 공개 강좌인 Embedded Systems - Shape the World Chapter 14의 예제 코드를 기반으로 합니다. 여담으로 앞서 언급한 강좌는 MCU 공부를 시작하는 사람에게 많은 도움이 될거라 생각합니다. 관심이 있다면 시간을 들여서 보시는 것을 추천합니다.
ADC 초기화 내용
초기화 과정에서 하는 일은 크게 두 가지 입니다. ADC 입력 소스로 사용할 GPIO 설정과 ADC 설정 설정입니다. 우리는 ADC 9번 채널로 사용할 수 있는 GPIOE 4번 핀에 아날로그 입력을 받을 수 있도록 기능을 설정할 것입니다. 그리고 하나의 소스로부터 초당 125,000번 샘플링 할 수 있도록 ADC 기능을 설정할 것입니다. 이런 일을 하기 위한 코드는 아래와 같습니다.
void ADC0_InitSWTriggerSeq3_Ch9(void)
{
SYSCTL_RCGCADC_R |= 0x0001; // 1) activate ADC0
SYSCTL_RCGCGPIO_R |= 0x10; // 2) activate clock for Port E
while((SYSCTL_PRGPIO_R&0x10) != 0x10){}; // 3 for stabilization
GPIO_PORTE_DIR_R &= ~0x10; // 4) make PE4 input
GPIO_PORTE_AFSEL_R |= 0x10; // 5) enable alternate function on PE4
GPIO_PORTE_DEN_R &= ~0x10; // 6) disable digital I/O on PE4
GPIO_PORTE_AMSEL_R |= 0x10; // 7) enable analog functionality on PE4
// while((SYSCTL_PRADC_R&0x0001) != 0x0001){}; // good code, but not implemented in simulator
ADC0_PC_R &= ~0xF;
ADC0_PC_R |= 0x1; // 8) configure for 125K samples/sec
ADC0_SSPRI_R = 0x0123; // 9) Sequencer 3 is highest priority
ADC0_ACTSS_R &= ~0x0008; // 10) disable sample sequencer 3
ADC0_EMUX_R &= ~0xF000; // 11) seq3 is software trigger
ADC0_SSMUX3_R &= ~0x000F;
ADC0_SSMUX3_R += 9; // 12) set channel
ADC0_SSCTL3_R = 0x0006; // 13) no TS0 D0, yes IE0 END0
ADC0_IM_R &= ~0x0008; // 14) disable SS3 interrupts
ADC0_ACTSS_R |= 0x0008; // 15) enable sample sequencer 3
}
아날로그 입력을 위한 GPIO 설정
GPIOE4 핀을 아날로그 입력핀으로 사용합니다. 이를 위한 GPIO 초기화 과정은 아래와 같습니다.
SYSCTL_RCGCGPIO_R |= 0x10; // 2) activate clock for Port E
while((SYSCTL_PRGPIO_R&0x10) != 0x10){}; // 3 for stabilization
GPIO_PORTE_DIR_R &= ~0x10; // 4) make PE4 input
GPIO_PORTE_AFSEL_R |= 0x10; // 5) enable alternate function on PE4
GPIO_PORTE_DEN_R &= ~0x10; // 6) disable digital I/O on PE4
GPIO_PORTE_AMSEL_R |= 0x10; // 7) enable analog functionality on PE4
처음 보는 레지스터는 SYSCTL_PRGPIO_R
입니다. 이 레지스터 이름은 General-Purpose Input/Output Peripheral Ready 입니다. 이름 그대로 GPIO가 사용가능한 상태인지 확인하기 위한 레지스터인 것이지요. 지난 글에서 GPIO에 clock을 공급해준 다음 3 clock의 지연 시간이 필요하다고 알려드렸습니다. 그래서 아래와 같은 의미 없는 코드를 넣기도 했지요.
delay = SYSCTL_RCGC2_R;
그때는 저도 잘 몰랐으니 그러려니 했습니다. 그런데 이렇게 주변장치가 준비된 상태인지 확인하는 번듯한 레지스터가 있다면 이것을 쓰는게 맞겠습니다.
이후 코드는 이미 다뤄본 레지스터이기 때문에 간단히 설명하겠습니다. GPIOE4를 아래와 같이 설정합니다.
- 입력으로 설정
- 별도 기능을 하용하도록 활성화
- 디지털 입/출력 비활성화
- 핀 기능을 아날로그로 설정
아날로그 입력을 위한 ADC 설정
SYSCTL_RCGCADC_R |= 0x0001; // 1) activate ADC0
// ...(GPIO 초기화 설정)
ADC0_PC_R &= ~0xF;
ADC0_PC_R |= 0x1; // 8) configure for 125K samples/sec
ADC0_SSPRI_R = 0x0123; // 9) Sequencer 3 is highest priority
ADC0_ACTSS_R &= ~0x0008; // 10) disable sample sequencer 3
ADC0_EMUX_R &= ~0xF000; // 11) seq3 is software trigger
ADC0_SSMUX3_R &= ~0x000F;
ADC0_SSMUX3_R += 9; // 12) set channel
ADC0_SSCTL3_R = 0x0006; // 13) no TS0 D0, yes IE0 END0
ADC0_IM_R &= ~0x0008; // 14) disable SS3 interrupts
ADC0_ACTSS_R |= 0x0008; // 15) enable sample sequencer 3
ADC Run Mode Clock Gating Control
SYSCTL_RCGCADC_R |= 0x0001;
SYSCTL_RCGCADC_R
레지스터는 GPIO 초기 설정에서 보았던 유사한 레지스터와 같은 기능을 가지고 있습니다. ADC 장치에 클록 공급 여부를 설정하는 기능을 합니다. ADC를 사용하려면 당연히 가장 먼저 이 레지스터 설정부터 해줘야 겠지요? ADC module 0를 활성화 하기 위해서 첫 번째 비트를 set합니다. 참고로 TM4C123GH6PM 칩에는 ADC 모듈이 두 개 있습니다. 이 글을 참고하세요.(ADC 모듈)
ADC Peripheral Configuration
ADC0_PC_R &= ~0xF;
ADC0_PC_R |= 0x1;
ADC0_PC_R
레지스터는 ADC 샘플링 속도를 설정하는 기능을 가지고 있습니다. 샘플링 속도별 설정 값을 아래 표를 참고하세요. 코드는 해당 레지스터 값을 모두 clear한 뒤 125 ksps(초당 125,000번 샘플링) 속도로 설정하는 내용입니다.
값 | 샘플링 속도 |
---|---|
0x1 | 125 ksps |
0x3 | 250 ksps |
0x5 | 500 ksps |
0x7 | 1 Msps |
ADC Sample Sequencer Priority
ADC0_SSPRI_R = 0x0123;
ADC0_SSPRI_R
레지스터로 샘플링 시퀀서의 우선순위를 설정합니다. 한 ADC 모듈당 4개의 시퀀서가 있습니다. 우선 순위는 0번이 가장 높고 1, 2, 3 순으로 낮아집니다. 데이터시트에서 이 레지스터 구조를 살펴보면 위에 있는 코드가 어떤 의미인지 쉽게 알 수 있습니다. 0x0123
이라는 값에서 16진수를 의미하는 0x
를 빼고 보았을 때 맨 왼쪽 숫자부터 3번 시퀀서, 2번 시퀀서, 1번 시퀀서, 0번 시퀀서의 우선 순위를 뜻합니다. 결국 우리가 사용할 3번 시퀀서를 가장 우선순위에 두는 설정을 하는 것이지요.
ADC Activate Sample Sequencer
ADC0_ACTSS_R &= ~0x0008;
3번 시퀀서 설정을 진행하기 위해서 비활성화 합니다.
ADC Event Multiplexer Select
ADC0_EMUX_R &= ~0xF000;
ADC 시퀀서가 값을 읽기 위한 트리거 소스를 설정합니다. 0xF는 항상 값을 읽는 continuosly sample 방식입니다.
ADC Sample Sequence Input Multiplexer Select 3
ADC0_SSMUX3_R &= ~0x000F;
ADC0_SSMUX3_R += 9;
3번 샘플 시퀀서의 입력 소스를 설정하는 레지스터 입니다. 9번 채널을 통해 아날로그 입력을 받기 위한 설정을 합니다.
Sample Sequence Control 3
ADC0_SSCTL3_R = 0x0006; // 13) no TS0 D0, yes IE0 END0
3번 샘플 시퀀서가 샘플링 할 때의 동작을 설정하는 레지스터 입니다. 온도 값과 차등 모드를 비활성화 시키고 인터럽트는 활성화 시켰습니다. 그리고 이 소스가 마지막 소스임을 알려주는 설정을 합니다. 3번 샘플링 시퀀서는 입력 소스가 1개이므로 당연히 항상 END0 비트가 set되어야 합니다.
ADC Interrupt Mask
ADC0_IM_R &= ~0x0008;
3번 샘플링 시퀀서가 샘플링을 마치고 인터럽트가 신호가 발생하더라도 처리되지 않도록 설정합니다.
###
ADC0_ACTSS_R |= 0x0008;
3번 샘플링 시퀀서를 사용하기 위해서 활성화 합니다.
'연구 노트 > Embedded' 카테고리의 다른 글
Windows 10에서 RTOS 개발환경 구축하기 1 - WSL 2를 활성화하자 (0) | 2021.01.12 |
---|---|
어셈블리 파일 확장자 .s와 .S는 다르다. (2) | 2020.12.25 |
[TM4C] GPIO 초기 설정 방법 해설 (0) | 2020.11.22 |
CCS 프로젝트 include 경로 설정 (4) | 2020.11.18 |
[Modulabs] 2020년 임베디드랩 시즌1 마지막 프로젝트 (0) | 2020.11.13 |