AVR을 동작시키기 위한 외부조건으로는 크게 세 가지가 만족되어야 되는데 다음과 같다.


       ① 전원이 적절히 인가되어야 한다.

       ② 클럭이 적절하게 인가되어야 한다.

       ③ 리셋(reset)핀에 ‘1’신호가 인가되어야 한다.


이 세 가지 조건을 만족하면 AVR은 내부 플래시롬에서 프로그램 명령어를 하나씩 꺼내서 실행하기 시작한다.

전원 인가

 ATmega8(A)의 동작 전압은 2.7V~5.5V이므로 정상 동작을 위해서는 이 사이의 전압값을 사용해야하며 보통 5V 또는 3.3V의 전압값을 많이 사용한다. ATmega8A의 전원 관련 핀들을 <그림 3.4.1>에 도시하였다. 여기서 7번 핀은 VCC로서 시스템에서 사용하는 전압에 따라 5V나 3.3V 등을 인가하면 되고 8번 또는 22번 핀에는 그라운드(GND)를 인가하면 된다.


[그림 1] 전원 관련 핀들


그리고 20번 핀은 내부의 ADC에 전원을 인가하는 AVCC핀이다. ADC는 아날로그 전압 값을 디지털 값으로 바꾸는 장치인데 전압 변화에 매우 민감하기 때문에 시스템의 전원과 분리되어 있다. 따라서, ADC를 사용하지 않는다면 연결하지 않아도 상관없으나, 만약에 ADC를 사용한다면 여기에도 전원을 인가해야 한다. 단, ADC는 전원의 잡음에 민감하기 때문에 데이터쉬트에는 다음 [그림 2]와 같이 LC필터를 사용할 것을 권장하고 있다. AREF핀은 ADC에서 기준으로 사용할 전압을 인가하는 핀이다.


[그림 2] AVCC 핀의 LC필터 회로


리셋(reset) 회로

 리셋은 것은 프로세서를 초기화 시켜서 프로그램의 동작을 처음부터 강제로 시작하게끔 하는 것이다. ATmega8(A)의 리셋회로의 구조도를 [그림 3]에 도시하였다.


[그림 3] ATmega8(A)의 리셋 로직


이 그림을 보면 ATmega8A가 리셋이 일어나는 경우는 다음과 같이 네 가지가 있다는 것을 알 수 있다.


       ① 전원을 인가하였을 때

       ② 외부 리셋핀(1번 핀)에 0신호가 인가되었을 때

       ③ 저전압이 감지되었을 때. (brown-out)

       ④ 워치독(watch dog) 타이머에 의해서


워치독 타이머는 퓨즈바이트에서 사용 여부를 설정할 수 있다.




Posted by 살레시오
,

락 비트 (lock bit)

 ATmega8(A)는 6개의 락 비트 (lock bit)가 있다. 락 비트은 플래시롬과 EEPROM을 다시 프로그램할 수 없도록 잠그는데 사용된다. 따라서 제품의 개발이 끝난 다음 다시 프로그램을 변경할 필요가 없거나, 혹은 외부인이 AVR내부의 프로그램을 읽어낼 수 없도록 막기 위해서 사용한다. 주의할 점은 ‘1’이 unprogrammed 이고 ‘0’이 programmed 이라는 것이다. 흔히 반대로 생각하기 쉬우니 주의해야 한다. (이것은 fuse byte에서도 동일하다.)


[표 1] 락 비트

Lock bits

bit

기술

기본 설정 값

7

-

1(unprogrammed)

6

-

1(unprogrammed)

BLB12

5

Boot lock bit 12

1(unprogrammed)

BLB11

4

Boot lock bit 11

1(unprogrammed)

BLB02

3

Boot lock bit 02

1(unprogrammed)

BLB01

2

Boot lock bit 01

1(unprogrammed)

LB2

1

Lock bit 2

1(unprogrammed)

LB1

0

Lock bit 1

