01. GPIO#
1. Setting#
1-1. 프로젝트 생성#
S32 Design Studio를 실행하고 왼쪽 하단의 S32DS Application Project를 클릭한다.
1-2. 프로젝트 설정#
Project name을 입력하고, Family S32K3xx->S32K312를 선택한 후 Next를 클릭한다.
이후 별도의 설정을 건드리지 않고 Finish를 클릭한다.
2. LED 예제 (타이머 주기에 따른 LED Toggle)#
- 새로운 예제를 위한 프로젝트를 생성한다.
- 원하는 동작을 위해 레지스터와 메모리에 직접 접근해 값을 써야 한다.
- 해당 예제에서는 LED를 사용하기 때문에 board schematic에서 LED 정보를 파악한다.
- LED가 연결된 GPIO 모듈의 메모리 맵을 분석한다.
- 분석 결과를 활용해 임베디드 프로그래밍을 한다.
2-1. Schematic 분석#
해당 보드의 Schematic과 HW manual을 참고하면 RGB LED는 PTC10, PTB17, PTB16에 연결되어 있으며 각각 Red, Green, Blue를 제어한다. (Schematic과 RGB 순서가 다르다)
본 예제에서는 RGB LED의 Red를 이용할 것이므로, PTC10을 사용한다.
2-2. Datasheet 분석#
2-2-1. IO 설정#
LED를 사용하기 위해 연결된 핀의 IO 설정이 필요하다.
- MSCR(Multiplexed Signal Configuration Register)의 SSS(Source Signal Select) 비트를 0으로 설정하면 GPIO로 동작한다.
- MSCR의 OBE 비트를 1로 설정하면 출력으로 동작한다.
PTCm을 제어하기 위한 MSCRn 번호는 \(\rm n=(m+64)\)이다.
MSCRn의 주소는 \(\rm SIUL2\ base + MSCR\ offset+ (n \times 4)\)로 구할 수 있다.
MSCR74 주소: 4029_0368h (4029_0000h + 240h + 128h)
2-2-2. Port Clock 설정#
S32K312는 GPIO를 사용하기 위한 별도의 클럭 설정을 할 필요가 없다.
2-2-3. 출력 데이터 설정#
GPDO 레지스터의 LSB를 write해 원하는 출력을 만들 수 있다.
PTCm을 제어하기 위한 GPDOn 번호는 MSCRn 번호와 동일하다. GPDOn의 주소는 \(\rm SIUL2\ base + GPDO\ offset+ (n+3-2\times(n\ mod\ 4))\)로 구할 수 있다.
GPDO74 주소: 4029_131Eh (4029_0000h + 1300h + 0x49)
2-3. 프로그래밍#
2-3-1. 매크로 정의#
- IO 설정 관련 레지스터 주소 및 비트 필드 정의
// SIUL2 Registers #define SIUL2_BASE (0x40290000UL) #define SIUL2_MSCR_BASE (SIUL2_BASE + 0x240) #define SIUL2_MSCR74 (*(volatile unsigned *)(SIUL2_MSCR_BASE + 0x128)) #define SIUL2_GPDO_BASE (SIUL2_BASE + 0x1300) #define SIUL2_GPDO74 (*(volatile unsigned char *)(SIUL2_GPDO_BASE + 0x49)) // MSCR Bits #define OBE_BIT 21 // Output Buffer Enable #define SSS_BITS 0 // Source Signal Select
2-3-2. main 코드#
- main 함수
MSCR74의 SSS를 0으로 만들고 OBE를 set해 GPIO output으로 설정한다.
int main(void) { int cycles = 0; SIUL2_MSCR74 &= (0b0000 << SSS_BITS); SIUL2_MSCR74 |= (1 << OBE_BIT); while (1) { cycles = 720000; while (cycles--); SIUL2_GPDO74 = 1; cycles = 720000; while (cycles--); SIUL2_GPDO74 = 0; } return 0; }
이후 일정 주기마다 GPDO29의 값을 바꾸도록 루프문을 작성한다.
2-4. 빌드#
상단 툴바에서 Build All 버튼을 눌러 빌드한다.
2-5. 디버그#
상단 메뉴에서 디버그 툴 옆 삼각형을 눌러 Debug Configurations에 진입한다.
GDB PEMicro Interface Debugging의 하위에서 (프로젝트명)_Debug_FLASH_PNE를 선택하고 Debug를 눌러 디버그에 진입한다.
3. Switch 예제 (Switch를 이용한 LED on/off 제어)#
- 새로운 예제를 위한 프로젝트를 생성한다.
- 원하는 동작을 위해 레지스터와 메모리에 직접 접근해 값을 써야 한다.
- 해당 예제에서는 switch를 사용하기 때문에 board schematic에서 switch 정보를 파악한다.
- Switch가 연결된 GPIO 모듈의 메모리 맵을 분석한다.
- 분석 결과를 활용해 임베디드 프로그래밍을 한다.
3-1. Schematic 분석#
해당 보드의 Schematic과 HW manual을 참고하면 User switch는 PTD2, PTD3에 연결되어 있다. Switch가 Active-low 구조이므로 GPDI 값이 0일 때 스위치가 눌린 것으로 파악할 수 있다.
3-2. Datasheet 분석#
3-2-1. IO 설정#
Switch를 사용하기 위해 연결된 핀의 IO 설정이 필요하다.
- MSCR(Multiplexed Signal Configuration Register)의 SSS(Source Signal Select) 비트를 0으로 설정하면 GPIO로 동작한다.
- MSCR의 IBE 비트를 1로 설정하면 출력으로 동작한다.
PTDm을 제어하기 위한 MSCRn 번호는 \(\rm n=(m+96)\)로 구할 수 있다.
MSCRn의 주소는 \(\rm SIUL2\ base + MSCR\ offset+ (n \times 4)\)로 구할 수 있다.
MSCR98 주소: 4029_03C8h (4029_0000h + 240h + 188h)
3-2-2. Port Clock 설정#
S32K312는 GPIO를 사용하기 위한 별도의 클럭 설정을 할 필요가 없다.
3-2-3. 입력 데이터 읽기#
GPDO 레지스터의 LSB를 write해 원하는 출력을 만들 수 있다.
PTBm을 제어하기 위한 GPDIn 번호는 MSCRn 번호와 동일하다.
GPDIn의 주소는 \(\rm SIUL2\ base + GPDI\ offset+ (n+3-2\times(n\ mod\ 4))\)로 구할 수 있다.
GPDI98 주소: 4029_1561h (4029_0000h + 1500h + 61h)
3-3. 프로그래밍#
3-3-1. 매크로 정의#
- IO 설정 관련 레지스터 주소 및 비트 필드 정의
// SIUL2 Registers #define SIUL2_BASE (0x40290000UL) #define SIUL2_MSCR_BASE (SIUL2_BASE + 0x240) #define SIUL2_MSCR74 (*(volatile unsigned *)(SIUL2_MSCR_BASE + 0x128)) #define SIUL2_MSCR98 (*(volatile unsigned *)(SIUL2_MSCR_BASE + 0x188)) #define SIUL2_GPDO_BASE (SIUL2_BASE + 0x1300) #define SIUL2_GPDO74 (*(volatile unsigned char *)(SIUL2_GPDO_BASE + 0x49)) #define SIUL2_GPDI_BASE (SIUL2_BASE + 0x1500) #define SIUL2_GPDI98 (*(volatile unsigned char *)(SIUL2_GPDI_BASE + 0x61)) // MSCR Bits #define OBE_BIT 21 // Output Buffer Enable #define IBE_BIT 19 // Input Buffer Enable #define SSS_BITS 0 // Source Signal Select
3-3-2. main 코드#
- main 함수
MSCR98의 SSS를 0으로 만들고 IBE를 set해 GPIO input으로 설정한다.
int main(void) { SIUL2_MSCR74 &= ~(0b1111 << SSS_BITS); // GPIO SIUL2_MSCR74 |= (1 << OBE_BIT); // output SIUL2_MSCR98 &= ~(0b1111 << SSS_BITS); // GPIO SIUL2_MSCR98 |= (1 << IBE_BIT); // input while (1) { if (!SIUL2_GPDI98) // Active-low switch SIUL2_GPDO74 = 1; else SIUL2_GPDO74 = 0; } return 0; }
이후 GPDI98의 값을 계속 체크해 눌린 경우(0)에 LED를 켜도록 루프문을 작성한다.
3-4. 동작 모습#
- 빌드, 디버그 후 스위치를 눌렀을 때 LED가 켜지는 것을 확인한다.