-
20140415 (define, 연결리스트 링크드리스트)부산IT학원/스마트컨트롤러 2014. 4. 15. 12:46
42일차
----------------------
ATMega128 Memory
----------------------
--- ATMega128 메모리 맵
어제 보았듯 다시 한 번 더 강조하는 것은 임베디드 프로그래밍을 할때에
가장 먼저 봐야 하는 것 중 하나이다.
ATMega의 경우 Memory map, register summary 가 따로 있지만
다른 것들은 Memory map에 다 같이 나와 있으므로 복잡하다고 한다.
- GPIO(General Purpose Register Input Output)
32가지 General Purpose Register인 기본적인 LED켜는 등
이 Reg를 GPIO라고 부르는데
ATMel 사에서 PORT라고 새로운 용어를 만들고
GP는 그냥 기억용으로만 사용하고 있다.
--- EEPROM
EEPROM은 그냥 접근할 수 없다. 외부 장치로 인식한다.
바로 EEPROM으로 접근 할 수 없고
EEPROM 컨트롤러를 통해서 접근하며,
C로 프로그래밍을 할 때에도 EEPROM을 쓴다는 코드를 따로 삽입해야 한다.
쓰기가 좀 번거로워 졌지만 갑자기 전원이 나가도
나가기 전까지의 메모리를 저장하고 있다는 장점이 있다.
- C
----------
#define
----------
- 우선 소스코드부터 보기로 한다.
ex)
#include <stdio.h>
#define PI 3.14
#define PRODUCT(X, Y) ((X) * (Y))
#define CIRCLE_AREA(R) (PRODUCT((R), (R)) * PI)
int main()
{
double rad = 2.5;
printf("반지름 %g 인 원의 넓이 : %g \n", rad, CIRCLE_AREA(rad) );
return 0;
}위의 코드에서 보면 감이 오듯
3.14를 계속 쓰기가 번거로울때, 또는 특정 같은 상수를 계속 사용하는 경우...등등
PI 처럼 선언하여 사용할 수 있다.
또 간편한 함수로도 사용하여 CPU나 메모리 등을 더 아낄 수 있다.
ATMega128 플밍할 때 꽤나 쓸 듯 싶다. 아래 예제 소스
ex)
#define DDRA (*((volatile unsigned char *)0x3A))
#define PORTA (*((volatile unsigned char *)0x3B))
#define DELAY(x) for(uiCnt = 0; (x) > uiCnt; ++uiCnt)
int main()
{
volatile unsigned int uiCnt;
DDRA = 0x01; // DDRA = 0x01
while(1)
{
DELAY(65000);
PORTA = 0x01; // PORTA = 0x01
DELAY(65000);
PORTA = 0x00; // PORTA = 0x00
}
return 0;
}이런식으로 계속 *((volatile unsigned char *)0x3A) 을 쓸 필요 없이
손쉽게 DDRA 라고 쓸 수 있다.
아래는 전처리 과정( #define 이 전처리 과정이므로 )이 처리되고 난 소스 코드이다.
# 1 "main.c"
# 1 "D:\\ATMega128A\\20140415//"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "main.c"
int main()
{
volatile unsigned int uiCnt;
(*((volatile unsigned char *)0x3A)) = 0x01;
while(1)
{
for(uiCnt = 0; (65000) > uiCnt; ++uiCnt);
(*((volatile unsigned char *)0x3B)) = 0x01;
for(uiCnt = 0; (65000) > uiCnt; ++uiCnt);
(*((volatile unsigned char *)0x3B)) = 0x00;
}
return 0;
}이런식으로 바뀌게 된다.
--- 연결리스트, 링크드리스트
이전까지는 데이터를 여러개 저장할 때 관리하기 쉽도록 배열을 써왔다.
하지만 큰 데이터를 관리하다 보면 얼마나 데이터가 필요한지 모르게 되므로
배열을 쓰기가 곤란해 진다.
예를 들어 각 학교별 학생 이름을 저장하는 데이터를 만든다고 치면
어떤 학교는 300명, 어떤학교는 500명.... 사람 수에 맞게 넉넉히 배열을
할당하다보면 메모리를 낭비하게 된다.
그러므로 전에 배운 메모리 할당(malloc)을 이용해서
필요할 때마다 메모리를 할당하여 데이터를 관리하는데
이것을 연결리스트라고 한다.
각 데이터 마다 다음 데이터 메모리의 주소가 저장되어 있다.
이런식으로 데이터를 관리하게 된다.
ex) 소스
#include <stdio.h>
#include <stdlib.h>
typedef struct _node
{
char data;
struct _node * next;
}Node;
int main()
{
Node * Head;
Node * temp;
Head = malloc(sizeof(Node)); // 메모리 할당
Head->data = 'a';
Head->next = malloc(sizeof(Node)); // 메모리 할당
Head->next->data = 'b';
Head->next->next = malloc(sizeof(Node)); // 메모리 할당
Head->next->next->data = 'c';
Head->next->next->next = NULL;
for(temp = Head; 0 != temp; temp = temp->next) // 다음 메모리로 이동
{
printf("%c -> ", temp->data);
}
printf("NULL \n");
for(temp = Head; 0 != temp; temp = Head) // 다음 메모리로 이동
{
Head = Head->next; // 다음 메모리 주소 저장.
free(temp); // 메모리 해제
}
return 0;
}이런식으로 데이터를 관리하게 된다.
주의 할 점은
- head 메모리는 해제를 제외하고는 값이 바뀌면 안된다.
- 메모리를 할당하면 항상 해제해야 한다.
- free(temp) 할 때 다음 메모리 주소를 저장해 둬야한다.
'부산IT학원 > 스마트컨트롤러' 카테고리의 다른 글
20140417 (LCD specification, 연결리스트 치환, 삽입) (0) 2014.04.17 20140416 (LED 실습, #if #ifdef #ifndef #endif #else, 분할 컴파일) (0) 2014.04.16 20140414 (ATMega128 내부, 메모리 방식 폰노이만 하바드, 연결리스트, 동적할당) (0) 2014.04.14 20140411 (용어, Register Summary, volatile, 구조체 복사, 공용체) (0) 2014.04.11 20140410 (프로그램 실행 구조, AvrStudio4 실행, 구조체 포인터, typedef struct) (0) 2014.04.10