본문 바로가기

AVR/AVR 연습, Tutorial

AVR 입출력 설정 레지스터, 핀상태 읽기,출력 제어 레지스터 - AVR 이론



AVR의 I/O를 제어하기 위해서는 3가지의 레지스터가 사용되는데 첫번째가 포트의 setting

입력으로 결정할지 출력으로 결정할지 정해주는 레지스터인 DDRx 레지스터, 그리고 DDRx에 

따라출력및 입력시 초기상태를 결정하는 레지스터인 PORTx 와 입력시에 사용하는 핀에 입력을 읽어들이는 레지스터인 PINx가 있습니다.

x는 사용하는 AVR에 따라 TINY2313의 경우 A포트, B포트, D포트를 쓸 수 있고 레지스터 설정 

할 때 값을 Bit 별로 주어야 합니다.


DDRx 입출력 방향 레지스터


Data Direction Resistor x(Port) 포트의 입출력을 설정하는 레지스터입니다.

DDRx레지스터는 입력으로 설정할 것인지 출력으로 설정할것인지만 결정하고 포트에 직접 출력

에관여하지는 않고 출력으로 설정하고 싶은 비트는 1로 입력으로 사용하고자 하는 비트는 0으로 

입력하면 입출력이 설정되고 이 레지스터의 사용방법은 C로 처리시에 2진수나 16진수로 

DDRx = 값 으로 입력하며값의 계산방법은 아래 방법으로 계산할수 있습니다.


예로 포트B의 비트계산 과 16진수 표현입니다.

포트B는 출력으로 사용하고 포트D는 입력으로 사용합니다.


DDRB와 DDRD 예제로 설정시 해당Bit 작성하면 표 같은 결과가 나옵니다.

(다른 포트도 포트번호에 따라 오름차순(0~큰수)으로 10진수 값이 할당됩니다.)

포트번호

PB7

PB6

PB5

PB4

PB3

PB2

PB1

PB0

10진수 값 

128

64

32

16

8

4

2

1

사용자설정 비트값

1

1

1

1

1

1

1

1


Tiny2313에는 포트D에 7번핀이 없습니다.

포트번호

X

PD6

PD5

PD4

PD3

PD2

PD1

PD0

10진수 값 

X

64

32

16

8

4

2

1

사용자설정 비트값

X

0

0

0

0

0

0

0


이걸 C로 2진수로 값을 입력하고 싶으면 값에 0b를 붙이고 다음처음

DDRB=0b11111111 로 입력하면 PB0~PB7 포트까지 모두 출력으로 설정되게 되고, 이 값을

16진수로 출력하고 싶다면 값 앞에 0x를 붙이고 다음과 같이 입력하시면 됩니다.

먼저 입출력 설정 된것은 2진수이기 때문에 16진수로 변환하면 사용자 설정 비트값이 1인 부분의 10진수를 모두 더하면 128+64+32+16+8+4+2+1 이므로 255입니다. 

이 값은 16진수로는 FF 로 컴파일러에서 C언어로 표현시에 DDRB=0xFF로 입력하면 위에 2진수로 표현한것과 같은 값이 됩니다.


D포트도 마찬가지로

DDRD=0b00000000

혹은

DDRD=0x00 을 입력합니다.



PORTx 입출력 설정 레지스터


PORTx 입출력 설정레지스터는 DDRx에서 입력으로 설정했는지 출력으로 설정했는지에 따라

설정할수 있는것이 다르며 4가지 경우가 있습니다.


 입출력설정

 PORTx = 비트값 1

 PORTx = 비트값 0

 DDRx의 비트가 1 (출력) 설정됬을시

해당 포트에 VCC(5V)를 출력합니다.

 해당 포트에 GND(0V)를 출력합니다.

 DDRx의 비트가 0 (입력) 설정됬을시

 해당 포트상태를 Pullup(풀업)

 입력되기 전상태가 1인 상태로 만듭니다.

 해당 포트상태를 Tri-State

입력되기 전상태가 0인 상태로 만듭니다.









C언어로 처리방법은 DDRx와 같습니다.

아래 예제에서 B포트는 출력으로 설정했고, D포트는 입력으로 설정했습니다.

