Pin을 어떤 용도로 사용할지 설정해주는 PCR(Pin Configure Register)의 설명은...못하겠엉 흑

 

pin이 GPIO로 설정되면, GPIO Registers에 의해 추가적인 속성이 지정됨

 

S32K1xx 모델에는 A,B,C,D,E 5개의 Port가 있고

각각의 시작주소들은 40h 씩 증가해서

 

GPIOA: 0x400F F000h
GPIOB: 0x400F F040h
GPIOC: 0x400F F080h 

GPIOD: 0x400F F0C0h 

GPIOE: 0x400F F100h

 

시작주소들은 이렇게 된다.

 

GPIO 사용 목적에 따라서 offset을 더해준 주소에 목적에 맞는 값(0 or 1)을 써준다.

이런 목적들이 있음..!!

 

LED를 키는 상황으로 예시를 들어보자

 

1. D17을 output pin으로 쓸거임

 - D니까 GPIOD port 사용

 - GPIOD의 base 주소는 0x400F F0C0

 - output으로 쓰겠단 다짐했으니 PDDR 레지스터에 값을 써서 방향을 설정해준다.

 - PDDR의 offset은 0x14

 - 0x400F F0C0 + 0x14 = 0x400F F0D4 에 "1" 을 써준다.

 

2. LED를 D17에 연결할거임

 - output으로 쓰고 있는 D17이니까 PDOR(출력 핀에서 구동되는 논리레벨을 구성하는 레지스터)의 값을 설정할거임

 - PDOR은 offset이 0

 - 0x400F F0C0 에 "1"을 써준다.

 

3. 스위치는 D10에 연결할거임

 - 스위치에선 입력이 들어가는 거니까 PDIR 설정

 - PDIR의 offset은 0x10임

 - 0x400F F0C0 + 0x10 = 0x400F F0D0의 10을 읽어옴

 

SW2 를 누르면 Blue LED가 켜지고 떼면 꺼지는 코드를 작성해보겠슴니다.

 

회로도

핀 구성

회로에서 입력으로 쓰이는 BTN0은 PORTC12

출력으로 쓰이는 BLUE LDE는 PORTD0 에 연결되있는걸 확인 확인

 

flow-chart / loop flow

PORTC_PCR_BASE EQU 0x4004B000
PORTD_PCR_BASE EQU 0x4004C000
PCR_C12 EQU 0x4004B000+0x30 ;12*4
PCR_D0 EQU 0x4004C000
	
GPIOA EQU 0x400FF000
GPIOB EQU 0x400FF040
GPIOC EQU 0x400FF080
GPIOD EQU 0x400FF0C0
PDDR_C EQU 0x400FF080+0x14
PDDR_D EQU 0x400FF0C0+0x14
PIDR_C EQU 0x400FF080+0x18
	
PCC_BASE EQU 0x40065000
PCC_PORTC EQU 0x40065000+0x12C
PCC_PORTD EQU 0x40065000+0x130
CLOCK_EN EQU 0x40000000 ; In S32K14x, GPIO can only be accessed by the core through the cross bar interface at 0x400F_F00
	
	AREA mycode, CODE
	ENTRY
	EXPORT __main