1(unprogrammed)


[표 2] 락 비트 설정

memory lock bit

기능설명

LB모드

LB2

LB1

1

1

1

아무런 제한 없음

2

1

0

플래시/EEPROM/퓨즈비트 프로그램 금지. (Fuse byte도 잠김)

3

0

0

플래시/EEPROM/퓨즈비트 프로그램 및 확인(verify) 금지. (Fuse byte도 잠김)

memory lock bit

기능설명

BLB0모드

BLB02

BLB01

1

1

1

아무런 제한 없음

4

0

1

boot loader의 LPM명령이 application section을 읽기 불가. 인터럽트벡터가 boot loader에 있다면 application section 실행 중 인터럽트 불가.

3

0

0

SPM으로 application section에 쓰기 불가. boot loader의 LPM명령이 application section을 읽기 불가, 인터럽트벡터가 boot loader에 있다면 application section 실행중 인터럽트 불가

2

1

0

SPM으로 application section에 쓰기 불가

memory lock bit

기능설명

BLB1모드

BLB12

BLB11

1

1

1

아무런 제한 없음

4

0

1

application section에 위치한 LPM명령으로 부트로더 영영의 읽기 불가, 인터럽트벡터가 application section에 있다면 boot loader 실행 중 인터럽트 불가

3

0

0

SPM으로 부트로더 영역에 쓰기 불가. application section 에 위치한 LPM명령이 부트로더 영역을 읽기 불가, 인터럽트벡터가 application section에 있다면 boot loader 실행 중 인터럽트 불가

2

1

0

SPM으로 부트로더 영역에 쓰기 불가


락비트를 프로그램하면 퓨즈바이트가 잠기기 때문에 반드시 퓨즈 바이트를 먼저 프로그램 한 다음에 필요하다면 락비트를 프로그램해야 한다.


퓨즈 바이트 (fuse byte)

 퓨즈 바이트는 AVR을 동작시키는데 있어서 전반적으로 설정해야 할 사항들을 선택하여 저장하는 내부메모리로서 ATmega8(A)의 경우에는 두 개의 바이트로 구성되어 있다. 각각의 퓨즈비트는 1 또는 0값을 가지게끔 설정할 수 있는데 한 가지 유의할 점은 datasheet상에서 사용하는 용어가 0으로 쓰는 경우를 programmed, 1로 쓰는 경우가 unprogrammed로 되어있다는 점이다. 보통은 반대로 생각하기 쉬우니 유의해야 한다.


 상위 퓨즈 바이트와 하위 퓨즈 바이트와 각각의 비트의 기능을 다음 표에 정리해 놓았다.


[표 3] 상위 퓨즈 바이트 기능

비트명

bit

기능

기본설정값

RSTDISBL (4)

7

PB6핀을 RESET으로 사용할 것인지 포트핀으로 사용할 것인지 설정

1(PB6는 리셋핀)

WDTON

6

Watch Dog Timer 사용

1(사용 안함)

SPIEN (1)

5

SPI통신으로 ISP 가능

0(SPI 다운로드 가능)

CKOPT (2)

4

오실레이터 옵션

1(unprogrammed)

EESAVE

3

칩erase 수행시에 EEPROM의 내용 유지

1 (EEPROM도 지움)

BOOTSZ1

2

부트 사이즈 설정

0 (3)

BOOTSZ0

1

부트 사이즈 설정

0 (3)

BOOTRST

0

리셋벡터 설정

1

(1) 직렬통신 모드에서는 이 비트는 접근 불가임.

(2) CKOPT 비트는 CKSEL3:0 의 설정에 따라 그 기능이 달라짐.

(3) 기본설정값으로는 부트섹터가 최대로 설정된 것임.

(4) 이 비트가 0(programmed)이면 병렬프로그램 모드를 사용해야 함.


