임베디드 개발(before)/IoT 임베디드 SW 개발자 양성과정

[17일차] 임베디드 C 프로그래밍 2

주운녕 2020. 8. 4. 19:20
  1. T32marm 시뮬레이터 기본 사용법
  2. 연산자, LED 점등 실습
  3. C언어 고급편 (배열, 포인터)

1. 연산자의 우선순위

 

3~5위까지는 기억하면 좋다.

 

2. 비트연산자 : |, &, ^, ~

| : OR연산. 둘 다 0일 때만 0

& : AND연산. 둘다 1일 때만 1

~ : NOT연산. 단항 연산자. 1개의 데이터의 각 비트를 반전 0->1  // 1->0

^ : XOR연산. 같으면 0, 다르면 1

<< , >> : 쉬프트 연산. 왼쪽, 오른쪽으로 비트를 shift 시킨다. 2의 n승 계산을 할 수 있다. 밀려난 빈자리는 0으로 채워지나, signed 타입에서는 부호 비트가 유지된다.

 

그 외 : 간접 참조 연산자(*), 레퍼런스 연산자(&), 배열 참조 연산자([]) 등이 있다.

- 구조체 직접 참조 연산자 : "." 구조체의 멤버를 직접 참조.

- 구조체 간접 참조 연산자 : "->" 구조체의 멤버를 포인터를 통해 참조 (주소를 통한 간접 참조와 비슷). 구조체의 포인터를 통해 간접 참조한 후, 멤버 변수를 직접 참조하는 순서.

 

3. C언어의 형 변환은 자동적으로 타입이 변경되는 암시적 형 변환과, 형 변환 연산자를 이용해 강제적으로 변경하는 명시적 형 변환이 있다.

 

4. 비트 연산자 활용

- 비트 셋(set)

data |= (0x20) 이런 식 보다는, data |= (0x1<<5) 이런 식으로 명시하는 것이 5번 비트를 1로 set 하는 것이라고 바로 알 수 있다.(직관성이 좋다.)

- 비트 클리어(clr)

data &= ~(0x1<<3)  // 세 번째 비트를 0으로 클리어하겠다. 0으로 &연산하면 무조건 0이 되는 걸 이용.

- 비트 반전(rev)

data ^= (0x1 <<5) //XOR은 같으면 0이므로 같은 5번 bit가 1이면 0으로 반전, 다르면 1 이므로 5번 bit가 0이면 1로 반전.

 

5. 비트 연산자의 활용 실습 - data의 Binary를 비트 연산자를 활용하여 1 글자씩 출력하는 예제

void main()
{
    int i;
    unsigned char data = 0xad;
	for(i=0; i<8; i++){
    // data의 Binary(10101101)를 Printf로 1글자씩 출력
	printf("%d\n", (data>>7-i) & 0x01);
	}
}

- LED 실습.

레지스터에 직접 접근하여 Port G를 output으로 설정하고, 여기에 연결된 보드의 LED를 점등시켜보았다.

- 관련 레지스터 매뉴얼

- GPG와 관련된 레지스터의 주소를 알 수 있다.

 

- GPGCON의 레지스터 설정 옵션

 

- 나머지 레지스터들에 대한 설명. UDP레지스터는 여기서 건들지 않는다. (회로적인 부분)

#include "../lib2450/Uart.h"
#include "../lib2450/Timer.h" 
#include <stdlib.h> 

// 0x56000060번지를 4바이트 R/W 할 수 있는 매크로 정의
#define		rGPGCON		(*(volatile unsigned int*)0x56000060)
// 0x56000064번지를 4바이트 R/W 할 수 있는 매크로 정의
#define		rGPGDAT		(*(volatile unsigned int*)0x56000064)

void Init_Led(void)
{
	// 1. GPGDAT 4,5,6,7에 HIGH(1) 출력 (LED OFF)
	rGPGDAT |= (0xf<<4);
	// 2. GPGCON 4,5,6,7을 출력(Output) 모드로 설정
	// clr [15:00]
	rGPGCON &= ~(0xff<<8);
	//set [01010101]
	rGPGCON |= (0x55<<8);
	
}

void Led_On(int num)
{
	/* 3. num이 1이면 GPGDAT4에 LOW 출력(LED ON)
     *    num이 2이면 GPGDAT5에 LOW 출력
     *    num이 3이면 GPGDAT6에 LOW 출력
     *    num이 4이면 GPGDAT7에 LOW 출력            */
	rGPGDAT &= ~(0x1<<num+3); //n번째 0으로 LOW(Led_On)
}

void Led_Off(int num)
{
	/* 4. num이 1이면 GPGDAT4에 HIGH 출력(LED OFF)
     *    num이 2이면 GPGDAT5에 HIGH 출력
     *    num이 3이면 GPGDAT6에 HIGH 출력
     *    num이 4이면 GPGDAT7에 HIGH 출력            */
	rGPGDAT |= (0x1<<num+3);
}

void User_Main()
{
	int ranNum = 0;
	
    Init_Led();
	
	while(1)
	{
		ranNum = 1 + rand() % 4;
		
		Led_On(ranNum);
		
		Timer_Delay(500);
		
		Led_Off(ranNum);
	}
}

 

동작 영상


3. C언어 고급편-배열, 포인터

이전에 C언어 교육에서 배웠던 내용을 임베디드 관점에서 배웠다. 주요 특징들을 다시 복습하는 시간이었다. C언어 배열, 포인터 정리 부분 다시 읽어보기

 

 


* 개인적인 학습 목적으로 작성한 글이기에 내용에 잘못된 정보가 있을 수 있습니다.