-
20140411 (용어, Register Summary, volatile, 구조체 복사, 공용체)부산IT학원/스마트컨트롤러 2014. 4. 11. 17:57
40일차
--------------
용 어
--------------
--- JTAG
디버거 역할.
cpu, memory, register등 모니터링
--- Watchdog Timer
스스로 신호를 감지해 시스템에 오류가 났을 시에 시스템을 리셋.
--- Brown-out Detection
회로마다 가용전압이 있는데 최고전압을 넘었을 시 회로가 타버리고, 최저전압 밑으로 떨어졌을 시 어떤 장비는 켜있고, 어떤 장비는 깜빡깜빡하고, 어떤 장비는 꺼지는 등으로 오작동을 일으킬 수 있으므로 최저전압 밑으로 떨어질 시 리셋을 시키는 장비.
--- RC Oscillator
주파수 발진기. CPU가 동작하도록 일정 주파수를 발생시켜줌
- 수정에 전기를 가하면 수정마다 특정 주파수가 계속 나온다.
딱딱이 : 수정을 쇠로 때리면 전자가 나온다. 그때 불꽃 발생.
--- SMD
Small Mounted device
칩형으로 소형화된 장비
--- lead, pad
lead는 다리가 나와 있는 것
pad는 뒷면에 홈이 있는 것.
--- Register Summary (p.366 ~ 368)
Reg 목록
ex)
- 그림을 크게 보면 주소에 "$1B ($3B)" 라고 있는데
$1B 는 호환용이고, () 는 ATMega128전용이다.
- CPU가 8Bit 이므로 Register도 8Bit 이다.
--- ATMega Pin Configurations
실사
- PA0 ~ PA7 : 8개
- PB0 ~ PB7 : 8개
- PC0 ~ PC7 : 8개
- PD0 ~ PD7 : 8개
- PE0 ~ PE7 : 8개
- PF0 ~ PF7 : 8개
- PG0 ~ PG4 : 5개
- 칩 내부에 PA0 ~ PA7 구조
- PORT'X' 라고 쓴것은 각 PA, PB,... PG 까지 A, B, ..가 X에 들어간다.
정리하자면 각 P 마다 저런 구조가 7개(ABCDEFG) 있다.
- DDRA 는 PORTA 에 입/출력 셋팅.
1 : 출력, 0 : 입력
- PORTA 는 우선 문을 여는지 닫는지 역할쯤으로 보자.
1 : 열기, 0 : 닫기
--- 지금까지 뭔말인지 모르겠지만 우선 소스를 보자.
int main()
{
*((volatile unsigned char *)0x3A) = 0x01; // DDRA = 0000 0001 pa01번을 출력으로
*((volatile unsigned char *)0x3B) = 0x01; // PORTA = 0000 0001 pa01번을 출력함.while(1);
return 0;
}이런식으로 ATMega 프로그래밍을 하는데 위의 소스는 LED에 불을 켜는 소스다.
우선 PA0 자리를 통해서 LED에 불을 키려하는데 Register Summary를 참고하여
0x3A는
DDRA의 레지스터 주소값이라고 알았다.
DDRA를 먼저 찾은 이유는 위에서 설명했듯 PortA의 입출력을 결정하는
이 주소값에 값을 바꾸어 입출력을 바꾸는 여기서는 출력으로 바꿨다.
그래서 0x3A에 값을 바꿔주는 것이다.
또 여기서 0x01 (0000 0001)을 주는 이유는 위에 표에서 bit0번째가 가리키는 곳이
PA0에 해당하는 자리이다. (위에 ATMega Pin 그림 참고)
PortA는 문 같은 역할로 알고 있자.
volatile은 최적화를 안한다는 의미인데
cpu에서 최적화를 위해서 어떤 값을 불러들이려는데 캐시에 저장되어 있다면
메모리에 가지 않고 바로 캐시에서 가져와 작업을 하는 최적화를 하는데
이것을 하지 않고 느리겠지만 다시 메모리에서 가져오라는 의미이다.
임베디드에서는 속도도 중요하지만 정확해야 하기 때문에
센서등을 제어할때 꼭 이 명령어를 붙인다고 한다.
아래는 프로그램 실행시 칩의 결과
LED판에 하나가 불이 들어옴
-C
--------------------
구조체와 공용체
--------------------
--- 구조체는 복사가 가능하다
어제 함수에 인자와 리턴값을 통해 보았듯이
배열이 들어있어도 구조체는 복사가 가능하다.
아래 소스 코드를 보자.
ex)
#include <stdio.h>
typedef struct _smart
{
int a[3];
char b[3];
}Smart;int main()
{
Smart s1 = { {1, 2, 3}, "AB\0" };
Smart s2;s2 = s1;
printf("%d %d %d \n", s2.a[0], s2.a[1], s2.a[2] );
printf("%s \n", s2.b );return 0;
}출력 화면
배열은 복사가 불가능한데 구조체면 가능하다.
그러나 복사할 때 자원이 많이 낭비되므로 이 방법은 비추천이고
포인터를 사용하는 것을 추천한다.
--- 공용체
구조체와 다르게 메모리를 공유한다.
무슨말이냐면 아래 소스 코드를 보자.
ex)
#include <stdio.h>
typedef union _smart
{
int a;
short b;
char c;
}Smart;int main()
{
Smart ss;ss.a = 0x12345678;
printf("%X \n", ss.a);
printf("%X \n", ss.b);
printf("%X \n", ss.c);return 0;
}출력 화면
a에만 값을 넣었는데 b, c에도 값이 들어간 것이 보이는가?
저런 식으로 메모리를 잡았을 경우 메모리 구조는
이런식으로 A의 공간에 B, C가 공동으로 사용한다.
이것이 공용체.
그럼 무슨 좋은점이 있는가?
아래의 소스를 보자.
ex)
#include <stdio.h>
typedef union _smart
{
int a;
short b[2];
char c[4];
}Smart;int main()
{
Smart ss;ss.a = 0x12345678;
printf("a : %X \n", ss.a);
printf("b : %X %X\n", ss.b[0], ss.b[1]);
printf("c : %X %X %X %X \n", ss.c[0], ss.c[1], ss.c[2], ss.c[3]);return 0;
}출력 화면
출력 화면에서 보이듯이
4byte 짜리든, 2byte짜리든 상수를 입력 받았을 때에 상위, 하위 비트로 나눌 수 있다.
지금은 상위, 하위 비트를 나눌 일이 없지만, 만약 생겼을 경우
공용체를 사용하면 손 쉽게 상위, 하위를 나눌 수 있다.
순서가 얶갈린 것은 little endian 방식이기 때문에 거꾸로 표시 되어있다.
'부산IT학원 > 스마트컨트롤러' 카테고리의 다른 글
20140415 (define, 연결리스트 링크드리스트) (0) 2014.04.15 20140414 (ATMega128 내부, 메모리 방식 폰노이만 하바드, 연결리스트, 동적할당) (0) 2014.04.14 20140410 (프로그램 실행 구조, AvrStudio4 실행, 구조체 포인터, typedef struct) (0) 2014.04.10 20140409 (CPU, Microcontroller, RAM, ROM, RISC, CISC, 구조체, #pragma pack) (2) 2014.04.09 20140408 (회로도 최적화, 4bit 덧셈, 구조체) (0) 2014.04.08