시중에 쉽게 구할 수 있는 ISP 기기들은 SPI 통신(직렬통신임)을 사용하고 있고 이러한 직렬 통신 프로그래밍은 리셋 모드일 때 진입할 수 있으며 리셋 핀이 하이(1)일 때 다운로드를 수행하므로 필수적으로 리셋 핀의 기능이 있어야 한다. 따라서 RSTDISBL 비트는 만약 직렬 통신 프로그래머를 사용한다면 1값을 계속 유지해야하며 만약 (실수로라도) 0으로 설정하면 그 다음부터는 SPI를 이용한 프로그래밍이 불가능해진다는 것에 유의하자.


 워치독타이머(watch dog timer, WDT)라는 것은 uC가 예측 불가능한 외부요인(외부 잡음, 온도, 배터리의 소모 등등)으로 인해서 정상적인 동작을 수행하고 있는지 아닌 지를 감시하는 기능을 수행한다. 만약 WDT가 활성화 되어 있다면 여기에서 주기적으로 어떤 신호가 발생하게끔 되어 있으며 따라서 이 신호가 정상적으로 발생한다면 uC가 정상적으로 동작하는 것으로 판단하게 된다. 만약 어떤 요인에 의해서 uC가 오동작을 하게 되면 WDT에서 발생하던 신호가 끊기게 되고 이러한 경우에는 uC를 리셋시키거나 어떤 조치를 취하여 프로그램이 다시 정상적으로 수행하도록 할 수 있는 것이다. WDTON비트는 이러한 시스템 감시기능의 활성화 여부를 설정하는 비트이다.


 SPIEN비트는 직렬통신모드로 ISP를 사용한다면 아예 접근할 수 없도록 막아져있다.


 플래시메모리는 크게 응용프로그램영역과 부트로더영역으로 나뉜다는 것은 앞에서도 설명했었다. 부트로더 영역의 크기를 BOOTSZ1:0 비트를 이용해서 설정할 수 있으며 각각의 경우에 대해서 부트로더의 크기는 다음 그림과 같다.

그리고 BOOTRST비트는 리셋이 걸린 이후 맨 첨음 실행을 시작하는 번지가 응용프로그램의 최하위번지(0번지)인지 부트로더의 최하위번지(이경우는 BOOTSZ1:0의 설정에 따라 달라짐)를 설정하는 비트이다.


[표 4] 부트로더 사이즈 설정

BOOTSZ1

BOOTSZ0

사이즈

페이지

응용프로그램영역

부트로더영역

1

1

128 word

4

0x000~0xF7F

0xF80~0xFFF

1

0

256 word

8

0x000~0xEFF

0xF00~0xFFF

0

1

512 word

16

0x000~0xDFF

0xE00~0xFFF

0

0

1024 word

32

0x000~0xBFF

0xC00~0xFFF


 하위 퓨즈바이트는 크게 클럭소스선택, 기동시간 설정, 그리고 BOD관련 설정 비트들로 이루어져 있다. BOD(brown out detector)는 시스템의 전원전압이 일정레벨 이하로 떨어지는 지를 감시하는 장치이다. 건전지나 충전지로 구동되는 시스템의 경우에는 시간이 지나면 정상 전압 이하로 떨어지고 방치하면 전체 시스템이 오동작을 일으킬 수 있으므로 그 전에 이것을 감지하여 적절한 조치를 취하도록 할 수있다. BODEN은 이러한 감시기능을 활성화 시킬 것인지를 설정하는 비트이고 BODLEVEL은 전압레벨을 설정하는 비트이다.


[표 5] 하위 퓨즈 바이트의 기능

비트명

비트

번호

기능

내정값

BODLEVEL

7

Brown Out Detector Tirgger Level

1

BODEN

6

Brown Out Detector enable

1(BOD disabled)

SUT1

5

기동 시간(start-up time) 설정

1(unprogrammed)

SUT0

4

0(programmed)

CKSEL3

3

클럭 소스 선택 (clock selection)

0(programmed)

CKSEL2

2

0(programmed)

CKSEL1

