AVR 컴퓨터의 동작 원리
컴퓨터의 동작
1. 원 칩 마이컴에 대해서
최근에는 많은 가전제품에 컴퓨터가 내장되어있다. 이처럼 전자제품안에 들어가 있는 것으로 한 칩에 프로그램 메모리나 입출력 회로가 내장된 "원 침 마이컴"이 사용된다. 종래에는 이런 종의 마이컴의 프로그램은 제조할 때, 프로그램이 짜넣었지만, 요즘처럼 간단하게 프로그램할 수 있는 것이 아니였다. 하지만 수년전에 플래쉬 메모리를 탑재한 원 칩 마이컴이 등장하여 현재는 마이컴에 모든 것을 짜넣는 것보다 고도의 기능을 가지는 기기를 쉽게 만들 수 있게 되었다.
손쉽게 구할 수 있는 원 칩 마이컴으로는 Microchip사의 PIC 마이컴과 Atmel사의 AVR 마이컴이 있다. 어느 것이나 개발 용의 소프트(어셈블러, 컴파일러, 라이터 소프트등)를 무료로 얻을 수 있으며, 라이터(프로그램을 쓰는 기기)의 제작도 어렵지 않다.
이와 같은 원 칩 마이컴을 사용한 기기를 설계, 제작하기 위해서는 전자회로, 논리회로, 컴퓨터의 동작원리, 프로그래밍등 광범위한 지식이 필요하다.
이 텍스트는 Atmel사의 AVR 마이컴(AT90S2313)을 사용하여 간단한 예제 프로그램을 움직이면서 주로 컴퓨터의 내부 동작에 관해서 학습한다. 학습에는 트레이닝 보드, 라이터, 개발용 소프트(어셈블러와 라이트 소프트)를 사용한다. 또 참고로 본문 중의 프로그램을 C언어로 바꾼 것을 PART2의 부록1에 개재한다. 앞으로 AVR판 GCC컴파일러 WinAVR을 인스톨하여 C언어로 프로그램 개발을 할 수 있다.
2. AVR 마이컴의 내부 구조
여기서 사용하는 AT90S2313의 내부 구조는 아래의 그림과 같다.

