본문 바로가기
공부/ATmega128

[ATmega128] C언어에서 bit이해하기.

by ding9 2009. 10. 1.


수업중에 많은 학우들이 비트에 대해 어려움을 겪는것 같아서 이 글을 씁니다. 레포트를 열심히 했으면 알겠지만 ATmega128의 각 포트는 보통 8개의 포트로 이루어져있습니다. 또한 많은 MPU계열에서 포트제어를 할때 사용하는것이 바로 0xff, 0x00 이런것들입니다.

예를들어 우리가 가장 많이 사용하는 PORTB를 예로 들면...

각 포트는 설정할때 0이면 입력, 1이면 출력입니다. 입력을 할건지 출력을 할건지를 결정하는 것은 바로 DDRB 입니다. 우리는 포트 B를 출력으로 사용하기때문에 아래와 같이 설정합니다.

DDRB=0xff;   or  DDRB=0xFF;

이 구문을 써주면 소스코드 어디에 있던간에 포트B는 출력으로 설정이 됩니다. 하지만 우리는 한번쓰고 거의 바꾸지 않기때문에 제일 위에 쓰고나서 그 뒤로는 이 구문을 사용하지 않습니다.

위 구문을 써주고 포트B의 초기화를 해줍니다. 보통은 PORTB=0x00; 이런식으로 해주지만 LED를 켜기위해선 외부파워를 쓰기때문에 PORTB=0xff; 로 설정해줍니다. 포트B를 설정하는건 DDRB구문 바로위든 바로 밑이던 크게 상관없습니다.

자. 여기까지하면 포트를 출력으로 사용하고 포트 초기화까지 끝났습니다. 여기까지를 소스코드로 작성해보면...

#include<mega128.h>
#include<delay.h>

void main()
{
 PORTB=0xff;
 DDRB=0xff;
}

이렇게 됩니다.

그리고 지금부터가 문제인데 예제소스는 예전에 보드가 제대로 동작하는지 테스트했던 소스를 이용하겠습니다.

#include<mega128.h>
#include<delay.h>

void main()
{
 int i;
 PORTB=0xff;
 DDRB=0xff;

 for ( i = 0; i < 8; i++)
 {
  PORTB = PORTB << 1;
  delay_ms(200);
 }

 for( i = 0; i < 8; i++)
 {
  PORTB = (PORTB >> 1) | 0x80;
  delay_ms(200);
 }
}

수업시간에 다들 봤겠지만 LED가 순차적으로 켜졌다가 순차적으로 꺼지는 프로그램입니다. 여기서 가장 중요한것은 <<, >>, | 이것들입니다. 이녀석들은 비트연산자라고 해서 숫자를 비트로 연산하는 연산자이기때문에 보통 숫자로 셈을 한다고 생각하면 안됩니다. 컴퓨터에서는 보통 1 Byte 즉 8 bit로 영어나 숫자를 인식합니다.

비트에 대한것은 인터넷에서 많이 찾아볼수 있기때문에 자세한 설명은 생략합니다.

이러한 비트연산자들이 중요한건 무엇때문이냐 하면 이녀석들을 가지고 LED를 켜고 끄고를 할수 있기때문이죠.

두번째 for문을 가지고 설명하겠습니다. 처음에 for문에 들어가면 i=0을 가지므로 for문의 조건이 맞기 때문에 for문을 실행합니다. PORTB에 0x00의 값이 들어있다고 가정하면 PORTB >> 1은 PORTB에 있는 값을 1비트만큼씩 오른쪽으로 밀겠다라는 거죠. 예를 들면 0000 0001 이라는 값이 있으면 오른쪽으로 1만큼 시프트가 되면 0000 0000 와 같이 됩니다.  이것이 가장 중요한 거죠. 본격적으로 for문을 해석하면....

두번째 for문에 처음 들어가는 값은 0x00입니다. 왜냐고 생각이 든다면 이 설명이 끝나고 첫번째 for문을 한번 따라가 보세요. 그럼 이해가 될겁니다. 아무튼 PORTB >> 1 하면 0x00이 되고 | 0x80을 해주게 되면 0x80 이라는 값이 PORTB에 최종적으로 입력이 됩니다. | <- 이건 OR연산자입니다. 0000 0000 | 1000 0000 = 1000 0000 = 0x80 이렇게 되죠. 그리고 delay함수로 인해서 200 ms만큼 지연이 되고 i++ 이 되어 i = 1 이 됩니다. for문이 돌아가는 조건에 맞으므로 PORTB = (PORTB >> 1) | 0x80; 구문이 실행됩니다. PORTB에 있는 값은 0x80 오른쪽으로 1만큼 시프트시키면 0x40이 되고 여기에 0x80을 | 연산자로 계산해주면 0xc0 이 되고 이 값이 PORTB에 최종적으로 들어갑니다.

PORTB 는 0x80
PORTB >> 1 을 하면 1000 0000 -> 0100 0000 이 되어 0x40. 이값에 | 0x80 를 하면 0100 0000 | 1000 0000 = 1100 0000 = 0xc0

이렇게 되는 거죠. 이런식으로 for문이 i=7까지 돌게 되니 최종적으로 0xff가 됩니다.

이제 이해가 되셨나요?? MPU프로그램은 C언어를 기반으로 하지만 여러분들이 배워왔던 C언어와는 어떻게 보면 조금은 다를수도 있습니다. 하지만 조금 더 기계적으로 생각을 하신다면 좀더 쉽게 접근할수 있을겁니다.

그럼 이글이 조금이라도 도움이 되셨길 바라면서....

반응형

'공부 > ATmega128' 카테고리의 다른 글

ATmega48  (0) 2009.08.21
ATmega128  (0) 2009.08.04
watchdog  (0) 2008.09.04
cisc와 risc  (0) 2008.09.04

댓글