1

0(programmed)

CKSEL0

0

1(unprogrammed)



 클럭 소스 선택 비트 CKSEL3:0과 기동 시간 설정 비트 SUT1:0에 대해서는 다음 포스트에서 상세히 설명하도록 하겠다.




Posted by 살레시오
,

 비트 마스킹은 다음과 같이 세 가지로 정리된다.

       ❶ 특정 비트를 0으로 만든다. (reset)

       ❷ 특정 비트를 1로 만든다. (set)

       ❸ 특정 비트을 반전시킨다. (toggle)

특정한 비트를 0으로 만들려면 0과 AND연산을 하면 되고 1로 만들려면 1과 OR연산을 하면 된다. 반전시키려면 1과 XOR연산을 취하면 된다. 다음 표에 이것을 정리하였다.

[표 1] 비트 마스크의 종류


x

x&0

0

0

1

0



x

x|1

0

1

1

1



x

x^1

0

1

1

0


이러한 비트 연산 특성을 이용하면 이진수의 특정위치의 비트들을 강제로 1, 0으로 만들거나 혹은 반전시킬 수 있으며 마이크로콘트롤러의 프로그래밍에서 사용빈도가 매우 높은 기법이다.

 비트 이동연산자 << 를 마스킹기법과 조합하여 사용하여 원하는 하나의 비트를 조작하기도 한다. 예를 들어서 unsigned short형 변수 usA가 0xa00b일 때 다른 비트값들은 그대로 유지한 채 8번 비트(b8)만 강제로 1로 만들고 싶다면 다음과 같이 하면 된다.


unsigned short usA = 0xa00b;
usA |= (1<<8);


여기서 (1<<8)의 결과는 이진수로 표시하면 0b 0000 0001 0000 0000 이며 b8만 1로 세트된 데이터이다. 반대로 n번 비트를 0으로 만들고 싶다면 ~(1<<n)과 AND연산을 하면 되고(1<<n 을 반전시켰음에 유의하라), n번 비트를 반전시키려면 (1<<n)과 XOR연산을 취하면 된다.


unsigned short usA = 0xa00b;
usA &= ~(1<<8); //8번 비트만 0으로 만든다


unsigned short usA = 0xa00b;
usA ^= (1<<8); //8번 비트만 반전한다.


 이러한 방법은 특정한 비트가 0인지 1인지를 조건 검사할 경우에도 사용된다. 만약 unsigned char형 변수 ucVar의 6번 비트(b6)가 0인지를 검사하려면 다음과 같이 조건 검사를 하면 될 것이다.


if (ucVar & (1<<6) == 0 ) {
   ...
   // ucVar 의 6번 비트가 0일 경우 수행할 명령들
   ...
} else {
   ...
   // ucVar 의 6번 비트가 1일 경우 수행할 명령들
   ...

}


일반적으로 n번 비트가 0인지를 조사하려면 (1<<n)과 변수와 and연산을 취하여 그 결과가 0인지 검사하면 된다. 이 조건이 거짓이라면 그 비트는 1이라는 결론을 얻을 수 있다.



Posted by 살레시오
,

 비트 이동(shift) 연산자는 방향에 따라 두 가지가 있는데 <<연산자는 왼쪽 이동 연산자이고 >>는 오른쪽 이동 연산자이다. 쉬프트(shift)는 비트의 자리를 이동시킨다는 용어인데 이 연산자의 오른쪽에 적인 숫자의 자리수만큼 순차적으로 이동시킨다. 사용 문법은 var<<n (혹은 var>>n) 이며 변수 var을 n비트 좌측(혹은 우측)으로 이동시킨다.


unsigned char uca = 0b01101100;

unsigned char ucb = uca >> 2; // 각 비트를 오른쪽으로 두 자리씩 이동

unsigned char ucc = ucc << 3; // 각 비트를 왼쪽으로 세 자리씩 이동