(1) 프로그램 메모리(Program Flash)는 1워드는 16비트로 1024 워드($000~$3FF)의 영역이 있다.
(2)데이터 메모리(SRAM)는 128바이트의 영역($60~$DF)이 있다.
(3)불휘발 데이터 메모리(EEPROM)는 128바이트의 영역($00~$7F)이 있다.
(4)범용 레지스터(Registers)는 8비트 짜리가 32개 있다.
(5)프로그램 카운터(Program Counter)에는 다음에 실행할 명령어의 어드레스($000~$3FF)가 들어있다.
(6)명령 레지스터(Instruction Register)에는 프로그램 메모리로 부터 프로그램 카운터가 지시한 번지의 내용, 말하자면 다음에 실행할 명령어가 전송된다. 그 내용은 명령 디코더(Instruction Decoder)로 디코딩(해독)되어 실행된다.
(7)스텍 포인터(Stack Pointer)는 데이터 메모리(SRAM)의 뒤에서 부터 확보하는 스텍 영역의 선두 어드레스를 가르치고 있다(~$DF). 처음으로 데이터 메모리(SRAM)의 최종 번지$DF에 세트하여 사용한다. 서브루틴을 콜할 경우, 돌아올 번지는 스텍 영역에 보존된다.
(8)산술 논리 연산 유닛(ALU)은 주로 레지서터에 저장된 값의 상호 연산을 한다.
(9)상태 레지스터(Status Register)는 ALU의 연산결과가 "0"이면 Z 플래그(Bit 1)가 1이 되고 케리어가 생기면 C플래그(Bit 0)가 1이 된다.
(10)DDRB레지스터는 PB0~PB7의 각 단자를 입력으로 하는지 출력으로 하는지를 지정하기 위해 사용한다. PB0~PB7에 대응하는 DDRB 레지스터의 비트를 입력으로 하는 경우는 "0", 출력으로 하는 경우는 "1"로 한다.
(11)DDRD레지스터는 PD0~PD6의 각 단자를 입력으로 하는지 출력으로 하는지를 지정하기 위해 사용한다. PD0~PD6에 대응하는 DDRD 레지스터의 비트를 입력으로 하는 경우는 "0", 출력으로 하는 경우는 "1"로 한다.
(12)PORTB레지스터는 각 비트를 "0" 혹은 "1"로 하면 PB0~PB7 중, 출력으로 지정된비트에는 그 값을 출력한다.
(13)PORTD레지스터는 각 비트를 "0" 혹은 "1"로 하면 PD0~PD6 중, 출력으로 지정된비트에는 그 값을 출력한다.
(14)Timer/Counter0는 8비트 카운터로 클럭 주파수(또는 그 1/8, 1/64, 1/256, 1/1024)을 카운터로 한다.
(15)Timer/Counter1は、16비트 카운터로 클럭 주파수(또는 그 1/8, 1/64, 1/256, 1/1024)을 카운터로 한다.
3. 프로그램의 작성과 실행
AVR마이크로 컴퓨터이 들어간 기기의 개발 프로세스는 아래와 같다.
- (1) 회로의 설계
(2) 회로의 조립
(3) 소스 프로그램의 작성・수정
(4) 어셈블러 소프트로 소스 프로그램로 기계어 프로그램을 생성
(5) 라이터와 라이터 SW를 이용하여 마이크로 컴퓨터에 기계어 프로그램을 써넣기
(6) 기기의 동작확인
(7) 완성. 의도한대로 동작하지 않으면 프로그램의 버그를 찻아서 (3)~(6)를 반복
(8) 2 대째 부터는(2)(5)(6)만으로 OK!
4. 프로그램의 동작(1)
다음의 소스 프로그램에서 어떻게 기계어가 만들어져 그 기계어 프로그램이 컴퓨터 내부에 어떻게 동작하는지를 자세하게 봐본다.
- prog.asm:
소스 프로그램의 1행은 어셈블러에 대한 제어명령으로 여기서 사용되고 있는 AT90S2313에 관한 정보가 정의된「2313def.inc」라는 파일을 읽어 들인다.
2행의「.cseg」은 어셈블러에 대한 제어명령으로 이하가 프로그램 코드 인 것을 선언하고 있다.
3행 이후가 기계어가 되는 프로그램 부문이다.
이 소스 프로그램은 어셈블러 소프트(ATMEL사의 avrasm32.exe)을 이용하여 어셈블하면 7워드(7×16bit)의 기계어 프로그램이 된다. 프로그램의 어느 부분이 어떻게 기계어가 되는지는 이하와 같은 리스트 파일(list.txt)로 확인할 수 있다.
으로 이것에 약간의 추가 정보를 붙인 것이 기계어 파일(prog.hex)이다. 짧은 프로그램이면 어셈블러 소프트를 쓰지않고 자료를 보면서 기계어 프로그램을 직접 쓸 수도 있다. 기계어 프로그램은 라이터와 라이터 소프트를 써서 컴퓨터의 프로그램 메모리(Program Flash) 1K워드($000~$3FF번지)의 선두 부분($000~$006번지)에 씌여진다.(밑의 그림 참조)
그러면 "씌여진 프로그램부터 명령이 하나씩 꺼내어져 실행되는 원리"를 상세하게 살펴보자. 동작의 원리는 어떤 컴퓨터에나 공통되는 기본적인 사항이기 때문에 꼼꼼히 봤으면 한다.
■ 000000 e00c LDI R16,0x0C
- (1) 전원 투입(혹은 리셋)에 의해 Program Counter의 내용이「0000000000($000)」으로 된다. Program Counter의 내용은 Program Flash의 실행할 어드레스를 나타낸다.
(2) Program Counter의 내용이 가르키는(지시하는) Program Flash의 어드레스의 내용「11100000 00001100」이 Instruction Register(명령 레지스터)에 올라간다.(음 좀 더 적합한 단어를 못찾겠다.) 이 동작은 패치(fetch)라 불리운다.
(3) Program Counter의 내용은 1이 더해진다.
(4) Instruction Register(명령 레지스터)의 내용이 Instruction Decoder(명령 디코더)에 의해 디코딩 된다. 디코더는 구체적으로 다음과 같이 실행된다. 또「LDI(및 대응하는 1110)」은 OpCode(Op코드),「R16, 0x0C(및 대응하는 000000001100)」은Operand(오퍼랜드:연산수)라고 불리운다.「R16(및 대응하는 0000)」는 제1 오퍼랜드, 「0x00(및 대응하는 00001100)」은 제2 오퍼랜드가 된다.
1110 | 0000 | 0000 | 1100 |
LDI명령 | 대입하는 값의 상위 4bit | R16~R31 중의 R16 | 대입하는 값의 하위 4bit |
(5) 이 명령의 실행에 필요한 타이밍 신호가 만들어져 실행(execute)된다. 이 경우는 레지스터 R16의 안이 「00001100」으로 된다.
(6) 이상의 (2)~(5)는 1클럭 사이클로 처리된다. 트레이닝 보드는 10MHz의 진동자를 쓰고있기 때문에 1클럭 사이클은 0.1μ초이다. AVR 마이컴의 경우는 명령을 실행(excecute)하고 있을 동안에 다음의 명령을 Instruction Register(명령 레지스터)에 패치(프리 패치)하는 것에 의해 고속화를 도모한다.
컴퓨터가 프로그램을 실행하는 원리는 이상의
|
→ |
|
→ |
|
컴마 앞에 지정된 레지스터 위치에 컴마 뒤의 값을 저장한다.