이때 PORTB포트를 출력으로 설정했으므로 원하는 비트를 1로 설정하면 해당 포트에 VCC (5V)가 출력되고 해당 비트를 0으로 설정하면 GND(0V)가 출력됩니다.

PORTD포트는 입력으로 설정했으므로 원하는 비트를 1로 설정하면 해당 포트는 입력 전 초기 

상태가 1인 Pullup 풀업으로 설정되고 비트를 0으로 설정하면 해당 포트는 입력 전 초기 상태가 

0인 Tri-State로 설정됩니다.

Tri-State시 Pull-Down 저항이 반드시 필요합니다.


PORTB 설정

 포트번호

PB7

PB6

PB5

PB4

PB3

PB2

PB1

PB0

 10진수 값 

128

64

32

16

8

4

2

1

 사용자설정 비트값(DDRB)

1

1

1

1

1

1

1

1

 사용자설정 비트값(PORTB)

1

1

1

1

1

1

1

1


PORTD설정

 포트번호

X

PD6

PD5

PD4

PD3

PD2

PD1

PD0

 10진수 값 

X

64

32

16

8

4

2

1

 사용자설정 비트값(DDRD)

X

0

0

0

0

0

0

0

 사용자설정 비트값(PORTD)

X

1

1

1

1

1

1

1


이 값을 2진수로 표현하면

PORTB=0b11111111

16진수로 표현하면

PORTB=0xFF 가 됩니다.


포트 D도 마찬가지로

PORTD=0b1111111

혹은 10진수 값 127을 16진수로 표현하면

PORTD=0x7F 가 됩니다.


PINx 핀 입력상태 READ어드레스


AVR에서 입력시에 입력상태를 읽어오는 레지스터와 유사한 읽기 어드레스가 PINx 입니다.

PINx어드레스는 AVR에서 스위치 입력이나 센서 입력을 판단 할 때 사용하고 DDRx에서 입력으로 설정한 핀의 현재 상태를 읽어옵니다.


위의 포트D은 DDRD에서 0값을 주어 입력으로 설정하고 PORTD로 아무입력이 없을 때를 

1 (Pullup 풀업)으로 설정해 두었습니다.

이 때 PD4에 에서 GND(0V)연결된 스위치를 눌렀다고 가정합니다.


 포트번호

X

PD6

PD5

PD4

PD3

PD2

PD1

PD0

 10진수 값 

X

64

32

16

8

4

2

1

 사용자설정 비트값(DDRD)

X

0

0

0

0

0

0

0

 사용자설정 비트값(PORTD)

X

1

1

1

1

1

1

 현재 입력 상태

X

1

1

0

1

1

1

1


이 상태를 C로 처리시 PIND는 직접 제어하거나 쓰기를 하지 못하고 읽기 만 가능해서

C언어 기본함수중에 if 문을 사용해서 값을 비교해야합니다.

if문으로 처리시에 다음처럼 처리합니다.

if(PIND&0x10 == 0)

{

PORTB=0b11111111;

}

PD4의 10진값 16을 16진수로 변환하면 0x10입니다.

PIND는 8비트를 모두 포함하는 레지스터 즉 모든비트의 값을 더한 255이며 PB4만 골라내야 하므로 PIND와 PD4의 값 0x10과 AND연산해서 그값이 0 이면 포트B의 출력으로 설정된 핀 전체에 VCC (5V)를 공급하라는 뜻입니다. 

혹은 현재 입력상태값을 구해서 PIND와 직접 비교 해도 됩니다. 현재 입력상태가 1인 부분의 10진값만 더합니다. 64+32+8+4+2+1 값은 111입니다. 이 10진 값을 16진수로 변환하면 0x6F가 됩니다. 여기서 if문으로

if(PIND == 0x6F)

{

PORTB=0b11111111;

}

비교하게 되면 동일한 동작을 볼수 있습니다.


마이크로 프로세서를 하는데 가장 어려운것이 레지스터의 개념입니다만 입출력 레지스터 정도는 크게 어렵지는 않습니다. 결국 마이크로프로세서도 계산기입니다.

레지스터에 숫자값을 대입하면 그게 설정의 전부입니다.