2011년5월9일...함수포인터, 배열, ATmega128 타이머/카운터 응용실습

 


★부드러우면서도 강하게...
★기억력 나쁘면 이해를 잘 하면되…
★프로그래머는 논리지능이 높을 수록 유리하다.
   인간의 지능은 개인의 노력에 의해 발달할 수 있으니 잘하는 것에 빗대어 다른 지능을 발달시키면 된다.
   예를 들어, 음악을 좋아하면 음악프로그램을 짜면 보다 빨리 논리지능을 높일 수 있다.
                로봇을 좋아하면 임베디드(?)

★자신의 가치를 높여라~
★노트필기 = 급여 (I like money!)
★비판을 위한 비판은 끌어내리기 위한 목적으로 하니 나쁘다.
   질문을 위한 질문은 하지 말 것. (뜨끔)

 

 

함수포인터

void test1( )
{
    printf(“test1\n”);
}

void test2( )
{
    printf(“test2\n”);
}

type


상기 test1()과 test2()의 type은 모두,
void (*) ( )
이다.

전에 man 3 printf명령으로 보았던 printf()의 type은,
int printf(const char *, …); 으로 type은,
int (*) (const char *,…)
이다.

 

image

 

선언

image

image

<symbol table>

type

name

void (*) ( )

name

void (*) ( )

test1

void (*) ( )

test2

int (*) (const char *,…)

printf

표준라이브러리 함수 printf()를 제외한 사용자정의 함수 name, test1, test2가 모두 같은 type인 것을 알 수 있다.

 

호출

image

○함수포인터의 사용예

int (*handle) (const char *,…);  
위와 같이 handle명의 함수포인터를 선언하고,

handle = printf;   →   handle은 화면에 문자를 출력할 수 있고,
handle = scanf;   →   handle은 키보드로 부터 문자를 입력 받을 수 있다.

이렇게 함수포인터로 printf()와 scanf() 이 두 함수를 자유롭게 호출할 수 있는 이유는 아래와 같이...
image
image

두 함수의 type이 같기 때문이다.

<symbol table>

type

name

int (*) (const char *,...)

printf

int (*) (const char *,...)

scanf

 

 

배열 (Array)

○같은 type의 변수가 여러 개 다다닥 붙어 있는 것을 배열이라 한다.

 

image image

배열A는 변수a와 다르게 주소를 출력할 때 ‘&’(엠퍼센트)를 붙이지 않아도 된다.
배열A에서 A라는 이름자체가 시작주소이다.

<symbol table>

type

name

address

int

a

0xBFFFF848

int *

A[ ]

0xBFFFF840

상기의 심볼테이블을 보면 배열A는 int형 포인터 type이고 주소를 보면 840으로 a의 주소 848과 8Bytes차이가 나므로..
A[2]의 크기는 8Bytes라는 것을 쉽게 알 수 있다. (stack구조라 처음 선언된 변수가 맨 아래에 놓인다.)

 

image image

변수에 대입하는 것과 관련하여, a = 10은 가능하나 A = 10은 에러다. (상기의 에러메세지 참조)
A는 주소상수라 대입이 불가능하다.

 

10개의 원소를 가지는 A배열을 선언하여 시작주소와 배열전체주소, 각 자리별 주소를 알아보면,

image

image

 

 

 

 

 

 

 

<symbol table>

type

name

address

비고

int

a

0xBFFFF848

&a = 주소

int *

A

0xBFFFF820

주소

int *

&A

0xBFFFF820

배열전체

int *

A + 1

0xBFFFF824

두 번째 원소주소

int *

&A + 1

0xBFFFF828

배열전체를 뜻함.
마지막원소 + 4 (int)

int *

&A + 1 (@A[10])

0xBFFFF848

上同

int *

A[0]

0xBFFFF820

int *

A[1]

0xBFFFF824

 

 

배열의 값대입

image

int A[2] = {1, 2};  →  A[0]에는 1이 들어가, A[1]에는 2가 들어간다.

*와 &은 전기의 (+)와 (-)극처럼 서로 상쇄된다. 따라서 다음과 같이 바꾸어 보면,

A[0] → *&A[0] → *(&A[0]) → *(A + 0)

배열에 값을 대입할 때 A[0] 또는 *(A + 0) 적어도 된다.


○ int A[2] = {1, 2}; 의 경우 A[2] ~ A[9]까지 모두 0으로 초기화된다.
○ int A[10] = { }; 의 경우 A[0] ~ A[9]까지 모두 0으로 초기화된다.

 

 

 

 

20110509_array/test.c

image

 

image

 

 

차원 (Dimension)

int array[10];      ← 1차원
int array[10][10];  ← 2차원

 

 

20110509/test_dim2.c

image image


int array[10][10]; 각 자리별 주소는,
image

 

임베디드C p.217 주소표기법

 

줄이동 칸이동 줄이동
array + 0 +1
array + 1
array[0] +1
array[1]
&array[0] +1
&array[1]
1줄의 주소 1개의 주소 1줄의 주소


  포인터식                  배열식
*(array + 0) + 1   →    array[0] + 1

○ [ ] (대괄호) 한 개가 * 한 개
○ &array + 1   400Bytes이동 (배열전체)

 

 

 

DK-128..ATmega128 타이머/카운터0

○0.5초 지연

sleep(1000);   →  sleep(500);

 

○prescaler를 64에서 128로 바꾸라.

image

 

타이머/카운터 응용실습문제

1. 1초씩 FND숫자가 증가되도록 하시오.

image

5월6일 소스코드 참조…

 

 

 

2. 1초마다 FND값을 증가시키다가 60초가 되는 순간 LED를 하나씩 ON 하시오.
   FND는 0으로 초기화된 후 다시 증가합니다.

image

 

 

 

 

참조 (Reference)

DSCN2946 DSCN2947 DSCN2948 DSCN2949 DSCN2950