비트들이 자리 이동을 하게 되면 밀려나서 버려지는 비트들이 있으며 반대로 채워야되는 자리가 생기게 되는데 두 가지 경우가 약간 차이가 있다. 먼저, 왼쪽으로 비트들을 이동시키는 << 연산자의 경우 비트들이 왼쪽으로 자리를 이동하게 되면 비는 공간을 0으로 채우게 되며 자리 이동으로 인해 밀려나가는 비트들은 모두 버려지게 된다.


반면, 오른쪽으로 비트들을 이동시키는 >>연산의 경우는 오른쪽으로 밀려나가는 비트들은 버려지지만 좌측에 생기는 빈 공간에는 부호가 없는 데이터형이면 0으로, 반대로 부호가 있는 데이터형은 부호를 유지시키기 위해서 원래 변수 값의 최상위비트(MSB)로 채운다. (주의할 것)


 예를 들어 (unsigned char) ucx=5 라면 ucx<<= 2 명령에 의해 원래 (0b00000101)이 (0b00010100) 십진수로 20이 된다. 왼쪽으로 쉬프트는 2를 곱하는 효과가 있으므로 2번 쉬프트하면 4를 곱한 효과가 난다.


unsigned char ucx = 0b00000101;

ucx <<= 2; // 0b00010100 이 된다.


반대로 ucx>>=2 는 결과값이 (0b00000001)이 된며 오른쪽으로 쉬프트하는 것은 2로 나눈 효과가 있게 된다. 이 경우 ucx변수가 부호가 없는 데이터형이기 때문에 최상위비트는 0으로 채워진다.


unsigned char ucx = 0b00000101;

ucx >>= 2; // 0b00000001 이 된다.


 만약 부호가 있는 데이터형 변수 (char) ca=-2 이라면 2진수로 표현하면 0b11111110 이다. 이것을 cA>>=1 연산을 한 결과는 0b11111111이 된다 (십진수로는 –1이다.). 이 경우는 부호가 있는 데이터형이기 때문에 최상위 비트가 원래 부호비트값인 1로 채워지는 것이다.


char ca = -2; // 이진수로 0b11111110 이다.

ca >>= 1; // 0b11111111 (십진수로 -1) 이 된다.


 다음 예제를 입력하고 결과를 확인해 보자.


#include "stdio.h"
typedef unsigned char uchar;
int main()
{
  uchar ucA = 0x05, ucB, ucC;
  ucB = ucA << 3;
  ucC = ucA >> 1;
  printf("ucA : 0x%x\n", ucA);
  printf("ucB : 0x%x\n", ucB);
  printf("ucC : 0x%x\n", ucC);
}


ucA : 0x5
ucB : 0x28
ucC : 0x2


이진수로는 0b00000101, 0b00101000, 0b00000010 에 각각 해당된다.


C++ 강좌 전체 목록 >>>


c{c++},n{c0054}

'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글

C언어의 표준안들 개요  (0) 2015.05.24
1.4 C 프로그램 개발 과정  (0) 2015.05.24
C/C++의 bitwise-not 연산 (~)  (0) 2015.05.20
C/C++의 bitwise-xor 연산 (^)  (0) 2015.05.20
C/C++의 bitwise-or 연산자 (|)  (0) 2015.05.20
Posted by 살레시오
,

 bitwise - not 연산자 ~ 는 단항 연산자로 각 비트를 반전(toggle)시킨다. 즉 1은 0으로, 0은 1로 바꾼다.


표 3.5.4 비트not연산

x

~x

0

1

1

0


이 연산은 전체 비트에 대해서 수행된다. 예를 들면 다음과 같다.


unsigned char uca = 0b10101100, ucb;

ucb = ~uca; // 0b01010011 이 대입된다.


 다음 예제는 위의 네 가지 비트 연산(&, |, ^, ~)을 수행한 결과를 16진수로 보여주는 예제이다. 전 절에서도 소개한 바와 같이 printf()함수에서 정수를 16진수로 표시하는 서식 문자는 ‘%x’이다. 연습을 위해서 16진수 하나하나를 이진수로 바꾼 다음 손으로 연산을 수행해 보기를 권한다.