__main
	LDR r0,=PDDR_C ; GPIO Controller, Port C Port Data Diretion Setting , PDDR offset 14h , PortC Base 400FFF080, Portc Diretion 
	LDR r1,=PCC_PORTC ; PCC_PORTC Registor= 12C, PCC Base address Portc Clock = 4006_5000h
	LDR r2,=CLOCK_EN ;  In S32K14x, GPIO can only be accessed by the core through the cross bar interface at 0x400F_F00
	
	STR r2,[r1,#0x00] ; PCC Clock Setting C, r2? [r1? ??? ?? + #0x00]? ?? ??? ??
	STR r2,[r1,#0x04] ; PCC Clock Setting D r2? [r1? ??? ?? + #0x04]? ?? ??? ??
	
	LDR           r1,[r0,#0x00] ; r1= contents of [PDDR_C]
	BIC           r1,r1,#0x1000 ;C12 is configured as input  
	STR           r1,[r0,#0x00] ; PDDR_C <-- 0x1000 D0 is input
	
	LDR			  r1,=PCR_C12 ; Pin control Registor, PORTC multiplexing contol base 0x4004B000,  /* Port C12: MUX = GPIO, input filter enabled */
	MOV           r2,#0x110 ; r2<--0x110 
	STR           r2,[r1,#0x00] ; PCR_C12 is configured as GPIO&PFE
	
	LDR           r2,[r0,#0x40] ; r2= contents of [PDDR_D] 
	ORR           r2,r2,#0x01 ; r2= 0x01
	STR           r2,[r0,#0x40] ;PDDR_D0 is configured as output
	
	MOV           r2,#0x100 ; r2=0x100
	LDR			  r1,=PCR_D0
	STR           r2,[r1,#0x00] ; PCR_D0 is configured as GPIO
	B             NOT_PUSH ; NOT PUSH Function?? ??
ON_PUSH
	LDR           r1,[r0,#0x34] ; r1 = contents of [PDDR_C + 0x34 = PCOR_D]
	ORR			  r1,r1,#0x01 ; Clear D0
	STR           r1,[r0,#0x34] ;
NOT_PUSH
	LDR           r1,[r0,#-0x04] ; r1 = contents of [PDDR_C - 0x04 = PDIR_C], Read C12 DATA
	LSLS          r1,r1,#19 ; Move C12 value to MSB
	BMI           ON_PUSH ; MSB = 1?
	LDR           r1,[r0,#0x30] ; r1 = contets of [PDDR_C + 0x30 = PSOR_D]
	ORR           r1,r1,#0x01 ; Set D0 '1'
	STR           r1,[r0,#0x30] ; 
	B             NOT_PUSH
	END

전체 코드는 이런데 부분부분 살펴 보겠어요

 

PCR설정

PORTD,C를 GPIO로 사용하기 위해서 일단 주소를 셋팅해놓는거

GPIO Register 설정

A~D 시작주소 설정해 주고

 

C,D 를 출력으로 쓰기 위한 PDDR

C를 입력으로 쓰기 위한 PDIR

D를 clear 하기 위한 PCOR

D를 set 하기 위한 PSOR

들을 레지스터의offset 에 맞게 설정 해 준다.

 

Clock을 설정하기 위한 코드

거의 data sheet에 나와있는걸 한줄로 적은거라고 보면 되겠네용

 

이까지가 define 과정이었고 소스코드에 넣기도 하지만

대부분은 헤더파일에 따로 추가해서 씀 ( 그게 편하니까 .. 당연함 )

 

이제 본격적으로 구동을 위한 코드

[Clock Configuration]

실제 코드의 시작 지점은 ENTRY

EXPORT __main 은 프로그램을 실행하다가 program memort 쪽으로 가야할 때 식별할 수 있는 명칭이 되어준다.

r1 레지스터에 PCC_PORTC를

r2 레지스터에 CLOCK_EN을 로드해서

C, D의 clock 을 세팅해준다...

 

[GPIO Switch Configyration(input)]

input 설정에 대한 부분

r1에 PDDR_C 을 담아주고 0x1000과 Bit clear 해서 입력이 되게 하고 다시 메모리에 ㄱㄱ

C12를 GPIO로 사용하기 위해서 PCR_C12 레지스터에 0x110을 입력하면 된단다.

(사용 목적에 따른 3bit 설정하는건데 시트 보니까 거의 다 chip-specific 이더라)

 

[GPIO LED Configuration(output)]

input 설정하는 거랑 걍 똑같음

D0를 사용하니까 C보다 40크게..(offset)

loop를 위한 branch 명령어가 들어갔다.

 

r1에 PCOR_D의 내용을 담고

1과 or 하는데 그러면 on 상태임 (flow-chart 참고...)

4h만큼 빠꾸해서 C12 의 data를 r1에 로드 (PDDR과 PDIR의 offset 차이가 4h 만큼 나니까)

의미있는 정보는 12번 bit에 -> 열 아홉번 shift하면(LSLS 명령어) 12번 bit가 MSB로 옴

BMI 명령어는 branch if minus라는 뜻. 즉 1이 담긴 상태가 아니면 ON_PUSH로 branch 하면  된다.

 

r1에 PSOR_D의 data를 로드하고 1을 더해서 D0 bit를 1로

1로 해준다는건 LED를 끄는거

그러고 계속 루프를 돌게해주면 꺼진상태 유지

 

BLUE LED를 껐다 키는 어셈블리 코드였고

RED LED점멸 코드와 번갈아 키는 코드도 써야함

C와 어셈블리 모두,,,,

+ Recent posts