이하는 패치와 실행(execute)이 반복되는 것을 나타낸 것이다.
■ 000001 bb07 OUT DDRB,R16
다음의 클럭 사이클에서는, 상기(3)에서 Program Counter의 내용이「0000000001」로 되었기 때문에, 그 값이 가르키는 Program Flash의 어드레스의 내용「10111011 00000111」이 Instruction Register(명령 레지스터)에 연관된다. Program Counter의 내용에 1이 더해져 Instruction Register(명령 레지스터)의 내용이 Instruction Decoder(명령 디코더)에 의해 디코딩된다. 디코더는 구체적으로는 다음과 같이 행해진다.
10111 | 01 | 10000 | 0111 |
OUT 명령 |
DDRB을 나타내는 IO 어드레스$17의 상위 2bit | R0~R31 중의 R16 | DDRB을 나타내는 IO 어드레스$17의 하위4bit |
이 명령의 실행에 필요한 타이밍 신호가 만들어져 실행(execute)된다. 그 경우는 DDRB 레지스터의 내용이「00001100」로 된다. IO포트로 직접 값을 출력하는 명령이 없기 때문에, 이와 같이 처음 명령으로 레지스터의 값을 세트하고 , 다음의 명령으로 레지스터의 내용을 IO포트에 출력한다. 여기서 행한 DDRB 레지스터의 설정은 「PB0, PB1, PB4~PB7을 입력으로서 사용하고, PB2, PB3을 출력으로서 사용한다.」라고 말하는 것을 지시하는 것이다.
DDRB에 레지스터 R16에 저장된 데이터를 출력한다.

■ 000002 e70f LDI R16,0x7F
다음의 클럭 사이클에서는, Program Counter의 내용이 「0000000010」로 되었기 때문에, 그 값이 가르키는 Program Flash의 어드레스의 내용「11100111 00001111」이 Instruction Register(명령 레지스터)에 카피된다. 그 내용이 Instruction Decoder(명령 디코더)에 의해 디코드된다. 디코더는 구체적으로 다음과 같이 행해진다. 디코드는 구체적으로는 다음과 같이 행해진다.
1110 | 0111 | 0000 | 1111 |
LDI명령 | 대입하는 값의 상위 4bit | R16~R31 중의 R16 | 대입하는 값의 하위 4bit |

■ 000003 bb01 OUT DDRD,R16
다음의 클럭 사이클에서는, Program Counter의 내용이 「0000000011」로 되었기 때문에, 그 값이 가르키는 Program Flash의 어드레스의 내용「10111011 00000001」이 Instruction Register(명령 레지스터)로 카피된다. 이 내용이 Instruction Decoder(명령 디코더)에 의해 디코드된다. 디코드는 구체적으로는 다음과 같이 행해진다.
10111 | 01 | 10000 | 0001 |
OUT 명령 |
DDRD을 나타내는 IO어드레스$11의 상위 2bit | R0~R31 중의R16 | DDRD을 나타내는 IO어드레스$11의 하위 4bit |
이 명령의 실행에 필요한 타이밍 신호가 만들어져 실행(execute)된다. 그 경우는 DDRD 레지스터의 내용이 「01111111」로 된다. IO포트에 직접 값을 출력하는 명령이 없기 때문에, 이와같이 처음 명령으로 레지스터에 값을 세트하고, 다음의 명령으로 레지스터의 내용을 IO포트 출력한다. 여기서 행한 DDRD 레지스터의 설정은 「PD0~PD6を출력으로서 사용한다.」라고 말하는 것을 지시하는 것이다.