#include <stdio.h>
typedef unsigned char uchar;
int main(void)
{
  uchar ucA1 = 0xfa;
  uchar ucB1 = 0x3a;
  uchar ucC1 = 0xc1, ucC2;
  uchar ucD1 = 0xbb, ucD2 = 0xa8, ucD3;
  ucC2 = ~ucC1;
  ucD3 = ucD1^ucD2;
  printf("0x%x & 0xf0 = 0x%x\n", ucA1, ucA1 & 0xf0);
  printf("0x%x | 0x8c = 0x%x\n", ucB1, ucB1 | 0x8c);
  printf("~0x%x = 0x%x\n", ucC1, ucC2);
  printf("0x%x ^ 0x%x = 0x%x\n", ucD1, ucD2, ucD3);
}


0xfa & 0xf0 = 0xf0
0x3a | 0x8c = 0xbe
~0xc1 = 0x3e
0xbb ^ 0xa8 = 0x13


여기에서 typedef 명령에 의해서 unsigned char 형은 uchar 로 줄여서 사용할 수 있다. 즉, main()함수 내의 uchar 은 unsigned char 와 같다.


C++ 강좌 전체 목록 >>>


c{c++},n{c0053}

Posted by 살레시오
,

 비트 xor 연산자(^)는 두 피연산자의 같은 위치의 비트끼리 xor 연산을 수행한다. 두 비트의 xor 연산은 두 비트가 서로 다른 경우에는 1, 같은 경우는 0이다. 그 진리표는 다음 표와 같다.


[표 1] 비트 xor 연산

x

y

x⊗y

0

0

0

0

1

1

1

0

1

1

1

0


두 비트의 연산은 이해하기 쉬우나 세 개 이상의 비트들에 대해서 xor 연산을 수행하면 결과가 어떻게 될지 예측하기는 쉽지 않다. 다음 표에 세 비트의 xor 결과를 기록하였다.


[표 2] 세 비트의  xor 연산

x

y

z

x⊗y⊗z

0

0

0

0

0

0

1

1

0

1

0

1

0

1

1

0

1

0

0

1

1

0

1

0

1

1

0

0

1

1

1

1


일반적으로 n개 비트들의 xor 결과는 1의 개수가 홀수 개이면 1, 짝수 개이면 0이다. 위의 두 표에서도 이 규칙이 적용되므로 확인해 보기 바란다.


 다음 예제로 xor 연산 결과를 살펴보자.


unsigned char ucX = 0x3a, ucY = 0xb2, uCZ ;
ucZ = ucX ^ ucY;


이제 변수 ucZ에 저장되는 값은 다음과 같이 계산된다.





b7

b6

b5

b4

b3

b2

b1

b0



ucX

=

0

0

1

1

1

0

1

0

(0x3a)

^

ucY

=

1

0

1

1

0

0

1

0

(0xb2)


ucZ

=

1

0

0

0

1

0

0

0

(0x88)


 이 bit-xor 연산을 이용하면 원하는 비트를 반전시키는데(toggle) 응용할 수 있다. 만약 어떤 데이터에서 상위 4비트는 그대로 유지하고 하위 4비트만을 반전시키고자 하면 다음과 같이 한다.


unsigned char uca = 0xba;
uca ^= 0x0f;





b7

b6

b5

b4

b3

b2

b1

b0



uca

=

1

0

1

1

1

0

1

0

(0xba)

^

0x0f

=

0

0

0

0

1

1

1

1

(0x0f)


uca

=

1

0

1

1

0

1

0

1

(0xb5)


위의 예에서 보면 0x0f(=0b00001111)과 xor연산을 취하면 하위 4비트만 반전됨을 알 수 있다. 상위 4비트는 원래 값을 유지한다. 그 결과로 uca변수에는 0xb5가 남는다.


