16진수와 2진수(Hex and binary)
16진법은 2진수를 나타내기에 편리한 방법이다.
- 0 : 0000
- 1 : 0001
- 2 : 0010
- 3 : 0011
- 4 : 0100
- 5 : 0101
- 6 : 0110
- 7 : 0111
- 8 : 1000
- 9 : 1001
- A : 1010
- B : 1011
- C : 1100
- D : 1101
- E : 1110
- F : 1111
0 부터 F(15) 까지 16개의 수를 다음과 같이 표현할 수 있다.
16진수 하나당 4비트의 이진수로 표현한다. 따라서 16진수 두자리 이상은 다음과 같이 표현한다.
- 0x01 : 00000001
- 0xFF : 11111111
- 0xAF : 10101111
- 0x1AAF : 0001101010101111
비트 단위 연산자(Bit - Wise operators)

& 와 | 는 논리회로 시간에도 많이 다뤘으므로 넘어간다.
^ 연산은 비교하고자 하는 두 비트가 다른 경우 1, 같은 경우는 0을 반환한다.
~ 연산은 비트의 보수를 반환한다.
<< 연산은 비트들을 왼쪽으로 한칸 민다.
>> 연산은 비트들을 오른쪽으로 한칸 민다.
c = 0x1C 인경우
0x1C = 00011100
- c << 1 => 00111000, 0x38
- c >> 2 => 00000111, 0x07
비트 연산의 필요성
임베디드 프로세서는 컨트롤과 상태 레지스터의 집합으로 주변기기와 상호작용한다.(An embedded processor interacts with a peripheral device through a set of control and status registers)
컨트롤과 상태 레지스터는 메모리에 저장되어있다.(Control and status registers are memory - mapped)
그래서 일반적인 포인터 변수처럼 다룰 수 있다.(Means that they can be handled just like ordinary pointer variables)
비트 연산의 예시
- 비트를 검사할 때 사용할 수 있다.
- 비트를 1로 만들때 사용할 수 있다.
- 비트를 0으로 만들때 사용할 수 있다.
- 비트를 바꾸는데 사용할 수 있다.
1)
int *pTimerstatus
int main(){
if(*pTimerstatus & 0x08){...}// 0x08 = 00001000으로 3번째비트가 1인지 확인한다.
}
2)
*pTimerstatus |= 0x10; // 0x10 = 00010000 4비트를 1로 세팅함
3)
*pTimerstatus &= ~(0x04)
/*
EX) *pTimerstatus = 01100101
0x04 = 00000100
~0x04 = 11111011
-> *pTimerstatus = 01100001
*/
4)
*pTimerstatus ^= 0x80;
/*
EX) *pTimerstatus = 01100101
0x80 = 10000000
*pTimerstatus = 11100101
*/
#define TiMER_COMPLETE(0x80)
#define BIT(X) (1<<(X))
#define TIMER_STATUS BIT(5)
BIT(5) = 00000001 -> 00100000 == 0x20
위와 같이 마스크나 매크로를 정의해서 코드를 더욱 간결히 할 수 있다.
연습문제 1번
7개의 LED를 갖는 LEDs 라는 unsigned char 변수에 이진수 00000001을 대입하면 0번째 LED가 켜지고, 이진수 00000010을 대입하면 1번째 LED가 켜지고 이진수 10000000을 대입하면 7번째 LED가 켜질때, 0부터 7까지 숫자를 입력받아서, LEDs 값을 다음과 같이 바꾸어주는 함수를 작성하시오.
- unsigned char LEDs;
- LEDs = 0x01;
- LEDs = 0x02;
- int LED_function(int input);
- LED_funcion(2)를 호출하면, 0x04를 return함
- LED_function에서 16진수를 return하거나, 이진수로 shift 연산자를 써서 return함
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
unsigned char LEDs;
unsigned char LED_function(int input) {
LEDs = 0x01;
for (int i = 0; i < input; i++) {
LEDs <<= 1;
}
return LEDs;
}
int main() {
int temp;
scanf("%d", &temp); // 0~7 숫자 입력
unsigned char val = LED_function(temp);
printf("return value : 0x%02x\n", val);
return 0;
}
연습문제 2번
상기 프로그램을 활용하여
- LEDs의 초기값을 이진수로 00000001을 대입하고
- LEDs 값을 왼쪽으로 1만큼 계속 shift하고
- LEDs 값이 이진수로 10000000일때
- 역으로 오른쪽으로 1만큼 계속 shift하는 함수를 만들고
- 1 ~ 4 과정이 총 4번 반복되는 프로그램을 작성하시오.
#define _CRT_SECURE_NO_WARNINGS
#define LeftShift(x) (x<<=1)
#define RightShift(x) (x>>=1)
#include <stdio.h>
unsigned char LEDs;
void LED_function() {
for (int i = 0; i < 4; i++) {
LEDs = 0x01;
if (LEDs == 0x01) {
while (LEDs != 0x80) {
printf("%d, ", LEDs);
LeftShift(LEDs);
}
}
if (LEDs == 0x80) {
while (LEDs != 0x01) {
if (LEDs == 0x80 && i==3) {
printf("%d ", LEDs);
break;
}
else {
printf("%d, ", LEDs);
RightShift(LEDs);
}
}
}
}
return;
}
int main() {
LED_function();
return 0;
}
연습문제 3번
Unsigned char 변수를 2진수로 변환하였을 때, 1의 개수를 세고, 그 개수만큼의 연속된 1을 최상위 비트부터 나열한 결과 값을 출력하시오. (shift 연산과 bit setting을 이용할 것)
- Input : 01010110, 십진수 : 86, 16진수 : 0x56
- Output : 11110000, 십진수 : 240, 16진수 : 0xF0
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
unsigned char LEDs;
unsigned char result = 0;
int count = 0;
void LED_function() {
while (LEDs)
{
if (LEDs & 0x01) {
count++;
}
LEDs >>= 1;
}
for (int i = 0; i < count; i++) {
result |= (1 << (7 - i));
}
printf("1의 개수? %d\n", count);
printf("Shift 시의 값은? %d", result);
}
int main() {
scanf("%uc", &LEDs);
LED_function();
return 0;
}
'CS공부 > 임베디드' 카테고리의 다른 글
[임베디드소프트웨어] 01-1. 임베디드소프트웨어 개요 (0) | 2023.08.30 |
---|