■ 000004 9ac2 SBI PORTB,2
다음 클럭 사이클에서는, Program Counter의 내용이「0000000100」로 되었기 때문에, 그 값을 가르키는 Program Flash의 어드레스의 내용「10011010 11000010」이Instruction Register(명령 레지스터)에 카피된다. 그 내용이 Instruction Decoder(명령 디코더)에 의해 디코드된다. 디코드는 구체적으로 다음과 같이 행해진다.
10011010 | 11000 | 010 |
SBI명령 | PORTB를 나타내는 IO 어드레스$18 | 셋하는 bit「2」의 지정 |
이 명령의 실행に필요한 타이밍 신호가 만들어져 실행(execute)된다. 여기서는 PORTB의 bit2(PB2핀)이 1(High레벨의 전압)이 되고, 외부회로의 LED-A가 점등된다. PORTB은 레지스터가 되어있기 때문에, 일단 값을 셋트하면 저장된다.
PORTB의 2 비트를 1로 바꾼다.
(2비트에 High 레벨 신호를 출력한다.)

■ 000005 98c3 CBI PORTB,3
다음의 클럭 사이클에서는 Program Counter의 내용이「0000000101」로 되었기 때문에, 그 값이 가르키는 Program Flash의 어드레스의 내용「10011000 11000011」이 Instruction Register(명령 레지스터)에 카피된다. 이 내용이 Instruction Decoder(명령 디코드)에 의해 디코드된다. 디코드는 구체적으로 다음과 같이 행해진다.
10011000 | 11000 | 011 |
CBI명령 | PORTB를 나타내는 IO어드레스$18 | 클리어하는 bit「3」의 지정 |
이 명령의 실행에 필요한 타이밍 신호가 만들어져 실행(execute)된다. 여기에서는 PORTB의 bit3(PB3핀)이 0(Low 레벨의 전압)이 되어, 외부 회로의 LED-B가 꺼진다. PORTB는 레지스터가 되었기 때문에 일단 값을 셋트하면 저장한다.
PORTB의 3 비트를 0으로 바꾼다.
(3비트에 Low 레벨 신호를 출력한다.)

■ 000006 cffd RJMP LOOP
다음의 클럭 사이클에서는 Program Counter의 내용이「0000000110」으로 되어있기 때문에, 그 값이 가르키는 Program Flash의 어드레스의 내용「11001111 11111101」이 Instruction Register(명령 레지스터)에 카피된다. 그 내용이 Instruction Decoder(명령 디코드)에 의해 디코드되어, 실행에 필요한 타이밍 신호가 만들어진다. 디코드는 구체적으로는 다음과 같이 행해진다.
1100 | 111111111101 |
RJMP명령 | 점프할 곳의 상대 어드레스로, 2의 보수표현의 「-3」 |
이 명령의 실행으로 필요한 타이밍 신호가 만들어져 실행(execute)된다. 일반적이면 이 명령실행 뒤의 Program Counter의 내용이 「0000000111」로 되는 것이지만 상대적으로「-3」되어「0000000100」가 Program Counter의 내용이 된다.
LOOP로 이동해서 프로그램을 실행한다.

■ 이후「SBI PORTB,2」「CBI PORTB,3」「RJMP LOOP」가 무한히 반복된다.
(복습)
이하와 같이, 소스 프로그램 안의「CBI PORTB,3」을「SBI PORTB,3」로 변경하고, 동작을 확인하게 할 것. 이것은 PORTB의 bit3을 클리어 부터 세트로 변경하는 것을 의미하고 있다. 그 결과, 프로그램의 일련의 명령이 실행 될 때까지 꺼져있던 LED-B가 켜진다.
|
→ |
|
→ |
|
→ |
|
이어서, 소스 프로그램 안의「SBI PORTB,2」을「CBI PORTB,2」로 변경하고, 동작을 확인할 것. 이것은 PORTB의 bit2를 셋트부터 클리어로 변경하는 것을 의미하고 있다.
(참고자료)
[1] ATMEL사(AVR 마이컴), http://www.atmel.com/products/AVR/[2] WinAVR-20060421, http://sourceforge.net/project/showfiles.php?group_id=68108
원문링크
http://siva.cc.hirosaki-u.ac.jp/usr/koyama/lecture/text/avr/part1.htm
-------------------------------------------------------------
음 찬찬히 보니까 겨우겨우 이해가 오는군
프로그램 카운터가 이제야 이해가 가는군.
저번에 프로그램 카운터에 글을 쓰기는 했었는데 이해가 안갔었는데.