C++ 강좌 전체 목록 >>>


c{c++},n{c0052}

Posted by 살레시오
,

 두 피연산자의 or 연산은 같은 자리의 비트끼리의 or 연산을 전체 비트들에 대해서 수행하며 다음  표에 bitwise - or 연산을 정리하였다. 두 비트가 모두 0이어야 0이고 하나라도 1이라면 1이 된다.


[표 1] 비트 or 연산

x

y

x+y

0

0

0

0

1

1

1

0

1

1

1

1


앞의 경우와 같은 예제를 살펴보자.


unsigned char ucx = 0x3a, ucy = 0xb2, ucz ;
ucz = ucx | ucy;


이제 변수 ucz에 저장되는 값은 다음과 같이 계산된다.





b7

b6

b5

b4

b3

b2

b1

b0



ucx

=

0

0

1

1

1

0

1

0

(0x3a)

|

ucy

=

1

0

1

1

0

0

1

0

(0xb2)


ucz

=

1

0

1

1

1

0

1

0

(0xba)


이 결과를 보면 같은 위치의 비트끼리 bit-or 연산을 취한 결과가 얻어진다는 것을 알 수 있다.


 여기서 소개한 bitwise-or 연산자는 특정 비트를 강제로 1로 만들고 싶을 때도 많이 사용된다. 예를 들어 ucm변수가 1바이트값 0x2A라고 했을 때 3번, 4번, 7번 비트만 1로 강제로 만들고 싶다면 다음과 같이 하면 된다.


unsigned char ucm = 0x2A;
ucm |= 0x98;


여기서 0x98은 이진수로 0b10011000 이고 3번, 5번, 7번 비트만 1, 나머지는 0인 수이다. 이것과 ucm을 or 연산을 한 결과는 3번, 5번, 7번 비트만 무조건 1로 만들고 나머지는 그대로 놔둔 수를 얻게 된다.





b7

b6

b5

b4

b3

b2

b1

b0



ucm

=

0

0

1

0

1

0

1

0

(0x2A)

|

0x98

=

1

0

0

1

1

0

0

0

(0x98)


ucm

=

1

0

1

1

1

0

1

0

(0xBA)


이렇게 특정한 비트를 1로 강제로 변환시키는 연산도 마스킹(masking)이라고 한다.


C++ 강좌 전체 목록 >>>


c{c++},n{c0051}

'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글

C/C++의 bitwise-not 연산 (~)  (0) 2015.05.20
C/C++의 bitwise-xor 연산 (^)  (0) 2015.05.20
C/C++의 bitwise-and 연산  (0) 2015.05.20
C/C++의 비트 연산자의 종류  (0) 2015.05.20
C/C++의 대입연산자  (0) 2015.05.20
Posted by 살레시오
,

 두 피연산자의 and연산은 같은 자리의 비트끼리 전체 비트들에 대해서 수행하며 [표 1]에 AND연산을 정리하였다. 두 비트가 모두 1이어야 1이고 하나라도 0이라면 0이다.


[표 1] 비트-and 연산

x

y

x▪y

0

0

0

0

1

0

1

0

0

1

1

1


예를 들면 다음과 같다.


unsigned char ucx = 0x3A, ucy = 0xB2, ucz ;
ucz = ucx & ucy;


이 경우 변수 ucz에 저장되는 값은 다음과 같이 계산된다.





b7

b6

b5

b4

b3

b2

b1

b0



ucx

=

0

0

1

1

1

0

1

0

(0x3A)

&

ucy

=

1

0

1

1

0

0

1

0

(0xB2)


ucz

=

0

0

1

1

0

0

1

0

(0x32)


이 그림에서 보듯이 (unsigned) char형 변수는 보통 최하위 비트를 0번으로 해서 1번, 2번, ...  , 7번 비트까지 있으며 각각 b0, b1, b2, … , b7이라고 표시한다. 변수의 가장 하위 비트를 LSB (least significant bit), 가장 상위비트를 MSB (most significant bit)라고 한다. 이 경우는 8비트 연산이지만 16비트(short)나 32비트(long) 연산도 원리는 동일하다. 즉, 같은 위치의 비트끼리 and연산을 취하는 것이다.


 다음과 같은 경우에도 and연산이 사용된다. 만약 어떤 데이터 값에서 상위 4비트는 그대로 유지하고 하위 4비트만을 0으로 만들고 싶다면 어떻게 해야 할까.


unsigned char uca = 0xBA;
uca &= 0xF0;





b7

b6

b5

b4

b3

b2

b1

b0



uca

=

1

0

1

1

1

0

1

0

(0xBA)

&

0xF0

=

1

1

1

1

0

0

0

0

(0xF0)


uca

=

1

0

1

1

0

0

0

0

(0xB0)


위의 예에서 보면 0xF0(=0b11110000)과 and연산을 취하면 그러한 동작이 일어남을 알 수 있다. 그 결과로 uca변수에는 0xB0가 남는다. 즉 상위 4비트는 그대로 유지하면서 하위 4비트는 0으로 바뀐다. 이러한 연산을 마스킹(masking)이라고 한다.


C++ 강좌 전체 목록 >>>


c{c++},n{c0050}

'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글

C/C++의 bitwise-xor 연산 (^)  (0) 2015.05.20
C/C++의 bitwise-or 연산자 (|)  (0) 2015.05.20
C/C++의 비트 연산자의 종류  (0) 2015.05.20
C/C++의 대입연산자  (0) 2015.05.20
C/C++의 증감연산자(++, --)  (0) 2015.05.19
Posted by 살레시오
,

 비트 연산자는 피연산자의 같은 자리에 있는 비트끼리의 연산을 수행한다. 마이크로콘트롤러(아두이노 등) 프로그래밍에서는 특정 레지스터의 비트값을 조작해야 하는 일이 매우 빈번하기 때문에 비트 연산에 대해서는 자세히 알아두는 것이 좋다. 사실 PC와 같은 환경에서는 비트 연산이 그리 유용하지 않으나 마이크로콘트롤러 프로그래밍에서는 그렇지 않다는 것을 실제로 실습을 진행해 보면 알게 될 것이다.


 다음 표에 비트 연산자의 종류와 동작에 대해서 정리하였다.


표 3.6.1 비트연산자의 종류

비트연산자

의미

수행 동작

&

논리-and

두 피연산자의 bit-wise AND

|

논리-or

두 피연산자의 bit-wise OR

^

논리-xor

두 피연산자의 bit-wise XOR

~

논리 -not

피연산자의 bit-wise NOT

<<

왼쪽shift

비트의 위치를 왼쪽으로 이동

>>

오른쪽shift

비트의 위치를 오른쪽으로 이동


비트 연산자는 정수형 데이터(char, int, short, long, long long 과 각각의 unsigned형)에만 적용되며 실수형 (float, double, long double)에는 사용하지 않는다는 것에 주의해야 한다.


 이항 연산인 & (and), | (or), ^ (xor) 세 연산자의 경우 비트 연산은 데이터의 같은 위치에 있는 비트끼리 연산이 이루어진다는 사실을 숙지해야 한다. 또한 연산 기호가 논리 연산자(&&, ||, ~)와 비슷해서 혼동하기 쉬우니 주의해야 한다.


C++ 강좌 전체 목록 >>>


c{c++},n{c0049}

'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글

C/C++의 bitwise-or 연산자 (|)  (0) 2015.05.20
C/C++의 bitwise-and 연산  (0) 2015.05.20
C/C++의 대입연산자  (0) 2015.05.20
C/C++의 증감연산자(++, --)  (0) 2015.05.19
C/C++의 조건 연산자(?:)  (0) 2015.05.19
Posted by 살레시오
,