제1부

기초 이론편

제1부에서는 8051에 대한 기초적인 것을 다룬다. 뭐든지 그렇지만, 마이크로콘트롤러도 기초가 중요하다. 기초를 모르고 응용에 들어갈 수는 없다. 유의해야 할 것은 이 장에서 8051에 대하여 다루는 것은 ATmel사의 AT89S51 또는 AT89C2051에도 적용된다는 것이다. 프로그램 메모리가 8051은 마스크 ROM으로 되어 있음에 반하여 AT89S51이나 AT89C2051은 플래쉬메모리로 되어 있다는 것, 내부 프로그램 메모리가 8051이나 AT89S51은 4K바이트임에 반하여 AT89C2051은 2K바이트라는 것, 8051이나 AT89S51은 아날로그 비교기가 내장되어 있지 않음에 반하여 AT89C2051은 그것이 내장되어 있다는 것, 8051이나 ST89S51에는 포트가 4개나 되지만 AT89C2051은 2개 밖에 없다는 것 등 만이 다를 뿐이다. 그럼에도 불구하고 AT89S51이나 AT89C2051은 8051에 비할 때 월등하게 저렴하고, 무엇보다도 프로그램 메모리가 플래쉬메모리로 되어 있어서 반복적으로 기록하기가 쉽다. 그래서 8051에 대한 실험은 AT89C2051이나 AT89S51로 하기를 적극 권장한다.

독자의 입장에서 볼 때 8051은 Intel사가 개발한 모든 마이크로콘트롤러의 기본이 된다. 그 기본 구조나 명령어 체계에 있어서 8051은 모든 Intel 마이크로콘트롤러의 기본이 되기 때문이다. 바꿔말해서 8051의 기본 구조 및 명령어 체계만 제대로 이해하면 Intel사가 개발한 어떤 마이크로콘트롤러에도 쉽게 접근할 수 있다. 이런 의미에서 그 기초가 되는 제1부를 철저히 공부하기 바란다.

1.1 마이크로콘트롤러 1.2 마이크로프로세서 및 마이크로콘트롤러의 역사 1.3 마이크로콘트롤러의 특징	1.4 마이크로콘트롤러의 응용 1.5 MCS-51 계열 마이크로콘트롤러의 특징 1.6 MCS-51 계열 마이크로콘트롤러의 종류 1.7 이 장의 간추림

컴퓨터의 중앙처리장치(CPU)가 가진 기능의 대부분을 하나 또는 몇 개의 반도체 칩(chip)에 집적한 것을 마이크로프로세서(microprocessor)라고 하고, 이것을 중심으로 그림 1.1과 같이 프로그램 메모리, 데이터 메모리, I/O포트 등으로 구성된 작은 규모의 컴퓨터 시스템을 마이크로컴퓨터(microcomputer)라고 한다. 예컨대, Z80이나 i80586(pentium)이나 MC68040은 마이크로프로세서이고, 이들을 중심으로 구성된 작은 규모의 컴퓨터 시스템은 마이크로컴퓨터이다.

그림 1.1  마이크로컴퓨터의 구성

마이크로컴퓨터는 일반 컴퓨터와 본질적으로 그 기능은 같으나, 구성이 비교적 간단하고, 한꺼번에 처리할수 있는 데이터의 폭이 작으며, 처리 속도가 느리다는 점에서 일반 컴퓨터에 비하여 그 기능이 떨어진다. 그러나, 마이크로프로세서의 고성능화와 고속화가 급진됨에 따라 그 간격은 급속히 좁혀지고 있다.

마이크로컴퓨터중에는 그 부품들을 여러 장의 기판 위에 배치해 놓은 것이 있고, 한 장의 기판 위에 배치해 놓은 것이 있는데, 후자를 특히 단일 보드 마이크로컴퓨터(one board microcomputer)라고 한다. 그림 1.2는 대표적인 8비트 마이크로프로세서인 Z80을 중심으로 ROM, RAM, PIO, CTC 등으로 구성된 단일 보드 마이크로컴퓨터이다.

그림 1.2  단일 보드 마이크로컴퓨터

전자공학의 급진적인 발달로 인하여 1970년대부터는 하나의 단일 보드 마이크로컴퓨터에 들어가는 모든 부품들을 하나의 반도체 칩에 집적하기에 이르렀는데, 이것을 단일 칩 마이크로컴퓨터(single chip microcomputer)라고 한다.

그림 1.3은 단일 칩 마이크로컴퓨터를 상징적으로 나타낸 것이다.

단일 칩 마이크로컴퓨터는 주로 제어에 사용된다. 모터를 제어한다든가, 자동차 엔진을 제어한다든가, 로봇을 제어하는 것과 같이 기계를 제어하는 데 주로 사용된다.

그림 1.3 단일 칩 마이크로컴퓨터

이처럼 제어에 사용되는 단일 칩 마이크로컴퓨터를 특히 마이크로콘트롤러(microcontroller)라고 한다. 제어장치(controller)를 소형(micro)으로 만든 것이라는 뜻일 것이다. 아무튼, 마이크로콘트롤러는 제어용의 단일 칩 마이크로컴퓨터이다.

마이크로콘트롤러는 그 용도에 맞게 진화되었기 때문에 입출력, 인터럽트, 명령어 등에 있어서 연산용 마이크로컴퓨터와는 상당한 차이가 있다.

(1) 입출력 능력

마이크로콘트롤러는 가전기기, 컴퓨터 주변장치, 통신장치, 의료기기, 공정기계 등의 제어를 목적으로 하므로, 이를 위하여 입출력 기능을 강화하고 있다. 외부 핀(pin)의 대부분을 입출력(I/O)에 할당하고, A/D변환기와 PWM을 내장하기도 하며, 타이머/카운터도 내장하고, 동기식/비동기식 직렬통신 포트도 내장한다.

(2) 인터럽트 처리 능력

마이크로콘트롤러는 역시 그 사용 목적상 인터럽트 처리 능력을 강화한다. 외부 인터럽트를 크게 강화하고, 개별적인 인터럽트 우선순위와 마스크 능력도 강화한다.

(3) 명령어 세트

마이크로콘트롤러에서는 비트 조작 명령어(bit manipulation instruction)를 매우 강화한다. 대개의 경우 제어는 비트별로 이루어지기 마련이므로, 비트 조작 명령어가 많으면 프로그램 작성이 수월하기 때문이다.

1969년에 일본의 샤프社는 전자식 탁상계산기의 CPU를 하나의 칩으로 만들고자 인텔社를 포함한 몇 개의 회사와 개발계약을 맺었다. 그로부터 2년 뒤인 1971년에 이들 회사중 오직 인텔社만이 요구된 제품을 만들어 내는 데 성공하였다. 그러나 아깝게도 이것은 처리속도가 요구된 것에 미치지 못하였다. TTL 대신 MOS 기술을 사용했기 때문이었다. 계약은 취소되었고, 그래서 인텔社는 실패작으로서 이것을 창고에 사장시키느냐, 아니면 새로운 상품으로서 이것을 시장에 내어 놓느냐의 갈림길에 서게 되었다. 논란 끝에 인텔社는 후자를 택하였다. 그래서 Intel4004라는 이름으로 시판에 들어갔다. 이것은 말이 탁상계산기의 CPU이지, 프로그램만 바꾸면 전혀 다른 용도에 사용될 수 있는 컴퓨터의 CPU이므로, 인텔社는 이것을 □싱글칩 CPU□로서 시판에 들어 갔던 것이다. 반응은 의외로 좋았다. 그래서 인텔社는 일약 돈방석에 앉게 되었다. 그 후 Intel4004는 Intel4040으로 개량되었고, 다음 해인 1972년에는 8비트 마이크로프로세서 intel8008을 개발해 내었으며, 다시 다음 해인 1973년에는 현재에도 널리 사용되는 Intel8080을 개발해 내었다.

한편 모토롤라社에서는 1974년에 8비트 마이크로프로세서 MC6800을 개발해 내었는데, 이 무렵부터 세계는 온통 마이크로프로세서 세상이라고 할 정도로 모든 분야에서 마이크로프로세서에 대한 관심이 고조되었다.

1970년대 중반으로부터 후반까지는 8비트 마이크로프로세서의 전성기라고 할 수 있다. Intel8080의 기능을 향상시켜 인텔社에서는 Intel8085를, 자이로그社에서는 Z80을 개발해 내었고, MC6800의 기능을 향상시켜 모토롤라社에서는 MC6802를, MOS텍크社에서는 MCS6502를 차례로 개발해 내었다. 이들 중 Z80은 8080을 기본으로 하여 개발된 것이긴 하나 고도의 개량이 이루어져서, 8비트 마이크로프로세서로서는 더 이상 좋은 것이 필요없다는 평이 나와 있을 정도이다.

한편, 1975년에 이르러 Texas Instrument사는 CPU 뿐만이 아니라 ROM, RAM, I/O 등을 하나의 칩에 집적한 TMS1000 시리즈를 내놓음으로써 단일칩 마이크로컴퓨터(마이크로콘트롤러) 시대를 열었는데, 이 때부터 마이크로프로세서 또는 마이크로컴퓨터는 성격이 서로 다른 두 개의 방향으로 분화 발전되었다. 그 중 하나는 연산용(데이터 처리用)이고, 다른 하나는 제어용이다.

연산용으로서 인텔社는 Intel8086, 80186, 80286, 80386, 80486, 80586, 80686 등으로 발전시켰고, 모토롤라社는 MC68000, 68010, 68020, 68030, 68040, 68050 등으로 발전시켰으며, 자이로그社는 Z80, Z8001, Z8003, Z80000 등으로 발전시켰다.

한편, 제어용, 즉 마이크로콘트롤러로서 인텔社는 8051(MCS-51시리즈), 8096(MCS-96시리즈), 80960(MCS-960시리즈) 등으로 발전시켰고, 모토롤라社는 6805, 68HC11, 68HC16, 68332 등으로 발전시켰으며, 자이로그社는 Z8, Z88C00(super8), Z89 시리즈 등으로 발전시켰다.

국산 마이크로콘트롤러로서는 삼성전자가 4비트 마이크로콘트롤러인 KS51 시리즈, KS56 시리즈, KS57 시리즈 등을 개발한 것이 효시가 되었다. 삼성전자는 또한 1991년에 이르러 자이로그社의 super8 코어를 도입하여 KS88 시리즈를 개발하였으며, 1995년에는 16비트 마이크로콘트롤러 KS16 시리즈와 32비트 마이크로콘트롤러 KS32 시리즈도 개발함으로써 4비트에서 32비트에 이르는 마이크로콘트롤러 시리즈를 모두 개발하였다. 또한 1999년도에 이르러 삼성전자는 8비트 저전력 RISC 마이크로콘트롤러 calm RISC8(KS85C00108)과 16비트 저전력 RISC 마이크로콘트롤러 calm RISC16을 개발 발표하였다.

표 1.1은 상기의 발전 과정중 마이크로콘트롤러에 관한 것만을 나타낸 것이다.

□표 1.1  마이크로콘트롤러의 발전

제조사	8비트	8비트 성능향상	16비트	16비트 성능향상	32비트
인 텔	8048	8051	8096	80196	80960
모토롤러	6805	68HC11		68HC16	68332
자이로그	Z8	Z88C00(super-8)	Z89
ATmel		AT89S51 AT89C2051 AT90S2313 ATmega8535 ATmega128
삼성전자		KS88		KS16	KS32

마이크로콘트롤러는 제어용 컴퓨터를 VLSI(very Large-Scaled Integration) 기술에 의하여 하나의 칩으로 만든 것이므로, VLSI로서의 장점과 컴퓨터로서의 장점을 다 갖추고 있다. VLSI로서의 장점은 소형, 경량, 저렴이고, 컴퓨터로서의 장점은 융통성과 신뢰성이다. 그러므로, 마이크로콘트롤러로 제품을 만들면 다음과 같은 장점을 가진다.

(1) 제품이 소형화되고 경량화된다. 시스템 제어부의 대부분이 단일칩 마이크로콘트롤러로 구성되므로 구성 소자의 수도 줄고, 그 만큼 더 가벼워진다.

(2) 제품의 가격이 저렴해진다. 마이크로콘트롤러로 제품을 만들면 부품비 및 제작비가 감소되고, 개발비와 개발시간 또한 절감되어 개별 논리회로(hard-wired logic)에 의하는 경우보다 제품의 원가가 적게 든다. 다만 복잡도가 크지 않을 경우에는 개별 논리회로에 의하는 편이 더 경제적이다.

(3) 융통성이 커서 기능 변경이나 확장이 용이해진다. 개별 논리회로는 그 목적, 그 용량 외에는 사용하지 못한다. 기능 변경이나 확장에는 부품의 추가 및 배선의 변경이 필요하고, 또한 장시간을 요한다. 그러나, 동일한 것을 마이크로콘트롤러로 구성하면 대개의 경우 프로그램만 변경하면 되므로, 설계시나 현장 조정시에는 물론, 설치 후에도 기능 변경이나 확장이 단시간 내에 이루어질 수 있어서 융통성이 크다.

(4) 신뢰성이 향상된다. 부품수가 적어서 시스템 구성이 간단하고, 신뢰도가 높은 소자를 사용하기 때문에 고장률이 적고, 또 고장이 난다해도 자기진단 등의 기술을 이용하여 곧 바로 보수할 수 있다.

전술한 바와 같이, 마이크로콘트롤러는 소형이고, 가벼우며, 저렴하고, 융통성과 신뢰성이 크다는 장점이 있어서, 단일 보드 마이크로컴퓨터의 시절보다 수십∼수백배 그 수요가 증가하고 있다. 또한 응용면에서 볼 때 이것은 간단한 가전기기에서부터 복잡한 산업용에 이르기까지 그 응용이 미치지 않은 곳이 거의 없다. 마이크로콘트롤러는 특히 전자렌지, 전기밥솥, 리모콘, 무선전화기, 전기세탁기, 에어콘, 전기스토브, TV채널, 음향기기 튜너, 플레이어나 카셋트 덱크 등 일상생활 용품의 제어기로서 널리 응용되고 있다. 다음은 그 구체적인 응용 예이다.

산 업

□ 모터 제어

□ 로봇 제어

□ 프로세스 제어

□ 수치 제어

□ 지능형 센서(transducer)

계 측

□ 의료용 계측기

□ 가스크로마토그래프

□ 오실로스코프

가전제품

□ 비디오 레코더

□ 레이저 디스크

□ 비디오 게임기

유도 제어

□ 미사일 제어

□ Torpedo 유도 제어

□ 지능형 무기(스마트 병기)

□ 우주선 유도 제어

데이터 처리

□ 플로터(plotter)

□ 복사기

□ 하드디스크 구동장치

□ 테이프 구동장치

□ 프린터

통 신

□ 모뎀

□ 지능형 line card의 제어

자동차

□ 점화 타이밍 제어

□ 연료 분사 제어

□ 변속기 제어

□ ABS 제어

□ 열방사 제어

마이크로콘트롤러의 응용면을 다시 CPU의 폭을 중심으로 살펴보면 다음과 같다.

4 비트 CPU

□ 전자렌지, 전기밥솥, 가스오븐, 전기세탁기 등 가전제품

□ 휴대용 음향기기

□ 자동차용 라디오

□ 게임기

□ LCD 및 LED 제어기

8 비트 CPU

□ 단말기 및 모니터

□ 계측기기

□ 고급 탁상계산기

□ 학습기

□ 재고 관리기

□ 감시장치

□ CTV

□ 카드 인식기

12 비트 CPU

□ 자동차 전자

□ 계측

□ 상수도, 가스 등의 telemeter

16 비트 이상의 CPU

□ 프로세서 제어

□ 네트워크 제어

□ 자동차 항법장치

□ FAX, LBP, HDD 등 오피스 자동화기기

□ 기타 복잡한 기계나 시스템 제어

끝으로 8비트 마이크로콘트롤러의 좀 더 구체적인 응용예를 몇 개만 들기로 한다.

자동차 주행 시험장의 점수계산장치

그림 1.4 자동차 주행 시험장의 점수계산장치

자동차 주행 시험장에서 체크하는 주요 사항은 브레이크 및 좌우 깜박이의 조작, 후진, 미끄러짐, 요철 진동, 주행 시간 및 속도 등이다. 이들 사항을 시험용 자동차에 장치된 마이크로콘트롤러(8051)가 각종 센서를 통하여 얻고, 이들 데이터를 처리하여 시험장 곳곳에 설치된 적외선 수신장치를 통하여 통제실 컴퓨터에 보내면, 통제실 컴퓨터는 마이크로콘트롤러가 보낸 이들 데이터를 다시 처리하여 합격 여부를 결정한다.

자동차 브레이크(ABS) 제어

자동차의 ABS(anti-lock break system)는 특히 눈이나 비가 올 때 차가 회전한다든가 미끄러지는 것을 최대한 줄이기 위한 것인데, 바퀴 부분에 부착된 센서가 양 바퀴의 회전수와 미끄러짐을 감지하여 마이크로콘트롤러에 보내면, 마이크로콘트롤러는 이들 데이터를 처리하여 솔레노이드 밸브에 디지털 출력을 내어 차의 회전과 미끄러짐이 거의 없이 단계적으로 차를 정지킴으로써 최적의 브레이크 동작을 하도록 한다.

그림 1.5 ABS 시스템

타자기

IBM 타자기(휠라이트 6)는 마이크로콘트롤러(8051)를 두 개 내장하고 있는데, 그 중 하나는 4개의 스테핑모터를 제어하여 글자판이 있는 휠, carriage, 리본, 라인 스페이스 등을 동작시키고, 다른 하나는 전체적인 중앙제어와 3200자의 메모리 기능을 담당한다.

하드 디스크 드라이버

하드 디스크 드라이버(HDD)는 제어부와 모터부로 되어 있는데, 제어부는 메모리, A/D변환기, 리드/라이트 헤드, 모터 제어부 등으로 구성된다. 이 제어부를 구성하는 CPU로서 8비트 마이크로콘트롤러를 사용한다.

PLC

PLC(Programmable Logical Controller)는 PC(Programmable Controller)라고도 하는 것으로서, 산업용 마이크로콘트롤러이다. 즉 PLC는 마이크로콘트롤러가 중심이 되고(LG계전 제품의 MASTER-K 시리즈는 8051로 되어 있음), 그 외에 전원과 입출력 인터페이스로 구성된 산업용 제어기이다. 그림 1.6은 이런 PLC의 구성도를 나타내고 있다.

그림 1.6  PLC 회로도

PLC는 시퀀스 제어에서 널리 사용되는데, 그 구체적인 용도는 다음과 같다.

·제철공업＞압연기 회전 제어, 후판밀 제어, 연소로 제어, 열풍로 제어

·상하수도＞양수장 제어, 하수처리장 제어

·시멘트 공업＞컨베이어 제어

·화학공업＞계장 제어, 화학장치 제어

·기계공업＞선반 제어, 컨베이어 제어

·기    타＞공업용 로봇, 운반 시스템, 자동 창고, 빌딩 설비 등의 제어

끝으로 통계청이 밝힌 국내 8051의 응용 현황은 다음 표와 같다.

□표 1.2  8051의 국내 응용 현황

회사명	모델명	사용부품	제품명	비 고
경방기계공업	클로버 ET-2300HC	8031AH	전자타자기
금성통신	PT-200	P8051AH	프린터	200 CPS
	PT-300	P8051	프린터	200 CPS
대우자동차	계기판	8051	슈퍼사롱(자동차)
대우통신	DT-9420	8051	그래픽 터미널	키보드 8031
	DT-9330	8031/86	그래픽 터미널	키보드 8031
	DT-9230	8031 AH	알파뉴메릭 터미널
삼미전산	Data log-40	8031	데이터로깅 시스템
서울미터		P8031	택시 미터기
스미스 코로나	5200	8032(주), 8052(주)	전자타자기
신도리코	CAT6300	P8051	복사기 sorter
오트론		P8031	전화기 자동응답장치
IBM	휠라이트 1	8051/2	타자기	3200자 메모리
	휠라이트 6	8051/2	타자기
자네트 시스템		8031	모뎀
지원산업		8051	곡물 수분 측정기
제일정밀		JP3400	프린터
전자과학	FA-052	8052AH-BASIC	EPROM프로그래머
프라이폴		8051	phone 보드
PTI	PF225	8031 PLCC	25MB HDD
	PT338	8031 PLCC	38MB HDD
	PT357	8031 PLCC	57MB HDD
	PT351	8031 PLCC	51MB HDD
콤텍시스템	X-TAL 32D	8051	다이얼모뎀1200bps
카스	Dolphin 60A/150A	8049	계수형 접시저울
효성중공업	ES-20, ES-40	P8051	PLC 20, 40 접점
하나계기	다이어트 스케일	P8031	계수형 접시저울
한국전자통신연구소	TDX-10	P8044	전자교환기 입출력 통신
한국미싱		8051AH	자동 재봉틀
한독인버터	HD-10-25	8051	중형 인버터 25kV
		P8051	엔진 제어

(1) 8051이 소속되어 있는 MCS-51 계열 마이크로콘트롤러는 CISC 머신에 속한다.

CISC는 Complex Instruction Set Code의 약자로, 복합명령을 포함해서 명령어의 수와 주소지정방식의 수를 필요한 만큼 많이 하는 컴퓨터 구조로서, 이것은 RISC 머신에 대한 것이다. RISC(Reduce Instruction Set Code)는 복합명령을 쓰지 않고 극히 간단한 명령어만을 씀으로써 명령어의 수를 필요한 최소한으로 줄이고, 주소지정방식 또한 필요한 최소한에 국한하는 컴퓨터 구조이다. RISC 머신은 속도에 있어서는 유리하나, 어셈블리어 단위의 프로그램 작성에는 불리하다. 8051, 68HC11, Z8 등 대부분의 마이크로콘트롤러는 CISC 머신에 속한다. 마이크로칩社의 PIC 계열과 ATmel社의 AT89C 계열 등 지극히 적은 것들 만이 RISC 머신에 속한다. 이들이 RISC 머신에 속한다고는 하나 참다운 의미의 RISC 머신이라고 보기는 어렵고, 그래서 유사 RISC 머신(RISC like machine)이라고 한다.

MCS-51 계열의 마이크로콘트롤러는 CISC 구조이어서 명령어가 111개나 된다. 일반적으로 명령어 수가 많으면 어셈블리語 단위의 프로그램 작성에 유리하다. MCS-51 계열의 마이크로콘트롤러는 또한 주소지정방식이 8개나 될 정도로 다양하여 역시 어셈블리語 단위의 프로그램 작성에 유리하다.

(2) MCS-51 계열의 마이크로콘트롤러는 하바드 구조(Havard architecture)로 되어 있다. 하바드 구조에서는 프로그램 메모리와 데이터 메모리가 확연히 구분되어 있어서 表데이터를 제외하고는 프로그램 메모리에 데이터를 넣을 수도 없고, 데이터 메모리에 프로그램을 넣을 수도 없다. 이에 반해서 Z80과 같은 폰 노이만 구조에서는 프로그램 메모리와 데이터 메모리가 확연히 구분되어 있지 않아서 프로그램과 데이터가 같은 메모리에 혼재한다.

일반적으로 하바드 구조에서는 데이터 메모리를 레지스터 파일 방식으로 통합 관리한다. 여기서 레지스터 파일(register file)이란 레지스터와 데이터 메모리의 구분이 없이 데이터 메모리 영역을 마치 범용 레지스터처럼 사용하는 메모리 관리 방식을 말한다.

(3) MCS-51 계열 중 일부는 대부분 CHMOS(High performance Complementary Metal Oxide Semi-conductor)로 되어 있다. CHMOS는 성능을 향상시킨 CMOS로서, NMOS보다 성능이 약 2배 향상되어 있다. 일부의  MCS-51은 CHMOS로 되어 있어서 다음과 같은 장점을 가진다.

□ 소비 전력이 매우 적다.

□ 전달 특성이 우수하다.

□ 잡음여유가 크다.

□ 집적도가 높다.

□ 입력 임피던스가 크다.

□ 동작 전압의 범위가 넓다. (4.5V∼5.5V )

□ 동작 온도의 범위가 넓다. (１40℃∼／85℃ )

반면 CHMOS이기 때문에 오는 단점도 있다.

□ 정전기에 의해서 산화막의 절연이 파괴되기 쉽다. 특히 건조한 겨울철에는 폴리에스텔과 같은 합성섬유의 마찰에 의한 정전기는 2만∼3만 Volt에 달하므로 각별한 주의를 요한다.

□ 과전압에 의한 latch-up 현상이 있다. 즉, 최대 정격 이상의 전압이 인가되면 과전류가 흘러서 발열로 인한 파괴의 염려가 크다.

다음은 MCS-51 계열 마이크로콘트롤러의 특징을 정돈한 것이다.

CPU

□ 제어에 적합하게 설계된 8비트 CPU

□ 강화된 부울대수 연산능력

메모리

□ 128 바이트의 레지스터 파일

□ 4K 바이트의 내부 프로그램 메모리

□ ROM-less 동작 모드

외부 인터페이스

□ 최대 64K 바이트의 외부 데이터 메모리

□ 최대 64K 바이트의 외부 프로그램 메모리(ROM-less 동작 모드의 경우)

발진주파수

□ 최대 24MHz

명령어 세트

□ 111개의 명령어

□ IDLE과 POWER DOWN의 전력 절약 모드

명령어 실행 시간

□ 0.5□초[발진주파수Ａ24MHz, 1기계사이클 명령의 경우]

인터럽트

□ 5개의 인터럽트 소스

□ 5개의 인터럽트 벡터

□ 2개의 인터럽트 우선순위 레벨

일반 I/O

□ 4개의 I/O포트(32개의 쌍방향성 I/O포트 라인)

타이머/카운터

□ 2개의 16비트 타이머/카운터

직렬포트

□ 하나의 동기 모드와 3개의 전이중 비동기 모드를 가진 USART

동작 온도 범위

□ １40℃∼／85℃

동작 전압 범위

□ 4.5V ∼ 5.5V

패키지 형태

□ 40핀 DIP, 44핀 PLCC

MCS-51 계열의 마이크로콘트롤러에는 표 1.3과 같이 여러 종류가 있으나, 이들중 중요한 것은 8051, 8031, 8751 등 3종류이다. 이들 마이크로콘트롤러간의 차이는 ROM 또는 EPROM의 내장 및 외장에 있다.

MCS-51 계열과 호환이 가능한 마이크로콘트롤러에는 앞에서 언급한 바와 같이 ATmel사가 내어놓은 AT89S51과 AT89S52와 AT89C2051이 있다.

AT89S51은 명령어와 구조 그리고 핀 배치에 있어 MCS-51(8051)과 100% 호환적(compatible)이다. 그러므로 현재의 시스템에서 8051을 빼내버리고 이것으로 대체해 넣어도 된다. 값은 월등하게 저렴하다.

AT89S52는 명령어와 구조 및 핀에 있어 MCS-51(8052)과 호환적이다.

AT89C2051은 MCS-51의 기능을 20핀의 컴팩트한 사이즈로 줄인 형태로서 ATmel의 AT90S2313에 유사하다. MCS-51의 기능을 거의 다 갖추고 있으면서도 지극히 저렴하고 프로그램 메모리가 플래쉬 메모리로 되어 있어서 MCS-51을 공부하는 사람에게는 최적의 것이라 할 것이다.

□표 1.3  MCS-51 계열의 주요 품명

품 명	내장메모리		타이머/카운터	인터럽드 발생원	A/D(bits) +PWM	I/O라인
	프로그램 메모리	데이터 메모리
8051	마스크ROM 4K×8	128×8	2	5		32
8031	ROM 외장형	128×8	2	5		32
8751H	EPROM 4K×8	128×8	2	5		32
8052AH	마스크ROM 8K×8	256×8	3	6		32
8032AH	ROM 외장형	256×8	3	6		32
8752	EPROM 8K×8	256×8	3	6		32
80251	16K ROM	1K	3+WD	6		32
80C51	ROM 4K	128×8	2	5		32
80C515	8K ROM	256	3+WD	12	8	48
8×C750	OTP & EPROM 2K	64×8	1	5	6	18
8×C752	OTP & EPROM 2K	64×8	1	5	8	21
8×C550	OTP & EPROM 4K	128×8	2+WD	6	8	32
83CL580	ROM 6K	256×8	2+WD	7	8+PWM	40
8×C562	ROM 8K	256×8	2+WD	7	8+PWM	48
8×C552	OTP & EPROM 8K	256×8	2+WD	7	8+PWM	48
83CE654	ROM 16K	256×8	2	6		32
8×C592	OTP & EPROM 16K	512×8	3+WD	7	10	48
8×CE528	ROM 32K	512×8	3+WD	7		32
AT89S51	PEROM 4K×8	128×8	2	6		32
AT89C2051	PEROM 2K×8	128×8	2	6		15
AT89S52	PEROM 8K×8	256×8	3	8		32

(1) 8051

이것은 MCS-51 계열중 가장 먼저 개발된 것으로, 마스크 ROM 내장형이다. 앞에서 설명한 것을 다시 한번 요약할 때 이것의 주요 특성은 다음과 같다.

·제어용에 적합하게 설계된 8비트 CPU

·강화된 부울대수(비트 조작) 연산 능력

·64K 바이트의 외부 프로그램 메모리 가능

·64K 바이트의 외부 데이터 메모리 가능

·4K 바이트의 내부 프로그램 메모리

·128 바이트의 내부 데이터 메모리

·32개의 양방향성 I/O라인

·두 개의 16비트 타이머/카운터

·전이중 UART

·두 개의 우선순위 레벨을 가지는 5개의 벡터 인터럽트

·클록발진기의 내장

8051은 ROM 내장형이므로 프로그램 메모리가 ROM으로 되어 있어서, 사용자가 주문한 프로그램을 칩 제조 과정에서 다량으로 구입하므로 값은 저렴하지만, 한번 기입된 것을 다시 변경할 수도 없고 사용자가 직접 기입할 수도 없는 단점이 있다.

(2) 8031

이것은 칩 내부에 프로그램 메모리(ROM)가 내장되어 있지 않아서 외부에 이것을 둔다는 것을 제외하고는 8051과 같다. 다시 말해서 8031은 ROM 외장형의 8051이다. 외부 ROM은 마스크 ROM이어도 좋고, EPROM이어도 좋으며, EEPROM이어도 좋고, 플래시메모리이어도 좋은데, 그 용량은 최대 64K 바이트이다. 최대 64k 바이트이므로, 8031은 프로그램의 용량이 4K 바이트보다 큰 경우에 적합하다.

(3) 8751

8751은 EPROM 내장형의 8051이다. 즉, 8751은 내부의 프로그램 메모리가 ROM 대신 EPROM으로 되어 있다. 그러므로, ROM writer를 사용하여 유저가 프로그램을 기록(write)할 수도 있고, 기록된 내용을 자외선 소거장치를 사용하여 지우고 다시 기록할 수도 있어서 개발 과정에서 흔히 사용된다. 8751 자체는 현재 생산되지 않고 8751H가 생산되고 있다.

(4) 8052, 8032, 8752

이들은 8051, 8031, 8751의 최초 후속 모델로서, 내부 프로그램 메모리와 데이터 메모리가 두 배이고, 타이머와 이에 관련된 인터럽트가 하나씩 더 추가되어 있다.

·내부 데이터 메모리 256바이트

·내부 프로그램 메모리 8K바이트

·인터럽트 소스 6개

·내장 타이머 3개

(5) 80C51BH

8051의 CHMOS형으로서, 전력소비가 적다. 또 전력소모를 극단적으로 줄일 수 있는 2가지 절약모드가 준비되어 있다.

·아이들 모드(idle mode)

·파워 다운 모드(power down mode)

(6) 80C251Sx

이것은 1994년에 차세대 8비트 마이크로콘트롤러로 개발한 8051 계열 성능 향상 제품이다. 8051을 뽑아내고 이것을 꽂으면 그대로 동작하나 성능은 5배정도  향상되어 있다.

·명령 파이프라인 구조

·16K 바이트의 내부 프로그램 메모리(OTPROM/ROM)

·1K 바이트의 내부 데이터 메모리

·내장 타이머 3개

·5개의 PCA(Programmable counter Array) 모듈

·1개의 위치독 타이머

(7) AT89S51

이것은 전술한 바와 같이 ATmel사가 내어놓은 것으로, 명령어 및 핀이 MCS-51과 100% 호환적(compatible)이나, 프로그램 메모리가 플래시 메모리로 되어 있어서 사용자가 프로그램을 직접 기록하기가 쉽다.

·4K 바이트의 PEROM(Flash Programable and Erasable ROM)

·128 바이트의 내부 RAM

·32의 I/O 핀

·2개의 16비트 타이머/카운터

·6개의 인터럽트 발생원

(8) AT89C2051

이것 역시 ATmel사가 내어놓은 것으로, 명령어가 MCS-51과 호환적이다. 규모는 AT90S2313에 유사하다.

·2K 바이트의 플래쉬 메모리(PEROM)

·128 바이트의 내부 RAM

·15개의 I/O핀

·2개의 16비트 타이머/카운터

·6개의 인터럽트 발생원

·하나의 아날로그 비교기

1. 단일 칩 마이크로컴퓨터는 마이크로컴퓨터의 모든 부품들을 하나의 반도체 칩에 집적시킨 것이다.

2. 마이크로콘트롤러는 제어용의 단일 칩 마이크로컴퓨터로서, 입출력 능력, 인터럽트 처리 능력, 명령어 등에서 연산용의 마이크로컴퓨터와는 상당한 차이가 있다.

3. 마이크로프로세서는 1971년의 Intel4004에서 시작해서 4 비트, 8 비트, 16 비트, 32 비트, 64 비트 등으로 발전되었다.

4. MCS-51 계열의 마이크로콘트롤러는 CISC 구조로 되어 있어서 명령어와 주소지정방식의 수가 많기 때문에 속도에 있어서는 RISC구조의 마이크로콘트롤러에 비하여 느리나, 어셈블리어 단위의 프로그램 작성에는 유리하다.

5. MCS-51 계열의 마이크로콘트롤러는 하바드 구조로 되어 있어서 데이터 메모리를 레지스터 파일 형식으로 통합 관리한다.

6. MCS-51 계열의 마이크로콘트롤러는 프로그램 메모리의 내장 여부, 메모리의 크기, 특수 기능의 내장 여부에 따라 여러가지 종류가 있다.

7. 마이크로콘트롤러는 크기가 작고, 가볍고, 저렴하고, 융통성이 있고, 신뢰성이 커서 가전제품에서 산업용에 이르기까지 널리 응용되고 있다.

8. PLC는 산업용 마이크로콘트롤러로서, 시퀀스 제어에서 널리 사용된다.

9. ATmel사의 AT89S51은 명령어 및 핀에 있어 MCS-51과 호환적이고, AT89C2051은 명령어에 있어 MCS-51과 호환적이다.

1.1 Microprocessor에 대한 다음 설명중 옳지 않은 것은?	(전산기조직응용)

㉮ Microprocessor는 처리 순서를 배선반(plugboard)에 배선하는 프로그램 방식의 원리로 등장한다.

㉯ Microprocessor는 중앙처리장치의 기능을 직접회로화한 것이다.

㉰ Microprocessor는 연산회로, 각종의 레지스터, 제어 회로 등으로 구성된다.

㉱ 최초의 Microprocessor는 intel사에서 개발한 4004이다.

1.2 마이크로컴퓨터와 마이크로프로세서에 관한 설명 중 잘못된 것은?	(전산기조직응용)

㉮ 마이크로컴퓨터의 기본 구성은 대형 컴퓨터나 미니 컴퓨터와 같다.

㉯ 최초의 마이크로프로세서는 1971년 미국 Intel사가 개발한 4004이다.

㉰ 마이크로컴퓨터의 중앙처리장치는 마이크로프로세서로 되어 있다.

㉱ 마이크로프로세서는 3개의 LSI칩으로 구성되어 마이크로컴퓨터에 사용된다.

1.3 마이크로프세서(microprocessor)에 대한 기술 중 옳지 않은 것은?	(전산기조직응용)

㉮ 마이크로프로세서는 마이크로컴퓨터내의 중앙처리장치만을 의미하는 가장 핵심이 되는 부분이다.

㉯ 마이크로프로세서는 중앙처리장치의 기능을 집적회로화한 것이다.

㉰ 마이크로프로세서는 입·출력장치의 기능을 향상시킨 집적회로이다.

㉱ 마이크로프로세서는 산술 논리부와 제어부 및 레지스터들로 구성되어 있다.

1.4 다음 중 Microprocessor의 특징이 아닌 것은?	(전산기조직응용)

㉮ VLSI로 설계된다.

㉯ 전력 소비가 적도록 설계한다.

㉰ 대용량 반도체 메모리를 내장하고 있다.

㉱ 명령이 고속으로 실행되도록 설계되고 있다.

1.5 Single board computer에 관한 설명 중 맞는 것을 아래에서 고르면?	(전산기조직응용)

㉮ 마이크로프로세서에만 있다.

㉯ 마이크로프로세서와 약간의 RAM 및 ROM만이 있다.

㉰ 마이크로프로세서, RAM, ROM 몇 개의 I/O 포트까지 갖추고 있다.

㉱ 마이크로프로세서 그리고 간단한 입력장치(keyboard)를 갖고 있다.

1.6 마이크로프로세서는 컴퓨터의 중앙처리장치를 LSI(large scaled integration) 기술에 의하여 실현한 것이다. LSI의 장점이 아닌 것은?	(전자계산기)

㉮ 높은 신뢰성	㉯ 빠른 수행속도

㉰ 낮은 가격	㉱ 소형, 경량

1.7 다음의 마이크로프로세서(microprocessor) 중에서 연산 속도가 가장 빠른 것은?	(전산기조직응용)

㉮ 4비트 마이크로프로세서	㉯ 8비트 마이크로프로세서

㉰ 16비트 마이크로프로세서	㉱ 32비트 마이크로프로세서

1.8 인텔사는 1971년 최초로 마이크로프로세서를 제작하였다. 다음 중 어느 것에 해당하는가?	(전자계산기)

㉮ 4004	㉯ 4040

㉰ 8008	㉱ 8080

1.9 최초의 마이크로프로세서 4004가 발표된 연도는?	(전자계산기)

㉮ 1951	㉯ 1961

㉰ 1971	㉱ 1981

1.10 다음 중 단일 칩 마이크로컴퓨터는?

㉮ Intel 8048	㉯ Motorola MC6809

㉰ Intel 8080A	㉱ Zilog Z8000

1.11 다음 중 단일 칩 마이크로컴퓨터가 아닌 것은?

㉮ Intel 8080	㉯ Intel 8048

㉰ Zilog Z8	㉱ Motorola MC6801

1.12 다음 중 8비트 마이크로프로세서가 아닌 것은?

㉮ 8086	㉯ 8080

㉰ MC6800	㉱ Z80

1.13 인텔사 8080A의 명령어를 모두 수용하면서 기능이 더욱 향상된 마이크로프로세서는?	(전산기 조직운영)

㉮ 6800	㉯ 8085

㉰ Z80	㉱ MC8000

1.14 8비트 마이크로프로세서 Z80에 대한 다음 설명 중 잘못된 것은?	(전산기조직응용)

㉮ Zilog사의 Z80은 Intel 8080의 개량형이라 할 수 있다.

㉯ ALU에서는 8비트의 산술 논리 연산 명령을 실행시킨다.

㉰ ALU는 레지스터, 외부 데이터버스, 내부 데이터버스 등과 통신한다.

㉱ 각각의 명령은 ALU에서 인출되고 외부의 플래그 레지스터에 의해 해독된다.

1.15 마이크로프로세서 4004의 주된 특징이 아닌 것은?	(전자계산기)

㉮ 기본 처리 단위는 4비트이다.

㉯ 10진 연산 기능이 있다.

㉰ 프로그램과 자료 모두 ROM에 기억된다.

㉱ 키보드와 LED만 연결해 간단한 시스템을 구성할 수 있다.

1.16 다음은 마이크로프로세서와 그 제조회사이다. 틀리게 짝지워진 것은?	(전자계산기)

㉮ 인텔-8086	㉯ 아이비엠-8088

㉰ 자일로그-Z8000	㉱ 모토롤라-68000

1.17 마이크로컴퓨터의 특징으로 옳지 않은 것은? (전자계산기)

㉮ 경제적이다.	㉯ 유지가 쉽다.

㉰ 제품이 소형화 된다.	㉱ 특정 응용 분야에만 이용된다.

1.18 다음 중 마이크로프로세서의 특성이 아닌 것은?

㉮ 소형·경량	㉯ 저 가격

㉰ 융통성	㉱ 저 신뢰도

1.19 비트 슬라이스 마이크로프로세서(bit sliced microprocessor)의 구성을 가장 잘 설명한 것은?

(전산기 조직응용)

㉮ CPU를 하나의 IC로 만든 프로세서

㉯ CPU, 기억 장치, I/O port가 IC에 구성된 프로세서

㉰ processor unit, microprogram sequencer control, memory가 각각 다른 IC로 구성된 프로세서

㉱ processor unit, microprogram sequencer control, memory가 한 IC로 구성된 프로세서

1.20 다음 중 비트 슬라이스형 마이크로프로세서는?

㉮ Intel 4004	㉯ Intel 8086

㉰ Zilog Z8	㉱ AMD Am2900

1.21 NANO Second의 단위는?	(전산기조직응용)

㉮ 10-6[sec]	㉯ 10-9  [sec]

㉰ 10-12 [sec]	㉱ 10-15  [sec]

1.22 다음 중 단일 칩 마이크로컴퓨터인 것은 어느 것인가?	(전산기 조직응용)

□ Intel 8080	□ Zilog Z80

□ Intel 8048	□ Motorola MC6800

1.23 다음 중 16비트 마이크로프로세서가 아닌 것은 어느 것인가?	(전산기 조직응용)

□ Z80	□ 8086	□ MC68000	□ 8088

1.24 실제 기능보다는 얼마나 시장 개척에 성공하느냐가 마이크로프로세서 생명인지를 잘 보여준 기종은?(Apple 컴퓨터에 사용하는)	(전산기 조직응용)

□ 6800	□ 8080A	□ Z80	□ 6502

1.25 마이크로프로세서 6502에 대한 설명으로 잘못된 것은?

□ 누산기가 한 개다.

□ 어드레스 버스와 데이터 버스는 모두 8bit로 되어 있다.

□ 8bit로 된 2조의 인덱스 레지스터가 준비되어 있다.

□ MOS 테크놀로지 회사의 제품이다.

1.26 마이크로프로세서를 이용한 기기의 특징을 나열한 것 중 가장 많이 틀린 것은?	(전산기 조직응용)

□ 장치의 소형화, 경량화가 가능하다.

□ 하드웨어를 적은 부품으로 통합하여 표준화할 수 있으며 제작도 합리화 할 수 있다.

□ 빠른 응답이나 대량의 자료처리에 적절하다.

□ 명령어 수준이 낮기 때문에 프로그램의 개발효율이 나쁘다.

1.27 마이크로컴퓨터에 가장 많이 쓰이는 IC 논리는 어느 것인가?	(전산기 조직응용)

□ DTL	□ RTL	□ TTL	□ ECL

1.28 더 빠른 처리 속도를 갖는 반면에 전력손실이 커서 단일 칩형 마이크로프로레서를 구성하는 기술로는 부적당한 방식은?

□ NOMS	□ C-MOS	□ TTL	□ P-MOS

1.29 마이크로컴퓨터는 대형컴퓨터나 미니컴퓨터에 비하여 어떤 이점을 가지는가?	(전산기 조직응용)

□ 소형이고 가격이 싸다.	□ 기억용량이 크다.

□ 처리속도가 빠르다.	□ 프로그램 작성이 용이하다.

1.30 일반적으로 16bit 마이크로프로세서의 단점은?(8bit에 비해서)	(전산시 조직응용)

□ 명령어의 빈약

□ 미니컴퓨터들과 소프트웨어 호환성이 없다.

□ Pin의 수가 늘어나므로 multiplexing등을 위해 시스템의 복잡도가 늘어남

□ 수행 속도가 느림

1.31 마이크로프로세서를 설명한 것 중 맞지 않는 것은?

□ 주기억장치로부터 명령을 가져오고 해석한다.

□ 연산기에 의해 논리적, 수치적 연산을 실시한다.

□ 클럭 펄스부를 반드시 내장한다.

□ 명령을 실시한다.

1.32 다음 마이크로컴퓨터에 관한 설명 중 맞지 않는 것은 어느 것인가?

□ 마이크로컴퓨터의 성능을 결정짓는 가장 중요한 회로소자는 메모리 칩이다.

□ 입.출력 장치와 보조기억장치를 일괄해서 주변장치라 한다.

□ CPU와 기억장치는 버스(bus)라는 공통배선으로 연결되어 신호를 전달한다.

□ 연산부와 레지스터부를 한데 묶어 RLAU라고도 한다.

1.33 MOS(Metal-Oxide Semiconductor)의 장점이 아닌 것은?

□ 양극성 소자(bipolar)보다 속도가 빠르다.

□ 집적도가 높다.

□ 소비전력이 양극성 소자에 비해 낮다.

□ 제조기술이 간단하고 경제적이다.

1.34 양극성 소자(bipolar)로 만든 비트 슬라이스(bit-slice) 마이크로프로세서의 잇점과 단점을 같이 묶어 놓은 것은?

□ 빠른 속도, 가격이 저렴

□ 고도의 집적도, 속도가 느림

□ 전력소비량이 적음, 낮은 집적도

□ 빠른 속도, 단일칩으로 제작이 안됨

1.35 다음 중 마이크로프로세서의 기능이 아닌 것은?

□ 명령어에 의해 산술적 논리적 연산을 실시한다.

□ 마이크로컴퓨터의 모든 부분들에 동기신호와 제어신호를 발생시킨다.

□ 기억장치와 주변기기 사이의 자료 전송을 담당한다.

□ 외부장치의 자료형태를 내부장치의 자료형식으로 변환한다.

1.36 CMOS RAM의 특징이 아닌 것은 어느 것인가?

□ 전원을 배터리 백업하여 불휘발성 IC memory로 쓸 수 있다.

□ 저소비 전력이다.

□ 스피드가 빠르다.

□ 비트 단가가 싸다.

1.1 마이크로프로세서와 마이크로컴퓨터는 어떻게 다른가?

1.2 연산용 마이크로컴퓨터와 제어용 마이크로컴퓨터(마이크로콘트롤러)는 어떻게 다른가?

1.3 마이크로콘트롤러는 연산용 마이크로컴퓨터에 비하여 어느 점을 강화하고 있는가?

1.4 MCS-51 계열 마이크로콘트롤러의 구조상 특징에 대하여 기술하라.

1.5 마이크로콘트롤러의 응용면을 3가지만 들어라.

1.6 PLC에 대하여 아는 바를 기술하라.

2.1 8051의 외형 2.2 8051의 내부 구성 2.3 CPU 2.4 프로그램 메모리 2.5 데이터 메모리 2.6 메모리 접근 방법	2.7 I/O포트 2.8 직렬포트 2.9 타이머/카운터 2.10 발진회로와 리세트 신호 2.11 이 장의 간추림

8051 및 AT89S51의 외형은 그림 2.1과 같이 40핀의 DIP형 또는 44핀의 PLCC형이다. 이들 외부핀 중 32개가 I/O 핀이고, 나머지는 전원, 클록, 리셋트 등의 핀이다. 표 2.1은 각 핀에 대한 간략한 설명이다.

그림 2.1  8051 및 AT89S51의 외관

□표 2.1  8051 및 AT89S51 핀 설명

핀이름	핀 형태	설 명	별도기능	별도기능 선택
P0.0∼P0.7	입출력	포트 0은 8비트 open drain 양방향성 I/O포트이다. 이 포트는 외부에 ROM 또는 RAM을 둘 경우에는 하위의 주소/데이터 버스로 동작한다.	AD0∼AD7	EA
P1.0∼P1.7	입출력	포트 1은 내부 풀업의 양방향성 I/O포트이다.
P2.0∼P2.7	입출력	포트 2는 내부 풀업의 양방향성 I/O포트이다. 이 포트는 외부에 ROM 또는 RAM을 둘 경우에는 상위의 주소버스로 동작한다.	A8∼A15	EA

P3.0∼P3.7	입출력	포트 3도 내부 풀업의 양방향성 I/O포트이다. 직렬포트, 인터럽트, 타이머 등의 외부 핀으로 사용되기도 하고, 외부메모리 등을 사용할 경우에는 이들에 대한 입출력 제어 핀으로 사용되기도 한다.	RxD, TxD INT0, INT1 T0, T1 WR, RD	명령으로
RST	입력	리셋 입력이다.
ALE/ PROG	출력/입력	외부 메모리에 접근하는 동안 주소의 하위 바이트를 래치하는 신호이다. 87C51의 EPROM을 프로그램할 경우에는 프로그램 펄스 입력( PROG)이 된다.	PROG	EPROM 프로그램
PSEN	출력	외부 프로그램메모리에 대한 판독 스트로브(read strobe)이다.
EA / VPP	입력	External Access enable 핀이다. 내부 프로그램 메모리를 사용할 때에는 이에 Vcc를 연결해 주고, 외부 프로그램 메모리를 사용할 때는 0V를 연결해 주어야 한다. EPROM 프로그램중에는 프로그램 공급전압(Vpp)을 여기에 인가해 주어야 한다.	Vpp	EPROM 프로그램
XTAL1 XTAL2	입력/출력	발진용 증폭기 입력 및 출력핀이다.

그림 2.2  AT89C2051의 외관

AT89C2051의 외형은 그림 2.2와 같이 20핀의 PDIP 또는 SOIC 형이다. 이들 외부 핀 중 16개가 I/O핀이고, 나머지는 전원, 클록, 리셋트 등이다. 표 2.2는 각 핀에 대한 간단한 설명이다. 8051에 비할 때 포트 0와 포트 2가 없다는 것이 다르다.

□표 2.2  AT89C2051 핀 설명

핀이름	핀 형태	설 명	별도기능	별도기능 선택
P1.0∼P1.7	입출력	포트 1은 8비트 양방향성 I/O포트이다. P1.0과 P1.1은 open drain이어서 외부 풀업이 필요하나, P1.2∼P1.7은 내부 풀업이어서 외부 풀업이 필요없다. P1.0과 P1.1은 내장의 아날로그비교기 입력(AIN0, AIN1)으로도 사용된다.	AIN0, AIN1
P3.0∼P3.7	입출력	P3.0∼P3.5와 P3.7은 내부 풀업의 양방향성 I/O핀이고, P3.6은 아날로그 비교기 출력에 대한 입력으로 hard-wired 연결되어 있기 때문에, 일반 I/O핀으로서는 사용될 수 없다. P3.0∼P3.5는 RxD, TxD등 별도 기능으로도 사용된다.	RxD, TxD INT0, INT1 T0,T1	명령
RST	입력	리셋 입력이다
XTAL1 XTAL2	입력/출력	발진용 증폭기 입력 및 출력핀이다.

제1장에서 논한 바와 같이, 마이크로콘트롤러는 입출력 능력, 인터럽트 기능, 명령어 등 만이 제어에 알맞게 개선되었을 뿐, 근본적으로는 단일 칩 마이크로컴퓨터이다. 그러므로, 마이크로콘트롤러 8051도 일반 마이크로컴퓨터와 같이 CPU, 프로그램 메모리, 데이터 메모리, I/O포트, 직렬포트, 타이머 등으로 구성되어 있다. 다만 하바드 구조의 특성상 프로그램 메모리 ROM과 데이터 메모리가 완전히 분리되어 있다는 점이 Z80과 같은 폰 노이만 방식의 마이크로콘트롤러와 다를 뿐이다.

그림 2.3  일반 마이크로컴퓨터의 구성

그림 2.4  마이크로콘트롤러 8051의 구성

이들 중 CPU는 프로그램 메모리에 들어 있는 명령어(프로그램)를 하나씩 호출해서 실행시키는 일을 하고, 프로그램 메모리 ROM은 8051의 경우 4K 바이트의 크기로서, 고정 프로그램 및 表데이터를 저장한다. 데이터 메모리 RAM은 레지스터 파일의 형태로 되어 있고, 128 바이트의 크기로서, 데이터를 일시 저장하고, I/O포트는 4개 포트에 32개 포트라인 구성으로서 병렬 I/O포트로서의 역할을 한다. 직렬포트는 비동기식 또는 동기식으로 외부와 직렬 통신을 하고, 끝으로 타이머는 16비트 타이머 2개로 구성되어 있고, 타이머 또는 카운터로서의 역할을 한다.

그림 2.5 8051의 구성

이하 8051의 CPU, 프로그램 메모리, 데이터 메모리, I/O포트, 직렬포트, 타이머 등에 대하여 하나하나 다룬다.

AT89C2051의 경우에는 전술한 바와 같이 그림 2.6과 같이 8051에 비하여 포트 0와 포트 2가 없고, 그래서 외부 메모리를 둘 수 없다. 대신 아날로그 비교기가 내장되어 있다. 아날로그 비교기는 두 전압의 크기를 비교하는 장치로서, 전압센서로도 사용될 수 있고 A/D변환기로서도 사용될 수 있다. 전술한 바와 같이, 기능적으로 AT89C2051은 ATmel社의 AT90S2313에 유사하나, 명령어로서는 8051의 것을 사용하여 8051 대용으로 사용된다.

그림 2.6 AT89C2051의 구성

CPU는 프로그램 메모리에 들어 있는 명령어를 순서대로 하나씩 호출(fetch)해서 실행(execute)시킴으로써 데이터를 처리하고, 다른 장치들을 제어하는 역할을 한다.

앞에서 언급한 바와 같이, CPU는 레지스터部, 연산部, 그리고 제어部로 구성된다.

그림 2.7  CPU가 8051에서 차지하는 위치

(1) 레지스터部

레지스터(register)는 데이터를 다른 곳으로 옮기는 일도 하지만, 주된 역할은 데이터를 일시 보존하는 일이다.

하드웨어 면에서 볼 때 레지스터는 플립플롭(D Flip-Flop)으로 이루어져 있는데, 하나의 플립플롭은 하나의 비트(bit)를 기억하는 회로이고, 이것이 8개 또는 16개 모여서 레지스터를 이룬다.

8051은 하바드 구조(Havard architecture)에 속하고 있어서 레지스터들은 데이터 메모리와 함께 레지스터 파일이라고 하는 통합된 공간에서 일괄 관리된다. 즉, Z80과 같은 폰 노이만 방식의 마이크로콘트롤러에 있어서는 레지스터와 데이터 메모리가 구분되어 있어서 자주 사용되는 것은 레지스터에, 그 밖의 것은 데이터 메모리(RAM)에 저장되지만, 하바드 구조에 속하는 8051에서는 이들을 레지스터 파일이라고 하는 통합된 공간에 같이 배치해 놓고 일관된 방법으로 접근(access)하도록 되어 있다. 따라서 레지스터와 데이터 메모리 간에 상호 전송이 필요 없고, 모든 공간을 레지스터 다루듯이 취급할 수 있다.

이상의 것을 소속면에서 보면 Z80과 같은 폰 노이만 방식의 마이크로콘트롤러에서는 □레지스터는 CPU에, 나머지는 데이터 메모리에□ 소속시키고 있지만, 8051과 같은 하버드 구조의 마이크로콘트롤러에서는 □CPU 소속의 레지스터는 원칙적으로 없고, 거의 모두를 데이터 메모리에□ 소속시키고 있다. 이에 레지스터에 관한 것은 데이터 메모리(레지스터 파일)에서 다루고자 한다.

그러긴해도 8051은 폰노이만 방식에서 완전히 탈피하지 못하여 CPU 소속의 레지스터(ACC)를 두고 이것을 통하여 데이터 전송 및 연산을 하고 있다. 예컨대 (R0←R1)의 작업을 MOV R0, R1으로 하지 못하고(MOV A, R1; MOV R0, A)로 한다.

(2) 연산부

8051의 연산부는 그림 2.8과 같이 ALU(arithmetic logical unit)를 중심으로 2개의 TMP 레지스터와 시스템 플래그 레지스터(PSW)로 구성된다. TMP 레지스터(temporary register)는 사용자가 직접 접근할 수 없는 일종의 버퍼이다.

연산부에서 하는 일은 다음과 같다.

·올림수(carry)가 없는 2진 가산 및 감산

·올림수(carry)가 있는 2진 가산 및 감산

·BCD 10진 보정

·곱셈 및 나눗셈

·AND, OR, EX-OR, 로테이트 등 논리연산

·8비트/16비트 인크리먼트 및 8비트 디크리먼트

·바이트 단위의 보수 연산 및 비트 단위의 보수(complement) 연산

·니블 단위의 데이터 교환 및 바이트 단위의 데이터 교환

·조건 분기의 판단 등

그림 2.8  8051의 연산부

(3) 제어부

제어부는 프로그램 메모리에 들어있는 일련의 명령을 순서대로 하나씩 호출해서, 그 명령의 뜻을 해독한 후, 그 뜻에 따라 8051 각 장치들을 동작시킴으로써 데이터를 명령의 내용대로 처리하는 논리회로로서, 그림 2.9와 같이 명령레지스터(instruction register), 명령해독기(instruction decoder), 그리고 제어신호기(control signal circuit)로 구성된다.

그림 2.9  마이크로프로세서의 제어부

프로그램 내장 방식에 속하는 8051에서 모든 명령은 프로그램 메모리(ROM)에 들어 있는데, 여기에 들어있는 명령들은 프로그램카운터가 지정하는 바에 따라 하나씩 호출(fetch)되어 명령해독기에서 해독(decode)된 후, 제어신호기를 거침으로써 그 명령을 실행시키는 데 필요한 각종 제어신호로 바꿔진다. 이 제어신호의 일부는 CPU와 칩 내의 회로들을 제어하고, 다른 일부는 외부 제어신호로서 밖으로 나가며, 나머지 일부는 명령해독기로 되돌아가서 다음 차례의 제어신호를 결정한다.

이 관계를 좀 더 자세히 설명하고자 한다. 그림 2.10은 마이크로콘트롤러의 기본 구조로서, Acc에 100H 번지의 내용을 가산하라는 ADD A, 100H라는 명령을 수행할 경우의 관계를 나타내고 있다. 프로그램 메모리 M에는 명령어들이 순서에 따라 연속적으로 들어 있다. 그리고 최초의 명령어가 들어 있는 주소만은 ORG 명령에 의해서 프로그램카운터 PC에 넣어져 있다. 프로그램을 실행시키면 한편으로는 다음과 같은 마이크로 동작(micro- operation)에 의해서 프로그램카운터가  지시하는 번지에 기억되어 있는 명령어가 명령레지스터 IR에 호출되고, 다른 한편으로는 프로그램카운터의 내용이 1∼3 증가하여 다음 차례의 명령을 지시한다.

[eqn: t_0]＞MAR←PC

[eqn: t_1]＞MBR←M[MAR], PC←PC+(1∼3)

[eqn: t_2]＞IR←MBR

이와 같이 프로그램 메모리에 들어 있는 명령어가 프로그램카운터의 지정에 따라 명령레지스터에 들어오는 컴퓨터 사이클을 호출사이클(fetch cycle)이라고 한다. 그리고 호출된 명령어가 실행되는 나머지 사이클을 실행사이클(excute cycle)이라고 한다. 호출사이클에 의해서 명령레지스터에 들어온 ADD A,100H라는 명령어가 실행될 때의 실행 사이클을 보기로 하자. 명령레지스터 IR에 들어온 ADD A,100H라는 명령어는 한편으로는 해독기 및 제어신호기에서 이 명령어를 실행시키는데 필요한 각종 제어신호를 만들고 한편으로는 다음과 같은 마이크로 동작으로 100H 번지의 내용을 T(TMP) 레지스터에 옮긴 후 Acc←Acc+T의 연산을 한다.

[eqn: t_3]＞MAR←IR[AD]   (단 AD=100H)

[eqn: t_4]＞MBR←M[MAR]

[eqn: t_5]＞T←MBR

[eqn: t_6]＞Acc←Acc+T

이상의 동작 과정을 순서로 표시한 것이 그림 2.10에서 ①②③… 이다. 문제는 이러한 동작이 어찌하여 일어나는가, 무엇이 이러한 동작을 일으키느냐에 있다. 한마디로 제어장

그림 2.10  마이크로프로세서의 기본 구성

치가 이러한 동작을 일으킨다. 호출사이클은 고정된 과정이고, 실행사이클은 호출된 명령이 해독기와 제어신호기를 통과하는 사이에 만들어지는 각종 제어신호에 의해서 이루어진다. 제어신호기에서 나가는 신호중에는 MBR_MAR, MBR_LD, … 등이 있다. 제어장치는 먼저 모든 신호를 0V로 하고 MBR_MAR만 5V로 한다. 그러면 그림 2.10의 맨 위에 있는 MBR_MAR만 열려서 마이크로 동작 t3＞MAR←IR[AD]가 이루어진다. 다음 순간 모든 신호를 0V로 한채 MBR_LD만 5V로 한다. 그러면 마이크로 동작 t4＞MBR←M[MAR]가 이루어진다. 다시 다음 순간 모든 신호를 0V로 하고 T_LD만 5V로 한다. 이로써 t5＞T←MBR가 이루어진다. 마지막으로 모든 신호를 0V로 하고 Add_LD와 Acc_LD만을 5V로 한다. 이로써 t6＞Acc←Acc+T가 이루어진다. 이렇듯 제어신호기에서 나오는 제어신호에 의해서 차례로 마이크로 동작이 이루어져서 ADD A,100H의 명령이 실행된다.

제어장치는 제어신호를 PLA(programmed logic array)와 같은 고정배선회로에서 얻느냐, 아니면 제어용 ROM에서 얻느냐에 따라 고정배선方式(hard-wired control)과 마이크로프로그램方式(microprogrammed control)으로 분류되는데, 8051의 제어부는 고정배선方式에 속한다.

여러번 언급한 바와 같이, 8051은 하바드 구조에 속하고 있어서 프로그램 메모리와 데이터 메모리가 엄격히 구분되어 각각 따로 존재한다.

8051의 프로그램 메모리는 ROM으로 되어 있다. 한편 다음에 다룰 데이터 메모리(레지스터 파일)는 SRAM으로 되어 있다.

다음은 8051의 경우에 이들을 비교해 놓은 것이다.

□표 2.3  프로그램 메모리와 데이터 메모리 비교

	프로그램 메모리	데이터 메모리 (레지스터 파일)
소 자	ROM	SRAM
크 기	4K 바이트	128 바이트
용 도	프로그램 및 表데이터를 저장	데이터만을 저장
종 류	내부 ROM 외부 ROM	내부 RAM 외부 RAM

그림 2.11  프로그램 메모리가 8051에서 차지하는 위치

프로그램 메모리는 ROM으로 이루어지는데, ROM(read only memory)은 판독(read) 전용의 메모리로서, 固定프로그램(특수한 경우에는 表데이터도)을 저장하는 데 사용된다. 그림 2.12는 ROM의 중심부이다. 번지선택회로(decoder)에서 예컨데 0번지가 선택되면 D7∼D0에는 01001000이라는 명령코드(op code)가 출력되고, 7번지가 선택되면 10010000이라는 명령코드가 출력된다.

원래 ROM은 이것에 프로그램을 기록하는 방법에 따라 마스크 ROM, PROM, EPROM, EEPROM, 플래시 메모리 등으로 분류되는데, 8051은 내부 ROM으로서 마스크 ROM (masked ROM)을 쓰고, 8751은 EPROM(Erasable PROM)을 쓴다. 그리고 8031은 내부 ROM이 아예 없고 모두 외부 ROM에 의존한다. 외부 ROM은 마스크 ROM이든 PROM이

그림 2.12  ROM의 핵심부

든 EPROM이든 플래시 메모리든 상관없다.

AT89C2051의 ROM은 플래시 메모리이다. 플래시 메모리(Flash Memory)는 EEPROM보다 한층 진보된 전기소거 가능의 ROM으로, ／5V 단일전원으로도 기록이 가능하고 타깃 시스템에 꽂은 상태에서도 기록이 가능하나 1,000∼10,000회 정도밖에 기록할 수 없는 단점이 있다.

8051에서 사용되는 마스크 ROM은 사용자의 요구에 따라 ROM 반도체 회사가 제조하는 것으로, 제조시 마스크(기록하는 정보에 따라 상이한 패턴을 가지는 엷은 막)를 사용한 데서 이러한 이름이 붙었다. 한 번 기록한 것은 자외선이나 전기로 다시 기록할 수 없다.

8051 내장 ROM의 크기는 4K(8052의 경우에는 8K) 바이트인데, 그 중 03H 번지에서 33H까지 48 바이트는 □인터럽트 벡터□라고 해서 인터럽트가 발생할 때 뛰어가는 번지(vector address)를 위한 공간으로 사용된다(그림 2.14 참조). 하나의 인터럽트 벡터에 8 바이트가 배정되어 있으므로, 간단한 인터럽트 서비스 루틴은 여기에 작성하지만 대개의 경우는 이곳에 JMP 명령을 두어 다른 공간으로 뛰어가서 처리하도록 되어 있다. 일반적으로 하나의 프로그램에서 한 두 개의 벡터만을 사용하므로 나머지 공간은 사용되지 않게 되는데, 사용되지 않는 이 공간은 다른 공간과 마찬가지로 정상적인 프로그램 메모리로 사용될 수 있다. 그러나, 이들 벡터 공간을 사용할 경우에는 현재 사용되고 있는 벡터 번지에 덮어 쓰는 일이 없도록 각별히 주의를 해야 한다.

프로그램 메모리의 처음 3 바이트는 □리세트 벡터□이다. 이것은 전원이 투입된다든가 리셋을 할 때 프로그램이 시작되는 번지이므로, 프로그램 초두에는 예컨대 다음과 같은

그림 2.13  8051의 프로그램 메모리

그림 2.14  프로그램 메모리의 하위부

명령들을 둠으로써 프로그램의 시작점을 지시해 주어야 한다.

ORG	0H

JMP	START

START＞	MOV	P1, #11H

□

지금까지는 8051에 내장되어 있는 4K 바이트의 프로그램 메모리에 대해서만 논하였다. 그러나 8051에서는 4K 바이트의 내장 프로그램만을 사용하는 대신 최대 64K 바이트의 외부 프로그램 메모리를 사용할 수도 있다.

내부 ROM만을 사용하느냐, 아니면 외부 ROM을 사용하느냐는 8051 외부 핀중 하나인 EA로 제어한다. EA(External Access)를 H레벨, 즉 ／5V로 하면 내부 ROM이 선택되고, 이 때 주소공간(address space)은 0000H에서 0FFFH까지 4K이다. 그러므로 프로그램이 4K바이트 미만이어서 내부 ROM 만을 사용하는 경우에는 EA핀을 ／5V에 연결해야 한다. 이 경우에는 맨 끝의 번지인 0FFFH 번지의 내용을 FFH로 해야 한다. 그러지 않으면 포트 P0 및 P2에 어드레스가 호출되어 오동작을 하게 된다. 한가지 유의해야 할 것은 EA를 H레벨로 할지라도 외부 ROM이 장착되어 있고 MOVC A, @A+DPTR와 같은 명령으로 1000H 번지 이상을 호출할 경우에는 자동적으로 외부 확장 ROM에 접근된다는 것이다.

한편 EA를 L레벨, 즉 접지를 해두면 외부 확장 ROM이 선택된다. 그러므로 ROM이 내장되어 있지 않은 8031을 사용할 때에는 반드시 EA를 접지해 두어야 한다. 그림 2.13은

EA를 H레벨로 하느냐 L레벨로 하느냐에 따라 선택되는 프로그램 메모리를 나타내고 있다.

그림 2.15는 외부에 프로그램 메모리를 장착할 경우에 대한 불록선도이고, 그림 2.16은 i2764(8K×8 EPROM)를 프로그램 메모리로서 장착한 시스템에 대한 구체적인 회로도이다. 이 경우에 주소(address)는 P2(A15∼A8)와 P0(AD7∼AD0)를 통하여 보내고, 명령어는 P0(AD7∼AD0)를 통하여 받는다.

그림 2.15  외부 확장 프로그램 메모리의 블록선도

그림 2.17은 외부에 프로그램 메모리를 둘 경우 이로부터 명령을 호출하는 데 필요한 신호와 타이밍을 보이고 있다. 이 그림에서와 같이, 포트 2는 상위 어드레스(A15∼A8)를

그림 2.16  intel 2764(8K×8 EPROM)을 외부 확장 프로그램 메모리로서 장착한 시스템의 회로도

출력하는 일을, 포트 0은 하위 어드레스(A7∼A0)를 출력하는 일과 외부 프로그램 메모리에 들어있는 명령어를 입력하는 일을 번갈아 한다. 상위 어드레스와 하위 어드레스는 PSEN이 high일 때 출력되고, 그 중 하위 어드레스는 ALE(address latch enable)의 하강에지에서 어드레스 래치(address latch)에 래치된다. PSEN(progam store enable)은 외부 프로그램 메모리에서 명령어를 호출할 때에만 동작한다.

그림 2.18은 이 관계를 좀 더 자세히 나타내고 있다. 그림 2.18에서 (A)는 외부 데이터 메모리에 접근하지 않는 경우이고, (B)는 명령의 호출과 함께 MOVX 명령으로 외부 데이

그림 2.17  외부 프로그램 메모리에서 명령을 호출할 때의 신호와 타이밍

터 메모리에서 데이터도 함께 입출력하는 경우이다. (A)의 경우, 즉 순전히 명령어만을 외부 프로그램 메모리에서 읽어드리는 경우에는 PSEN 신호가 하나의 기계사이클당 두 개씩 있지만, (B)의 경우, 즉 명령어 호출과 함께 외부 데이터 메모리에서 데이터도 읽어드리는 경우에는 PSEN이 두 번 건너뛴다. 이 기간 동안에 외부 데이터 메모리에서 데이터를 읽어오기 위함이다. 데이터를 읽어오는 데는 명령을 읽어오는 것보다 2배의 시간이 필요하다. 데이터를 읽어오는 경우 외에 데이터를 기록(write)하는 경우에도 같다.

그림 2.18에서 기계사이클(machine cycle)에 대해서 집고 넘어갈 필요가 있겠다.

일반적으로 하나의 명령을 호출(fetch)해서 실행(excute)시키는 데 필요한 시간을 명령사이클(instruction cycle)이라고 하는데, 하나의 명령사이클은 1∼4개의 기계사이클로 이루어지고, 하나의 기계사이클은 6개의 상태사이클(state cycle)로 이루어지며, 하나의 상태사이클은 2개의 T사이클(T cycle)로 이루어진다. T사이클은 클록사이클이다. 그러므로 외부 발진주파수가 12MHz이면 t=1/f의 관계에서 T사이클은 1/12□초이고, 상태사이클은 1/6□초이며, 기계사이클은 1□초이다. 그리고 명령사이클은 1∼4□초이다.

그림 2.18  외부 프로그램 메모리에서 명령을 호출할 때의 타이밍 상세도

수차 언급한 바와 같이, 8051은 그 구조가 하바드형으로 되어 있어서, 프로그램 메모리와 데이터 메모리가 따로 존재하는데, 데이터 메모리는 RAM으로 되어 있다. RAM은 내부 RAM과 외부 RAM으로 구분되고, 그 중 내부 RAM은 레지스터 파일로 사용된다. 즉, 8051에 있어서는 내부 RAM 자체가 레지스터 파일이다.

바꿔말해서, RAM(Random Access Memory)은 원래 사용자의 프로그램이나 데이터를 기억 또는 판독하는 장치이나, 8051의 경우에는 하바드 구조상 내부 RAM은 데이터만을 기억, 판독하는 레지스터파일로 동작하는 것이다.

그림 2.19  플립플롭과 레지스터와 RAM의 관계

기억장치의 기본 단위는 하나의 비트를 기억하는 회로, 즉 플립플롭이다. 이 플립플롭을 8개 또는 16개 한 묶음으로 해 놓은 것이 레지스터이고, 이러한 레지스터들을 병렬적으로 나열해 놓은 것이 RAM이다. 즉, RAM은 레지스터 하나하나가 모여서 이루어진다. 그리고 이들 각각의 레지스터에는 그림 2.20과 같이 번지(address location)가 붙는다. 각 가옥에 번지가 붙는 이치와 같다.

하나의 번지에 들어갈 수 있는 비트 수는 기종에 따라 다르나, 8051은 8비트이다.

앞에서 RAM은 레지스터들이 병렬적으로 나열되어 있는 것이라고 하였다. 그러나 RAM에는 이 외에도 그림 2.21과 같이 번지선택회로(decoder)와 버퍼와 제어회로가 필요하다. 번지선택회로는 어떤 특정의 번지를 선택하기 위해서 필요하고, 버퍼(buffer)는 선택된 특정 번지의 내용을 잠시 보존하기 위해서 필요하다. 그리고, 제어회로는 RAM을 선택하는

그림 2.20  기억번지

그림 2.21  RAM의 블록선도

데 필요한 칩 선택선과 판독할 것인지 기록할 것인지를 제어하는 R/W 선을 위해서 필요하다.

8051의 데이터 메모리 RAM은 그림 2.22와 같이 내부 RAM과 외부 RAM으로 분류되는데, 내부 RAM은 256(00H∼FFH) 바이트이고, 외부 RAM은 최대 64K(0000H∼FFFFH) 바이트이다. 내부 RAM에 대해서는 조금 뒤에 설명하기로 하고, 먼저 외부 RAM부터 보기로 한다.

8051은 최대 64K 바이트의 데이터 메모리를 외부에 둘 수 있다. 이 경우에 외부 데이터 메모리의 주소를 지정하는 방법에는 1바이트를 쓰는 것과 2바이트를 쓰는 것이 있는데, 2바이트를 쓰는 방법에서는 그림 2.15와 유사하게 P0와 P2를 통하여 주소(address)를 지정하고, 1바이트를 쓰는 방법에서는 P0를 통하여 하위 주소를 보내고 P2의 몇 개 라인으로 페

그림 2.22  8051의 데이터 메모리

이지를 지정한다.

먼저 2바이트를 쓰는 방법부터 보기로 한다. 이 경우 8051과 외부 데이터 메모리와의 하드웨어 연결은 프로그램 메모리에서 설명한 그림 2.15와 동일하다. 다만 EPROM 대신 RAM을 쓰고, WR 선이 더 있을 뿐이다. 그림 2.16의 상위부는 외부 데이터 메모리를 둘 경우의 구체적인 회로도이다. 이 때 관여하는 신호와 그 타이밍은 그림 2.23 및 그림 2.24와 같다. 프로그램 메모리에 관한 앞의 그림들과 비교컨대 PSEN 은 사용되지 않고, RD, WR가 데이터의 방향을 지정하는 데 사용되는 것이 다를 뿐이다.

외부 데이터 메모리의 주소를 지정하는 방식으로 2바이트를 쓰는 경우에 대해서는 이정도로 하자. 이제 1바이트를 쓰는 방법을 보기로 한다.

그림 2.23  외부 데이터 메모리 read cycle

그림 2.24  외부 데이터 메모리 write cycle

그림 2.25는 페이지 방식을 쓰는 2K바이트의 외부 데이터메모리에 대한 블록선도이다. 이 경우에도 포트 P0는 외부 RAM으로 가는 하위 주소버스와 데이터버스로서의 역할을 번갈아(multplex)한다. 즉 먼저 주소정보(A7∼A0)를 P0를 통하여 보내서 그것을 래치에 잡아놓고, 다음 순간에 데이터정보(D7∼D0)를 주거나 받는다. 이 때 P2의 3개선은 RAM을 페이징(paging)하는 데 사용된다. 즉, 8개의 하위 주소버스(A7∼A0)에 의해서 선택되는 데이터 메모리 공간은 256 바이트인데, 이것을 단위(page)로 해서 page 0에서 page 7까지 8개의 공간을 만들고 페이지 중심으로 데이터 메모리 공간을 사용한다.

어느 경우에도 외부 RAM이 접근되고 있는 동안 CPU는 RD 또는 WR 신호를 P3.7과 P3.6을 통하여 출력한다.

외부 RAM은 특별한 경우를 제외하고는 쓰지 않는다. 또한 AT89C2051에는 아예 이것

그림 2.25  2K 바이트의 외부 RAM 연결

이 없다. 아무튼 이에 대한 설명은 이 정도로 하고, 이제 내부 RAM을 보기로 한다. 8051의 내부 RAM은 그림 2.26과 같이 2개의 불록으로 되어 있다.

·하위 128바이트의 범용레지스터

(8052의 경우에는 상위 128바이트의 데이터 메모리를 포함해서 이 영역이 256 바이트임)

·상위 128바이트의 특수기능레지스터

그림 2.26  내부 RAM의 구성

2.5.1 범용레지스터

하위 128 바이트의 데이터 메모리는 범용레지스터에 속한다. 범용레지스터(general purpose register)는 이렇게도 쓸 수 있고, 저렇게도 쓸 수 있는 레지스터라는 뜻으로서 특수기능레지스터(SFR)에 대한 개념이다. 범용이라고는 하나, 실은 프로그램 수행중의 각종 데이터를 일시적으로 저장하는 데 주로 사용되는데, 이처럼 프로그램 수행중의 중간 결과나 기타 각종 데이터를 저장하는 데 사용되는 데이터 메모리내의 레지스터를 속칭 스크랫치패드(scratch pad)라고 한다.

8051의 범용레지스터는 그림 2.27과 같이 다시 3개 부분으로 되어 있다.

·레지스터 뱅크 공간(00H∼1FH)

·비트 주소지정 공간(20H∼2FH)

·자유 공간(30H∼7FH)

레지스터 뱅크 공간(register bank space)에는 4개의 레지스터 뱅크가 있고, 각 뱅크에는 R0∼R7의 8개 워킹레지스터(working register)가 있다. 이들 4개의 레지스터 뱅크는 PSW의 두 비트(RS1과 RS0) 값에 따라 선택되는데, 특별히 어느 뱅크를 선택하지 않으면 뱅크 0이 선택된다(default).

그림 2.27  내부 RAM의 하위 128 바이트

뱅크내의 이들 워킹레지스터는 Acc와 직접 데이터를 주고 받을 수 있고, 이들 중 R0과 R1은 RAM의 주소를 간접 지정할 수도 있다.

MOV  A, R0

MOV  A, @R0

레지스터 뱅크를 사용할 때의 주의사항은 CALL이나 PUSH 명령을 사용하면 스택 영역이 자동적으로 08H 번지로부터 확보된다는 것이다. 그러므로 뱅크 1∼3을 사용해야 할 경우에는 예컨대 다음과 같은 명령으로 스택 영역을 30H 이후로 설정해야 한다.

MOV  SP,#70H

비트주소지정 공간(bit-addressable space)은 20H에서 2FH까지의 16바이트로서, 여기에는 비트 단위로 번지(bit address location)가 지정되어 있어서, 그 중 어느 비트 번지의 내용을 다음과 같은 명령으로 세트 또는 클리어할 수 있다. 비트 단위의 리셋 명령은 없다. 일반 CLR 명령으로 클리어해야 한다.

SETB  bit       단, bit=비트 주소의 값(00H∼7FH)

CLR    bit

비트 주소로 직접 표시하는 대신 □바이트 주소의 몇번째 비트□ 형태로 비트 지정을 할 수도 있다. 예컨대 비트 주소 3 대신 바이트 주소 20H의 3번째 비트로 표시하기도 한다.

SETB  20H.3

CLR   20H.3

비트주소지정 공간도 비트주소로 사용하지 않는 경우에는 자유공간처럼 바이트 주소 공간으로 사용할 수 있다.

자유 공간(free space)은 비트주소지정 공간 위에 있는 주소 공간(30H∼7FH)으로서, 직접 주소지정방식 또는 간접 주소지정방식으로 접근할 수 있다. 여기에는 일반 데이터를 저장할 수도 있고, 앞에서 밝힌 바와 같이 스택 영역으로도 사용할 수 있다.

MOV  A,40H

또는

MOV  R0, #40H

MOV  A, @R0

2.5.2  특수기능레지스터(SFR)

8051 내부 RAM의 80H에서 FFH까지의 128 바이트는 특수기능레지스터의 영역으로, 여기에는 직접 주소지정방식에 의해서만 접근할 수 있고, 이들 중 일부는 비트 주소지정도 가능하다.

MOV  A, 90H(또는 MOV  A,P1)

SETB  90H.2(또는 SETB P1.2)

특수기능레지스터(SFR Special Function Register)에 속하는 레지스터들은 다시 다음과 같이 크게 두 부류로 분류된다.

·소프트웨어 제어 및 연산에 사용되는 레지스터

·내장된 주변장치의 기능을 제어하는 데 사용되는 레지스터

소프트웨어 제어 및 연산에 사용되는 레지스터에는 Acc, B, DPTR, PSW, SP 등이 있고, 내장된 주변장치의 기능을 제어하는 데 사용되는 레지스터에는 타이머/카운터용으로서 TH1, TL1, TH0, TL0, TCON, TMOD, 직렬포트용으로서 SBUF, SCON, PCON, 인터럽트 제어용으로서 IE와 IP, 병렬 I/O포트용으로서 P0, P1, P2, P3가 있다.

그림 2.28은 이들 특수기능레지스터들이 내부 RAM의 80H번지에서부터 FFH번지까지에   할당되어 있는 모양을 나타내고 있다. 빈 공간은 차후의 버전을 위해서 남겨 놓은 것들이다. 그리고 반흑 부분은 8051에는 없고 8052에만 있는 것들이다. 또 맨 왼쪽 열의 B, Acc, PSW, IP, IE, P3, P2, P1, P0, SCON, TCON 등은 비트 주소지정이 가능한 것들이다.

AT89S51 및 AT89C2051은 8051에 호환적(compatible)이므로 특수기능레지스터도 8051과 같다.

(주소) F8									(주소) FF
F0	B								F7
E8									EF
E0	ACC								E7
D8									DF
D0	PSW								D7
C8	T2CON		RCAP2L	RCAP2H	TL2	TH2			CF
C0									C7
B8	IP								BF
B0	P3								B7
A8	IE								AF
A0	P2								A7
98	SCON	SBUF							9F
90	P1								97
88	TCON	TMOD	TL0	TL1	TH0	TH1			8F
80	P0	SP	DPL	DPH				PCON	87
□ 비트 지정 가능 ※ 반흑부분은 8052에만 있음

그림 2.28  특수기능레지스터(SFR)

(1) Acc(accumulator)

이것은 연산의 중심이 되는 레지스터이다. 즉, 이 레지스터는 데이터의 처리와 논리 기능의 중심이 되며, CPU의 일시적 기억장소가 된다. 8비트 레지스터이고, 8051 명령어에서는 A로 표시된다.

MOV A, #23H

(2) B레지스터

이 레지스터는 곱셈 및 나눗셈에서 어큐뮬레이터와 함께 사용되고, 기타의 명령어에서는 범용 레지스터로 사용된다.

MUL  AB ; (※ MUL A, B가 아님에 유의하라)

DIV   AB

MOV  B, A

(3) DPTR(Data Pointer Register)

이 레지스터는 그림 2.28의 82∼83 번지와 같이 상위 바이트 DPH와 하위 바이트 DPL로 구성되어 있다. 보통 하나의 16비트 레지스터로 사용되나, 때로는 2개의 8비트 레지스터로 사용되기도 한다. 이 레지스터는 대개의 경우 외부 데이터 메모리에서 데이터를 전송(read/write)할 때 데이터가 들어 있는 주소를 지정하는 data pointer로 사용되지만(예 : MOVX A, @DPTR), 레지스터 간접 점프에서는 주소값을 저장하기도 하고(예 : JMP @A+DPTR), 프로그램 메모리 내에 있는 표(table) 참조의 명령에서는 베이스 레지스터가 되기도 한다(예 : MOVC A, @A+DPTR).

(4) PSW(Program Status Word)

이 레지스터의 각 비트는 역시 그 자신 하나의 플립플롭(memory cell)으로서, 산술연산이나 논리연산, 기타의 명령어가 실행된 후의 CPU 상태를 비트별로 나타낸다. 예컨대, 두 수의 덧셈 명령이 실행된 결과 올림수(carry)가 발생하면 그림 2.29의 비트 7(CY)이 1로 세트되고, 오버플로(overflow)가 발생하면 비트 2(OV)가 1로 세트된다. 산술연산에서 비트 3의 자리에서 올림수가 발생되어 비트 4의 자리로 올라가면 비트 6(AC)이 세트되고, 어큐뮬레이터의 내용에서 1의 수가 홀수이면 비트 0(P)이 세트된다. 비트 4와 비트 3은 RS1과 RS0로 표시되고, 이들은 전술한 바와 같이 레지스터 뱅크(register bank)를 선택하는 데 사용된다. 이들 비트의 내용에 따라 선택되는 레지스터 뱅크는 다음과 같다.

RS 1	RS 0	선택되는 레지스터 뱅크
0	0	0
0	1	1
1	0	2
1	1	3

그림 2.29  PSW의 구성

레지스터를 선택하는 8051 명령은 SETB와 CLR이다. 예컨대, 레지스터 뱅크 1을 선택하는 명령은 다음과 같다.

SETB	RS0 (또는 SETB  PSW.3)

CLR   RS1 (또는 CLR   PSW.4)

끝으로, 범용 플래그 F0는 사용자가 일반 목적으로 사용하는 비트 플래그이다.

SETB  F0 (또는 SETB  PSW.5)

(5) SP(Stack Pointer)

전술한 DPTR는 데이터가 들어 있는 주소를 지시하는 data pointer이고, 후술하는 프로그램카운터는 다음번에 실행될 명령어의 주소를 지시하는 instruction pointer임에 반하여, 스택포인터는 서브루틴 콜 또는 인터럽트 발생시 PUSH나 POP할 위치(address)를 지시하는 스택 위치 pointer이다. PUSH 또는 CALL 명령을 수행할 때에는 데이터를 저장하기 전에 그 값을 하나 증가하고(즉 8051의 SP는 위로 성장한다), POP 또는 RET 명령을 수행할 때에는 SP가 지시하는 주소에서 데이터를 가져간 후 그 값을 하나 감소한다.

8051의 경우 SP는 8비트 레지스터이므로, 명령어의 오퍼랜드도 바이트 단위이다.

MOV  SP, #70H

8051의 SP는 반드시 내부 RAM에만 두어야 하는데 내부 RAM중 어느 곳에도 둘 수 있지만, 리셋후에는 07H로 자동 설정된다(default). 그러므로, 리셋 후에는 따로 지정하지 않는한 스택 영역이 08H에서부터 시작된다. 그런데, 내부 RAM의 08H 번지는 레지스터 뱅크1의 영역이므로 뱅크 1 이상의 레지스터를 사용할 경우에는 예컨대 MOV SP,#70H와 같은 명령으로 스택 영역을 옮겨야 한다.

(6) 타이머용 레지스터

그림 2.28에서 88H 번지에서 8DH 번지까지에 내장되어 있는 (TH0, TL0), (TH1, TL1), 그리고 TCON과 TMOD가 이에 속한다. 이들은 두 개의 16비트 타이머/카운터를 사용하는 데 필요한 것들로서, 후에 자세히 논한다.

같은 그림의 C8H 번지에서부터 내장되어 있는 T2CON, RCAP2L, RCAP2H, TL2, TH2 등은 8051에는 없고, 8052에만 있는데, 이들은 타이머2를 사용할 때 필요하다.

(7) 직렬포트용 레지스터

직렬포트용 레지스터에는 직렬포트를 제어할 때 사용되는 SCON(Serial Port Control Register)과 보율(baud rate)을 제어하는데 사용되는 PCON(Power Control Register), 그리고 송수신 버퍼로 사용되는 SBUF(Serial Data Buffer) 등이 이에 포함된다. 이들에 대해서도 후에 자세히 논한다.

(8) 인터럽트 관련 레지스터

8051에는 두 개의 외부 인터럽트, 두 개의 타이머 인터럽트, 한 개의 직렬 포트 인터럽트 등 다섯 개의 인터럽트 소스(interrupt source)가 있는데, 이들 인터럽트의 마스크에 사용되는 IE(Interrupt Enable register)와 우선순위의 지정에 사용되는 IP(Interrupt Priority register)가 이에 속한다. 이들에 대해서도 후에 자세히 논한다.

(9) I/O포트 관련 레지스터

이들은 4개의 병렬 I/O포트 P0, P1, P2, 그리고 P3의 래치(latch)이다. 이들에 대해서도 후에 논한다.

2.5.3  프로그램카운터

이상과 같은 레지스터 외에도 8051 레지스터에는 프로그램카운터가 있는데, 이것은 특수기능레지스터(SFR) 영역에도 포함되지 않고, 레지스터 뱅크 영역에도 포함되지 않는다. 모든 마이크로콘트롤러에 공통된 하나의 회로인데, 구태어 그 소속을 논한다면 CPU에 소속된다고 할 것이다.

프로그램카운터(program counter)는 16비트 레지스터로서, 다음번에 실행될 명령어가 들어 있는 주소(address)를 지시하는 일을 한다.

프로그램카운터는 다른 레지스터와는 달리 주소를 지정한 후에는 그 내용이 명령어에 따라 1∼3만큼 자동 증가된다. 프로그램카운터의 최초의 값을 설정하는 일은 어셈블리어 프로그램에서는 ORG라는 의사명령으로 프로그래머가 지정하고, C와 같은 고급언어의 프로그램에서는 로더(loader)라는 시스템 프로그램이 적당히 지정한다.

8051의 경우 리셋 후에 프로그램카운터는 0으로 된다(default). 이 때문에 프로그램은 0번지에서부터 시작된다. 그러므로 프로그램의 초두에는 JMP 명령을 두어서 실제 프로그램이 들어 있는 최초의 번지로 뛰어가야 한다. 그러나, 대개의 트레인 키트는 0번지에 예컨대 JMP START와 같은 명령을 두어서 사용 가능한 메모리 영역의 최초 번지로 뛰도록 되어 있다. 여기서 START는 실제 프로그램의 시작번지이다.

리셋 후의 프로그램카운터 값과 관련하여 특별히 유념해야 할 것은 트레인키트의 경우에는 메이커에 따라 이 값이 다르다는 것이다. 더러는 8000H인 것도 있고, 더러는 4000H인 것도 있으며, 더러는 2000H인 것도 있고, 더러는 0H인 것도 있다. 뿐만 아니라 같은 회사제품이라도 모델에 따라 다르다. 예컨대 같은 마이다스 엔지니어링 제품이라고 해도 MDE-8051에서는 2000H이지만, MDA-WIN8051에서는 0H이다. 그러므로 반드시 구입한 제품의 설명서를 읽고 ORG를 설정해야 한다. 예컨대 리셋 후의 프로그램카운터가 2000H인 제품에서는 다음과 같이 ORG를 설정해 두어야 한다.

ORG	2000H

JMP	START

＞

이 장 마지막에 있는 표 2.1은 리셋후 특수기능레지스터들의 초기값을 망라한 것이다. 이들 값을 알아야 할 경우가 더러 있다.

앞에서 밝힌 바와 같이 8051 메모리는 크게 프로그램 메모리와 데이터 메모리로 분류되고, 데이터 메모리는 다시 내부 RAM과 외부 RAM으로 분류되는데, 내부 RAM은 다시 직접 주소지정방식으로 접근(access)할 수 있는 영역과 간접 주소지정방식으로 접근할 수 있는 영역, 그리고 비트 주소지정이 가능한 영역으로 분류된다. 그런데, 이들 메모리 영역에 접근하는 명령이 메모리 종류에 따라 모두 다르다.

2.6.1 프로그램 메모리(code memory)

프로그램 메모리에 있는 표 데이터에 대해서는 그것이 내부 ROM에 있건 외부 ROM에 있건 간에 프로그램 메모리 전용명령인 MOVC  A,@A+DPTR 또는 MOVC  A,@A+PC를 사용하여 접근한다.

MOV    DPTR, #1234H

MOV    A, #03

MOVC  A, @A+DPTR   ; (A+DPTR)번지의 내용을 A에 옮겨라

MOVC A, @A+DPTR은 주로 표데이터를 읽어들일 때 쓰는 것으로써, C에서는 다음과 같이 일차원 배열문 table[]를 쓴다.

O_data = table[offset];

2.6.2  내부 RAM(data/idata memory)

내부 데이터 메모리에는 직접 주소지정방식 또는 간접 주소지정방식으로 접근한다. 그림 2.27과 같이 00H∼7FH 번지의 내부 RAM(범용레지스터)에는 MOV A,70H와 같이 직접 주소지정방식으로 접근할 수도 있고, MOV A, @R1과 같이 간접 주소직정방식으로 접근할 수도 있다. 그러나 8052에 있는 80H∼FFH 번지의 내부 RAM(범용레지스터)에는 간접 주소지정방식으로만 접근할 수 있다.

MOV   R1, #90H	(8052의 경우 80H∼FFH 번지에 접근할 때)

MOV   A, @R1

그림 2.28과 같은 80H∼FFH 번지의 특수기능레지스터 SFR에는 직접 주소지정방식으로만 접근할 수 있다.

MOV   A, 90H(또는 MOV  A,P1)

C에서는 다음과 같이 직접 주소지정방식으로 표시한다.

i_data = P1;

2.6.3  외부 RAM(xdata/pdata memory)

앞에서 밝힌 바와 같이, 외부 데이터 메모리에 접근할 때에는 2바이트 어드레스로 주소지정을 하는 방법이 있고 1바이트 어드레스와 페이지 정보로 주소지정을 하는 방법이 있다. 2바이트 어드레스로 할 경우에는 전용 명령어 MOVX A,@DPTR로 접근한다.

MOV    DPTR,#8000H

MOVX   A, @DPTR  (8000H 번지의 내용을 Acc에)

1바이트 어드레스와 페이지 정보로 주소지정을 하는 경우, 즉 그림 2.25와 같이 페이지된 외부 데이터 메모리에 접근하는 경우에는 MOVX A, @Rn로 접근한다.

MOV    R1, 0F3H  (0F3H 번지의 내용을 R1에)

MOVX A, @R1 (R1이 지시하는 번지의 내용을  Acc에)

2.6.4  비트 주소지정 영역(bdata memory)

역시 앞에서 밝힌 바와 같이 내부 RAM의 20∼2FH 번지는 비트 주소지정 공간인데, 이 영역에 접근하여 비트 주소지정을 하고자 할 경우에는 바이트 주소에 점을 찍든지, 비트 주소를 직접 지정한다.

SETB   20H.3

SETB   03H

또한 전술한 바와 같이 그림 2.28의 특수기능레지스터 SFR 중 제1열에 있는 Acc, B, PSW, IP, IE, SCON, PCON, P0, P1, P2, P3 등도 비트 주소지정이 가능하므로, 점을 찍고 비트번호를 지정하든지 비트 이름을 지정함으로써 비트주소에 접근할 수 있다.

SETB   IE.7  (또는 SETB  EA)

CLR    IE.7  (또는 CLR  EA)

C에서도 비트 주소지정을 허용하고 있다.

EA =1;

EA=0;

표 2.4는 각 메모리 영역에 접근하는 방법을 종합한 것이다.

□표 2.4  메모리 종류에 따른 접근 방법

메모리 형태	메모리 영역	명령 형태
code	program memory(64K byte) 프로그램 메모리(외부ROM 또는 내부 ROM)	MOVC A,@A+DPTR MOVC A,@A+PC
data	Direct addressable internal data memory 직접 주소지정방식으로 접근할 수 있는 00H∼7FH의 내부 RAM과 SFR	MOV A,70H

idata	Indirectly addressable internal data memory 8052에서 간접 주소지정방식만으로 접근할 수 있는 80H∼FFH의 내부 RAM, 그리고 8051 또는 8052에서 직접 주소지정방식으로 접근하는 것이 원칙이나 간접 주소지정방식으로도 접근할 수 있는 00H∼7FH의 내부 RAM	MOV A,@Rn (단, Rn=R0 또는 R1)
xdata	External data memory 2 바이트 어드레스로 주소가 지정되는 외부 데이터 메모리(64k바이트)	MOVX A,@DPTR
pdata	Paged external data memory 1 바이트 어드레스와 3비트 페이지 정보로 주소가 지정되는 페이지된 외부 데이터 메모리(페이지 된 256바이트)	MOVX A,@Rn (단, Rn=R0 또는 R1)
bdata	Bit-addressable internal data mamory 비트 주소지정이 가능한 20H∼2FH의 내부RAM 또는 SFR(Acc, B, PSW, IP, IE, SCON, PCON, P0, P1, P2, P3)	SETB 20H.3 CLR 20H.3 SETB P1.4 CLR P1.4

I/O포트(Input/Ouput Port)는 I/O 인터페이스라고도 하는 것으로, 입출력장치와 CPU 사이에 존재하여 이들 간에 데이터의 전송이 원활하게 이루어지도록 하게 하는 역할을 한다.

입출력장치를 CPU에 연결할 때 직접 연결할 수 있으면 좋겠으나, 일반적으로 그럴 수가 없다.

첫째로, 속도가 맞지 않는다. 일반적으로 입출력장치의 속도는 CPU의 속도에 비교가 되지 않을 정도로 느리다.

둘째로, 전압 레벨이 맞지 않는다. 입출력장치의 전압 레벨은 기종에 따라 각양각색이다.

셋째로, 전송 사이클(transfer cycle)의 길이가 맞지 않는다. 상당수의 입출력장치는 기계장치이기 때문에 전송 사이클의 길이가 길다.

이와 같은 것들을 서로 맞게 하기 위해서 CPU와 입출력장치 사이에 특별한 하드웨어를 만들어 넣어야 하는데, 이것을 I/O포트 또는 I/O인터페이스라고 하는 것이다.

그림 2.30은 I/O포트가 8051에서 차지하는 위치를 나타내고 있다.

Z80과 같은 멀티 칩 마이크로컴퓨터에 있어서 I/O포트는 인텔의 PPI, 자이로그의 PIO, 모토롤라의 PIA와 PI/T, 시너텍스의 VIA 등의 이름으로 상품화되어 있어서 이를 외부에 장착한다.

그림 2.30  I/O포트가 8051에서 차지하는 위치

8051의 경우에는 물론 I/O포트도 8051 내에 장착되어 있는데, 포트의 수는 P0∼P3 등 4개이다. 이들 포트는 각기 8개의 I/O라인을 가지고 있다. 그림 2.1의 8051 외부 핀을 보면 대부분의 핀이 I/O라인에 할애되어 있음을 알 수 있을 것이다.

이들 I/O라인은 각기 하나의 래치와 출력 드라이버와 입력 버퍼로 구성되어 있고, 양방향성으로서, 비트별로 데이터를 입력할 수도 있고 출력할 수도 있다. 즉 범용 병렬 I/O포트로서의 역할을 한다.

8051 I/O포트 중 P0와 P2는 앞에서 설명한 바와 같이, 8051의 외부에 프로그램 메모리 및 데이터 메모리를 확장 설치할 경우에 이들 메모리를 참조하는 데 필요한 주소정보와  데이터정보를 입출력하는 데에도 사용된다. 이 경우 P0은 외부 메모리의 하위 어드레스(A0∼A7)와 데이터(D0∼D7)를 번갈아(multiplexing) 입출력하고, P2는 16비트 어드레스의 상위 바이트인 A8∼A15를 출력한다.

또한 P3은 외부 인터럽트 입력 핀(INT0, INT1)으로도 사용되고, 직렬포트의 직렬 데이터 송수신(RxD, TxD)으로 사용되기도 하며 카운터의 입출력(T0, T1) 핀으로도 사용되고, WR, RD, 등 외부 메모리를 장착할 경우 이를 제어하는 신호로도 사용된다.

전술한 바와 같이 마이크로콘트롤러는 기기를 제어하기 위한 것인데, 실제 제어는 대부분 I/O포트를 통하여 한다. 이런 의미에서 마이크로콘트롤러를 정복한다는 것은 I/O포트를 정복한다는 것을 의미한다고 할 정도로 I/O포트의 사용법을 터득함은 중요하다고 할 것이다. 이에 대하여는 장을 바꾸어서 다루고자 한다. I/O포트의 사용 방법을 설명하려면 8051의 명령어 세트, 주소지정방식, 8051 어셈블러 등에 대한 기초 지식이 필요하기 때문이다.

8051은 비동기식 또는 동기식으로 직렬 통신을 할 수 있는 직렬포트를 하나 내장하고 있다. 직렬포트(serial port)는 데이터를 직렬로 입출력하는 I/O포트이다.

원래 데이터를 전송하는 방식에는 병렬 방식과 직렬 방식이 있다. 병렬 전송방식은 그림 2.31의 (a)와 같이 데이터를 구성하는 비트를 병렬로 배열하여 전송하는 방식이고, 직렬 전송방식은 같은 그림 (b)와 같이 직렬로 배열하여 전송하는 방식이다. 전자는 키보드와 같이 가까운 거리에 있거나 자기디스크장치와 같이 빠른 속도를 필요로 하는 장치에서 사용되고, 후자는 원거리에 있거나 프린터와 같이 빠른 속도를 필요로 하지 않는 장치에서 사용된다.

그림 2.31  데이터 전송 방식

8051의 직렬 포트는 전이중(full-duplex) 방식이고 또한 완충수신(receive-buffered) 방식이다. 전이중 방식이 무엇이고 완충수신이란 무엇인가, 기타 8051 직렬포트에 관한 자세한 것은 이것에 관한 프로그램과의 연계상 역시 장을 바꿔서 논고자 한다. 그림 2.32는 직렬포트가 사용되는 형태이다.

그림 2.32  직렬포트가 사용되는 형태

8051은 독립된 2개의 16비트 타이머/카운터를 내장하고 있는데, 이들은 모두 타이머로서의 기능과 카운터로서의 기능을 가진다. 또 8052에만 있는 타이머 2는 캡쳐 기능과 16비트 자동재로드 기능, 그리고 보율발생 기능이 있다.

그림 2.33은 8051 내에서 타이머/카운터가 차지하는 위치이다.

그림 2.33  타이머/카운터가 8051에서 차지하는 위치

타이머/카운터의 사용 방법을 터득함은 8051의 이용상 매우 중요하나 이에 대해서도 장을 바꾸어서 다루기로 한다. 이것의 사용 방법을 설명하기 위해서는 역시 8051의 명령어 세트, 주소지정방식, 8051 어셈블러 및 컴파일러 등에 대한 기초 지식이 필요하기 때문이다.

(1) 발진 회로

모든 MCS-51 마이크로콘트롤러는 클록 발진회로를 내장하고 있는데, 이것을 사용하기 위해서는 크리스털 또는 세라믹 공진자를 그림 2.34와 같이 외부 핀 XTAL1과 XTAL2에 연결해야 한다.

그림 2.34  발진회로

(2) 리셋트 동작

시스템 리셋은 모든 동작 조건에 우선하며, 8051을 어떤 일정의 상태가 되도록 한다. 리셋은 그림 2.35와 같이 RST 핀을 적어도 2기계사이클(24 클록시간) 동안 □high□로 함으로써 이루어진다.

리셋 동작 중에는 다음의 동작이 수행된다.

·모든 인터럽트는 불능(disable)으로 된다.

·포트 0∼3은 0FFH로 되어 입력 모드로 된다.

·스택포인터는 07H로 된다.

·포트와 SP를 제외한 거의 모든 특수기능레지스터는 표 2.5와 같이 00H로 클리어 된다.

·프로그램카운터는 ROM 리셋 번지인 00H로 된다.

전원을 켤 때에는 전원이 허용 값으로 된 뒤로부터 10m초 정도 핀 RST가 □high□로 되어야 한다. 이것은 클록 발진이 안정될 시간을 주기 위함이다.

그림 2.35  리셋 타이밍

□표 2.5  리셋후의 각 레지스터 내용

레지스터	리셋후의 내용	레지스터	리셋후의 내용
PC	000H	TH0	00H
ACC	00H	TL0	00H
B	00H	TH1	00H
PSW	00H	TL1	00H
SP	07H	TH2	00H
DPTR	0000H	TL2	00H
P0-P3	0FFH	RLDH	00H
IP	(XX000000)	RLDL	00H
IE	(XX000000)	SCON	00H
TMOD	00H	SBUF	Intermediate
TCON	00H	PCON	(0XXX0000)
T2CON	00H

1. 8051은 하나의 CPU, 4K 바이트의 ROM, 128 바이트의 RAM, 4개의 I/O포트, 하나의 직렬포트, 2개의 타이머/카운터, 그리고 이들을 연결하는 각종 버스로 구성되어 있다.

2. 일반적으로 CPU는 레지스터部, 연산部, 제어部로 구성된다.

3. 8051의 레지스터部는 하바드 구조상 데이터 메모리에 통합되어 있다.

4. 8051의 연산부는 ALU와 TMP 레지스터와 PSW로 구성되어 있다.

5. 8051의 제어부는 일반 마이크로컴퓨터와 같이 명령레지스터와 명령해독기와 제어신호기로 구성되어 있다.

6. 8051은 내부 ROM으로서 마스크 ROM을 쓰고, 8751은 EPROM을 쓴다. 8031은 내부 ROM이 없고 아예 외부 ROM에 의존한다. 외부 ROM으로서는 ROM, PROM, EPROM, EEPROM, 플래시 메모리 어느 것을 써도 된다. 외부 ROM을 쓸 때에는 EA핀(pin no.31)을 0V로 해야 한다.

7. 8051의 내부 RAM은 특수기능레지스터와 범용레지스터로 크게 분류되는데, 이들 중 특수기능레지스터는 소프트웨어를 제어하거나, I/O포트, 직렬포트, 타이머 등의 내장된 주변장치를 제어하는 레지스터이고, 범용레지스터는 레지스터 뱅크공간, 비트 주소지정 공간, 자유공간으로 되어있다.

8. 레지스터 뱅크(register bank)에 속하는 레지스터는 모두 32개로서, 이들은 4개의 뱅크에 R0∼R7의 이름으로 들어 있다. 뱅크의 선택은 PSW의 비트 4와 비트 3으로 하고, 리셋 후에는 뱅크 0이 자동적으로 선택된다.

9. 8051의 메모리 형태에는 code, data, idata, bdata, xdata, pdata 등이 있는데, 이들에 대한 접근 명령은 각기 다르다. code는 code memory로서 MOVC A, @A+DPTR나 MOVC A, @A+PC로 접근하고, data는 directly addressable 내부 RAM으로서 직접 주소지정방식으로 접근하며, idata는 indirectly addressable 내부 RAM으로서 간접 주소지정방식으로 접근하고, xdata는 external 데이터 메모리로서 MOVX A, @DPTR로 접근하며, pdata는 paged 데이터 메모리로서 MOVX A, @Rn으로 접근하고, bdata는 bit-addressable 데이터 메모리로서 비트 주소지정방식으로 접근한다.

10. 8051 내부 ROM 중 0번지는 리셋 후 프로그램이 시작되는 번지이므로, 프로그램 초두에 예컨대 다음과 같은 명령을 두어서 실제의 프로그램 선두 번지로 뛰도록 해야 한다. 트레인키트는 제품에 따라 리셋 번지가 다르다.

ORG	00H

JMP	START

11. 8051의 외부 ROM에 대한 접근(access)은 I/O포트 P0와 P2를 통하여 한다. 이 때 P0은 하위 어드레스 A0∼A7과 데이터 D0∼D7을 멀티플렉스 입출력하고, P2는 상위 어드레스 A8∼A15를 출력한다.

12. 8051은 I/O포트를 4개 내장하고 있는데, 이들은 모두 8개씩의 양방향성 I/O포트 라인을 가지고 있다.

13. 8051의 I/O포트는 주로 범용 I/O포트로서 사용된다. 다만 외부 메모리를 장착할 경우에 P0와 P2는 외부 메모리에 대한 주소버스 및 데이터버스로 사용되고, P3은 외부 메모리를 제어하는 신호로 사용된다. 또, 직렬포트나 타이머나 외부 인터럽트를 사용할 경우에도 사용된다.

14. 8051의 직렬포트는 전이중 방식이고, 완충수신 방식이다.

15. 8051은 타이머 0과 타이머 1을 내장하고 있는데, 이들은 16비트 타이머로 사용되기도 하고 카운터로 사용되기도 한다. 또한 이들은 직렬포트의 비동기식 통신 모드에서 보율(baud rate)를 발생하는 기능도 가지고 있다.

2.1 마이크로컴퓨터의 기본 구조는 크게 3부분으로 구성된다. 이에 속하지 않는 것은?	(전자계산기)

㉮ 중앙처리장치	㉯ 입출력장치	㉰ 기억장치	㉱ 보조기억장치

2.2 마이크로컴퓨터 CPU의 내부구조를 기능별로 분류한 것은?	(전자계산기)

㉮ 연산부, 제어부, 어드레스부	㉯ 연산부, 제어부, 레지스터부

㉰ 연산부, 어드레스부, 레지스터부	㉱ 연산부, 어드레스부, 버퍼부

2.3 CPU의 내부 구성 요소가 아닌 것은?	(전자계산기)

㉮ Instruction Register	㉯ RAM

㉰ Program counter	㉱ Accumulator

2.4 마이크로프로세서의 처리 능력(Performance)을 향상시키는 방법으로 일반적으로 가장 비중이 적은 것은?	(전산기조직응용)

㉮ 클록 주파수를 증가시킨다.	㉯ 데이타버스의 폭을 증가시킨다.

㉰ 명령어 캐시(instruction cache)를 마련한다.	㉱ 내부 레지스터(register)를 증가시킨다.

2.5 연산기(ALU)가 공통적으로 갖고 있는 기능이 아닌 것은?	(전자계산기)

㉮ 2진 가감산	㉯ 승산 및 제산

㉰ 부울 대수연산	㉱ shift 혹은 Rotate

2.6 마이크로프로세서 CPU의 내부 구조에서 읽어들인 명령을 해독하는 부는?	(전자계산기)

㉮ 제어부	㉯ 연산부

㉰ 주소부	㉱ 레지스터부

2.7 연산장치에 있어서 4칙연산, 논리연산 등의 결과를 일시 기억하고 있는 레지스터는?	(전산기조직응용)

㉮ Stack	㉯ IR	㉰ PC	㉱ Acc

2.8 ALU에 의해 수행되는 여러가지 동작에 참여하는 레지스터를 무엇이라 하는가?	(전산기조직응용)

㉮ 명령 레지스터	㉯ 누산기

㉰ 프로그램 카운터	㉱ 메모리 주소 어드레스

2.9 일반적으로 8비트 마이크로프로세서(microprocessor)라 할 때 다음 중 그 길이가 8비트인 것은?

(전산기조직응용)

㉮ 누산기(Accumulator)	㉯ 프로그램 카운터(Program Counter)

㉰ 스택 포인터(Stack Pointer)	㉱ 어드레스 레지스터(Address Register)

2.10 연산 후의 결과가 저장되는 기억 장소는?	(전산기조직응용)

㉮ 데이터 카운터(data counter)	㉯ 어큐뮬레이터(accumulator)

㉰ 인스트럭션 레지스터(instruction register)	㉱ 프로그램 카운터(program counter)

2.11 범용(General Purpose) 레지스터의 기능이 아닌 것은?

㉮ Index 레지스터로 쓰임.

㉯ 기억장치에서 읽어들인 자료를 보관

㉰ 스택포인터의 다음 번지에 들어갈 주소를 보관

㉱ 카운터

2.12 다음 중 반드시 프로세서에 내장되는 레지스터가 아닌 것은?	(전산기조직응용)

㉮ 컨트롤(control) 레지스터	㉯ 인덱스(index) 레지스터

㉰ 스택포인터(stack pointer)	㉱ 컨디션코드(condition code) 레지스터

2.13 Z80 마이크로프로세서의 데이터포인터(data pointer)로 주로 사용되는 범용 레지스터는?	(전자계산기)

㉮ SP	㉯ HL	㉰ DE	㉱ BC

2.14 마이크로프로세서 내부 레지스터 중 인스트럭션의 OP코드가 저장되는 레지스터는?	(전자계산기)

㉮ GPR	㉯ IR	㉰ PC	㉱ AC

2.15 마이크로프로세서 내부의 레지스터 중에서 수행하고자 하는 인스트럭션의 주소를 가리키는 레지스터는?	(전자계산기)

㉮ IR	㉯ MAR	㉰ PC	㉱ AC

2.16 Program Counter에 대한 설명으로 잘못 된 것은?	(전산기조직응용)

㉮ 다음에 수행할 명령의 주소를 기억하고 있는 register이다.

㉯ Jump나 Subroutine call 등을 제외하고는 하나의 동작을 수행할 때마다 그 내용이 1~4씩 증가한다.

㉰ Address line이 16개이면 Program Counter는 16 bit로 되어 있다.

㉱ 연산 중심의 Register라고 할 수 있다.

2.17 마이크로프로세서 CPU의 레지스터 중에서 메모리 내의 현재의 스택 위치를 지시하는 레지스터로서 서브루틴 등을 이용할 때 필요한 것은?	(전자계산기)

㉮ 스택포인터	㉯ 인터럽트 벡터

㉰ 인덱스레지스터	㉱ 프로그램카운터

2.18 프로세스 내에 범용 레지스터를 두고, 데이터를 일시적으로 이에 저장하여 연산하는 마이크로프로세서는?	(전산기조직응용)

㉮ 8085	㉯ 6800	㉰ 6502	㉱ PPS 8

2.19 다음 중 산술연산이나 논리연산의 결과에 관한 정보를 저장할 수 있는 레지스터는?	(전산기조직응용)

㉮ data counter	㉯ program counter

㉰ flag register	㉱ index register

2.20 가산 또는 감산 결과 MSB에서 자리올림이나 자리내림이 생겼을 때 set되는 flag는? (전산기조직응용)

㉮ sign flag	㉯ carry flag

㉰ zero flag	㉱ parity flag

2.21 연산 결과 MSB가 1일 때 세트되고 0일 때 리셋 되는 플래그(Flag)는?	(전산기조직응용)

㉮ Carry Flag	㉯ Sign Flag

㉰ Zero Flag	㉱ Auxiliary Carry Flag

2.22 명령레지스터의 역할은?

㉮ 명령코드를 일시 보존한다.	㉯ 해독된 제어신호를 일시 보존한다.

㉰ 오퍼랜드를 영구 보존한다.	㉱ 번지부를 영구 보존한다.

2.23 컴퓨터의 각 구성 요소 간의 데이터 전송에 사용되는 공통의 전송로를 무엇이라 하는가?

(전산기조직응용)

㉮ port	㉯ channel	㉰ bus	㉱ interface

2.24 컴퓨터 회로에서 버스선(bus line)을 사용하는 가장 큰 이유는?	(정보처리)

㉮ Speed를 향상시킨다.	㉯ 보다 정확한 전송이 가능하다.

㉰ register의 수를 줄이기 위함이다.	㉱ 결선의 수를 줄이기 위함이다.

2.25 마이크로프로세서 장치로 들어가는 4가지 입력 중에서 출력과 겸해져 쌍방향성인 것은? (전산기조직응용)

㉮ 전원 공급 입력	㉯ 클럭 입력

㉰ 인터럽트 입력	㉱ 데이터버스 입력

2.26 다음 중에서 양방향성(bidrectional) 버스는?	(전산기조직응용)

㉮ 주소버스	㉯ 제어버스

㉰ ALU버스	㉱ 데이터버스

2.27 마이크로컴퓨터의 연결버스는 주소버스, 자료버스, 제어버스로 구분된다. 다음 중 양방향 버스는?

(전자계산기)

㉮ 자료버스	㉯ 자료버스, 주소버스

㉰ 주소버스	㉱ 주소버스, 제어버스

2.28 마이크로컴퓨터의 기억장치에는 기억장소를 식별하기 쉽도록 기억장소마다 번호가 붙여져 있다. 이 번호를 무엇이라 하는가?	(전산기조직응용)

㉮ byte	㉯ bit

㉰ Location	㉱ address

2.29 다음의 회선 중에서 기억장치에 연결되어 있지 않은 것은?	(전산기조직응용)

㉮ 번지버스	㉯ 제어선

㉰ I/O버스	㉱ 데이터버스

2.30 마이크로프로세서와 기억장치를 연결하는 버스의 종류가 아닌 것은?	(전자계산기)

㉮ 상태버스	㉯ 제어버스

㉰ 주소버스	㉱ 자료버스

2.31 다음 그림이 나타내는 것은 무엇인가?	(전산기조직응용)

㉮ 양방향 3상태 버퍼(buffer)	㉯ 단방향 3상태 버퍼

㉰ 3상태 라인 드라이버(line driver)	㉱ 3상태 라인 리시버(line receiver)

2.32 CPU가 입출력 데이터 전송을 메모리에서의 데이터 전송과 같은 명령으로 수행할 수 있는 입출력 제어 방식은?	(전자계산기)

㉮ programmed I/O	㉯ memory mapped I/O

㉰ interrupt I/O	㉱ isolated I/O

2.33 입출력장치의 연결에서 isolated I/O 방식의 장점이 아닌 것은?	(전자계산기)

㉮ 입출력 포트의 갯수를 크게 할 수 있다.

㉯ 입출력 전용 인스트럭션을 사용할 수 있다.

㉰ 입출력이 언제 수행되는지 알아보기 쉽다.

㉱ 입출력 전용의 제어신호를 사용할 수 있다.

2.34 마이크로컴퓨터의 구성에서 memory mapped I/O와 isolated I/O 방식에 대한 설명 중 맞는 것은?

(전산기조직응용)

㉮ memory mapped 입출력에는 입출력 전용 명령어가 요구된다.

㉯ memory mapped 입출력은 주기억 공간을 최대로 활용할 수 있다.

㉰ isolated 입출력은 버스 연결이 쉽다.

㉱ memory mapped 입출력에는 입출력 전용 명령어가 필요 없다.

2.35 마이크로프로세서가 가지는 리셋(reset) 단자의 기능에 관한 설명 중 맞는 것은?	(전자계산기 조직응용)

㉮ 인터럽트 처리 루틴을 동작시키는 데 사용한다.

㉯ 프로그램 카운터(program counter)에 초기 값을 부여할 때 사용한다.

㉰ 프로그램 내의 특정 명령어를 지울 때 사용한다.

㉱ 컨디션 코드의 값을 일정 값으로 부여할 때 사용한다.

2.36 다음 중 micro operation에 대한 정의로 바른 것은?	(전자계산기)

㉮ register에 저장된 data에 의해서 이루어지는 동작

㉯ computer의 빠른 계산 동작

㉰ flip flop의 상태 변환 동작

㉱ 2진수 계산에서 쓰이는 동작

2.37 어떤 명령을 수행하기 위해 마이크로프로세서가 가장 먼저 하는 마이크로 오퍼레이션은?	(정보처리)

㉮ MAR←PC	㉯ PC←PC+1

㉰ IR←MBR	㉱ MBR←PC

2.38 명령(instruction)을 수행하기 위해 CPU 내부에서 실행되는 것은?	(전자계산기)

㉮ shift operation	㉯ count operation

㉰ fetch operation	㉱ micro operation

2.39 다음의 흐름圖는 命令코드(OP code) fetch시의 동작을 순서대로 나열한 것이다. A부분에 일어날 동작에 해당하는 것은 무엇인가?	(전자계산기 조직응용)

(단, M = Memory, IR = Instruction Register, AR = Address Register, PC = Program counter, (M) = 기억장치의 내용)

㉮ (M) → IR	㉯ (M) → (AR)

㉰ (M) → Accumulator	㉱ (M) → Decoder

2.40 기억장치에 저장된 자료를 읽는(read) 순서는?	(전자계산기)

① CPU가 자료를 읽을 것인지 쓸 것인지를 지정한다.

② 접근시간(access time)만큼 기다린다.

③ CPU가 기억장치에 주소를 보낸다.

④ 자료를 읽는다.

㉮ ①→②→③→④	㉯ ③→①→②→④

㉰ ②→③→①→④	㉱ ③→②→①→④

2.41 다음은 각 인스트럭션들에 공통으로 포함되는 사이클을 열거해 놓았다. 이중 맞지 않는 것은?

(전산기조직응용)

㉮ 인스트럭션을 기억장치로부터 가져온다.

㉯ 프로그램 카운터가 증가된다.

㉰ 기억장치로부터 데이터를 가져온다.

㉱ 인스트럭션이 해독되고 수행된다.

2.42 중앙처리장치에 비해 외부장치의 속도가 느리기 때문에 특별하게 발생되는 대기사이클은?	(전자계산기)

㉮ 패치 사이클	㉯ Tw 사이클

㉰ 머신 사이클	□ T  사이클

2.43 다음은 기억장치와 입출력장치의 동작에 대한 설명이다. 이 중 옳지 않은 것은?	(전산기조직응용)

㉮ 입출력장치는 그 속도가 기억장치에 비하여 상당히 느린 것이 보통이다.

㉯ 기억장치에서 처리하는 정보의 단위는 단어(word)이며, 입출력 장치가 다루는 정보의 단위는 보통 문자(character)로서 1바이트이다.

㉰ 중앙처리장치의 제어기는 자기디스크의 회전속도 제어 등 입출력장치의 모든 동작을 제어한다.

㉱ 중앙처리장치와 입출력장치 사이에 에러(error)가 발생할 가능성은 입출력장치가 보다 크다.

2.44 명령코드의 呼出사이클을 무엇이라고 하는가?

㉮ M1 사이클	㉯ 메모리의 read 사이클

㉰ 메모리의 write 사이클	㉱ I/O read 사이클

2.45 命令레지스터를 거쳐서 命令解讀器에서 해독(decode)된 制御信號가 하는 일은?

㉮ 그 명령의 실행을 위한 각 장치의 게이트를 개폐한다.

㉯ 입출력장치의 입출력제어에만 사용된다.

㉰ 연산장치의 제어에만 사용된다.

㉱ 위의 것들과는 무관하다.

2.46 입력제어 신호로서 마이크로프로세서 내의 레지스터들을 0으로 만드는 것은?

㉮ IRQ	㉯ MREQ	㉰ Reset	㉱ INTE

2.47 컴퓨터에서 tri-state buffer가 유용한 이유는?

㉮ 전력 소모가 낮다.	㉯ 신호 전달 속도가 빠르다.

㉰ 많은 장치들의 접속을 수월하게 한다.	㉱ 3가지 상태의 논리 레벨을 제공한다.

2.48 Z80 CPU는 외부로부터의 어느 동작에 의해서 CPU 대기 상태로 될 수 있는가?

㉮ HALT 라인을 low 상태로 함으로써

㉯ HALT  라인을 high 상태로 함으로써

㉰ WAIT  라인을 low 상태로 함으로써

㉱ WAIT  라인을 high 상태로 함으로써

2.49 다음 중 데이터를 기억하는 요소에 해당되지 않는 것은?	(전산기조직응용)

㉮ 플립플롭(Flip Flop)	㉯ 카운터(Counter)

㉰ 레지스터(Tegister)	㉱ 디코더(Decoder)

2.50 memory cell이 flip flop으로 되어 있는 것은?

㉮ PROM	㉯ EPROM	㉰ SRAM	㉱ DRAM

2.51 주기억장치의 특정 주소를 찾아 그 내용을 읽는 데는 자료의 위치와 관계없이 약간의 시간이 소요된다. 이를 무엇이라 하는가?	(전자계산기)

㉮ clock time	㉯ access time

㉰ refresh time	㉱ load time

2.52 기억소자 ROM, RAM의 액세스(access) 방식은?	(전산기조직응용)

㉮ 랜덤 액서스(random accessible)

㉯ 시퀀셜 액세스(secquentially accessible)

㉰ 소자 액세스는 랜덤, 소자내 기억 액세스는 시퀀셜

㉱ 소자 액세스는 시퀀셜, 소자내 기억장소 액세스는 랜덤

2.53 제조 과정에서 내용을 미리 기억시킨 것으로, 사용자는 어떤 경우에도 그 내용을 바꿀 수 없는 소자는?	(전산기조직응용)

㉮ RAM	㉯ EPROM	㉰ mask ROM	㉱ PROM

2.54 다음 중 모니터 프로그램을 보관하기 곤란한 장치는?	(전산기조직응용)

㉮ RAM	㉯ ROM	㉰ EPROM	㉱ DISKETTE

2.55 마이크로컴퓨터에서 시스템 제어 또는 번역 프로그램을 저장하고 있는 부분은 다음 중 어느 것인가?	(전산기조직응용)

㉮ RAM	㉯ ROM

㉰ 마이크로프로세서	㉱ 인덱스 레지스터

2.56 소형의 마이크로컴퓨터를 구성하려고 할 때 모니터 프로그램을 둘 장소로서 가장 적합한 것은?

(전산기조직응용)

㉮ 디스켓(Diskette)	㉯ ROM(Read only Memory)

㉰ RAM(Random Access Memory)	㉱ MPU(Micro processor Unit)

2.57 다음 메모리 중 오직 한번만 프로그램을 써넣을 수 있는 것은?	(조직응용)

㉮ PROM	㉯ EPROM

㉰ EAPROM	㉱SRAM

2.58 마스크(mask) ROM에 관한 설명 중 틀린 것은?	(전산기조직응용)

㉮ 다시 고쳐 써넣을 수 없는 ROM이다.

㉯ 소량 사용시 유리하다.

㉰ 집적도를 높일 수 있다.

㉱ 대용량의 칩을 만들 수 있다.

2.59 전원이 끊어져도 기억 내용이 손실되지 않으면서 기입은 가능한 기억소자를 무엇이라 하는가?

(전산기조직응용)

㉮ 다이나믹 램(dynamic RAM)	㉯ 스태틱 램(static RAM)

㉰ 마스크 롬(mask ROM)	㉱ 프로그래머블 롬(programmable ROM)

2.60 다음 중 써넣은 자료를 자외선을 쪼여서 지울 수도 있고, 다시 새로운 자료를 써넣을 수도 있는 메모리 소자는?	(전자계산기)

㉮ EEPROM	㉯ EPROM

㉰ PROM	㉱ ROM

2.61 EPROM에 기억된 내용을 소거하려면 다음 중 어떤 수단을 사용해야 하는가?	(전산기조직응용)

㉮ 고주파	㉯ 적외선	㉰ 자외선	㉱ X선

2.62 ROM(read only memory)과 마이크로프로세서의 연결에 있어서 다음 중 ROM에 입력되는 신호로 볼 수 없는 것은?	(전산기조직응용)

㉮ 8비트의 데이터선

㉯ ROM과 프로세서를 동기시키는 클록 신호

㉰ 접근(access)해야 할 메모리 워드의 주소

㉱ 읽기 제어 신호

2.63 다음 중 불휘발성 기억장치가 아닌 것은?

㉮ EPROM	㉯ magnetic bubble

㉰ static RAM	㉱ floppy disk

2.64 다음 중 비휘발성 메모리는?

㉮ 스태틱 RAM	㉯ 다이나믹 RAM

㉰ CMOS RAM	㉱ MNOS RAM

2.65 SRAM이 DRAM보다 나은 특성은 어느 것인가?	(전산기조직응용)

㉮ 집적도	㉯ 전력 손실

㉰ 비트당 가격	㉱ 액세스 시간

2.66 정적인 램(static RAM)의 특징이 아닌 것은?	(전자계산기)

㉮ flip flop으로 구성된다.

㉯ refresh를 위한 전용회로가 필요없다.

㉰ 대용량의 메모리가 필요할 때 사용한다.

㉱ 전원이 유지되는한 기억된 내용을 유지한다.

2.67 다음은 Static RAM에 관한 설명이다. 틀린 것은?	(전산기조직응용)

㉮ 전원이 계속 공급되는 동안 내용을 유지한다.

㉯ Memory 집적도를 dynamic RAM보다 높일 수 있다.

㉰ 사용이 간편하다.

㉱ refresh 회로가 필요 없다.

2.68 동적 MOS메모리(Dynamic MOS Memory)의 특성으로서 틀리는 것은?	(전산기조직응용)

㉮ 개개의 소자가 간단하다.

㉯ 칩당 집적도를 높여 준다.

㉰ 가장 기본적인 기억 단위는 2진 셀(cell)이다.

㉱ 축전기로부터 계속 전하가 방전되기 때문에 2초마다 재충전하는 과정이 필요하다.

2.69 다이나믹 RAM(dynamic)의 장점은 무엇인가?	(전산기조직응용)

㉮ 스태틱 RAM보다 속도가 빠르다.

㉯ 전력의 재충전(refresh)이 필요 없다.

㉰ 집적도가 높다.

㉱ 읽어낸 정보는 파괴되지 않는다.

2.70 다음 메모리 중 리프레시(refresh) 사이클이 사용되는 것은?	(전산기조직응용)

㉮ SRAM	㉯ EPROM	㉰ DRAM	㉱ PLA

2.71 다음 기억장치 중에서 refresh가 필요한 것은?	(전자계산기)

㉮ static memory	㉯ volatile memory

㉰ dynamic memory	㉱ non volatile memory

2.72 기억장치 중 Dynamic RAM과 Static RAM을 비교하여 보았다. 다음 중 틀린 항목은? (전산기조직응용)

㉮ 통상 Dynamic RAM은 Static RAM보다 많은 기억 용량을 가진다.

㉯ Static RAM은 매 밀리 초(mS)마다 Cell에 refresh 신호를 가해야 한다.

㉰ Dynamic RAM의 Storage Cell은 Static RAM의 것보다 작다.

㉱ Static RAM은 전원을 끊는 순간 기억된 data가 소멸된다.

2.73 다이나믹(dynamic) RAM에 대한 설명 중 잘못된 것은?	(전산기조직응용)

㉮ 리프레시(refresh) 펄스가 계속 공급되어야 한다.

㉯ 소비 전력이 크고 동작 속도가 늦다.

㉰ 주변 회로가 복잡하여 용량이 큰 메모리 회로에 주로 사용된다.

㉱ 스태틱(static) RAM보다 집적도가 높고 가격이 싸다.

2.74 동적인 램(dynamic RAM)의 특징이 아닌 것은?	(전자계산기)

㉮ 대용량의 메모리가 필요할 때 사용한다.

㉯ 전력소모가 적다.

㉰ refresh를 위한 전용회로가 필요하다.

㉱ 전원이 유지되는한 기억된 자료가 없어지지 않는다.

2.75 다음 주소 디코더 회로는 어디에 해당하는가? (단, IO/M=0이면 기억장치 접근 IO/M=1이면 입출력 접근)	(전산기조직응용)

㉮ isolated I/O에서 입·출력 포트 주소 해독

㉯ isolated I/O에서 기억장치 주소 해독

㉰ memory mapped I/O에서 입·출력 포트 주소 해독

㉱ memory mapped I/O에서 기억장치 주소 해독

2.76 메모리 셀은 무엇에 의해 액세스되는가?	(전산기조직응용)

㉮ 어드레스 인코더	㉯ 어드레스 디코더

㉰ 어드레스 레지스터	㉱ 어드레스 메모리

2.77 번지 해독기(address decoder)의 출력은 일반적으로 어느 것에 연결하는가?

㉮ RAM의 WR 에	㉯ RAM의 CE 에

㉰ CPU의 HALT 에	㉱ CPU의 WAIT  에

2.78 번지선이 4개, 출력 Data선이 8개인 ROM의 기억용량은?	(전산기조직응용)

㉮ 16 byte	㉯ 8 byte	㉰ 32 byte	㉱ 64 byte

2.79 주소비트가 n이고 단어 길이가 m인 메모리의 용량은?	(전자계산기)

㉮ 2×n	㉯ 2n×m

㉰ n×m	㉱ 2n×m

2.80 어떤 컴퓨터의 메모리 용량이 4086 word이다. 하나의 word가 32비트라 하면 MAR(Memory Address Register)과 MBR(Memory Buffer Register)은 각각 몇 비트로 구성되는가?	(전자계산기)

㉮ 12, 5	㉯ 12, 32	㉰ 32, 12	㉱ 5, 12

2.81 어드레스 신호선이 A0로부터 A9까지 10개인 경우 기억장치가 가질 수 있는 어드레스의 범위로 다음 중 옳은 것은?	(전산기조직응용)

㉮ 0∼9	㉯ 0∼1023

㉰ 0∼1024	㉱ 1∼1024

2.82 512 byte 크기의 메모리를 필요로 하는데 사용되는 어드레스 라인(address line)은 몇 개인가?

(전산기조직응용)

㉮ 8	㉯ 9	㉰ 11	㉱ 10

2.83 번지(Address) 단자가 16개 준비된 마이크로프로세서의 경우 몇 종류의 데이타를 기록할 수 있는가?	(전자계산기조직응용)

㉮ 16,384	㉯ 32,768

㉰ 65,536	㉱ 131,072

2.84 8 bit data bus와 16 bit address bus를 갖는 마이크로컴퓨터의 최대 주기억 용량은?

(전산기조직응용)

㉮ 256 byte	㉯ 32K byte

㉰ 64K byte	㉱ 128K byte

2.85 다음 그림과 같은 칩(chip)에 필요한 핀(pin)의 수는?	(전산기조직응용)

㉮ 3	㉯ 17

㉰ 18	㉱ 19

2.86 1M byte의 용량은 정확히 몇 byte인가?	(전산기조직응용)

㉮ 1000000 byte	㉯ 1048576 byte

㉰ 100600 byte	㉱ 1024000 byte

2.87 다음은 CPU에 2개의 ROM을 연결한 경우이다. 여기서 A8이 □1□이면 ROM B가 동작되고, A8이 □0□이면 ROM A가 동작된다. ROM A와 ROM B의 주소는?	(전자계산기)

㉮ ROM A;0~255, ROM B;0~255

㉯ ROM A;0~255, ROM B;256~511

㉰ ROM A;256~511, ROM B;0~255

㉱ ROM A;256~511, ROM B;256~511

2.88 다음은 연산장치에서 사용되는 플래그(flag) 레지스터들이다. 설명이 틀린 것은?	(전산기조직응용)

㉮ 제로 플래그(Z)는 연산 결과가 □0□으로 되었을 때 세트된다.

㉯ 부호 플래그(S)는 연산시에 최상위 비트가 □0□일 때 세트된다.

㉰ 캐리 플래그(C)는 시프트(shift), 회전, 연산 결과에 의해 세트될 수도 있다.

㉱ 오버플루 플래그(O)는 2의 보수 연산에서 오버플루가 발생되었을 때 세트된다.

2.89 Von Neuman형 컴퓨터의 연산자들이 가져야 하는 기능과 가장 거리가 먼 것은?	(전산기조직응용)

㉮ 증폭 기능	㉯ 함수연산 기능

㉰ 전달 기능	㉱ 제어 기능

2.90 여러 회선이 하나의 회선을 공유하려면 어떤 회로를 사용하면 좋은가?	(전산기조직응용)

㉮ 멀티플렉서	㉯ 디멀티플렉서

㉰ 인터페이스	㉱ 버스 회로

2.91 다음은 기억장치에 대한 설명이다. 잘못된 것은?

㉮ 반도체 기억소자(IC)는 휘발성(Volatile) 기억소자이다.

㉯ 자기코어(magnetic core)는 비휘발성(nonVolatile) 기억소자이다.

㉰ 자기코어는 비파괴적(non-destructive) 기억소자이다.

㉱ 반도체 기억소자에서 접근(access)시간과 사이클 시간(cycle time)은 같다.

2.92 데이터 카운터(Data Counter)의 기능은?

㉮ 상태 플래그를 저장한다.	㉯ 명령어 어드레스를 지정한다.

㉰ op 코드를 저장한다.	㉱ 데이터 어드레스를 저장한다.

2.93 다음 (    )안에 알맞는 것은?

□software를 ROM 등에 기록하여 hardware와 유사한 성질을 갖도록 했을 때 이것을 (  )라고 한다.□

㉮ firmware	㉯ program

㉰ interface	㉱ register

2.94 어떤 RAM이 8비트로 된 주소버스와 4비트로 된 입출력 자료버스를 가지고 있다면 이 RAM의 용량은 얼마가 되겠는가?

㉮ 512비트	㉯ 1024비트

㉰ 2048비트	㉱ 4096비트

2.95 액세스(access)하는 메모리 셀은 무엇에 의해 구동되는가?

㉮ 어드레스 인코더	㉯ 어드레스 디코더

㉰ 어드레스 레지스터	㉱ 어드레스 메모리

2.96 8bit 마이크로프로세서가 14bit 메모리 번지 워드를 가지고  있다. 이것이 가질 수 있는 메모리 워드의 최대 숫자는 얼마인가?	(전자계산기 응용)

㉮ 256	㉯ 4096	㉰ 16,348	㉱ 65,538

2.97 ALU의 대부분 연산에 간여하는 레지스터는?	(전산기조직응용)

(오퍼랜드를 간직하거나 연산 결과를 보관함)

㉮ PC	㉯ MB	R㉰ IR	㉱ AC

2.98 프로그램카운터(PC)의 역할은 무엇인가?	(전산기 조직응용)

㉮ 자료의 주소를 가르킨다.

㉯ OP 코드를 저장한다.

㉰ 명령어의 주소를 가르킨다.

㉱ 오퍼랜드(operand)의 주소를 가르킨다.

2.99 다음 중 MPU로 부터의 Address bus가 연결되지 않는 것은?	(전산기조직응용)

㉮ 주변장치의 chip select	㉯ ROM의 R/W

㉰ RAM의 Address Pin	㉱ 입출력장치

2.100 기억장치로부터 명령이나 데이터를 읽을 때 제일 먼저 하는 일은 무엇인가?	(전산기 조직응용)

㉮ 어드레스 인출	㉯ 어드레스 지정

㉰ 명령지점	㉱ 명령입력

2.101 기억장치에서 번지가 지정된 내용은 어느 버스를 통해 CPU로 가는가?	(전산기 조직응용)

㉮ 데이터버스	㉯ 제어버스

㉰ I/O포트버스	㉱ Address버스

2.102 8bit, 16bit 등의 구분에 간여되지 않는 부분은?	(전산기 조직응용)

㉮ 데이터버스	㉯ 레지스터의 비트수

㉰ 제어선의 수	㉱ 연산기의 처리능력

2.103 다음 중 마이크로프로세서의 읽기 동작에 들어가지 않는 사항은?	(전산기조직응용)

㉮ Read/Write선을 1로 만든다.

㉯ 선택한 주소를 주소버스에 싣는다.

㉰ 마이크로프로세서는 8비트의 자료를 자료버스에 싣는다.

㉱ 기억장치는 8비트의 자료를 자료버스에 싣는다.

2.104 명령어를 하나하나 호출하여 해독하는 장치는 어느 것인가?	(전산기 조직응용)

㉮ 기억장치	㉯ 입력장치

㉰ 연산장치	㉱ 제어장치

2.105 Read / Write나 INT(interrupt), RESET 등의 신호는 어느 버스에 싣게 되는가?	(전산기조직응용)

㉮ 자료버스	㉯ 주소버스

㉰ 제어버스	㉱ 보조버스

2.106 MDR에 온 자료가 IR로 보내지게 되는데(OP 코드일 때) IR에 들어온 자료는 어떤 곳으로 보내져서해석되는가?	(전산기조직응용)

㉮ 연산기(ALU)	㉯ Status Register

㉰ 제어부(Control Unit)	㉱ MAR

2.107 명령코드(operation code)가 호출되는 곳은 어느 것인가?	(전산기조직응용)

㉮ 데이터 버퍼 레지스터(data buffer register)

㉯ 어큐뮬레이터(assumulator)

㉰ 명령레지스터(instruction register)

㉱ 번지 버퍼 레지스터(address buffer register)

2.108 제어장치의 역할이 아닌 것은 어느 것인가?	(전산기조직응용)

㉮ 시스템 전체를 감시 제어한다.

㉯ 두수의 크기를 비교한다.

㉰ 입출력을 제어한다.

㉱ 다른 장치로 데이터 전송한다.

2.109 명령레지스터에 호출된 명령코드(op code)를 해독하여 그 명령을 수행시키느데 필요한 각종 제어신호를 만들어 내는 장치는 어느 것인가?	(전산기조직응용)

㉮ 명령 카운터(instruction counter)	㉯ 명령 인코더(instruction encoder)

㉰ 명령 디코더(instruction decoder)	㉱ 명령 전송기(instruction transfer)

2.110 다음 중 명령의 실행 사이클에서 사용되지 않는 레지스터는 어느 것인가?	(전산기 조직응용)

㉮ Data buffer(MBR)	㉯ Address buffer(MAR)

㉰ Accumulator	㉱ Insturction register

2.111 CPU는 외부로부터의 어느 동작에 의해서 정지될 수 있는가?	(전산기 조직응용)

㉮ Wait라인을 Low상태로 함으로써

㉯ Wait라인을 High상태로 함으로써

㉰ Halt라인을 High상태로 함으로써

㉱ Halt라인을 Low상태로 함으로써

2.112 호출 사이클(fetch cycle)의 시작점에서 프로그램카운터(PC)는 다음중 어느 것을 가지는가?

(전산기조직응용)

㉮ 명령의 Op 코드	㉯ Operand

㉰ 호출될 Operand의 번지	㉱ 호출될 Op code의 번지

2.113 명령사이클이란 어느것인가?	(전산기조직응용)

㉮ 명령의 실행 사이클	㉯ 명령의 호출사이클과 실행 사이클

㉰ 명령의 호출사이클	㉱ 명령의 해독사이클

2.114 다음 중 페치 사이클 동작으로 맞는 것은 어느 것인가?	(전산기조직응용)

㉠ PC의 내용이 어드레스에 놓임

㉡ 명령 레지스터에서 명령어 해석

㉢ PC의 번지를 1만큼 증가

㉣ 지정된 메모리의 내용이 명령 레지스터에 전송

㉤ 명령에 의한 제어신호 발생

㉮ ㉠-㉢-㉣-㉤-㉡	㉯ ㉠-㉣-㉢-㉤-㉡

㉰ ㉠-㉢-㉣-㉡-㉤	㉱ ㉠-㉣-㉢-㉡-㉤

2.115 콘덴서의 전하 축적을 이용하는 메모리는 어느 것인가?	(전산기조직응용)

㉮ CMOS RAM	㉯ Dynamic RAM

㉰ Static RAM	㉱ MNOS RAM

2.116 Semiconductor memory 중 RAM(random access memory)의 종류에 속하는 것끼리 묶은 것은 어느것인가?	(전산기조직응용)

㉮ Read only memory(ROM), Read mostly memory(RAM), Read / Write memory (RWM)

㉯ ROM, SAM, RWM

㉰ RMM, SAM, RWM

㉱ ROM, SAM(sequential access memory), RMM

2.117 스테틱(Static) 메모리 셀은 무엇으로 구성되는가?	(전산기조직응용)

(단, FF는 Flip Flop)

㉮ 일반 FET로 구성한다.	㉯ FET로된 FF로 구성된다.

㉰ MOSFET로 구성한다.	㉱ MOSFET에 의한 FF로 구성된다.

2.118 컴퓨터의 하드웨어적 구성요소의 설명으로 옳은 것은 어느 것인가?	(전산기조직응용)

㉮ IC(직접회로)는 전력을 소비하지 않으므로 고장이 별로 없다.

㉯ 기억장치의 동작 속도는 기억정보의 내용에 따라 다르다.

㉰ 하나의 Magnetic core에 1bit의 정보가 기억된다.

㉱ 직접회로로 구성된 레지스터(register)에 저장된 정보는 전원이 끊어진 후에도 지워지지 않는다.

2.119 대량으로 생산되는 컴퓨터의 Monitor program 용으로 가장 적합한 것은 어느것인가? (전산기조직응용)

㉮ PROM	㉯ MASK ROM

㉰ S-RAM	㉱ EPROM

2.120 다음 반도체 메모리 소자중 Sequential memory인 것은 어느 것인가?	(전산기조직응용)

㉮ C-RAM	㉯ S-RAM	㉰ D-RAM	㉱ CCD

2.121 Dynamic RAM과 Static RAM에 관한 설명 중 잘못된 것은 어느 것인가?	(전산기조직응용)

㉮ D-RAM과 대부분의 S-RAM은 휘발성이다.

㉯ D-RAM은 일정시간내에 Refresh 해주어야 한다.

㉰ D-RAM은 S-RAM보다 일반적으로 전력소모가 크다.

㉱ D-RAM은 S-RAM보다 일반적으로 그 용량이 크다.

2.122 마이크로프로그램 제어 방식의 이점이 아닌 것은?	(전산기조직응용)

㉮ 마이크로컴퓨터의 개발이 용이하다.

㉯ 원가를 절감시킬 수 있다.

㉰ 새로운 명령어를 쉽게 추가 할 수 있다.

㉱ 속도가 빨라진다.

2.123 다음 중 Firmware에 적합하지 않는 것은 어느 것인가?	(전산기조직응용)

㉮ S-RAM	㉯ EPROM

㉰ PROM	㉱ MASK ROM

2.124 컴퓨터가 PC없이 구성되어 있다고 하자. 대신에 명령어는 OP코드, operand 번지, 다음 수행 명령의 번지로 구성되어 있다. 56개의 명령어를 가지고 있으며 32768워드의 기억장치를 가지고 있다. 이 마이크로컴퓨터의 명령어 형태를 보인 것은?	(전산기조직응용)

㉮ OP＞8bit  addrl＞12bit  addr2

㉯ OP＞7bit  addrl＞13bit  addr2

㉰ OP＞6bit  addrl＞15bit  addr2

㉱ OP＞5bit  addrl＞16bit  addr2

2.125 어떤 마이크로컴퓨터는 158개의 명령어 수를 갖는다. 이 컴퓨터의 한 워드(word)가 32비트라면, 또한 하나의 워드가 하나의 명령어를 나타낸다면 (워드의 구성이 OP코드와 주소로 되어 있음) 이 컴퓨터는 OP코드와 주소부분이 각각 몇 비트로 되어 있겠는가? (최소한의 비트로)	(전산기조직응용)

㉮ OP코드＞8비트	㉯ OP코드＞10비트

주소번지＞24비트	주소번지＞22번지

㉰ OP코드＞24비트	㉱ OP코드＞11번지

주소번지＞25비트	주소번지＞21번지

2.1 8051의 구성을 기술하라.

2.2 8051의 CPU 부분의 구성을 설명하라.

2.3 8051의 레지스터에 대하여 써라.

2.4 8051 내부 ROM의 하위 어드레스 구성을 기술하라.

2.5 8051 내부 RAM의 구성을 기술하라.

2.6 8051의 외부 RAM으로서 2K 바이트를 쓰고자 할 때의 결선을 그리고 설명하라.

2.7 8051의 메모리 종류를 들고, 이들 메모리에 접근하기 위한 명령을 기술하라.

3.1 프로그래밍言語 3.2 오퍼랜드의 형태 3.3 8051의 주소지정방식 3.4 8051의 명령어 세트 3.5 프로그램의 작성 순서 3.6 프로그램의 실행 과정 3.7 8051 하드웨어 개발지원툴	3.8 8051 소프트웨어 개발지원툴 3.9 Keil Software의 설치 3.10 시뮬레이터 환경 설정 3.11 Keil Software의 시작과 종료 3.12 Keil Software에 의한 프로그램의 실행 3.13 디지털제어 산업기사 8051 MICOM 보드 3.14 이 장의 간추림

컴퓨터가 다른 기계와 다른 점은 프로그램에 따라 이런 일도 할 수 있고, 저런 일도 할 수 있다는 데 있다. 문제는 프로그램을 무엇으로 작성하느냐이다. 프로그램을 작성하려면 언어가 있어야 할텐데, 그 언어를 우리는 무엇이라고 하고, 이에는 어떤 것들이 있는가?

프로그램을 작성하는 데 필요한 언어를 우리는 프로그래밍言語(programming language)라고 한다. 그리고 이에는 기계어, 어셈블리語, 컴파일러語 등 3종류가 있다. 이들 3종류의 프로그래밍言語 중 컴퓨터가 직접 이해할 수 있는 것은 기계어뿐이다.

기계어(machine language)는 0과 1로 된 코드, 즉 2진 코드로 되어 있어서 마치 암호와 같다. 예컨대 □Acc의 내용을 하나 증가하라□라는 명령을 8051에서는 00000100이라고 하는데, 이것이 기계어이다. 다음 표는 8051 기계어의 일부이다.

기계어는 쓰고 읽을 때의 번잡을 피하기 위해서 흔히 16진수로 표기된다. 예컨대 00000100 대신 04H라고 쓴다.

□표 3.1  8051 기계어의 일부

기계어	16진 표기	내 용
11101000 11111000 00101000 10011000 00000100 00010100 11110100 11100100	E8 F8 28 98 04 14 F4 E4	레지스터 R0의 내용을 Acc에 옮겨라 Acc의 내용을 레지스터 R0에 옮겨라 레지스터 R0의 내용을 Acc에 가산하라 Acc의 내용에서 레지스터 R0의 내용과 빌림수(bollow)를 빼라 Acc의 내용에 1을 더하라 Acc의 내용에서 1을 빼라 Acc의 내용에 대한 보수(complement)를 구하라 Acc의 내용을 0으로 하라

기계어는 2진 코드로 되어 있어서 이해가 어려울 뿐만 아니라, 컴퓨터의 기종에 따라 다르고, 프로그램을 작성할 때에도 많은 시간과 노력을 필요로 한다. 또한 프로그램의 일부를 삭제한다든가 추가하는 소위 에디팅(editing)이 어려우며, 프로그램에서 잘못된 곳을 찾아내는 디버깅(debugging)이 매우 어렵다. 그래서 2진 코드로 된 기계어 대신 우리의 일상 언어에 가까운 기호(symbol)를 쓰는 것이 어떻겠느냐는 의견이 나왔다. 예컨대 00000100 대신 INC A이라고 하면 Increment Accumulator(A←A+1)가 연상되고, 11101000 대신 MOV A, R0라고 하면 Move R0 to Accumulator(A←R0)가 연상되므로, 이해도 쉽고,

□표 3.2  8051 니모닉 코드의 일부

니모닉 코드	대응되는 기계어	내 용
MOV A, R0 MOV R0, A ADD A, R0 SUBB A, R0 INC A DEC A CPL A CLR A	11101000 11111000 00101000 10011000 00000100 00010100 11110100 11100100	A←R0 R0←A A←A／R0 A←A１R0１C A←A／1 A←A１1 A← A A←0

프로그램 작성도 쉬우며, 에디팅이나 디버깅도 쉽지 않겠느냐는 의견이다. 이런 의견에 따라 □기계어를 기호화한 언어□가 나오게 되었는데, 이것을 어셈블리語(assembly language)라고 한다. 그리고 어셈블리語에서 기계어와 1 대 1의 대응 관계에 있는 알파벳 코드를 니모닉 코드(mnemonic code)라고 한다. 표 3.2는 표 3.1의 기계어와 1 대 1의 관계에 있는 니모닉 코드이다.

여기서 반드시 명심할 것이 있다. 그것은 컴퓨터가 알아들을 수 있는 언어는 0과 1만으로 된 기계어 뿐이라는 사실이다. 그러므로, 어셈블리語로 작성된 프로그램을 컴퓨터에 아무리 넣어 보았자 소용이 없고, 이것을 기계어로 고쳐서 컴퓨터에 넣어 주어야 한다. 어셈블리語로 작성된 프로그램을 原始프로그램(source program)이라고 하고, 기계어로 고쳐진 프로그램을 目的프로그램(object program)이라고 한다.

그러면 어떻게 어셈블리語로 작성된 原始프로그램을 기계어로 된 目的프로그램으로 고치는가?

간단한 경우에는 命令코드表를 보면서 고칠 수 있다. 예컨대 MOV A, R0을 11101000으로 표 3.2와 같은 표를 보면서 고치는 것이다. 실제로 컴퓨터 발전의 초기에는 이렇게 일일이 사람이 표를 보면서 고쳤다고 한다. 그러나, 현재에는 대부분의 경우 어셈블러(assembler)라는 번역용 프로그램의 힘을 빌어서 컴퓨터가 고친다. 방법은 사람이 표를 보면서 하나하나 고치는 것과 같다. 그림 3.1은 이 관계를 나타내고 있다.

어셈블리語는 기계어를 기호화함으로써 이해하기 쉽고, 프로그램하기 쉬우며, 에디팅이나 디버깅하기 쉽다는 점에서 매우 편리한 언어이다. 그러나 기계어와 1 대 1의 대응 관계에 있으므로, 수많은 명령들을 하나하나 단계적으로 해주어야 한다는 점에서는 기계어와 다를 바 없다. 예컨대, YＡ2X／6이라는 간단한 계산을 하는 데도 10여 개의 명령이 있어

그림 3.1  어셈블 처리 과정

야 한다. 더구나 어차피 컴퓨터에 의해서 기계어로 고쳐야 하므로 □이왕 그럴 바엔 그렇게 많은 과정을 거칠 필요가 있겠는가? 그저 YＡ2.0*X／6.0이라고 우리 인간은 써 주고, 컴퓨터가 이것을 기계어로 바꿀 때 여러 과정으로 나누어주면 되지 않겠느냐□라는 의견이 나오게 되었다. 이러한 의견에 따라 우리가 일상 쓰는 언어 또는 계산식에 가까운 표현으로 프로그램을 작성하는 프로그래밍言語가 출현하였는데, 이것을 컴파일러語(compiler language) 또는 고급 言語(high level language)라고 한다. 그러므로, 컴파일러語는 □기계어를 일상 언어화한 것□이라고 할 수 있다.

컴파일러語에는 하늘의 별 만큼이나 많은 것들이 있으나, 마이크로콘트롤러에서 사용되는 것에는 BASIC, FORTRAN, PASCAL, PL/M, C 등이 있다.

어느 것이든 간에 이러한 언어로 작성된 原始프로그램은 반드시 기계어로 된 프로그램으로 고쳐야 한다. 컴파일러(compiler)라는 번역용 프로그램의 힘을 빌어 소위 컴파일(compile)을 해야 한다.

그림 3.2  컴파일 처리 과정

컴파일러語로 프로그램을 작성하면 프로그램 작성이 쉽고, 에디팅이나 디버깅이 쉬운 장점이 있는 대신, 마이크로콘트롤러의 경우에는 하드웨어와 관련성이 있는 것에 대한 세부적인 처리가 어렵다는 단점이 있다. 그러나 이러한 단점은 프로그램 초두에 두는 헤더파일(header file)을 통하여 거의 모두 해결되고 있다.

이상에서 설명한 프로그램言語중 8051에서는 주로 어느 것을 사용하는가? 8051 개발 시스템을 포함한 대부분의 교육 및 개발 시스템은 IBM PC와 같은 데이터 처리용 컴퓨터에 연결해서 사용하도록 되어 있으므로, 8051 어셈블리語 또는 C와 같은 컴파일러語를 쓴다. 물론 개발이 끝난 실제 시스템에서는 내부 ROM 또는 외부 ROM(EPROM 또는 Flash Memory)에 기계어로 된 目的프로그램을 넣어서 쓴다.

keil software는 다음과 같이 다양한 데이터 형태를 지원하는데, 이것은 제어에 매우 효율적이다.

(1) bit / 비트

bit는 1과 0의 불(Boolean)값을 갖는 단일 비트 오퍼랜드이다. 원래 C는 비트 데이터를 다루기 어렵게 되어 있으나, 마이크로콘트롤러에 따라서는 BITSET나 BITCLR, 또는 BITTST 명령으로 직접 비트 데이터를 처리하는 것도 있으나, 일반적으로 16진수와의 AND, OR, XOR 등의 연산으로 비트 데이터를 처리한다.

(2) unsigned char/바이트

unsigned char는 0에서 255 사이의 값을 갖는 부호가 없는 8비트 변수(variable)이다. 바이트 데이터에 대하여 산술연산이나 비교와 같은 관계연산(relational operation)을 할 수는 있으나, 결과는 모듈로(modulo) 256으로 해석되어야 한다. 결과가 모듈로 256이라 함은 결과값을 256으로 나누고 그 나머지 값만을 실제 결과값으로 한다는 것을 의미한다. 예컨대 결과값 259를 모듈로 256하면 3이 된다.

unsigned char에 대한 논리연산은 비트별로 이루어지는데, 바이트 내의 비트 위치는 0에서 7까지이다.

unsigned char에 대하여는 배열(alignment)의 제한이 없기 때문에 8051 주소공간 내에는 어느 곳에서든지 사용할 수 있다.

(3) unsigned int/워드

unsigned int는 unsigned short라고도 하며, 이것은 0에서 65535 사이의 값을 갖는 부호가 없는 16비트 변수이다.

워드 오퍼랜드에 대해서 산술연산 또는 관계연산을 할 수는 있으나, 결과는 모듈로 65536으로 해석되어야 한다.

워드에 대한 논리연산도 비트별로 이루어진다.

워드는 8051 주소공간(address space)에서 짝수번지에서부터 배열된다. 워드의 하위 바이트는 짝수번지에, 상위 바이트는 홀수번지에 배치되지만, 워드에 대한 주소지정(addressing)은 하위 바이트의 (짝수)번지에 대해서 한다.

(4) signed char/단정수

signed char는 8비트 변수를 2의 보수로 표시한 것이다. 즉, 이것은 １128∼／127 사이의 값을 갖는 8비트 부호가 있는 변수이다. signed char의 8비트 중 최상위 비트(MSB)가 부호비트인데, 이것이 0이면 ／, 1이면 １의 수를 뜻한다. -의 수는 2의 보수로 표시된다.

단정수는 １128∼／127의 값을 가지므로, 연산 결과가 이 범위를 넘으면 PSW의 OV(overflow) 비트를 세트시킨다. 배열의 제한이 없기 때문에 주소공간내 어디에서든지 사용할 수 있다.

(5) signed int/정수

이것은 signed short라고도 하며, 16비트 변수를 2의 보수로 표시한 것이다. 즉, 이것은 １32,768에서 ／32,767 사이의 값을 갖는 부호가 있는 16비트 변수이다. 산술연산을 해서 결과가 이 범위를 넘으면 PSW의 OV(overflow) 비트를 세트한다. 정수는 워드와 같이 짝수 번지에서부터 배열되어야 한다.

(6) unsigned long/더블 워드

이것은 0에서 4,294,967,295 사이의 값을 갖는 부호가 없는 32비트 변수이다. stdlib에서는 32/16 나눗셈과 16×16 곱셈에서 시프트 연산의 오퍼랜드로서만 이것이 사용된다. 이들 연산에서 unsigned long은 레지스터 파일내에 있어야 하고, 주소는 4로 나누어지는 번지에 배열되어야 한다. 이것도 최하위 바이트에 의해서 주소지정된다.

(7) signed long / 롱정수

이것은 32비트 변수를 2의 보수로 표시한 것이다. 즉, 이것은 １231(１2,147,483,648)에서 231１1(／2,147,483,647) 사이의 값을 갖는 부호가 있는 32비트 변수이다.

32/16 나눗셈과 16×16 곱셈에서 시프트 연산의 오퍼랜드로서만 이 데이터 형태는 인정된다.

signed long도 정규화(normalize)될 수 있는데, 그러기 위해서는 이것이 레지스터 파일내에 있어야 하고, 4로 나누어지는 번지에서부터 배열되어야 한다. 이것도 최하위 바이트의 주소로 주소지정된다.

직접 지원되지 않는 signed long에 대한 연산은 두 개의 정수연산으로 실현할 수 있다.

구 분	데이터의 형태	바이트의 수	값
부호가 없는 변수	bit/비트		1 또는 0
	unsigned char / 바이트		0∼255
	unsigned int / 워드		0∼65535
	unsigned long/ 더블 워드		0∼4,294,967,295
부호가 있는 변수	signed char /단정수		１128∼／127
	signed int /정수		１32,768∼／32,767
	signed long / 롱정수		１2,147,483,648∼ ／2,147,483,647

그림 3.3  오퍼랜드의 형태

주소지정방식(addressing mode)은 □오퍼랜드의 실효 주소(effective address) 표시법□이다. 전술한 바와 같이, 하나의 명령어는 命令코드와 오퍼랜드로 구성되는데, 그 중 命令코드(op code)는 그 명령으로 해야 할 동작(operation)이고, 오퍼랜드(operand)는 명령의 대상인 데이터, 또는 데이터가 들어 있는 번지이다. 주소지정방식은 명령의 대상인 데이터 그 자체, 또는 데이터가 들어있는 번지를 표시하는 방식이다. 즉, 명령의 대상인 오퍼랜드의 실효 주소를 표시하는 방식이다. 바꿔말해서, 명령의 대상인 오퍼랜드가 어디에 있는지, 그 소재처를 밝히는 것이다. MOV A, R1과 같이 오퍼랜드의 소재처가 레지스터이면 레지스터 주소지정방식이고, MOV A, 80H와 같이 오퍼랜드의 소재처가 어느 번지이면 직접 주소지정방식이며, MOV A, @R1 또는 MOV A, @DPTR와 같이 오퍼랜드의 소재처가 레지스터가 지정하는 번지이면 레지스터 간접 주소지정방식이고, MOV A, #80H와 같이 오퍼랜드가 직접 수치로 부여되면 즉시 주소지정방식이고, MOVC A, @A+DPTR과 같이 오퍼랜드의 소재처가 (베이스 레지스터+인덱스 레지스터)가 지정하는 번지이면 베이스／인덱스 간접 주소지정방식이다.

이처럼 주소지정방식은 오퍼랜드의 소재처가 어디냐의 문제이지만, 점프(jump) 또는 브랜치(branch) 명령만은 명령의 대상인 오퍼랜드가 어디에 소재하느냐의 문제가 아니고, 어디로 건너 뛰느냐의 문제이다. 즉 프로그램카운터의 내용을 바꾸는 문제이다. AJMP 01B3H와 같이 13비트 표시의 어떤 절대번지로 뛰면 절대 주소지정방식이고, LJMP 2DB3H와 같이 16비트 표시의 절대번지로 뛰면 롱 주소지정방식이며, SJMP 03H와 같이 현재의 위치로부터 (offset+2)만큼 건너 뛰면 상대 주소지정방식이다.

8051에서 사용되는 이상의 주소지정방식을 요약하면 다음과 같고, 이들 주소지정방식과 명령의 대상인 오퍼랜드와의 관계를 표로 나타내면 다음 표 3.3과 같다.

그림 3.4  8051의 주소지정방식

마이크로콘트롤러 8051에는 이상과 같은 주소지정방식이 있으나, C와 같은 고급언어로 프로그램을 작성하는 경우에는 이를 의식할 필요가 없으므로 이에 대한 자세한 설명은 생략한다.

□표 3.3  주소지정방식과 그 내용

주소지정방식	오퍼랜드의 실효 주소	예
레지스터 주소지정방식	레지스터 뱅크내 워킹레지스터, A, B, DPTR, CY	MOV A,R1
직접 주소지정방식	00H∼0FFH 번지 (범용 레지스터와 특수기능레지스터)	MOV A,70H
레지스터 간접 주소지정방식	R0나 R1이나 DPTR이 지정하는 번지	MOV A,@R0 MOVX A,@R1 MOVX A,@DPTR
베이스+인덱스 주소지정방식	프로그램 메모리의 (베이스+인덱스) 번지	MOVC A,@A+DPTR
즉시 주소지정방식	정수	MOV A,#80H
절대 주소지정방식	13비트 표시의 절대번지	AJMP 01B3H
롱 주소지정방식	16비트 표시의 절대번지	LJMP 20B3H
상대 주소지정방식	(offset+2)만큼 떨어진 번지	SJMP 03H

8051에는 111개나 되는 강력한 니모닉 코드를 가지고 있다. 그러나, C와 같은 고급언어로 프로그램을 작성할 경우에는 니모닉 코드 단위의 명령어는 불필요하여 이들 명령어에 대한 설명은 생략한다.

프로그램을 작성할 때 그것을 직접하면 자칫 오류(error)를 범하기 쉽다. 그리고, 일단 오류를 범할 경우 그것을 고친다는 것은 새로 프로그램을 작성하는 것보다 더 힘들 때도 있다. 특히 기계어나 어셈블리語와 같은 저급어로 작성할 때에는 더욱 그렇다. 그러므로, 특히 초보자는 다음과 같은 단계를 거쳐서 프로그램을 작성함이 바람직하다.

① 문제의 해석

② 순서도(flow chart)의 작성

□ 코딩(협의의 프로그래밍)

□ 디버깅(debugging)

(1) 문제의 해석

이는 문제의 핵심을 파악하고, 가능한한 수식화하는 과정이다. 말은 쉽지만 실제로 어떤 문제의 핵심을 파악하고 그것을 수식화한다는 것은 그리 쉬운 일이 아니다. 그러나, 대개의 경우 □이 문제가 목적으로 하는 바가 무엇인가□, □이 문제에 대한 실예는 무엇인가□, 즉 그 문제에 대한 目的과 實例를 따짐으로써 쉽게 그 핵심을 파악하고 수식화할 수 있다. 그래서 이 책에서는 문제의 해석을 目的과 問題例라는 이름으로 해설하고자 한다.

(2) 순서도의 작성

이는 그 문제를 푸는 방법 및 순서를 그림으로 나타내는 과정이다.

순서도의 장점은 다음과 같다.

첫째로, 순서도를 작성함으로써 문제의 처리 과정, 즉 데이터의 처리 순서가 전반적으로 파악되고, 논리적인 모순이라든가 처리상의 잘못이 쉽게 발견된다.

둘째로, 후에 자기 또는 다른 사람에게 그 프로그램의 내용 및 논리를 이해시키기가 쉽다.

셋째로, 여러명의 프로그래머가 프로그램을 공동 개발할 때 서로 협력하고 상의하기가 쉽다.

(3) 코딩(coding)

이는 순서도를 프로그래밍言語, 즉 컴퓨터言語로 옮기는 과정이다.

프로그램은 컴퓨터가 직접 이해할 수 있는 기계어로 작성함이 바람직하나, 이것이 어렵기 때문에 어셈블리語나 컴파일러語로 작성하는 것이 일반적이라는 것은 이미 논하였다.

(4) 디버깅(debugging)

이는 프로그램중의 오류를 찾아내는 과정이다.

오류에는 문법적인 오류와 논리적인 오류가 있다. 문법적 오류(semantic error)는 어셈블 또는 컴파일 중에 컴퓨터가 지적해 주므로 크게 문제가 되지 않는다. 문제는 논리적 오류(logical error)이다. 이것은 컴퓨터가 지적하지 못한다. 논리적 오류를 찾아내는 방법에는 컴퓨터 덤프(computer dump)와 추적 루틴(tracer routine)이 있다. 전자는 관계 메모리의 내용을 모두 출력(dump)하는 방법이다. 출력해서 각 번지의 내용을 비교 검토함으로써 오류를 찾아낸다. 후자는 프로그램중에 임시 명령을 넣어서 도중도중의 중간 결과를 출력하는 방법이다. 도중도중의 중간결과를 출력해서 검토함으로써 오류를 찾아 낸다. 추적루틴의 일종에 싱글스텝 실행 방법이 있다. 근래에는 싱글스텝(single step) 기능이 거의 모든 트레인 키트 또는 인서키트 에뮬레이터 또는 시뮬레이터에 구비되어 있는데, 이 기능을 이용하면 논리적인 오류를 발견하는 데 크게 도움이 된다.

디버깅, 특히 문법적 오류에 대한 디버깅은 原始프로그램을 컴퓨터에 입력시킨 후 어셈블 또는 컴파일하는 중에 이루어진다. 그러므로, 디버깅은 프로그램 실행 과정의 일부로 보아야 하나, 편의상 여기에서 다룬다.

일반적으로 디버깅이라고 하면 이상과 같은 소프트웨어 디버깅을 뜻한다. 그러나 때로는 하드웨어 디버깅이 문제로 되는 경우도 있다. 마이크로콘트롤러에 의해서 제어되는 시스템을 개발할 때에는 먼저 하드웨어를 개발하고, 그 후에 하드웨어를 움직일 소프트웨어를 개발하기 마련인데, 막상 개발된 시스템이 동작하지 않을 경우에는 어느 쪽에서 문제가 생겼는지, 둘 다 의심을 해야 하기 때문이다.

아무튼, 디버깅은 시스템의 개발에 있어서 가장 어렵고 시간이 많이 걸리는 부분이다. 개발된 시스템이 제대로 동작하지 않을 경우에는 하드웨어와 소프트웨어 둘 다 의심할 수 밖에 없지만, 막상 소프트웨어에 문제가 있다는 것이 확실하다고 해도 어디에 잘못이 있는지를 찾아내기란 그리 쉬운 일이 아니다. 컴퓨터 덤프나 추적도 매우 힘들고 잘되지 않는 경우가 대부분이고, 무엇보다도 시간이 매우 많이 걸린다. 프로그램의 ROM 기록도 수십번 이루어져야 한다. 이처럼 시간이 많이 걸리고 번거로운 작업을 손쉽고 빨리하기 위해서 개발된 것이 다음에 논하는 인서키트 에뮬레이터(in-circuit emulator)이다.

문제의 해석, 순서도의 작성, 코딩 등의 과정을 밟아서 작성된 소위 原始프로그램(source program)은 그대로 실행될 수 없다. 原始프로그램을 컴퓨터에 입력하여 소위 소스 파일(source file)을 만들어야 하고, 어셈블러 또는 컴파일러의 힘을 빌어 기계어로 번역도 해야 하며, 오류가 있으면 디버깅도 해야 하고, 目的프로그램이 여러 모듈로 되어있는 경우에는 링커(linker)라는 프로그램에 의하여 이들을 링크(link)도 해야 한다. 또한 8051 트레인 키트나 인서키트 에뮬레이터나 타깃 시스템(target system)에 전송하기 위한 형태(Hex file)로 고쳐서, 이것을 이들에게 전송(down loading)을 해야 한다. 그런 뒤에야 인서키트 에뮬레이터나 트레인 키트나 타깃 시스템에서 실행을 할 수 있다. 그림 3.5는 이러한 관계를 설명하고 있다. 여기서 타깃 시스템(target system)이란 마이크로컴퓨터에 의한 제어장치(microcomputer- based control system)를 말한다. 즉 기계를 개발할 때 그 기계를 제어하는 장치를 마이크로

그림 3.5  프로그램 실행 과정

콘트롤러로 만들 경우 그 제어장치를 타깃 시스템이라고 한다.

일반적인 프로그램 실행 과정은 이상과 같지만, 실제로는 시스템에 따라 실행 과정이 다소 다르다. 대개의 마이크로콘트롤러는 그 목적상 제어 프로그램만을 내장하므로 그 자신은 이러한 작업을 하지 못하기 때문이다. 즉 대부분의 마이크로콘트롤러는 소스 파일을 작성하는 에디터(editor)도, 기계어로 번역하는 어셈블러(assembler)나 컴파일러(compiler)도, 여러 모듈을 링크하는 링커(linker)도 그 자신은 내장하지 않고, 오직 제어 프로그램만을 내장한다. 그러므로, 그 자신은 소스 파일의 작성도, 어셈블(또는 컴파일)도, 링크도 하지 못한다. 결국 마이크로콘트롤러는 실제 제어장치에서 사용되는 것이든, 트레인 키트로서 교육에 사용되는 것이든 간에 외부에서 작업을 해서 마이크로콘트롤러에 넣어 주어야 한다. 그런데, 외부에서 이들 작업을 하는 방법에는 두 가지가 있다. 그 중 하나는 이 모든 것을 수작업으로 해서 결과로 만들어진 目的프로그램을 일일이 각 번지에 넣어 주는 방법이고, 다른 하나는 IBM PC와 같은 호스트 컴퓨터로 이들 작업을 해서 마이크로콘트롤러에 down loading을 하는 방법이다. 전자를 수작업에 의한 방법, 후자를 컴퓨터에 의한 방법이라고 하는데, 지금은 특수한 경우 외에는 후자의 방법에 의한다.

8051 시스템을 개발하는 데 지원되는 하드웨어 툴(hardware tool)에는 트레인 키트와 ROM 에뮬레이터와 인서키트 에뮬레이터와 ROM 라이터가 있다.

트레인키트(training kit)는 마이크로콘트롤러의 원리와 프로그램을 교육할 목적으로 개발된 교육용 마이크로콘트롤러 시스템이다. Z80 트레인 키트와 같은 것에서는 CPU, ROM, RAM, I/O포트, 타이머 등의 컴퓨터 기본 구성 요소들이 각각 독립된 칩으로 되어 있기 때문에 사용자가 이들을 직접 관찰할 수 있지만, 8051과 같은 단일 칩 마이크로콘트롤러에서는 이들이 모두 하나의 칩에 내장되어 있기 때문에 외부에서 직접 관찰하기가 어렵다.

아무튼 8051 트레인 키트가 있으면 마이크로콘트롤러의 원리와 프로그램 교육에 크게 도움이 된다.

트레인키트의 구조상 특징은 □프로그램을 RAM에□ 저장할 수 있도록 되어 있다는 것이다. 기계를 제어하는 제어장치(microcomputer based control system)가 마이크로컴퓨터로 되어 있을 때 이것을 타깃 시스템이라고 한다 함은 앞에서 언급하였다. 타깃 시스템에서는 프로그램이 ROM에 저장된다. ROM에 프로그램을 저장해 두고 언제나 같은 루틴을 반복 수행함으로써 시스템을 제어한다. 그러나 트레인키트에서는 프로그램이 수시로 바뀌어야 하므로 이를 RAM에 넣어 둘 수 밖에 없다. 이 때 ROM에는 모니터 프로그램을 넣어 둔다. 이처럼 트레인키트에 있어서는 프로그램을 RAM에 저장하지만, 근래에 출시되는 마이크로콘트롤러 중에는 ROM이 플래시 메모리로 되어 있는 것이 많고, 이런 것들은 ROM을 RAM처럼 지웠더 썼다 할 수 있기 때문에 따로 RAM에 기록하지 않고 ROM(플래시 메모리)에 기록한다.

시판되는 8051 트레인 키트에는 최소한의 구성에서부터 복잡한 것에 이르기까지 여러 가지가 있는데, 전술한 바와 같이, 프로그램 시작번지가 제품에 따라 프로그램 적재 공간이 다르니 ORG 설정에 유의해야 한다. 8051 트레인키트 중 디지털제어 산업기사에서 현재 사용되고 있는 것에 대해서는 뒤에서 따로 설명한다.

ROM 라이터(ROM writer)는 ROM 프로그래머(ROM programmer)라고도 하는 것으로서, 작성된 프로그램(Hex file)을 칩 내장의 EEPROM 또는 EPROM 또는 플래시 메모리에 기록하는 장치이다.

ROM 라이터로 프로그램을 개발하려면 이것 외에도 ROM 소거기와 타겟 시스템이 필요하고, ROM 라이팅, 칩의 타겟 시스템에의 장착, 실험, ROM 소거 등의 귀찮은 작업을 반복해야 한다. 뿐만 아니라 칩 내부의 프로그램 실행 상황을 알 수 없어서 프로그램의 디버깅에 어려움이 크다. 그러긴 하나, 비교적 고가인 인서키트 에뮬레이터를 구입할 수 없는 입장에서는 이를 사용할 수 밖에 없다.

시판되는 ROM 라이터에는 All-11 등 여러 가지가 있으나, 8051과 AT89S51 및  AT89C2051이 지원되는 것은 어느 것이든 상관없다.

ROM 라이터는 좀 귀찮기는 해도 올바로 마이크로콘트롤러를 공부하는 데는 매우 유용하다. 학생들은 이를 사용하여 □Vision에서 만든 Hex파일을 8751 또는 AT89S51 또는 AT89C2051에 기록한 후 실제 시스템에 꽂아 쓰기를 적극 권장한다.

ROM 에뮬레이터(ROM emulator)는 신제품의 개발 중 타깃 시스템의 임시 ROM 역할을 하는 장치이다.

마이크로콘트롤러로 제어되는 신제품을 개발할 때에는 하드웨어를 구성한 후에도 그 하드웨어를 제어하는 프로그램을 개발해야 하는데, 여기에 많은 시간과 노력이 필요하게 된다. 프로그램을 개발하자면 프로그램의 내용을 변경해 가면서 그 동작 상태를 확인해야 하기 때문이다. 그런대, 프로그램의 내용을 변경할 때마다 그것을 ROM 라이터로 ROM에 기록해 넣어서 장착해야 한다고 한다면 엄청난 시간과 노력이 필요하게 될 것이다. 그래서 그림 3.6과 같이 IBM PC와 같은 호스트컴퓨터에서 프로그램을 변경해서 ROM 에뮬레이터에 보내면, 이것이 타깃 시스템의 ROM 역할을 함으로써 개발을 빠르고 쉽게 한다. ROM 에뮬레이터는 호스트컴퓨터가 보낸 프로그램을 자신의 RAM에 저장한다.

Z80과 같이 ROM을 CPU 외부에 두는 시스템에서는 ROM 에뮬레이터를 사용할 수 있지만, 8051과 같이 ROM이 내부에 있는 시스템에서는 그 실현이 어렵다. 그러나 8031과 같은 ROM 외장형에서는 그것이 가능하다.

그림 3.6 ROM 라이터

그림 3.7  ROM 에뮬레이터

인서키트 에뮬레이터(ICE＞In-Circut emulator)는 본격적인 마이크로콘트롤러 개발장치(Microcontroller Development System)로서, 신제품 개발중 이것이 타깃 시스템의 마이크로콘트롤러 역할을 한다. Z80과 같은 멀티 칩 마이크로콘트롤러의 인서키트 에뮬레이터에서는 인서키트 에뮬레이터가 타겟 시스템의 CPU와 ROM 역할만을 하지만, 8051과 같은 단일 칩 마이크로콘트롤러의 인서키트 에뮬레이터에서는 인서키트 에뮬레이터가 타겟 시스템의 마이크로콘트롤러 역할을 한다.

그림 3.8과 같이 개발된 原始프로그램을 호스트컴퓨터가 어셈블(또는 컴파일)하고 디버깅해서 Hex파일로 만든 후, 인서키트 에뮬레이터에 보내면(down loading), 인서키트 에뮬레이터는 그 프로그램을 자신의 메모리에 저장하고, 이 프로그램을 자신의 마이크로콘트롤러(8051)로 실행시킨다. 인서키트 에뮬레이터의 외부핀 40개는 모두 밴드선을 통하여 타깃 시스템의 마이크로콘트롤러 자리에 들어가므로 인서키트 에뮬레이터가 곧바로 타깃 시스템의 마이크로콘트롤러로서 동작하는 셈이다. 다시 말해서 타깃 시스템에서 마이크로콘트롤러를 빼내 버리고, 그 자리에 인서키트 에뮬레이터의 외부 핀 40개를 꽂아 놓음으로써, 인서키트 에뮬레이터가 곧바로 타깃 시스템의 마이크로콘트롤러 역할을 하도록 한다.

이처럼 인서키트 에뮬레이터는 시스템 개발에 가장 편리한 것이긴 하나, 너무 고가이어서 구입에 문제가 있다.

그림 3.8  인서키트 에뮬레이터

지금까지 논한 것이 마이크로콘트롤러 개발 지원 툴(tool) 중 하드웨어 툴 이다. 개발 지원 툴은 MDS(Microcontroller Development System)라고도 하는 것으로서, 마이크로콘트롤러 메이커가 제공하는 각종 개발 지원 시스템을 일컫는다. 여기에서는 개발 지원 툴 중 스프트웨어 툴에 대하여 논한다.

소프트웨어 툴은 PC상에서 운용되는 개발용 프로그램을 말한다. 대표적인 것으로서 에디터, 크로스 어셈블러, 크로스 컴파일러, 다운 로더, 시뮬레이터 등이 있다.

에디터(editor)는 전술한 바와 같이, 시스템 프로그램의 유틸리티 프로그램에 속하는 것으로, text를 새로 만들거나 기존의 text를 수정하는 데 사용된다. text란 편집된 문자열(character string)을 말한다. 그것은 프로그램으로 될 수도 있고, 데이터로 될 수도 있다. DOS용으로서는 EDLIN, Q, TURBO 등이 흔히 사용되는 에디터이고, window용으로서는 메모장이 흔히 사용되는 에디터이나, Keil Software에서는 별도의 에디터도 제공하고 있다. 이것은 특히 프로그램의 어셈블 또는 컴파일 중 에러를 수정할 때 유용하다.

크로스 어셈블러(cross assembler)는 어떤 컴퓨터의 어셈블리語로 작성된 原始프로그램을 별개의 다른 컴퓨터가 어셈블할 때 그 어셈블러를 일컫는다. 예컨데 8051 어셈블리語로 작성된 프로그램을 IBM PC가 어셈블할 때 IBM PC의 어셈블러를 크로스 어셈블러라고 한다.

일반적으로 마이크로콘트롤러는 제한된 메모리 용량 때문에 자신의 어셈블리語로 작성된 原始프로그램을 자신이 기계어로 번역하는 어셈블러를 내장할 수 없다. 그래서 IBM PC와 같은 별개의 컴퓨터가 이를 대신해서 어셈블을 해 주어야 하는데, 이 어셈블러를 크로스 어셈블러라고 하는 것이다. 흔히 사용되는 8051의 크로스 어셈블러에는 A8051.EXE가 있다.

크로스 컴파일러(cross compiler)는 어떤 컴퓨터의 컴파일러語로 작성된 原始프로그램을 별개의 다른 컴퓨터가 컴파일할 때 그 컴파일러를 일컫는다. 흔히 사용되는 8051의 크로스 컴파일러에는 51C.EXE가 있다. keil software의 □Vision에는 크로스 어셈블러와 크로스 컴파일러가 내장되어 있다.

다운 로더(down loader)는 PC에서 어셈블(또는 컴파일)해서 전송 포맷화한 헥사 파일(Hex file)을 트레인 키트의 메모리, ROM 에뮬레이터의 메모리 또는 인서키트 에뮬레이터의 메모리에 적재(load)시키는 프로그램이다.

끝으로 시뮬레이터(simulator)는 작성된 프로그램이 실제 칩상에서 어떻게 동작하는지를 PC상에서 모의실험(simulate)하는 프로그램이다. 지금껏 시뮬레이터는 사용 방법이 복잡하고 한계가 너무 커서 잘 사용되지 않았지만, 근래에 나온 시뮬레이터는 매우 잘 되어 있어서 마이크로콘트롤러를 공부하려는 분에게 긴요한 보조도구가 되리라고 믿는다. 시뮬레이터의 가장 큰 장점은 IBM PC(호환종)와 이 프로그램만 있으면 트레인 키트나 인서키트 에뮬레이터, 그리고 귀찮은 외부 실험장치를 만들지 않더라도 얼마든지 실험(simulate)을 할 수 있다는 데 있다. keil software의 dScope는 □Vision에서 만든 obj 파일을 시뮬레이션하는 시뮬레이터이다.

이상과 같은 소프트웨어 툴 중 Keil Sofeware가 지원하는 것에는 다음과 같은 것들이 있다.

에디터

Keil Software는 text를 새로 만들거나 기존의 text를 수정하는 데 사용되는 에디터를 제공한다. 그러나 Q나 EDLIN나 메모장과 같은 기존 에디터를 사용하는 데 익숙한 사람은 새로운 text를 만들 때 구태여 이를 사용할 필요는 없다. 다만 이를 이용하여 프로그램 실행을 위한 작업을 하다가 프로그램을 수정할 필요가 있어서 후술하는 edit project 작업을 할 때, 또는 [eqn: mu `]Vision화면의 □Edit□에 클릭할 때 나타나는 프로그램에서 이를 수정하는 것이 훨씬 손쉽기 때문에 이런 경우에는 이 에디터를 사용함이 편리하다.

크로스 어셈블러

Keil Software는 재배치가 가능한(relocatable) 크로스 어셈블러로서 A51 Macro Assembler를 제공한다.

크로스 컴파일러

Keil Software는 역시 재배치가 가능한 크로스 C컴파일러로서 C51 Optimizing C compiler를 제공하고 있다.

디버깅

Keil Software는 single step, break-point, trace, timer, run history 등의 기능을 이용하여 빠르고 능률적으로 디버깅할 수 있는 dScope Debugger를 제공한다.

링커

Keil Software는 링커 및 relocator로서 BL51 Code Banking Linker/Locator를 제공하고 있다.

기타 : keil software는 다음과 같은 프로그램을 제공한다.

OC51 Banked Object File Converter

OH51 Object-Hex converter

LIB51 Library Manager

dScope-51 Target Debugger

Monitor-51 ROM Monitor and Terminal program

RTX-51 Tiny Real Time OS

Keil Software는 또한 윈도우 사용자를 위해서 다음과 같은 툴(tool)을 제공한다.

□Vision/51＞Integrated Development Environment for Windows

이것은 편집을 위한 에디터, 프로젝트(project) 관리를 위한 프로젝트 매니저, 8051 환경을 제어하는 도구 등을 포함하고 있다.

dScope＞Simulator/Debugger for Windows

이것은 소스 레벨의 디버거이고 시뮬레이터로서, Keil C51 compiler, A51 assembler, Intel PL/M-51 compiler, ASM-51 assembler 등으로 컴파일 또는 어셈블을 한 뒤 BL51 Code Banking Linker/Locator로 링크한 ABS OBJ 프로그램을 시뮬레이트한다. 이것은 I/O포트, 타이머, 직렬포트 등 다양한 주변기기를 외부장치에 연결함이 없이 시뮬레이트할 수 있도록 한다.

Keil Sofeware를 설치하기 위해서는 우선 사용자가 다음과 같은 사양을 가진 컴퓨터를 구비해야 한다.

·386 이상의 IBM 호환 컴퓨터

·윈도우 3.1 이상(윈도우 기반의 경우)

·4MB 이상의 메인 메모리

·6MB 이상의 하드디스크 용량

하드웨어 설치가 끝나면 이젠 이것을 구동할 소프트웨어로서 Keil Sofeware를 설치할 차례이다.

다음의 기본 디렉토리에 이들을 복사해 넣는다.

디렉토리	툴 종류
\C51 \C51EVAL	8051 개발 툴 8051 평가 툴

이들 중 개발 툴은 다음 목록의 서브디렉토리(subdirectory)에 복사해 넣는다.

서브 디렉토리	설치 소프트웨어
...\ASM ...\BIN ...\DS51 ...\EXAMPLES ...\RTX51 ...\RTX_TINY ...\INC ...\LIB ...\MON51 ...\TS51	어셈블러가 포함된 디렉토리 실행파일 DOS IOF 드라이버용 dScope-51 샘플 응용 프로그램 RTX-51 Full files RTX-51 Tiny files C 컴파일러가 포함된 디렉토리 C 컴파일러 라이브러리 파일과 시작코드(start-up code) Target monitor files DOS IOT 드라이브용 TScope-51

이들을 설치하는 방법은 대략 다음과 같다. 자세한 것은 한국MDS(주)에서 제공하는 □8051/251 Evaluation kit 매뉴얼□과 □DScope for window□를 참조하기 바란다. 또 이미 Keil Software가 설치되어 있는 경우에는 이 부분을 건너 뛰어도 된다.

(1) DOS 기반의 경우

이 책에 첨부된 CD를 CD 드라이브에 넣고, INSTALL이라고 타이핑한 후 ENTER 키를 누른다.

C＞\INSTALL □

이제 프로그램에 나오는 명령대로 하기만 하면 된다.

(2) 윈도우 기반의 경우

역시 첨부 CD를 CD드라이버에 넣고, 프로그램 매니저의 File 메뉴에서 Run을 선택한다. 명령라인에서 A＞SETUP을 타이핑하고 OK를 선택한다. 나머지는 역시 설치 프로그램에서 하라는 대로 하기만 하면 된다.

시뮬레이터의 설정이 끝나면 컴파일러와 유틸리티가 도스환경에서 파일과 라이브러리를 포함하도록 경로(path)를 설정해야 하고, …\BIN\ 디렉토리도 추가해야 한다. 다음 표는 환경변수와 기본경로와 이들에 대한 설명이다.

변 수	경 로	설 명
PATH PATH TMP C51INC C51LIB	\C51\BIN \C51EVAL\BIN \C51\INC \C51\LIB	8051 개발 툴(development tool)의 경로를 정한다. 8051 평가 툴(evaluation tool)의 경로를 정한다. 임시로 생성된 파일의 경로를 지정한다. 가장 좋은 것은 RAM 디스크를 정하는 것이다. 환경변수를 설정하려면 경로가 지정되어야 한다. 경로가 없으면 □fatal error□라고 표시하고 실행을 중단한다. 표준 C51 컴파일러의 경로를 지정한다. 표준 C51 컴파일러 위치의 경로를 지정한다.

환경 설정은 설치 프로그램이 AUTOEXEC.BAT에 자동적으로 추가하며 배치 파일에 이 설정을 넣으려면 다음과 같이 해야 한다.

8051 개발 툴	8051 평가 툴
PATH=C＞\C51\BIN;… SET C51INC=C＞\C51\INC SET C51LIB=C＞\C51\LIB	PATH=C＞\C51EVAL\BIN;… SET C51INC=C＞\C51EVAL\INC SET C51LIB=C＞\C51EVAL\LIB

여기에서는 Keil Software가 제공하는 □Vision과 dScope를 이용하여 윈도우 기반의 툴을 사용하는 방법을 간단히 설명한다. 자세한 것은 역시 한국MDS가 제공하는 □8051/251 Evaluation kit 매뉴얼□과 □dScope for windows□를 참조하기 바란다. 이 책에 첨부된 CD에도 사용방법을 해설해 놓았으므로 이를 참조하기 바란다.

윈도우 상에서 Keil Software를 시작하기 위해서는 설치 프로그램이 만들어 놓은 그림 3.9와 같은 윈도우 화면에서 아이콘 □Vision을 더블클릭해야 한다. 즉 설치 프로그램은 □

그림 3.9  □Vision과 dScope가 있는 윈도우 화면

Vision과 dScope라는 두 개의 아이콘을 만들어 놓는데, 먼저 □Vision을 선택하여 여기에서 소스 파일도 만들고, 소스파일을 편입시킬 프로젝트도 지정하고, 어셈블 또는 컴파일도 하고, 링킹도 해야 한다. 그럼으로써 시뮬레이션에 사용될 Obj 파일과 ROM 라이팅에 사용될 Hex 파일을 만들어야 한다. 그런 다음, 시뮬레이터 dScope를 이용하여 프로그램을 시뮬레이션하고자 하는 경우에는 dScope를 선택하여 여기에서 실행시킬 CPU도 선택하고, 주변장치도 선택하고 프로그램이 들어있는 프로젝트를 다시 불러다가 실행(simulate)시킨다.

이 프로그램을 실제 시스템에 실행시키고자 할 경우에는 □Vision에서 만들어진 Hex 파일을 ROM 라이트로 8751 또는 AT89C51 또는 AT89C2051에 기록해 넣는다.

Keil Software를 종료시키는 것은 간단하다. 윈도우 상에서 일반 프로그램을 종료시키는 것과 같이 하면 된다.

□Vision-51과 dScope-51에 의하여 프로그램을 실행시키는 방법도 그림 3.5에서 설명한 것과 같다.

1. C컴파일러어(또는 어셈블리어)로 된 소스 파일을 만든다.

2. 소스 파일을 컴파일 또는 어셈블을 하고, 링크를 한다.

3. 소스 파일에 에러가 있으면 이를 정정(debugging)한 후 다시 컴파일 또는 어셈블 및 링크를 한다.

4. 그 결과 Obj 파일과 Hex 파일이 만들어진다.

이상의 일은 □Vision-51에서 한다. □Vision-51에서 이런 일들을 하기 위해서는 먼저 Open project 작업을 하고 Edit project 작업을 한 후 Build project 작업을 해야한다.

Open project 작업(최초의 경우에는 New project 작업)은 실행시킬 프로그램을 수용할 프로젝트를 지정하기 위함이다. □Vision에서는 하나의 프로그램을 개발하는 데 필요한 모든 프로그램과 데이터를 하나의 프로젝트에 수용하고 여기에서 서로를 연결 사용하도록 되어 있다. 하나의 프로젝트에 하나의 프로그램만이 들어가게 할 수 있으나, 귀찮으니까 하나의 프로젝트에 어느 프로그램든지 들어가도록 한다.

Edit project 작업은 open project에 의해서 지정된 프로젝트에 포함될 프로그램(소스 파일)을 지정하는 과정이다.

Build project 작업은 edit project에 의해서 지정된 프로그램(소스 파일)에 대하여 컴파일(또는 어셈블)을 하고 디버깅을 하고 링크를 연속해서 한꺼번에 함으로써 obj 파일과 Hex 파일을 만드는 과정이다.

이상의 과정을 밟아서 일단 obj 파일과 Hex 파일을 만들기만 하면, 이들은 여러 가지로 사용될 수 있다. 트레인키트 또는 타킷시스템에 다운로드하여 실험할 수도 있고, IBM PC상에서 시뮬레이트할 수도 있다.

시뮬레이트하는 것은 dScope-51에서 한다. dScope-51에서 시뮬레이트를 하기 위해서는 시뮬레이트할 CPU를 먼저 선택하고, 이에 관계되는 주변장치(peripheral)를 선택한 후, □Vision-51에서 지정한 프로젝트 이름을 다시 지정 호출한 다음, Go(시뮬레이트)한다.

editor	□Vision	dScope
소스 파일의 작성	1. open project (최초에는 new project) 2. edit project 3. build project (여기서 소스 파일에 대한 컴파일(또는 어셈블), 디버깅, 링킹이 한꺼번에 이루어진다)	1. CPU의 선택 2. peripheral의 선택 3. project의 지정 4. Go(여기서 시뮬레이션이 이루어진다.

그림 3.10  시뮬레이터에 의한 프로그램 실행 과정

(1) 소스 파일의 작성

수차 언급한 바와 같이, 프로그램을 개발할 때 맨 먼저 할 일을 소스 파일(source file)을 만드는 일이다. 이것은 에디터(editor)라는 시스템 프로그램의 힘을 빌어서 사용자가 지면에 작성한 프로그램을 텍스트 파일(text file)로 만드는 과정이다. 사용되는 에디터에는 앞에서 밝힌 바와 같이 DOS의 Edlin, Q, Turbo, Window의 메모장, 그리고 Keil Software 제공의 에디터 등이 있는데, 이들 중 어느 것을 사용해도 된다. 일반적으로 이미 만들어진 소스 파일을 고친다든가 할 경우에는 □Vision 화면에서 Keil software 제공의 에디터로 하는 것이 편하고, 소스 파일을 새로 만드는 것은 DOS에 익숙한 사람에게는 DOS에서 만드는 것이 더 편하고, 윈도우에 익숙한 사람은 메모장을 사용하는 것이 더 편할 것이다. 구체적인 방법은 생략하기로 한다. 어느 것이든 에디터를 부른 상태에서 워드프로세서를 다루듯이 한자한자 타이핑하면 된다.

(2) Open project 작업

Open project 작업은 작성된 소스 파일을 수용할 프로젝트를 지정하는 과정이다. 원래 □Vision을 처음 이용하는 경우라면 Open project 작업에 앞서 New project 작업부터 해야 한다. 어느 것이든 작업은 □Vision에서 한다. □Vision에서 작업을 하기 위해서는 그림 3.9의 윈도우 화면에서 □Vision에 더블클릭을 한다. 그러면 그림 3.11(a)와 같은 □Vision 화면이 뜬다. 여기서 menu bar와 tool bar에 대해서 익혀 두어야 한다.

그림 3.11  □Vision 화면

① □Vision 화면 맨 위 메뉴바에서 □project□에(메뉴바에는 project만 있다고 해도 과언이 아닐 정도로 project가 많이 사용되므로, 항상 이것부터 클릭하는 것을 잊지말아야 한다) 마우스 클릭을 한다.

그러면 그림 3.12와 같은 프로젝트 창이 뜬다.

□Vision/51

File  Edit  Project  Run  Options  Tools  Window  Heip

Compile file

Make＞ Update Project

Make＞ Build Project

Make＞ Link Project

Download to ProROM

New Project

Open Project

Edit Project

Close Project

Project operation

그림 3.12  프로젝트 파일 대화상자

② 최초로 □Vision을 이용하는 경우이어서 새로운 프로젝트를 만들려면 □New Project□를 선택한다. 그리고 최초로 이용하는 경우가 아니어서 기존의 프로젝트를 선택하려면 □Open Project□을 선택(클릭)한다.

New Project

그림 3.13  New Project

□ 그림 3.13의 화면 중앙의 디렉토리에서 프로젝트 이름을 넣어둘 곳을 정한다. 예컨대 51C-PRG에 만들고 싶으면 hkmd에 더블클릭할 때 나타나는 것들 중 51C-PRG에 더블클릭한다.

□ 그림 3.13의 화면이 나올 때 □*.prj□의 □*□에 프로젝트 이름을 타이프하고, □*□는 지운다. 이 때 프로젝트 파일의 확장자는 자동적으로 □.prj□로 된다.

8051

□ 같은 화면에서 □확인□에 클릭한다. 이로써 새로운 프로젝트 이름이 만들어진다.

□ 전술한 바와 같이 프로젝트 이름은 하나만 만들어 놓아도 되므로 Keil software를 설치한 후 최초로 사용하는 경우가 아니면 New Project를 선택할 필요없이 Open Project를 선택한다.

이것은 □Vision 화면의 메뉴바 중 Project를 선택하고 이 때 나타나는 그림 3.12와 같은 프로젝트 대화 상자에서 □open project□에 클릭하고, 이 때 나타나는 화면(그림 3.13과 같으나 프로젝트 이름이 들어 있음)에서 프로젝트 이름에 클릭을 한 후 □확인□에 클릭하든지 아니면 프로젝트 이름에 더블클릭한다.

(3) Edit project 작업

① Open project가 끝나면 이젠 그 프로젝트 이름 밑에 현재 들어있는 프로그램(지난번 수행된 프로그램)을 없애버리고, 새로 들어갈 프로그램을 지정할 차례이다. 그림 3.12의 프로젝트 대화상자의 □project□에 클릭하고 이 때 나타나는 대화 상자에서 □Edit Project□에 클릭하면 그림 3.14와 같은 화면이 나타난다.

이 때 앞의 프로그램 실행으로 인하여 그 프로젝트 밑에 어떤 프로그램이 남아 있는 경우에는 □Remove□에 클릭함으로써 그 프로그램을 제거한 후 □Add□에 클릭하고, 프로그램이 없는 경우에는 Remove 과정 없이 처음서부터 □Add□에 클릭한다. □Add□는 에디터를 사용하여 작성한 소스 프로그램들을 이 프로젝트에 포함시키는 명령이다.

그림 3.14  Edit Project 화면

□Add□에 클릭하면 그림 3.15와 같은 창이 생긴다.

그림 3.15  Add 창(1)

② 이 화면 좌하에 있는 □파일형식(T)□의 밑에 있는  의 ∇에 클릭하면 다음과 같은 창이 나온다. 이 때 로드하려는 소스파일이 C 프로그램이면 C Source(*.C)에 클릭하고, 어셈블리어 프로그램이면 Assembly Source(*.a51)에 클릭한다. 물론 이미 이 란이 제대로 선택되어 있는 경우에는 이 과정을 생략한다. 이 과정에서 소스 파일을 어셈블 또는 컴파일 할 translator가 선택된다.

C Source(*.C)

Assembly Source(*.a51)

PL/M Source(*.plm)

Libruary Files(*.lib)

＞

③ 그림 3.15 Add 화면의 정중앙은 프로그램의 경로를 표시한다. 그러므로 지정할 프로그램의 경로가 제대로 되도록 해야 한다. 예컨대 지정할 프로그램 EX1.C가 C드라이브 hkmds의 51C_PRG라는 곳에 넣어 두었다면 경로창의 □□hkmds□에 더블클릭을 할 때 나타나는 그림 3.16의 우편과 같은 창에서 51C_PRG을 골라 더블클릭한다. 그러면 그림의 좌편과 같은 창이 뜬다. 이때 지정할 프로그램 EX1.C를 마우스를 이용하여 접근하고 이에 더블 클릭한 후 □Close□에 클릭함으로써 경로를 바로 잡는다.

51C_prj에 더블클릭

ex1.C에 더블클릭

close에 클릭

그림 3.16  Add 창(2)

④ 프로그램의 지정이 끝나면 이젠 지정된 프로그램을 CRT에 표시할 차례이다. 이것은 □Open□과 □Save□에 클릭함으로써 이루어진다. close에 클릭할 때 나타나는 화면에서 □Open□과 □Save□에 클릭하면 지정된 소스 파일이 표시된다. 표시된 소스 파일을 수정할 일이 있으면 여기서 한다.

⑤ 이로써 프로젝트와 그 밑에 들어갈 프로그램의 지정이 끝나고 프로그램의 수정도 끝났다. 이젠 이를 컴파일 또는 어셈블하고 링크할 차례이다.

(4) Build project 작업

앞에서와 같이 해서 프로젝트와 그 밑에 들어갈 프로그램이 지정되면 다음에는 이를 컴파일(또는 어셈블)하고 링킹을 하는 과정이다. 그런데 □Vision에서는 이들 작업을 하나씩 하지 않고 한꺼번에 일괄 처리하도록 되어 있다. 이것이 build project 작업이다.

① 먼저 □Vision 화면에서 Project에 클릭한다. 이 때 나타나는 그림 3.12와 같은 프로젝트 화면에서 □Make＞Build Project□에 클릭한다.

② 소스 파일에 잘못(error)이 있는 경우에는 그림 3.17과 같이 컴파일(또는 어셈블) 상태, error 파일, 소스 파일 등이 겹쳐서 나타난다.

그림 3.17  컴파일 상태와 error 파일과 소스 파일

③ 소스 파일에 Error가 있으면 위와 같이 표시되고 Project Status에 □Error(S) Reported□로 표시되는데, 이 때 OK에 클릭하면 뒷면에 있는 error 파일이 보인다. error 파일에서는 빨강선으로 Error의 위치와 error의 종류 및 내용을 표시해준다. □에 클릭함으로써 error 파일에서 벗어난 후 소스파일 화면에서 Error를 고친다. 사실은 Error가 여러개 있는 경우에도 빨강선이 하나만 표시해주므로 여러번 이 작업을 해주어야 한다.

④ Error를 정정한 뒤에는 다시 □Project□와 □make＞Build Project□에 클릭을 하는 과정을 밟는다.

⑤ 소스 파일에 Error가 없는 경우에는 컴파일(또는 어셈블)화면, 링크 화면, Hex 파일 화면이 차례로 나타난다. 그리고 status가 □Make Successful-Hex file Created□라고 표시된다. □OK□에 클릭하면 이것으로써 Build project 작업이 끝나고, 또 이로써 □Vision 영역에서 할 일이 모두 끝난다. 이로써 Obj 파일(Absolute Object file)과 Hex 파일(Hex file)이 만들어진다. Hex 파일은 ROM 라이트로 8751을 또는 AT89S51 또는 AT89C2051에 기록해서 실제 시스템에 꽂아 쓸 때 또는 트레인키트에 다운로드할 때 쓰고, Obj 파일은 시뮬레이트를 할 때 쓴다.

(5) 시뮬레이트

프로그램의 시뮬레이트는 dScope에서 한다. dScope의 선택은 리셋 후 맨처음에는 그림 3.11의 □Vision 화면 맨오른쪽에 있는 Tool bar

□

에 클릭을 함으로써 이루어지고, 그 다음부터는 맨 아래에 생긴 dScope 상태표시바에 클릭함으로써 이루어진다. 그날 최초의 경우가 아니면 맨 아래의 dScope 표시바에 클릭한다. dScope에서는 □Vision에서 만들어 놓은 obj 파일을 시뮬레이트시키는 것이 주 임무이지만 그것을 시뮬레이트하기 위해서는 시뮬레이트시킬 CPU를 선정하고, 시뮬레이트시킬 프로그램이 들어있는 프로젝트를 불러오고, 관련 주변장치, 레지스터, 인터럽트 등에 대한 창을 열고…하는 절차도 밟아야 한다.

① dScope이 선택되면 그림 3.18과 같은 dScope 화면이 뜬다.

그림 3.18  dScope 화면

② 먼저 시뮬레이트할 CPU를 선택한다. 그림 3.18의 위에서 3번째 줄에 있는

∇

의 ∇에 클릭하면 각종 CPU가 표시되는데 마우스로 ∇를 이용하여 끝까지 갈 때 나타나는 8051.Dll를 선택한다. 물론 CPU driver란에 8051.Dll이 이미 선택되어 있는 경우에는 이 작업이 필요없다.

③ 다음으로 주변장치, 레지스터 등 필요한 것들에 대한 창을 설정한다. 먼저 peripheral에 클릭하고 이때 다음과 같이 나타나는 창에서 필요한 주변기기를 선택한다.

Peripheral

I/O port

Interrupt

Timer

Serial

예컨대 port 1을 선택하고 싶으면 I/O Port에 클릭할 때 나타나는 포트 중 port 1에 클릭한다. 그러면 다음과 같은 창이 화면에 나타난다. 이것을 적당한 위치에 끌어다 둔다. 포트 창의 윗쪽 파랑 부분에 클릭을 한 채 옮기면 된다.

그림 3.19  포트 1 창

레지스터 창은 그림 3.18의 툴바중 왼쪽으로부터 다섯 번째(오른쪽부터 11번째)에 있는 Register window에 클릭함으로 만든다. 기타 필요한 창들을 여기에서 만들어 놓는다.

④ 이제 시뮬레이트할 프로그램이 들어있는 프로젝트를 불러 올 차례이다. 프로젝트 내에 어떤 프로그램이 있는가는 □Vision에서 지정해 주었으므로 프로젝트 이름만 불러오면 된다. 이 때 실제로 불려오는 것은 obj 파일이다. 그러므로 프로그램 수정을 다시 할 때도 그림 3.18 dScope 화면의 맨 밑에 있는 □Vision/51에 클릭함으로써 □Vision에 들어가서 프로그램을 수정하고 컴파일(또는 어셈블)을 한 후 다시 dScope에 들어와서 이 작업을 해야 한다. 프로젝트를 불러오기 위해서는 그림 3.18에서 위 두 번째 줄에 있는 메뉴바 □File□의 바로 밑(위 세 번째 줄 CPU 왼쪽)에 있는 툴바에 클릭한다. 그러면 그림 3.20과 같은 창이 뜬다.

그림 3.20  Open project 창

여기서 □Vision에서 지정했던 프로젝트 이름, 예컨데 8051에 더블클릭한다. 이 때 프로젝트 이름을 만들어 놓은 곳의 디렉토리가 제대로 되어 있는지를 점검한다. 예컨대 프로젝트 이름 8051을 51C_PRG 밑에 만들어 두었으면 디렉토리에 51C_PRG가 있는가를 점검한다. 자칫 bin에 있는 것을 더블클릭하기 쉽다.

□ C＞W

□ hkmds

□ 51C_PRG

8051 (더블클릭)

⑤ 이로써 프로그램을 시뮬레이트할 모든 준비가 끝났다. 이젠 실제 시뮬레이트하는 일만 남았다. 그림 3.18 dScope 화면 위로부터 두 번째 줄 툴바에서 좌로부터 4번째에 클릭하면 disamble된 어셈블리어 형태의 소위 Debug window가 나타나는데, 이것이 나타나면 그림 3.18의 맨위의 □Go□에 클릭한다. 그런 다음 예컨대 I/O포트의 동작 상태를 보고 싶으면 설치해논 창에서 그것을 확인할 수 있다.

적당한 시점에서 정지시키고 싶으면 □stop□에 클릭한다.

⑥ 한 명령어씩 실행시키고 싶으면 □stepxxx□에 클릭한다. 세 종류나 있으므로 적절히 선택 사용한다. 이들 중 stepover는 지연루틴에서 벗어나고자 할 때 유용하다.

실로 step 기능은 논리적인 error를 찾아내는 데 매우 유용하다. 프로그램을 작성해서 어렵게 위 과정을 밟았는데도 제대로 동작하지 않으면 참으로 암담하고 답답할 것이다. 이럴 때는 step 기능을 이용하면 대개의 경우 그 원인이 발견된다.

⑦ 또다른 프로그램을 시뮬레이트하고자 한다면 역시 □Vision에 들어가서(그림 3.18 dScope 화면 맨 밑에 있는 □Vision/51에 클릭하면 □Vision에 들어간다) 이상의 작업을 다시 해야 한다. 다만 최초의 경우가 아니면 Open project 과정은 생략해도 무방하다. 즉 Edit Project부터 해도 된다. 그림 3.21은 이상의 과정을 요약해 놓은 것이다.

(1) □Vision 영역 작업

□Vision 에	(클릭) ; □Vision의 선택

(open project 작업)

Project에	(클릭) ; 프로젝트의 선정

Open project에	(클릭) ; (시스템을 최초로 사용할 경우에는 New project)그 후 부터는 open project에 클릭하고 프로젝트 이름 예컨대 8051.PRG에 (더블클릭)

(edit project 작업)

Project에	(클릭)

Edit project에	(클릭)

Remove에	(클릭) ; 선정된 프로젝트 내용의 클리어

Add에	(클릭)

파일형식(T) 밑  의 ∇에 (클릭) ; Translator의 선택

C51 Compiler(또는 A51 Assembler)에	(클릭)

hkmds에	(더블클릭) ; 프로그램 경로의 지정

소스파일을 넣어둔 곳(예컨대 51C_PRG)에 (더블클릭)

좌측의 원하는 소스파일에 (더블클릭) ; 프로그램의 선택

Close에	(클릭)

Open에	(클릭) ; 지정된 프로그램을 화면에 표시

Save에	(클릭) ; 이 때 나타나는 프로그램에서 수정을 할 수 있다

(build project 작업)

project에	(클릭) ; 컴파일(또는 어셈블), 링킹

Make＞Build Project에 (클릭)

Error가 있으면 edit project 작업에서 이를 정정한 뒤 Build project 작업을 다시 한다

Hex File Created OK의 OK에 클릭

(2) dScope 영역 작업

dScope에	(클릭) ; dScope의 선택

(CPU 선정)

CPU driver 에	(클릭) ; CPU의 선택(이미 되어 있으면 생략함)

프로젝트 이름 예컨대 8051.dll에 (더블클릭)

(주변장치 지정)

Peripheral 메뉴바에	(클릭) ; 주변장치, 레지스터 등의 선택

필요한 주변장치(예, I/O port)에	(클릭)

Register window에	(클릭) ; (기타 필요한 창을 만들어 놓는다)

(프로젝트 지정)

메뉴바 File 밑에 있는 툴바에	(클릭) ; 시뮬레이트할 project를 불러온다

□Vision에서 지정한 project 이름(예의 경우 8051)에 (더블클릭)

(실행)

좌로부터 4번째 툴바에 클릭함으로써 Debug window를 표시한 상태에서 Go에 (클릭)

시뮬레이트 정지를 원할 때는 stop에 (클릭)

(step 동작)

Step 동작을 원할 때 Stepxx에 (클릭)

그림 3.21  Keil Software에 의한 시뮬레이트 과정

3.13.1  트레인키트

전술한 바와 같이 트레인키트는 마이크로콘트롤러의 원리와 프로그램을 교육할 목적으로 개발된 교육용 마이크로콘트롤러 시스템이다. 8051 트레인키트에는 간단하고 저렴한 것에서 매우 복잡하고 고가인 것에 이르기까지 여러 종류가 있으나, 여기에서는 비교적 간단하고 효율적인 디지털제어 산업기사 실기시험에서 사용되고 있는 것을 간단히 소개하고자 한다. 그림 3.22는 그 외관이고, 그림 3.23은 그 회로도이다.

이것의 CPU는 AT89S51로서, 이것은 8051과 100% 호환 가능하다. 또 CPU와 각종 주변장치(키보드, FND, LCD 등)과의 연결은 연결홈을 통하여 밴드선으로 연결할 수 있도록 되어 있다.

그림 3.22 디지털제어 산업기사 8051 MICOM 보드의 외관(마이더스 엔지니어링 제공)

그림 3.23 회로도(마이더스 엔지니어링 제공)

전원

／5[V]. GND＞별도의 전원장치로 공급하도록 되어 있다.

／12[V], １12[V]

CPU

AT89S51

시스템 클록

22.1184(MHz)

스위치

리셋 스위치를 누르면 프로그램은 000H 번지에서부터 실행된다.

Write/read LED

AT89S51에 기록을 할 때는 빨강 LED가 점등하고, AT89S51에 프로그램을 실핼할 때에는 파랑 LED가 점등된다.

키보드

4*4 매트릭스 키보드가 준비되어 있고, 사용자는 밴드선을 통하여 이들을 CPU에 연결하도록 되어 있다.

FND

공통 애노드형의 FND 4개가 준비되어 있고, 이들도 사용자가 밴드선을 통하여 CPU에 연결해 사용한다.

LCD

16*2 라인의 캐릭터 LCD가 하나 준비되어 있고, 이를 사용하고자 하면 사용자가 밴드선을 통하여 해당 CPU 포트라인에 연결한다.

A/D변환기

직렬형 12비트 AD변환기 MCP3202 하나가 준비되어 있고, 이를 사용하고자 하면 사용자는 밴드선을 통하여 CPU의 해당 포트라인에 연결하고, SPI 방식으로 변환을 주도해야 한다.

LED

이 트레인키트에는 LED가 준비되어 있지 않다. 아래쪽에 있는 만능키판을 이용하여 사용자가 만들어 넣어야 한다. 싱크형태로 330∼470(□)을 통하여 ／5[V]에 연결한다.

MAX232C

이것은 PC와 AT89S51 사이에 RS-232C 방식으로 직렬통신을 할 때 사용되는 것으로서, TTL 레벨을 RS-232C 레벨로, 또는 RS-232C 레벨을 TTL 레벨로 바꾸는 역할을 한다. AT89S51의 P3.0/RXD와 P3.1/TXD가 이에 직접 연결되어 있어서 이들 핀은 포트라인으로는 사용할 수 없다. MAX232C를 사용하여 직렬통신을 하고자 할 경우에는 RS-232C 케이블로 PC의 RS-232C 포트와 연결해야 한다.

프린터 포트

IBM PC에서 프로그램을 어셈블 또는 컴파일해서 얻은 Hex 파일을 이 트레인키트에 기록할 때 이 포트를 쓴다. IBM PC의 프린터 포트에 병렬 케이블로 연결해야 한다.

3.13.2  MICOM PROGRAMMER

앞에서 Keil software를 이용하여 프로그램을 어셈블 또는 컴파일함으로써 Hex 파일을 만드는 방법을 익혔다. 문제는 이렇게 해서 만든 Hex 파일을 어떻게 디지털제어 산업기사 8051 MICOM 보드(정확히 말한다면 이 키트의 CPU의 플래시메모리)에 기록해 넣느냐에 있다. 결론부터 말한다면 이 키트의 메이커에서 공급하는 MICOM PROGRAMMER라는 프로그램의 도움을 얻어서 기록해 넣는다. 이 프로그램이 예컨대 디지털제어 산업기사>8051>MICOM_programmer에 들어있다고 한다면 이에 들어가서 MICOM_programmer에 클릭하면 그림 3.24와 같은 메인화면이 뜬다.

그림 3.24 MICOM_programmer 메인화면(마이더스 엔지니어링 제공)

□ 아이콘 □선택□에 클릭하고 사용할 CPU(AT89S51)를 지정한다. 이 작업은 최초 한번만 하면 된다.

□ 아이콘 □열기□에 클릭하고 트레인키트 89S51의 플래시메모리에 기록할 Hex 파일을 지정한다. Keil의 □_Vsion에서 지정한 Hex 파일이 바로 표시되지 않으면 □를 클릭하고 그 Hex 파일(예: 8051.hex)을 찾아 이에 더블클릭한다.

□ 아이콘 □자동□에 클릭함으로써 Hex 파일을 기록한다.

□ CPU 89S51의 플래시메모리에 기록이 다되면, 기록된 프로그램은 즉시 실행된다.

1. 컴퓨터言語에는 기계어, 어셈블리語, 컴파일러語 등이 있는데, 이들 중 컴퓨터가 직접 이해할 수 있는 것은 2진 코드로 된 기계어 뿐이다.

2. 어셈블리語는 기계어를 기호화한 것으로, 이것으로 작성한 프로그램은 어셈블러(assembler)라는 번역용 프로그램의 힘을 빌어 기계어로 번역되어야 한다.

3. 컴파일러語는 기계어를 일상언어화한 것으로, 이것으로 작성한 프로그램은 컴파일러(compiler)나 인터프리터(interpreter)라는 번역용 프로그램의 힘을 빌어 기계어로 번역되어야 한다.

4. 오퍼랜드의 형태에는 비트, 바이트, 워드, 롱워드 등이 있다.

5. 주소지정방식(addressing mode)이란 오퍼랜드의 실효 주소(effective address) 표시법이다. 바꿔말해서 오퍼랜드의 소재처를 밝히는 방식이다. 레지스터 주소지정방식에서는 오퍼랜드가 선택된 레지스터 뱅크의 특정 레지스터에 소재하고, 직접 주소지정방식에서는 오퍼랜드가 내부 RAM의 하위 128 바이트 또는 SFR의 특정 번지에 소재하며, 레지스터 간접 주소지정방식에서는 오퍼랜드가 레지스터 R0, R1 또는 DPTR이 지정하는 번지에 소재하고, (베이스+인덱스) 레지스터 간접 주소지정방식에서는 오퍼랜드가 베이스 레지스터(DPTR 또는 PC)+인덱스 레지스터(Acc)가 지시하는 번지에 소재하며, 즉시 주소지정방식에서는 오퍼랜드가 직접 부여된다. 끝으로 점프 및 브랜치에 관한 주소지정방식인 절대, 상대, 롱 등의 주소지정방식은 오퍼랜드의 소재처 문제가 아니고 어디로 건너 뛰느냐의 문제이다. 절대 주소지정방식에서는 지정된 11비트의 번지로 건너 뛰고, 롱 주소지정방식에서는 지정된 16비트의 번지로 건너 뛰며, 상대 주소지정방식에서는 현재의 위치로부터 (offset+02)만큼 건너 뛴다.

6. 프로그램을 작성하는 순서는 문제의 해석, 순서도의 작성, 코딩, 디버깅 등이다.

7. 프로그램을 실행시키는 과정은 소스 파일의 작성, 어셈블 또는 컴파일, 오브젝트 모듈의 링크, Hex 파일의 작성, 다운로딩, 실행 등이다.

8. 트레인 키트를 포함한 실제의 8051 시스템은 그 목적상 제어 프로그램만을 내장하기 때문에 소스 파일을 작성하는 에디터(editor)도, 기계어로 번역하는 어셈블러(assembler)나 컴파일러(compiler)도, 여러 모듈을 링크하는 링커(linker)도 그 자신 내장할 수 없다. 그러므로, 외부에서 이런 작업을 할 수 밖에 없는데, 외부에서 이런 작업을 하는 방법에는 수작업에 의한 방법도 있으나, 8051 대부분의 트레인 키트나 in-circuit 에뮬레이터나 시뮬레이터에서는 컴퓨터에 의한 방법을 사용한다.

9. 컴퓨터에 의한 방법에서는 소스 파일의 작성, 어셈블 또는 컴파일, 링크, Hex 파일의 작성, 다운로딩(down loading), 프로그램의 실행 등을 IBM PC와 같은 호스트 컴퓨터로 한다.

10. 트레인 키트(train kit)는 마이크로컴퓨터의 원리와 프로그램을 교육할 목적으로 개발된 교육용 마이크로콘트롤러 시스템으로서, 이것의 구조상 특징은 프로그램을 RAM에 저장할 수 있도록 되어 있다는 것이다. 그러나 ROM이 플래시메모리로 되어 있는 마이크로콘트롤러의 경우에는 프로그램을 내부의 플래시메모리에 저장한다.

11. ROM 에뮬레이터(ROM emulator)는 신제품의 개발중 타깃트 시스템(target system)의 임시 ROM 역할을 하는 개발장치(MDS)이다.

12. 인서키트 에뮬레이터(ICE＞ In-Circuit emulator)는 신제품의 개발중 타깃트 시스템의 마이크로콘트롤러(또는 CPU와 ROM) 역활을 하는 장치로서, 본격적인 마이크로콘트롤러 개발장치(MDS)이다.

13. Keil Software (□Vision 및 dScope)는 한국MDS에서 보급하고 있는 프로젝트 매니저 및 시뮬레이터인데, 이것을 사용하는 방법은 먼저 □Vision에서 Open project, Edit project, Build project 등의 과정을 통하여 프로젝트와 프로그램을 지정하고, 컴파일(또는 어셈블), 디버깅, 링킹 등의 작업을 한 후, dScope에서 CPU와 프로젝트 이름을 지정한 뒤에 Go한다.

14. 시뮬레이터(simulator)는 작성된 프로그램이 실제의 칩에서 어떻게 동작하는지를 PC상에서 모의실험(simulate)하는 프로그램이다. 이것을 사용하면 트레인 키트나 인서키트 에뮬레이터 없이 프로그램을 개발할 수 있어 매우 편리하다.

15. 메모리 맵(memory map)은 메모리 주소공간의 할당표이다. 이것은 회사별, 시스템별로 다르므로, 시스템을 구입할 때에는 그것을 사용하기 전에 이것부터 보아야 한다.

3.1 source program을 기계어 코드로 번역하기 위한 프로그램이 아닌 것은?	(전산기조직응용)

㉮ assembler	㉯ debugger

㉰ compiler	㉱ interpreter

3.2 컴퓨터가 직접 이해할 수 있는 언어는?	(전산기조직응용)

㉮ machine language	㉯ BASIC

㉰ assembly	㉱ high level language

3.3 machine instruction에 있어서 꼭 필요한 부분은?	(전산기조직응용)

㉮ OP code와 index register field

㉯ OP code와 operand field

㉰ base register와 index register field

㉱ indirect addressing과 address field

3.4 목적(object) 프로그램과 관계가 깊은 것은?	(전산기조직응용)

㉮ 고수준언어	㉯ 어셈블리언어

㉰ 기계어	㉱ BASIC

3.5 기계어와 1대 1로 대응하여 컴퓨터의 기능을 충분히 발휘할 수 있는 언어는?

㉮ PL/1	㉯ 어셈블리어

㉰ BASIC	㉱ DDT

3.6 사용자가 짠 각각의 부호 명령어(symbolic instruction)를 하나의 2진코드 명령어로 바꾸어주는 특수한 프로그램을 무엇이라 하는가?	(전산기조직응용)

㉮ 컴파일러	㉯ 기계어 프로그램

㉰ 어셈블러	㉱ 파스칼

3.7 어셈블리 언어로 작성된 한 문장의 구성 요소가 아닌 것은?	(전자계산기)

㉮ 인스트럭션 위치의 이름	㉯ 인스트럭션 동작의 이름

㉰ 필요한 자료의 종류	㉱ 인스트럭션의 설명

3.8 A 컴퓨터에서 B 컴퓨터의 어셈블리 소스 프로그램을 B 컴퓨터의 오브젝트 프로그램으로 어셈블하였다면 이때 사용한 어셈블러를 특히 무엇이라 하는가?	(전산기조직응용)

㉮ macro assembler	㉯ absolute assembler

㉰ cross assembler	㉱ relocation assembler

3.9 다른 기종의 컴퓨터를 사용하여 object program을 만드는 것은?	(전산기조직응용)

㉮ Cross assembler	㉯ Macro Assembler

㉰ Interpreter	㉱ Compile

3.10 마이크로컴퓨터를 위한 대규모 프로그램을 개발하려고 할 때 마이크로컴퓨터를 사용하여 어셈블하려면 여러가지 제한(메모리 용량, 입˛출력 장치의 제한 등)을 받게된다. 이 때 이용할 수 있는 소프트웨어 유틸리티(Utility)는?	(전산기조직응용)

㉮ Cross assembler	㉯ Debugger

㉰ Screen editor	㉱ simulator

3.11 다음 중 번역어(translator)에 속하지 않는 것은?	(전산기조직응용)

㉮ Assembler	㉯ Loader

㉰ Interpreter	㉱ Compiler

3.12 다음 (A), (B)에 각각 적합한 것은?	(전자계산기)

원시 프로그램	(A) ――――→	목적 프로그램	(B) ――――→	실행 가능 프로그램

㉮ compiler, loader	㉯ interpreter, loader

㉰ compiler, interpreter	㉱ loader, compiler

3.13 다음은 프로그래밍 시스템을 구성하는 소프트웨어적인 설명이다. 설명에 적합한 프로그래밍 언어는 어느 것인가?	(전산기조직응용)

□고급 언어로 씌여진 원시프로그램을 직접 수행하는 프로그램□

㉮ 컴파일러(Compiler)	㉯ 인터프리터(Interpreter)

㉰ 어셈블러(Assembler)	㉱ 기계어(Machine lenguage)

3.14 다음 설명 중 옳지 않은 것은?	(전산기조직응용)

㉮ 개방형 서브루틴과 폐쇄형 서브루틴의 차이는 부프로그램 실행을 위한 제어 관계에        있다.

㉯ 인터프리터는 목적프로그램을 형성한 다음 이 목적프로그램을 실행하는 언어 번역 프       로그램이다.

㉰ 로더의 기능은 기억장소 할당과 부프로그램의 연결, 적재 및 리로케이션이다.

㉱ 매크로는 개방형 서브루틴이다.

3.15 다음의 출력 결과로 맞는 것은?	(전자계산기)

출력

원시 프로그램	――――→	interpreter	――――→	?

㉮ 목적 code	㉯ compiler

㉰ 프로그램 실행 결과	㉱ loader

3.16 제어 프로그램 개발시 중요한 점과 거리가 먼 것은?	(전산기조직응용)

㉮ 기억 장소를 효율적으로 사용하여야 한다.

㉯ 수행 속도가 빠르도록 해야 한다.

㉰ 이해하기 쉬워야 하며 조직적이라야 한다.

㉱ 고급(high lever) 언어일수록 좋다.

3.17 많은 마이크로컴퓨터가 BASIC을 기본 언어로 사용하고 있는 이유가 아닌 것은?	(전산기조직응용)

㉮ 실행 속도가 빠르다.

㉯ 메모리가 적게 필요하다.

㉰ 명령 즉시 결과를 얻을 수 있다.

㉱ 착오 교정(error debugging)이 쉽다.

3.18 untility program에 속하지 않는 것은?	(전자계산기)

㉮ sort/merge program	㉯ text editor

㉰ tape copy program	㉱ application program

3.19 컴퓨터 사용자가 응용 프로그램을 사용함에 있어서 여러 가지 편리함을 제공하는 시스템 프로그램이 아닌 것은?	(전산기조직응용)

㉮ Language Processor	㉯ Operating System

㉰ Diagnostic Program	㉱ Expert System

3.20 다음 중 처리 프로그램과 관계가 먼 것은?	(전산기조직응용)

㉮ Editor	㉯ Loader

㉰ Monitor	㉱ Assembler

3.21 0번지 명령형(zero address instruction format)을 갖는 전자계산기 구조 원리는 다음 중 어느 것을 사용하는가?	(전산기조직응용)

㉮ An accumulator extension register

㉯ Virtual memory architecture

㉰ Stack architecture

㉱ Micro programming

3.22 마이크로컴퓨터에서 가장 많이 사용되는 것으로 대상 자료 중 하나의 주소만을 지정하는 인스트럭션 형식은?	(전자계산기)

㉮ 0 주소 인스트럭션	㉯ 1 주소 인스트럭션

㉰ 2 주소 인스트럭션	㉱ 3 주소 인스트럭션

3.23 다음 중 주소지정방식이 아닌 것은?	(전자계산기)

㉮ Immediate Addressing Mode	㉯ Direct Addressing Mode

㉰ Branch Addressing Mode	㉱ Indexed Addressing Mode

3.24 누산기가 꼭 필요한 명령 형식은?	(전자계산기)

㉮ 0주소 인스트럭션	㉯ 1주소 인스트럭션

㉰ 2주소 인스트럭션	㉱ 3주소 인스트럭션

3.25 모든 명령어의 길이가 같다고 할 때 수행 시간이 가장 긴 주소지정방식은?	(전산기조직응용)

㉮ 간접 주소지정방식	㉯ 상대 주소지정방식

㉰ 직접 주소지정방식	㉱ 자료 자신 주소지정방식

3.26 주소지정방식 중에서 인스트럭션의 주소부분과 프로그램카운터의 내용을 더해서 그 결과를 유효주소로 사용하는 주소방식은?	(전자계산기)

㉮ 인덱스 주소방식	㉯ 페이지 주소방식

㉰ 상대 주소방식	㉱ 자료자신 주소방식

3.27 다음 중 주소지정방식을 선택할 때 고려해야 할 사항이 아닌 것은?	(전자계산기)

㉮ 사용하기가 쉬워야 한다.

㉯ 수행속도가 빨라야 한다.

㉰ 될수 있는대로 주소부분이 길어야 한다.

㉱ 하나의 인스트럭션으로 여러 실제 주소를 지정할 수 있어야 한다.

3.28 다음 중 인스트럭션에서 자료의 위치를 직접 지정하는 주소지정방식은?	(전자계산기)

㉮ 즉시 주소방식	㉯ 상대 주소방식

㉰ 간접 주소방식	㉱ 직접 주소방식

3.29 메모리상의 operand 위치가 명령어 다음에 명시되는 Address인 주소지정방식은 어느 것인가?

(전산기조직응용)

㉮ 레지스터 지정방식	㉯ Immediate 어드레스 지정방식

㉰ 간접 어드레스 지정방식	㉱ 직접어드레스 지정방식

3.30 주소지정방식 중 기억장치에 최소 2번 접근(access)해야 오퍼랜드(operand)를 얻을 수 있는 것은?

(전자계산기)

㉮ 직접 주소지정방식(direct addressing)

㉯ 간접 주소지정방식(indirect addressing)

㉰ 임미디어트 주소지정방식(immediate addressing)

㉱ 상대 주소지정방식(relative addressing)

3.31 상대 주소지정방식은 프로그램카운터(PC)와의 관계에 의한 주소지정방식이지만 이와 비슷하면서 명령 중에 지정된 어드레스는 PC 이외의 레지스터 내용과 관련하여 오퍼랜드 어드레스가 계산되는 주소지정방식(Address Mode)은?	(전산기조직응용)

㉮ 실제값 주소지정방식(Immediate Addressing)

㉯ 레지스터 주소지정방식(Register Addressing)

㉰ 인덱스 주소지정방식(Indexed Addressing)

㉱ 비트 주소지정방식(Bit Addressing)

3.32 명령의 주소부에 있는 값(變位値)과 인덱스레지스터의 내용을 더해서 그 결과를 유효번지로 하는 주소지정방식은?	(전자계산기)

㉮ 직접 지정방식(direct addressing)	㉯ 간접 지정방식(indirect addressing)

㉰ 인덱스 지정방식(indexed addressing)	㉱ 상대 지정방식(relative addressing)

3.33 다음 설명 중 옳은 것은?	(전산기조직응용)

㉮ 메모리 참조 명령은 레지스터 참조 명령보다 시간이 적게 소요된다.

㉯ 간접 주소지정방식의 첫번째 메모리 참조로부터 얻어지는 것은 자료 값이다.

㉰ 직접 주소지정방법에서는 오퍼랜드를 얻기 위한 메모리 참조가 한번 필요하다.

㉱ 페이지 주소지정방식은 인덱싱에 적합하다.

3.34 프로그램카운터가 명령어의 번지부와 더해져서 유효 번지를 결정하는 어드레싱 모드(addressing mode)는?	(전산기조직응용)

㉮ 레지스터 모드	㉯ 인덱스드 어드레싱 모드

㉰ 상대 번지 모드	㉱ 간접 번지 모드

3.35 간접 주소지정방식이 직접 주소지정방식보다 우수한 점은?

㉮ 명령(instruction)의 실행시간이 짧다.

㉯ 기억장치로부터의 呼出(fetch) 횟수가 적다.

㉰ 큰 용량을 가진 컴퓨터에 유리하다.

㉱ 데이터의 위치를 직접 지정한다.

3.36 다음 중 operand부에 목적하는 데이터가 들어 있는 주소지정방식은?	(전산기조직응용)

㉮ implied addressing mode	㉯ relative addressing mode

㉰ immediate addressing mode	㉱ indexed addressing mode

3.37 재배치(relocation)와 관계 있는 주소지정방식은?

㉮ 직접지정방식	㉯ 간접지정방식

㉰ 인덱스지정방식	㉱ 상대지정방식

3.38 Z80의 다음 명령어는 어큐뮬레이터의 내용을 2FFF 번지에 옮겨 놓는 것이다. 이 명령어의 주소지정방식을 무엇이라고 부르는가?

LD  (2FFFH), A

㉮ 상대 주소 지정	㉯ 암시 주소 지정

㉰ 즉시 주소 지정	㉱ 직접 주소 지정

3.39 다음 중 명령어 자신의 기억번지를 기준으로 하여 명령의 대상인 데이터의 위치를 지정하는 주소지정방식은?	(전자계산기)

㉮ 직접지정방식	㉯ 간접지정방식

㉰ 인덱스지정방식	㉱ 상대지정방식

3.40 세분된 컴퓨터 동작(operation)을 기호화한 것을 무엇이라고 하는가?

㉮ 命令(instruction)	㉯ 呼出(fetch)

㉰ 目的프로그램(object program)	㉱ 原始프로그램(source program)

3.41 각각의 인스트럭션에 포함될 필요가 없는 정보는?	(전자계산기)

㉮ OP코드	㉯ 자료의 종류

㉰ 자료의 주소	㉱ 결과를 넣을 곳

3.42 명령(instruction)에 대한 설명으로 옳지 않은 것은?

㉮ 일정의 목적을 위하여 작성된 명령의 집합을 프로그램이라고 한다.

㉯ 명령은 명령코드(op code)와 오퍼랜드 또는 번지로 구성된다.

㉰ 오퍼랜드라 함은 명령의 대상인 데이터, 즉 數値를 말한다.

㉱ 명령은 2진수의 형태를 하고 있고, 폰 노이만 방식에서는 명령코드와 오퍼랜드가 구분된다.

3.43 다음 중 프로그램의 실행 순서를 정해주는 명령은?

㉮ 로드명령	㉯ 연산명령

㉰ 제어명령	㉱ 입출력명령

3.44 마이크로프로세서의 인스트럭션들을 그 기능별로 분류한 것에 속하지 않는 것은?	(전자계산기)

㉮ 함수연산 인스트럭션	㉯ 자료전달 인스트럭션

㉰ 제어 인스트럭션	㉱ 수치연산 인스트럭션

3.45 특정한 비트 또는 특정의 문자를 삭제하기 위해 가장 필요한 연산은 어느 것인가?	(정보처리)

㉮ AND 연산	㉯ Complement 연산

㉰ OR 연산	㉱ MOVE 연산

3.46 제어 인스트럭션은 프로그램 수행순서를 정해준다. 다음 중 제어 인스트럭션으로 분류되지 않는 것은?	(전자계산기)

㉮ HALT, NOP 인스트럭션	㉯ STACK 인스트럭션

㉰ JMP 인스트럭션	㉱ 서브루틴 CALL 인스트럭션

3.47 다음 명령 중 상대 주소지정방식에 속하는 것은?

㉮ JP nn	㉯ JR e

㉰ JP NZ, nn	㉱ LD A, (nn)

3.48 다음 중 단일 오퍼랜드(operand) 명령어는 어느 것인가.

㉮ COMPARE	㉯ LOAD

㉰ AND	㉱ COMPLEMENT

3.49 논리 마이크로 동작(logic micro operation) 중 Exclusive OR과 같은 동작을 하는 것은?	(전산기조직응용)

㉮ selective set 동작	㉯ mask 동작

㉰ compare 동작	㉱ selective clear 동작

3.50 Branch 혹은 Jump 명령은 결국 다음중 어떤 register의 내용을 변경하고자 하는 것인가?	(전자계산기)

㉮ Accumulator	㉯ MAR(Memory Address Register)

㉰ PC(Program Counter)	□ MBR(Memory Buffer Register)

3.51 지정된 어드레스(Address)의 내용이 누산기에 기억되는 명령은 다음 중 어느 것인가?	(전산기조직응용)

㉮ 연산 명령(Arithmetic Instruction)	㉯ 로드 명령(Load Instruction)

㉰ 스토어 명령(Store Instruction)	㉱ 브랜치 명령(Branch Instruction)

3.52 다음 중 스택(Stack)과 관계없는 것은?	(전산기조직용용)

㉮ PUSH	㉯ POP

㉰ Stackpointer	㉱ ALU

3.53 다음은 1의 보수(1's complement)에 대한 설명이다. 관계가 없는 것은?	(전산기조직응용)

㉮ 보수를 만들기가 쉽다.

㉯ 덧셈의 경우 최대 1번의 산술 덧셈을 해야 한다.

㉰ 덧셈의 경우 최대 2번의 산술 덧셈을 해야 한다.

㉱ 두가지 형태의 zero가 있을 수 있다.

3.54 자료전달 인스트럭션은 CPU 내의 레지스터나 메모리의 자료를 변형하지 않고 다른 자리로 옮기는 일을 수행한다. 이에 속하지 않는 것은?	(전자계산기)

㉮ 서브루틴 콜 인스트럭션	㉯ 메모리 사용 인스트럭션

㉰ 레지스터간 전송 인스트럭션	㉱ 스택 인스트럭션

3.55 AＡ[0, 0, 1, 0]의 레지스터가 있다. 직렬포트에 입력 1이 들어오면서 좌측 시프트(left shift) 연산을 한다면 A 레지스터에는 어떤 결과가 남겠는가?	(전자계산기)

㉮ AＡ[1001]	㉯ AＡ[0100]	㉰ AＡ[0101]	㉱ AＡ[0001]

3.56 다음 중 산술연산 또는 논리연산 인스트럭션으로 분류할 수 없는 것은?	(전자계산기)

㉮ 시프트 인스트럭션	㉯ 스택 인스트럭션

㉰ 비교 인스트럭션	㉱ 논리연산 인스트럭션

3.57 Memory mapped I/O 구조의 시스템에서 CPU와 주변장치 간의 데이타 전송 명령은?

㉮ 로드명령	㉯ 연산명령

㉰ 제어명령	㉱ 입출력명령

3.58 다음 중 제어명령에 속하지 않는 것은?

㉮ 무조건 점프명령	㉯ 조건부 점프명령

㉰ 스택명령	㉱ 서브루틴 콜 명령

3.59 HALT 명령이 실행되면 CPU는 NOP를 계속하는데, 이 상태로부터 탈출하기 위해서는 어떤 일이 있어야 하는가?

㉮ 인터럽트	㉯ DMA

㉰ 또 다른 HALT 명령	㉱ 메모리요청신호(MREQ)가 있을 때

3.60 다음 중 命令(instruction)의 구성부분이 될 수 없는 것은?

㉮ 명령코드(operation code)	㉯ 데이터(operand)

㉰ 조건코드(condition code)	㉱ 번지부(address)

3.61 데이터 카운터(Data Counter)의 기능은?	(전산기조직응용)

㉮ 상태 플래그를 저장한다.	㉰ op코드를 저장한다.

㉯ 명령어 어드레스를 지정한다.	㉱ 데이터 어드레스를 저장한다.

3.62 다음 중 누산기(AC)의 내용이 0이 될 때 세트(set)되는 플래그는?	(전자계산기)

㉮ C플래그	㉯ S플래그

㉰ Z플래그	㉱ P플래그

3.63 다음 플래그 중 연산결과 Acc에 □1□인 비트가 홀수개일 때 세트되며 짝수개일 때 리세트되는 플래그는?	(전자계산기)

㉮ 패리티 플래그	㉯ 캐리 플래그

㉰ 부호 플래그	㉱ 제로 플래그

3.64 전자계산기의 연산장치에서 부호와 크기의 가산 과정에서 초과상태(overflow)가 발생할 조건으로 알맞는 것은?	(전자계산기)

㉮ 음수에 비하여 양수가 큰 경우

㉯ 양수에 비하여 음수가 큰 경우

㉰ 두 수가 모두 양수이거나 음수인 경우

㉱ 가산에서는 모든 경우에 초과상태가 발생하지 않는다.

3.65 가산 또는 감산 결과 MSB에서 자리 올림이나 자리 내림이 생겼을 때 set되는 flag는?

㉮ sign flag	㉯ carry flag

㉰ zero flag	㉱ parity flag

3.66 두 수를 뺀 결과가 양수이며 오버플로우가 발생했다. 이 두 수를 A, B라 할 때 A, B 각각의 부호는?

㉮ A는 음수, B는 양수	㉯ A는 양수, B는 음수

㉰ A는 음수, B도 음수	㉱ A는 양수, B도 양수

3.67 연산 결과 MSB가 1이면 set되고, 0이면 reset되는 flag는?

㉮ carry flag	㉯ sign flag

㉰ parity flag	㉱ half carry flag

3.68 다음 중 pseudo instruction에 대하여 옳게 설명한 것은?	(전산기조직응용)

㉮ 오퍼랜드(operand)가 없는 명령

㉯ 인터럽트(interrupt) 사용을 위한 명령

㉰ 어셈블러(assembler)에 특별한 정보를 제공하기 위한 명령

㉱ 메모리 액세스(memory access)를 효율적으로 하기 위한 명령

3.69 다음 명령 중 의사명령어(pseudo instruction)가 아닌 것은?	(전산기조직응용)

㉮ LOAD 또는 STA	㉯ EQU

㉰ ORG	㉱ DB 또는 DW

3.70 프로그램의 시작번지를 어셈블러에게 지시하는 의사명령은?	(전자계산기)

㉮ MACRO	㉯ ORG

㉰ DEFW	㉱ DEFS

3.71 어셈블리어 문장의 구성요소 중 인스트럭션이 차지하는 기억장소를 나타내며 필요에 따라 생략할 수 있는 요소는?	(전자계산기)

㉮ Label	㉯ 동작이름

㉰ 주소나 자료이름	㉱ 설 명

3.72 assembly언어로 되어 있는 source program에서 label의 역할은?

㉮ 절대 번지(absolute address)	㉯ 기호 번지(symbolic address)

㉰ 상대 번지(relative address)	㉱ 베이스 번지(base address)

3.73 사용자 자신이 정의하는 일련의 명령어 집단을 무엇이라 하는가?

㉮ MACRO	㉯ ORG	㉰ Instruction	㉱ DEFW

3.74 다음 중 MACRO의 설명으로 옳지 않은 것은?	(전자계산기)

㉮ 같은 인스트럭션 순서를 반복해서 작성할 필요가 없다.

㉯ 인스트럭션의 순서를 바꿀 경우 한군데만 바꾸면 된다.

㉰ 서브루틴 사용시보다 수행속도는 느리다.

㉱ 서브루틴보다 기억공간을 많이 차지한다.

3.75 MACRO와 서브루틴에 공통된 장점이 아닌 것은?	(전자계산기)

㉮ 같은 인스트럭션 순서를 반복해서 작성할 필요가 없다.

㉯ 프로그램이 읽기 쉽고 이해하기 쉽다.

㉰ 따로 서브루틴을 부르는 과정이 없으므로 수행속도가 빠르다.

㉱ 인스트럭션의 순서를 바꿀 경우 한군데만 바꾸면 된다.

3.76 매크로 레벨(macro level) 구조의 정의로 볼 수 없는 것은?	(전산기조직응용)

㉮ 데이터 형식	㉯ 소프트웨어의 종류

㉰ 명령의 집합	㉱ 기억장치의 논리적 호출 방식

3.77 다음 命令(instruction)중 疑似命令이 아닌 것은?

㉮ ORG	㉯ HALT	㉰ END	㉱ MACRO

3.78 어셈블리語 명령의 4가지 부분 중 명령실행과 관계가 없는 것은?

㉮ label	㉯ op code	㉰ operand	㉱ comment

3.79 인스트럭션의 길이를 줄이는 방법이 아닌 것은?	(전자계산기)

㉮ 프로그램카운터를 사용한다.

㉯ 다음 인스트럭션의 주소를 인스트럭션에 포함시킨다.

㉰ 오퍼랜드 중의 하나에 결과를 저장한다.

㉱ 레지스터 내에 있는 자료만을 오퍼레이션에 사용한다.

3.80 좋은 소프트웨어가 갖는 특징이 아닌 것은?	(전산기조직응용)

㉮ 전체적인 흐름을 추적하기가 용이하다.

㉯ 필요한 사항을 빠짐없이 만족한다.

㉰ 프로그램이 짧다.

㉱ 사용자가 이해하기 쉽다.

3.81 번역과 수행이 한꺼번에 이루어지는 것은?	(전산기조직응용)

㉮ compiler	㉯ assembler

㉰ interpreter	㉱ interrupt

3.82 마이크로컴퓨터의 시스템 소프트웨어 중 사용자가 작성한 프로그램을 실행하면서 에러를 검출하고자 할 때 사용되는 것은?	(전산기조직응용)

㉮ 로더(loader)	㉯ 텍스트 에디터(text editor)

㉰ 디버거(debugger)	㉱ 컴파일러(compiler)

3.83 그림에 보여진 프로그램이 수행된 후 accumulator의 내용은?(단, immediate 어드레싱 모드를 사용하는 □Exclusive OR Accumulator with data"의 OP-Code는 EE(16진수)이고 mnemonic은 XRI이다.)

㉮ 1100 1100	㉯ 0010 0010

㉰ 1000 1000	㉱ 0101 0101

3.84 조건에 의한 분기(Branch)를 하기 위해서 검사되어지는 레지스터는?	(전산기조직응용)

㉮ IR	㉯ MAR	㉰ Status R	㉱ MDR

3.85 다음 중 이중 오퍼랜드 명령어는 어느 것인가?	(전산기조직응용)

㉮ increment	㉯ clear

㉰ OR	㉱ shift

3.86 8bit 마이크로컴퓨터에서 그림과 같이 오퍼랜드가 없는 명령어는 몇 워드 명령어인가?	(전산기조직응용)

오퍼랜드

㉮ 1워드 명령어	㉯ 2워드 명령어

㉰ 4워드 명령어	㉱ 3워드 명령어

3.87 번지(address)를 실제 기억공간에 연관시키는 방법에는 절대번지와 상대번지가 있다. 다음 중 상대번지와 관계있는 단어는 어는 것인가?	(전산기조직응용)

㉮ Overlapping	㉯ Relocation

㉰ Overhead	㉱ Overlap

3.88 현 명령어의 위치를 기준으로 하여 Branch한 위치를 지정하는 것은 어느 것인가?	(전산기조직응용)

㉮ 기호번지	㉯ 상대번지

㉰ 절대번지	㉱ 베이스번지

3.89 직접 주소지정방식에 대한 다음의 설명으로 틀린 것은 어는 것인가?	(전산기조직응용)

㉮ 실제 주소를 사용하므로 프로그래머가 사용하기 쉽다.

㉯ 명령(instruction)의 번지부에 실제 주소가 들어간다.

㉰ 명령code에서는 자료의 위치를 직접 지정하지는 않는다.

㉱ 간접 지정방식에 비하여 실행 속도가 빠르다.

3.90 다음 Addressing mode 중 명령의 오퍼랜드로 번지를 가지고 있는 레지스터를 지정하는 형식은 어느 것인가?	(전산기조직응용)

㉮ Register mode	㉯ immediate mode

㉰ Implied mode	㉱ Register indirect mode

3.91 오퍼랜드 메모리가 아니고 CPU 내부의 레지스터인 어드레스 지정방식은 무엇인가?	(전산기조직응용)

㉮ 인덱스 어드레스 지정방식	㉯ 레지스터 어드레스 지정방식

㉰ Immediate 어드레스 지정방식	㉱ 간접 어드레스 지정방식

3.92 상태 레지스터(flag register)의 내용을 점검하여 그 조건에 따라 Jump 또는 Branch 하는 번지 지정방식은 어느 것인가?	(전산기조직응용)

㉮ Indexed addressing	㉯ Direct addressing

㉰ Immediate addressing	㉱ Relative addressing

3.93 주기억장치에 이미 고정된 번지가 붙여져 있는 어드레스는 어느 것인가?	(전산기조직응용)

㉮ 절대 어드레스(absolute address)	㉯ 베이스 어드레스(base address)

㉰ 기호 어드레스(symbolic address)	㉱ 상대 어드레스(relative address)

3.94 Branch Always 명령이 3A30 번지에 있고 3A50 번지에 Branch하고 싶을 때 3A31 번지의 내용은 무엇이 기억되어야 하는가?	(전산기조직응용)

㉮ 1E	㉯ 82	㉰ 18	㉱ 1

3.95	MAR←SP

MBR←M

SP←SP-1

if (SP=RL) then EMPTY

※ RL은 Lower limit(하한선)을 가르키는 주소인 오퍼레이션들은 무엇을 나타내는가?	(전산기조직응용)

㉮ 기억장치로 부터의 로드(Load)	㉯ 스택의 push

㉰ 스택의 pop	㉱ 기억장치로의 저장(store)

3.96 가장 나중에 기억된 것이 가장 먼저 출력되는 기억장치는?	(전산기조직응용)

㉮ stack	㉯ Queue

㉰ FIFO	㉱ register

3.97 LIFO(Last-In First-Out) 구조는?	(전산기조직응용)

㉮ ROM	㉯ queue

㉰ ALU	㉱ stack

3.98 스택(stack)이란?	(전산기조직응용)

㉮ RAM에 있는 자료구조로서 잠시 정보의 저장이나 검색을 위해 사용한다.

㉯ RAM에 있는 자료구조로서 테이블이나 코드와 같은 정보 검색에 쓰인다.

㉰ RAM에 있는 구조로서 I/O 제어에 사용된다.

㉱ RAM에 있는 구조로서 다음에 수행될 명령어를 저장한다.

3.99 스택(stack)의 특성을 바르게 설명한 것은?	(전산기조직응용)

㉮ 선입 선출(first-in first-out) 방식의 구조이다.

㉯ 서브루틴을 호출한 어드레스가 보존된다.

㉰ 레지스터값의 일시적인 대피 및 복구에서 사용된다.

㉱ 스택 영역은 사용자 프로그램에서 지정할 수 없다.

3.100 Program 수행 중 서브루틴(subroutine)으로 돌입한 프로그램의 리턴 번지(return address) 수를 LIFO(last-in first-out) 기술로 메모의 일부에 저장한다. 이 메모리 부분을 무엇이라 하는가?

(전산기조직응용)

㉮ 주기억 장치(main memory)	㉯ 보조기억장치

㉰ 스택(stack)	㉱ 어셈블러(assembler)

3.101 서브루틴 호출이나 인터럽트 서비스를 위해 되돌아갈 주소를 저장하는 주소를 가리키는 레지스터는?	(전산기조직응용)

㉮ MAR(Memory Address Register)	㉯ PC(Program Counter Register)

㉰ SP(Stack Pointer Register)	㉱ 어큐뮬레이터

3.102 다음 중 스택(Stack)과 직접 관계있는 것은?

㉮ Acc	㉯ POP	㉰ DPTR	㉱ALU

3.103 큐(Queue) 메모리에 대한 설명으로서 틀리는 것은?	(전산기조직응용)

㉮ 두 장치 사이의 Data 전송 속도 차이를 해소하기 위하여 사용된다.

㉯ FIFO(First-in First-out) 메모리라고도 한다.

㉰ LIFO(Last-in first-out) 메모리라고도 한다.

㉱ 처리할 수 있는 정보의 양은 큐의 용량을 초과하지 못한다.

3.104 SP(Stack Pointer)가 기억하고 있는 내용의 메모리 번지를 지정하는 스택구조를 무엇이라고 하는가?	(전산기조직응용)

㉮ 연속(eascade) 스택	㉯ 모듈(module) 스택

㉰ 메모리 스택	㉱ 간접 번지지정 스택

3.105 8비트 마이크로프로세서 Z80에서 스택포인터가 200번지를 가리키고 있다. 3바이트 내용을 스택에 push하면 스택포인터는 몇 번지를 가리키는가?	(전산기조직응용)

㉮ 197번지	㉯ 198번지

㉰ 199번지	㉱ 202번지

3.106 연산을 수행하기 전에 SP(stack pointer)는 4FFF16이다. 일반 연산을 끝낸 뒤의 SP값은 어떻게 변하겠는가?

㉮ 4FFB	㉯ 4FFC	㉰ 4FFE	㉱ 4FFF

3.107 프로그램 수행중 Subroutine의 Return address와 관련있는 것은 어느 것인가?	(전산기조직응용)

㉮ PC	㉯ queue	㉰ stack	㉱ ALU

3.108 다음의 Assembler 제어 명령중에 설명이 틀린 것은?	(전산기조직응용)

㉮ ORG(Origin)＞ 어느 address로부터 program을 시작하고 싶은가를 표시

㉯ EQU＞ label용의 memory space를 확보하기 위해 사용

㉰ NAM＞ program에 이름을 붙이기 위해 사용

㉱ FCB＞ 1byte의 정수를 연속하는 address에 할당하기 위해 사용

3.109 마이크로컴퓨터의 구성에서 memory-mapped I/O와 isolated I/O 방식에 대한 설명 중 맞는 것은?

(전산기조직응용)

㉮ memory-mapped  입·출력에는 입·출력 전용 명령어가 요구된다.

㉯ memory-mapped 입·출력은 주기억 공간을 최대로 활용할 수 있다.

㉰ isolated 입·출력은 버스 연결이 쉽다.

㉱ memory-mapped 입·출력에는 입·출력 전용 명령어가 필요없다.

3.110 LD A,B의 T 사이클은 4이다. 기본 클록으로서 2MHz를 쓸 때 이 명령을 실행하는데는 몇 □가 소요되는가?	(전산기조직응용)

㉮ 4	㉯ 2	㉰ 1	㉱ 8

3.111 다음 프로그램이 수행된 후에 A에는 어떤 값이 남겠는가?	(전산기조직응용)

LD	A,44H

LD	B,(1000H)

ADD	A,B

OR	0111 0111 B

AND	44H

OR	1011 1011 B

㉮ FF	㉯ EE	㉰ DD	㉱ BB

3.112 A＞3F, B＞71, C＞A9, D ; 5E의 데이터를 저장하고 있는 레지스터들 사이에서 아래의 데이터 전달 동작이 수행된 후 각 레지스터에 저장되는 데이터는? (단, 번호는 동작수행순서)	(전산기조직응용)

1. A←B	2. C←A

3. C←D	4. D←B

㉮ A＞71	B＞5E	㉯ A＞71	B＞71

C＞5E	D＞71	C＞5E	D＞71

㉰ A＞A9	B＞71	㉱ A＞3F	B＞5E

C＞5E	D＞A9	C＞5E	D＞71

3.113 진단 프로그램(diagnostic program)의 목적을 적절히 설명하지 못한 항은?	(전산기조직응용)

㉮ 하드웨어적인 고장을 찾기 위해서 사용한다.

㉯ 고장 증상을 결정하고 해석한다.

㉰ 기능적 부분에서의 고장을 찾는다.

㉱ 소프트웨어의 오류를 진단한다.

3.114 프로그래머가 컴퓨터 언어로 작성한 프로그램을 무엇이라 하는가?

㉮ source program	㉯ l	isting program

㉰ object program	㉱ mac	hine program

3.115 program 작성 후 기계어로 번역시 또는 수행시 문법적, 논리적 오류를 찾아 바로 잡는 것을 무엇이라 하는가?

㉮ loading	㉯ debugging

㉰ editing	㉱ trouble shooting

3.116 프로그램에서 같은 처리 과정을 데이터만 바꾸면서 여러 번 되풀이해야 할 경우에 반복 횟수를 표시하는 counter 등을 사용하여 프로그램을 간단히 처리하는 기법을 무엇이라 하는가?

㉮ branch	㉯ table

㉰ loop	㉱ subroutine

3.117 loader의 기능에 해당하지 않는 것은?	('85 조직응용 1급)

㉮ 할당(allocation)	㉯ 로딩(loading)

㉰ 연결(linking)	㉱ 번역(translation)

3.118 한 컴퓨터가 다른 컴퓨터처럼 똑같이 동작하도록, 소프트웨어나 마이크로 프로그램을 사용하는 기법은?

㉮ 로더(Loader)	㉯ 에뮬레이터(Emulator)

㉰ 컴파일러(Compiler)	㉱ 에디터(Editor)

3.119 마이크로프로그램 방식을 사용하여 다른 계산기의 동작을 모방하는 것은?

㉮ 트랜스레이션(Translation)	㉯ 에뮬레이션(Emulation)

㉰ 컨버젼(Conversion)	㉱ 리프레이스머트(Replacement)

3.1 컴퓨터言語의 종류를 들고, 이들 간의 관계를 논하라.

3.2 주소지정방식(addressing mode)에 대하여 논하라.

3.3 8051의 주소지정방식의 종류를 들고, 간단히 설명하라.

3.4 레지스터 간접 주소지정방식과 간접 주소지정방식의 차이를 기술하라.

3.5 절대 주소지정방식과 상대 주소지정방식의 차이는 무엇인가?

3.6 캐리(carry)와 오버플로(overflow)을 비교 논하라.

3.7 8051 어셈블리語의 의사명령(pseudo operation) 5가지를 들고 설명하라.

4.1 C의 기초 4.2 헤더 파일 4.3 2진 가산 4.4 배정도 가산 4.5 메모리 클리어 4.6 데이터의 로드 4.7 데이터의 검색	4.8 8비트 2진수의 BCD 변환 4.9 16비트 2진수의 BCD 변환 4.10 BCD의 2진수 변환 4.11 BCD 가산 4.12 탐색표 4.13 지연루틴 4.14 이 장의 간추림

문법적으로 하자가 없는 가장 간단한 C 프로그램은 다음과 같다.

main(){}

이 프로그램은 실제로 동작은 하지만, 아무런 일도 하지 않는다. 일을 하는 가장 간단한 C 프로그램은 아마 CRT 화면에 □HI□라고 표시하는 다음과 같은 프로그램일 것이다.

main()

{

printf (″HI″);

}

여기서 제1행의 □main()□은 함수 이름이다. 일반적으로 C 프로그램은 하나 이상의 함수로 구성되는데, 프로그램의 시작 함수는 main( )으로 정해져 있다. 이것은 void main(void)에서 앞 뒤 void가 생략된 형태이다. 앞의 void는 함수 main이 리턴 값을 가지지 않음을 뜻한다. 일반적으로 함수는 그 함수를 사용하는 호출함수에 어떤 값을 리턴하지만, 리턴 값이 없을 경우에는 void라고 표시한다. void 및 int는 ANSI C에서 main( )을 정의할 때 필요한 구성요소이다.

뒤의 void는 인수(argument)가 없음을 표시한다. 인수가 필요할 때에는 이곳에 그것을 넣는다.

제2행의 □{□는 함수 본체의 시작을 뜻하고, 제 4행 줄의 □}□는 그것의 끝남을 뜻한다. 제2행의 □{□는 제1행의 main( ) 다음에 두어도 된다.

제 3행의 □printf (″HI″)□는 HI라고 CRT화면에 표시하라는 화면 출력문이다. 그리고 마지막의 □;□는 하나의 문장이 끝났음을 표시한다. C에서 모든 문장은 반드시 ;(semicolon)으로 끝나야 한다.

일반적으로 8051과 같은 마이크로콘트롤러에 있어서는 CRT 화면 표시는 필요없고, I/O포트에 어떤 값을 출력한다든가, A/D 변환을 한다든가, 타이머를 동작시킨다든가, 직렬포트의 TxD 핀으로 데이터를 전송한다든가와 같이 8051만의 하드웨어를 제어하는 일을 한다. 문제는 8051만의 하드웨어를 어떻게  C 프로그램에서 다룰 수 있느냐에 있다. 이것은 하드웨어 주소를 직접 지정하든지, 8051 해더 파일(reg51.h)을 include문으로 포함시킴으로써 가능하다. include는 컴파일을 할 때 별개의 다른 파일을 본 파일에 포함시키는 전처리문으로서, 그 확장자는 *.h이다. 앞에서 언급한 바와 같이 reg51.h의 내용을 보면 R0, R1, …A, B, DPTR, P1, P2 …등 8051의 특수기능 레지스터(SFR)에 대한 정의가 망라되어 있다. 그러므로, 프로그램 초두에서 이것을 include문으로 포함시키면 8051의 모든 특수기능 레지스터들을 일반 변수처럼 사용할 수 있다.

다음 프로그램은 8051의 포트 1에 00010010B(0x12)라는 값을 출력하기 위한 것이다.

# include <reg51.h>

main()

{

P1 = 0x12;

}

위에서 0x12의 □0x□는 16진수 표시라는 뜻이다.

이상이 8051 C 프로그램의 기본 틀이다.

다음 프로그램은 포트 1에 전류흡입형으로 연결된 LED들을 2진 가산 형태로 바뀌게 하는 것이다.

/*==============================*/

/* EXAMPLE PROGRAM EX1_1.C)    */

/*==============================*/

#include <reg51.h>	/* 8051 헤더 파일을 포함하라 */

delay(int i)	/* delay 루틴, 인수는 정수 i */

{

while(i--);	/* 주어진 i값에서부터 i=0이 될 때까지 */

/* i를 하나씩 감소하라  */

}

main( )	/* main 함수, 인수 없음 */

{

unsigned char number;	/* number는 부호가 없는 8비트 데이터임 */

do {	/* 다음 루프를 반복하라 */

for(number = 0xff; number >= 0; number--)

/* number=255에서 0까지 number를 하나씩 감소하면서 다음 명령들을 수행하라 */

{

P1 = number;	/* 포트 1에 number를 출력하라 */

delay(0xffff);	/* i=65535로 하고, delay 루틴으로 가라 */

}

}while(1);	/* 반복하라 */

}

제 2행에서 제 5행까지는 지연 루틴이다. 원래 while문은 조건 수식이 거짓(0)이 될 때까지 반복하는 순환문이다. 그러므로 뒤의 □delay(0xffff)에서 0xffff라는 수치를 인수 i로 가져와서 하나씩 감소하면서 0이 될 때까지 반복 수행한다. 반복하는 횟수만큼 시간이 지연된다. 실제로 얼마만큼이나 지연되는지는 어셈블리어 단위에서 따져야 한다. #pragma code라는 전처리문을 넣어두고 컴파일 작업을 한 후에 리스트 파일 마지막 부분을 보면 C 프로그램을 컴파일해서 만들어진 기계어를 dissamble하여 어셈블리어 프로그램으로 만든 것이 있다. 이것을 보고 따져야 한다.

제 8행의 □unsigned char number;"는 number가 부호가 없는 8비트 데이터라는 것을 선언하고 있다. 이 형의 데이터는 0∼255(0∼FFH) 사이의 1바이트 정수 값을 가진다.

제 10행의 □for(number = 0xff ; number □= 0; number--□는 number=0FFH에서 0까지 number 값을 하나씩 감소하면서 { } 내의 것을 반복 수행하라는 것이다.

제 12행의 □P1 = number;□는 number의 값을 포트 1에 출력하라는 것이다. P1이 SFR의 90H 번지라는 것은 #include문에서 밝히고 있다.

제 13행의 □delay(0xffff);□는 제 2행에서부터 시작되는 delay 함수의 인수 i의 초기값을 16진수 FFFFH(65535)로 하고, delay 함수를 실행하라는 것이다. 인수 i를 FFFFH로 하고 delay 함수를 실행시킬 때 얼마만큼의 시간이 지연되느냐는 전술한 바와 같이 어셈블리어 단위에서 따져야 한다.

제 15행의 while(1)은 언제까지나 루프를 반복 수행하라는 것이다. 1은 항상 참(眞)이기 때문이다.

제2장에서 밝힌 바와 같이, 8051의 레지스터는 A, B, R0∼R7과 같이 이름만으로 접근할 수 있는 몇 개의 레지스터를 제외하고는 모두 번지로 접근되도록 되어 있다. 번지로 접근되는 공간은 20H에서 2FH까지의 비트 지정 공간, 30H에서 7FH까지의 자유공간(scratch pad), 그리고 80H에서 FFH까지의 특수기능레지스터(SFR) 공간인데, 이들 중 SFR 공간은 그 주소와 명칭이 고정적이므로 SFR 하나하나에 대해서 그 주소를 정의해서 하나의 프로그램으로 만들어 놓고, 일반 프로그램에서는 일일히 그 주소를 정의할 필요없이 주소를 정의한 이 프로그램을 include 문으로 포함시키기만 하면 되도록 되어 있다. 이 때 SFR의 주소를 정의한 이 프로그램을 헤더파일(header file)이라고 한다. 이것은 특히 C와 같은 고급언어로 프로그램을 작성할 때 유용하다. 어셈블리어로 작성할 경우에는 프로그램에서 지정해주므로 include할 필요가 없다.

다음은 8051의 헤더 파일 reg51.h의 내용이다. hkmds에 들어가면 INC 파일이 있다. 이것을 선택하면 8051에 속하는 모든 마이크로콘트롤러의 헤더 파일이 들어있다. 이들 중 reg51.h를 선택하고 F4를 누르면 8051의 헤더 파일이 표시된다.

/*--------------------------------------------------------------

REG51.H

Header file for 8051.

Copyright (c) 1988-1997 Keil Elektronik GmbH and Keil Software, Inc.

All rights reserved.

--------------------------------------------------------------*/

/*  BYTE Register  */

sfr P0	= 0x80;	sfr P1	= 0x90;

sfr P2	= 0xA0;	sfr P3	= 0xB0;

sfr PSW	= 0xD0;	sfr ACC	= 0xE0;

sfr B	= 0xF0;	sfr SP	= 0x81;

sfr DPL	= 0x82;	sfr DPH	= 0x83;

sfr PCON	= 0x87;	sfr TCON	= 0x88;

sfr TMOD	= 0x89;	sfr TL0	= 0x8A;

sfr TL1	= 0x8B;	sfr TH0	= 0x8C;

sfr TH1	= 0x8D;	sfr IE	= 0xA8;

sfr IP	= 0xB8;	sfr SCON	= 0x98;

sfr SBUF	= 0x99;

/*  BIT Register  */

/*  PSW   */

sbit CY	= 0xD7;	sbit AC	= 0xD6;

sbit F0	= 0xD5;	sbit RS1	= 0xD4;

sbit RS0	= 0xD3;	sbit OV	= 0xD2;

sbit P	= 0xD0;

/*  TCON  */

sbit TF1	= 0x8F;	sbit TR1	= 0x8E;

sbit TF0	= 0x8D;	sbit TR0	= 0x8C;

sbit IE1	= 0x8B;	sbit IT1	= 0x8A;

sbit IE0	= 0x89;	sbit IT0	= 0x88;

/*  IE   */

sbit EA	= 0xAF;	sbit ES	= 0xAC;

sbit ET1	= 0xAB;	sbit EX1	= 0xAA;

sbit ET0	= 0xA9;	sbit EX0	= 0xA8;

/*  IP   */

sbit PS	= 0xBC;	sbit PT1	= 0xBB;

sbit PX1	= 0xBA;	sbit PT0	= 0xB9;

sbit PX0	= 0xB8;

/*  P3  */

sbit RD	= 0xB7;	sbit WR	= 0xB6;

sbit T1	= 0xB5;	sbit T0	= 0xB4;

sbit INT1	= 0xB3;	sbit INT0	= 0xB2;

sbit TXD	= 0xB1;	sbit RXD	= 0xB0;

/*  SCON  */

sbit SM0	= 0x9F;	sbit SM1	= 0x9E;

sbit SM2	= 0x9D;	sbit REN	= 0x9C;

sbit TB8	= 0x9B;	sbit RB8	= 0x9A;

sbit TI	= 0x99;	sbit RI	= 0x98;

(1) 目    的

지금껏 프로그램을 작성하는 방법과 이를 실행시키는 방법을 다루었다. 이젠 실제로 간단한 프로그램을 작성하고, 이를 실행시킴으로써 8051 프로그래밍의 기초를 다질 차례이다. 이것은 8051을 이용하여 외부장치를 제어하는 기술에 들어가기 전에 밟아야 할 기초 과정이 될 것이다.

최초의 문제로서 두 개의 8비트 2진수를 가산하는 프로그램을 작성하고자 한다.

(2) 問題의 例

(NUM_1)Ａ33H

(NUM_2)Ａ24H

결과 (RESULT)Ａ57H

(3) 順序圖

여기에서 주의를 요하는 것은 아래 순서도가 입력, 연산, 출력의 형태로 되어 있다는 것이다. 간단한 것이든 복잡한 것이든 프로그램은 입력, 연산, 출력이라는 이 기본 패턴을 벗어나서는 안된다.

그림 4.1  2진 가산의 순서도

(4) 프로그램(EX4_1.C)

/*=====================================*/

/* PROGRAM EX4_1.C (BINARY ADDITION)  */

/*=====================================*/

#pragma code symbols debug oe

#include  <reg51.h>

data unsigned char num_1,num_2,result;

void  bin_add(void)	/* 두 2진수를 가산하는 함수 */

{

result = num_1 + num_2;

}

void main(void)	/* 위 함수를 응용하는 메인 함수 */

{

num_1 = 0x33;	/* NUM_1과 NUM_2의 값을 지정한 후 */

num_2 = 0x24;

bin_add ( );	/* 서브루틴 bin_add( )를 콜한다 */

}

(5) 프로그램의 解說(C)

#pragma code symbols debug oe

C 컴파일러에 대한 제어지시어(control directive)이다. 원래 pragma는 □컴파일시에 명령(제어지시어)을 컴파일러에게 건내주어라□는 뜻의 전처리문(pre_processor)으로, 이것이 있는 라인을 command 라인으로 취급할 것을 지시할 때 사용된다. pragma 뒤에 있는 code, symbol, debug, oe 등은 모두 제어지시어이다. 다음 2개의 표는 8051.C에서 사용되는 전처리문과 제어지시어들이다.

□표 4.1  C51 전처리문

define	매크로를 정의한다.
undef	매크로를 딜리트한다.
include	외부 파일에서 소스 문장을 읽어드린다.
pragma	이것이 있는 문을 커맨드 라인으로 취급토록 한다.
error	정의된 에러 메시지를 출력한다.
if	조건 컴파일에서 조건 만족 여부를 평가한다.
ifdef	조건 컴파일에서 조건 만족 여부를 평가한다. 평가하는 인수(argument)는 정의된 이름이다.
ifndef	ifdef에서와 같지만, 인수가 정의되어 있지 않았으면 그 다음을 한다.
elif	전의 if, ifdef, ifndef, else-branch를 취하지 않을 때 alternative if-branch를 초기 설정한다.
else	전의 if, ifdef, ifndef-branch를 취하지 않을 때 alternative branch를 초기 설정한다.
line	라인수를 지정한다.

□표 4.2  제어지시어

제어지시어	약 자	디폴트	설 명
DEFINE	DF	１	조건컴파일에서 전처리문에게 묻는 이름이다.
[NO]LISTINCLUDE	[NO]LC	NOLISTINCLUDE	리스트파일에 인크루드된 파일을 출력한다.
[NO]SYMBOLS	[NO]SB	NOSYMBOLS	모든 기호(symbol)를 출력한다.
[NO]PREPRINT	[NO]PP	NOPREPRINT	전처리 리스팅을 만들어낸다.
[NO]CODE	[NO]CD	NOCODE	리스팅 파일에 어셈블리어를 추가한다.
[NO]PRINT	[NO]PR	PRINT(bname.LST)	리스팅 파일을 만들어 낸다.
[NO]COND	[NO]CO	COND	조건 컴파일 부분을 리스트한다.
PAGELENGTH	PL	PAGELENGTH(69)	리스팅 파일의 라인수/페이지를 결정한다.
EJECT	EJ	１	리스팅 파일에서 특정페이지를 생략한다.
PAGEWIDTH	PW	PAGEWIDTH(132)	리스팅 파일의 문자수/라인을 결정한다.

[NO]DEBUG	[NO]DB	NODEBUG	OBJ 파일에 있는 DEBUG 정보를 포함함.
[NO]OBJECT	[NO]OJ	OBJECT(bname.OBJ)	OBJ 파일을 변경한다.
OPTIMIZE	OT	OPTIMIZE(2)	최적화 정도를 지정한다(0∼3)
SMALL	SM	SMALL	모든 로컬데이터와 변수는 내부 데이터에
COMPACT	CP	１	모든 로컬데이터와 변수는 내부 페이지된 외부 데이터 메모리에
LARGE	LA	１	모든 로컬데이터와 변수는 외부데이터 메모리에
REGISTERBANK	RB	REGISTERBANK(0)	레지스터뱅크를 선택하는데 사용됨
[NO]INTVECTOR	[NO]IV	INTVEDTOR	LJMP명령을 사용하여 점프
OBJECTEXTEND	OE	１	OBJ 파일을 변경할 때 사용한다.
1. 디폴트(default)＞특별히 지정해주지 않을 경우에 응당 지정되는 값 2. bname(basename)＞컴파일 될 소스 코드의 이름과 관계된 디렉티브

#include <reg51.h>

include문은 디스크상에 수록되어 있는 외부 파일을 편입시킬 것을 지시하는 전처리문이다(표 4.1 참조). 그러므로 이 문장이 들어있는 프로그램을 컴파일하면 □해더파일□에서 설명한 reg.51이라는 파일을 본 프로그램에 편입시킨다.

unsigned char num_1, num_2, result

변수 num_1, num_2, result 등이 부호 없는 8비트 데이터임을 선언한 것이다. data형의 메모리에 있는 데이터임을 표시하기 위해서 unsigned 앞에 data를 붙이기도 한다. data형의 메모리는 앞에서 설명한 바와 같이 직접 주소지정이 가능한 내부 데이터메모리이다.

(6) 프로그램의 實行

에디터를 사용하여 原始프로그램을 소스파일로 만든 후(이 책에 첨부된 디스켓에서 copy해서 사용해도 됨), □Vision의 New project에서 프로젝트를 만들고(Keil Software를 설치하고 최초의 경우가 아니면 이 작업은 필요없음), Open project에서 앞에서 정한 project 이름을 지정하고, Edit project에서 프로그램(EX4_1.C 또는 EX4_1.A51)을 지정한 후 Build project 작업을 한다. Build project에서는 어셈블 또는 컴파일을 하고 링크를 하여 Obj 파일과 Hex 파일을 만든다.

이 프로그램을 포함한 이 장의 프로그램들은 어느 포트에 출력을 낸다든가 … 그런 것들이 아니기 때문에 시뮬레이트로 그 결과를 볼 수 밖에 없다. 그러므로 시뮬레이터 dScope를 가동시켜서 CPU를 선택하고(처음의 경우에만), 프로젝트 이름을 지정하고, Debug window에서 Go한다. 그리고 곧바로 STOP에 클릭한다. 그림 3.11의 툴바에서 좌로부터 7번째 칩모양을 한 곳에 클릭하면 데모리 번지들의 내용이 표시된다. 이곳을 보면 08H 번지에서부터 57 24 33 …로 되어 있어서 프로그램이 제대로 되어 있음을 확인할 수 있을 것이다.

어셈블리어 프로그램 EX4_1.A51에 대해서도 동일한 방법으로 실행을 시킨다. 이 경우에는 한번 실행한 뒤이므로 □Vision에서(□Vision으로 되돌아 가고자 할 때에는 그림 3.18 dScope 화면의 맨 밑에 있는 □Vision/51에 클릭하면 됨) New project도, open project도 필요없이 곧바로 edit project를 하고 build project를 하면 된다. 다만 어셈블리 프로그램과 C프로그램이 각각 다른 곳에 들어있으므로 edit project 작업을 할 때 project→edit program→Remove→add→파일형식에서 Assemble Source에 클릭→hkmds에 클릭 후 51a_prg 선택→프로그램(ex4_1.a51) 선택(더블 클릭)→close→open→save 등의 절차로 어셈블리어 프로그램이 들어 있는 파일에서 해당 프로그램을 선택하는 과정이 있어야 한다. dScope에서도 CPU 선정 작업 없이 곧바로 project 지정을 한 후 Go하면 된다. stop 후 메모리를 보면  30H 번지부터 33 24 57로 되어 있음을 확인할 수 있을 것이다.

(7) 課  題

1. 위 프로그램을 dScope에서 Single-step으로 실행시키고, 그 결과를 확인하라.

2. NUM_1에서 NUM_2를 빼서 그 결과를 RESULT에 넣는 프로그램을 작성한 후 이를 실행시켜 보라.

(1) 目 的

두 개의 16비트 2진수를 가산하는 프로그램을 작성하고자 한다.

(2) 問題의 例

num1Ａ01FF

num2Ａ7FF7

결과  rsltＡ81F6

(3) 順序圖

어셈블리어 프로그램에서는 NUM1(16비트)+NUM2(16비트)→RSLT(16비트)의 처리를 하기 위하여 다음의 작업을 한다.

(a) 첫 번째 오퍼랜드(16비트의 2진수)를 NUM1_LO와 NUM1_HI에 로드한다.

(b) 두 번째 오퍼랜드(16비트의 2진수)를 NUM2_LO와 NUM2_HI에 로드한다.

(c) NUM1_LO + NUM2_LO → RSLT_LO

NUM1_HI + NUM2_HI + Carry → RSLT_HI의 연산을 한다.

(d) 결과는 RSLT_LO와 RSLT_HI에 들어있다.

그러나, C의 경우는 그럴 필요가 없다. num1과 num2가 8비트 데이터가 아니고 16비트 데이터라는 것만 밝히고 앞의 예에서와 같이 직접 플러스하면 된다.

(4) 프로그램(EX4_2.C)

/*===========================================*/

/* PROGRAM EX4_2.C (16 bit BINARY ADDITION) */

/*===========================================*/

#pragma code symbols debug oe

#include  <reg51.h>

unsigned int num1, num2, rslt;

void  dbl_add(void)

{

rslt = num1 + num2;

}

void main(void)	/* 위 함수를 응용하는 메인 함수 */

{

num1 = 0x01ff;	/* 두 16비트 2진수값을 지정한 후 */

num2 = 0x7ff7;

dbl_add();	/* 서브루틴 dbl_add를 콜한다 */

}

(5) 프로그램의 解說(C)

unsigned int num1, num2, rslt;

num1, num2, rslt 등이 integer, 즉 16비트 데이터임을 선언한 것이다.

rslt = num1 + num2;

num1과 num2가 16비트 데이터임이 선언되어 있으므로, 하위 것끼리 가산하고 상위 것끼리 가산할 필요없이 한꺼번에 가산한다.

(6) 프로그램의 實行

컴퓨터를 켠 후 이미 open project를 했으므로, 이것은 생략하고 곧바로 □Vision에서 Edit project, build project를 한다. dScope에서도 CPU 선택은 생략하고 곧바로  project 이름을 지정한 뒤 Debug window에서 Go, stop한다. 그런 다음 메모리 내용을 본다.

D 0000	00 00  00 00 00 00 00	…

D 0010	00 00  00 00 00 00 00	…

D 0020	00 00  00 00 00 00 00	…

D 0030	01 FF 7F F7 81 F6 00  …

□	□

num1=01FF

／    num2=7FF7

rslt = 81F6

이므로 결과가 맞음을 확인할 수 있다.

(7) 課 題

1. 두 개의 16비트 2진수를 감산하는 프로그램을 작성하고, 이를 실행하여 결과를 확인하라.

(1) 目 的

data 메모리 영역의 30H∼7FH번지를 클리어하고자 한다.

(2) 問題의 例

(실행전)	(30H)=35

(31H)=F3

□

(7FH)=AF

(결과)	(30H)=0

(31H)=0

□

(7FH)=0

(3) 順序圖

그림 4.2  메모리 클리어 순서도

이 문제를 어셈블리어로 프로그램하려 한다면 내부 RAM의 각 번지를 지정하는 address pointer(R0)에 최초의 번지값 30H를 주고, Acc에는 0을 넣은 후 MOV @R0,A라는 명령으로 pointer가 지시하는 번지를 클리어한 뒤, pointer R0는 하나 증가하고 카운터 R1은 하나 감소하되, 카운터 R1이 0이 될 때까지 이 작업을 반복하면 된다. 애초에 카운터 R1에는 클리어시킬 번지의 수를 넣어둔다. 어셈블리어로 프로그램한다면 이렇게 복잡하지만 C로 프로그램한다면 DBYTE[i]라는 매크로 함수를 이용하면 된다. DBYTE[0x0030]=0; 라고 하면 30H번지가 클리어된다.

(4) 프로그램(EX4_3.C)

/*====================================*/

/* PROGRAM EX4_3.C (MEMORY CLEAR)  */

/*====================================*/

#pragma code symbols debug oe

#include  <reg51.h>

#define DBYTE ((unsigned char volatile idata *) 0)

void main(void)

{

unsigned char i;

for (i=0x0030; i<=0x007f; i++)

{

DBYTE [i] = 0;

}

}

(5) 프로그램의 解說(C)

#define DBYTE ((unsigned char volatile idata *) 0)

void main(void)

{

unsigned char i;

for (i=0x0030; i<=0x007f; i++)

{

DBYTE [i] = 0;

}

}

이들 부분 프로그램을 이해하려면 절대번지 접근 매크로 DBYTE를 알아야 한다. 이것은 C51 표준 library에 있는 것으로, 8051의 내부 데이터메모리내에 있는 어느 번지에 접근하기 위한 것이다. define문도 그 매크로에서 정의되어 있는 것이다.

다음은 DBYTE 매크로를 이용해서 02H 번지의 내용을 rval에 읽어드리는 예와 02H 번지에 5를 기록하는 예이다. 주소를 02로 나타내지 않고 0002로 나타냄에 유의해야 한다.

rval = DBYTE[0x0002];  /*02번지의 내용을 읽어드리라는 판독 명령*/

DBYTE[0002] = 5;       /*02번지에 5를 넣으라는 기록 명령*/

(1) 目 的

30H∼7FH번지에 다음과 같이 데이터를 로드하고자 한다.

범용 레지스터	내 용
30H 31H 32H . . . 7EH 7FH	30H 31H 32H . . . 7EH 7FH

(2) 프로그램(EX4_4.C)

/*==================================*/

/* PROGRAM EX4_4.C (MEMORY LOAD) */

/*==================================*/

#pragma code symbols debug oe

#include  <reg51.h>

#define DBYTE ((unsigned char volatile idata *) 0)

void main(void)

{

unsigned char i;

for (i=0x0030; i<=0x007f; i++)

{

DBYTE [i] = i;

}

}

(3) 課 題

1. 위 프로그램을 실행시키고, 각 번지의 내용을 확인하라.

2. 30H∼7FH번지의 내용이 다음과 같이 되도록 하라(힌트＞ DBYTE[i]=00a0-i).

범용 레지스터	내 용
30 31 32 . . . 7E 7F	7F 7E 7D . . . 31 30

(1) 目 的

30H에서부터 6FH까지의 번지에 기억되어 있는 데이터 중 ASCII 코드로 空白(20H)이 있는지를 검색하고자 한다. 空白이 있으면 그것이 들어 있는 최초의 번지를 70H번지에 넣고, 없으면 마지막 번지의 다음 번지를 역시 70H 번지에 넣는다.

(2) 問題의 例

空白(20H)이 35H에 들어 있는 경우

(70H)=35H

空白(20H)이 30H∼6FH에 들어 있지 않는 경우

(70H)=70H

(3) 順序圖

이것도 DBYTE[i] 함수를 이용한다. i값을 0x0030에서 0x0060까지 하나씩 증가하면서 DBYTE[i]Ａ0x20인지를 검사하고, yes이면 그 루프에서 빠져나온다(break).

(4) 프로그램(EX4_5.C)

/*==================================*/

/* PROGRAM EX4_5.C (MEMORY LOAD) */

/*==================================*/

#pragma code symbols debug oe

#include  <reg51.h>

#define DBYTE ((unsigned char volatile idata *) 0)

void main(void)

{

unsigned char i;

for (i=0x0040; i<=0x0050; i++)

{

DBYTE [i] = 0x20;

}

for (i=0x0030; i<=0x006f; i++)

{

if (DBYTE [i] == 0x20)	/* 그 번지의 내용이 공란이면 */

break;;	/* for 루프를 벗어난다 */

}

DBYTE [0x0070] = i;

}

(5) 프로그램의 解說(C)

for (i=0x0040; i<=0x0050; i++)

{

DBYTE [i] = 0x20;

}

40H 번지에서 50H 번지까지를 20H로 채우기 위한 것이다. 이것은 課題와 관련하여 미리 20H를 넣어 놓은 것이다.

for (i=0x0030; i<=0x006f; i++) {

if (DBYTE [i] == 0x20)

break;

}

DBYTE [0x0070]=i;

DBYTE[i]가 20H이면 for 루프에서 벗어나서 DBYTE[0x0070]=i를 실행하라는 것이다.

(6) 프로그램의 實行

□-vision의 edit project에서 project→edit project→Remove→add→hkmds 더블클릭(51a_prg 또는 51c_prg 선택)→파일형식(Assembly source 또는 C source 선택)→해당 프로그램 선택(ex4_5.C 또는 ex4_5.a51에 더블클릭)→close→open→save한 후 build project에서 project→build project→ok한다. dscope에서는 프로젝트 이름 확인(최초의 툴바에 클릭→8051에 더블클릭)후, Debug window(4번째 툴바에 클릭)에서 go한다. stop후 Memory룰 본다. 30H∼69H번지에 공백(20H)이 있으면 그 번지가 70H 번지에 표시되고, 없으면 70H가 70H 번지에 표시된다.

(7) 課 題

1. 30H∼6FH에 空白이 몇 개나 되는지 그 수를 세어서  70H번지에 저장하는 프로그램을 작성하라(힌트＞count를 카운터로 하고 空白이 있을 때 마다 하나씩 증가한다).

(1) 目 的

bin이라는 번지에 들어 있는 8비트 2진수를 세 단위의 BCD로 변환하여 BCD100과 BCD10과 BCD1이라는 세 개의 번지에 넣고자 한다.

(2) 問題의 例

2진수  BIN=11111111B

결과   BCD100=02, BCD10=5, BCD1=5       ∵11111111B=255

(3) 順序圖

2진수를 2진화 10진수(BCD)로 변환하기 위해서는 바로 뒤에서 소개하는 덴마크의 N.S Gundestrop이 개발한 3 더하기 알고리즘(Add 3 algorithm)을 이용할 수도 있겠으나, 여기에서는 이해가 보다 빠른 방법을 쓰기로 한다. 이것은 주어진 2진수를 100단위, 10단위, 1단위 등으로 나누어서 환산하는 방법이다.

그림 4.3  8비트  2진수의 BCD 변환 순서도

주어진 2진수를 BCD로 환산할 때 100단위의 BCD가 몇개나 되는가를 알기 위해서는 2진수를 100(2진수 1100100)으로 나눠야 한다. 나눠서 그 몫(Quotient)으로 나온 값이 100단위의 BCD이다. 10단위의 BCD는 그 나머지를 10(2진수 1010)으로 나눠서 그 몫으로 나온 것이고, 1단위 BCD는 그 나머지이다. BCD10과 BCD1을 하나의 바이트에 수용하여 BCD10_1로 하기 위해서는 BCD10을 좌측으로 4번 시프트하여 상위 니블에 옮겨놓은 후 BCD1과 OR한다.

(4) 프로그램(EX4_6.C)

/*==================================*/

/* PROGRAM EX4_6.C (BINARY to BCD)*/

/*==================================*/

#pragma code symbols debug oe

#include  <reg51.h>

unsigned char bin,BCD100,BCD10_1,BCD10,BCD1,remain10;

void  bin_BCD(void)	/* 2진수를 BCD로 고치는 함수 */

{

BCD100 = bin / 100;	/* BCD100 = 100단위의 BCD*/

remain10 = bin % 100;	/* remain10 = bin을 100으로 나눈 나머지 */

BCD10 = remain10 / 10;	/* BCD10 = 10단위의 BCD */

BCD1 = remain10 % 10;	/* BCD1 = 1단위의 BCD*/

BCD10 <<= 4;	/* 10단위의 BCD를 상위 니블로 */

BCD10_1 = BCD10 □ BCD1;	/* BCD10_1 = 10단위와 1단위의 BCD*/

}

void main(void)	/* 메인 함수 */

{

bin = 0xff;	/* bin의 내용=0FFH */

bin_BCD();	/* bin_BCD 함수를 불러 쓴다 */

}

(5) 프로그램의 解說(C)

BCD100 = bin / 100;

remain10 = bin % 100;

BCD100=bin/100이 실행되면 bin을 100으로 나누고, 그 몫을 BCD100에 넣는다. remain10=bin%100이 실행되면 bin을 100으로 나누고, 그 나머지를 remain10에 넣는다. %는 modulo라고 읽는다.

(6) 課 題

1. 프로그램 EX4_6.C를 실행시키고 메모리의 내용이 다음과 같이 되는지를 확인하라. 실행시키면 09H 번지부터 FF 55 02 … 로 된다. 순서가 바꾸어짐은 역시 로더가 빈자리를 찾아 변수들을 적당히 배치하기 때문이다.

D 0009	FF 55 02 … … …

(1) 目  的

bin에 들어있는 16비트 2진수를 5단위의 BCD로 변환해서 각각 BCD5, BCD4, BCD3, BCD2, BCD1에 넣는 프로그램을 작성하고자 한다.

(2) 문제 例

bin=$FFFF이면 BCD5=06, BCD4=05, BCD3=05, BCD2=03, BCD1=05이다.

(3) 順序圖

어셈블리어로 16비트 2진수를 BCD로 고치는 프로그램을 작성할 경우에는 덴마크의 N.S Gundestrop이 개발한 □3 더하기 알고리즘(Add 3 Algorithm)□으로 할 수 밖에 없다. 이 알고리즘은 다음 예와 같이 2진수를 계속 좌측으로 자리이동을 하면서 각 단위별로 5를 초과하는지를 조사하여 초과했으면 3을 가산하는 방법이다. 자리이동은 2진수의 비트 수 만큼 한다. 다음은 16비트는 너무 번거로워서 8비트로 압축한 상태에서 3 더하기 알고리즘으로 변환하는 과정이다.

	100단위 BCD				10단위 BCD					1단위 BCD					2진수 (BIN)
															1	1	1	1	1	1	1	1
													1		1	1	1	1	1	1	1			자리이동
												1	1		1	1	1	1	1	1				자리이동
											1	1	1		1	1	1	1	1					자리이동
										1	0	1	0		1	1	1	1	1					1단위에 3을 가산
								1		0	1	0	1		1	1	1	1						자리이동
								1		1	0	0	0		1	1	1	1						1단위에 3을 가산
							1	1		0	0	0	1		1	1	1							자리이동
						1	1	0		0	0	1	1		1	1								자리이동
					1	0	0	1		0	0	1	1		1	1								10단위에 3을 가산
			1		0	0	1	0		0	1	1	1		1									자리이동
			1		0	0	1	0		1	0	1	0		1									1단위에 3을 가산
		1	0		0	1	0	1		0	1	0	1											자리이동
			2			5					5

C로 작성할 경우에는 3 더하기 알고리즘을 쓸 필요가 없다. 앞에서와 같이 나누기(/)와 모듈러스(%)를 이용하면 된다.

(4) 프로그램(EX3_7.C)

;

;***************************************************************************

;* 16비트 2진수의 BCD 변환

;*

;* 이 프로그램은 16비트 2진수(bin)를 5단위의 BCD(BCD5＞BCD4＞BCD3＞BCD2＞

;* BCD1)로 고친다.

;* target＞ 8051

;* bin=$FFFF일 때 변환결과는 BCD5=6, BCD4=5, BCD3=5, BCD2=3, BCD1=5이다.

;***************************************************************************

unsigned int  bin,remd5,remd4;

unsigned char BCD5,BCD4,BCD3,BCD2,BCD1,remd3;

void bin_BCD16( void ) {

BCD5 = bin / 10000;	//BCD5=10000단위 BCD

remd5 = bin % 10000;	//remd=나머지

BCD4 = remd5 / 1000;	//BCD4=1000단위 BCD

remd4 = remd5 % 1000;

BCD3 = remd4 / 100;	//BCD3=100단위 BCD

remd3 = remd4 % 100;

BCD2 = remd3 /10;	//BCD2=10단위 BCD

BCD1 = remd3 % 10;	//BCD1=1단위 BCD

}

int main( void ) {

bin = 0xffff;

bin_BCD16();

}

(5) 프로그램의 解說

unsigned int bin, remd5, remd4

remd5와 remd4를 char로 정의하지 않고 int로 정의한 이유는 16비트 2진수 bin 중 10,000단위 또는 1,000단위 BCD를 빼버린다해도 그 나머지가 8비트 2진수의 범위를 넘는 경우가 있기 때문이다.

(6) 프로그램의 實行

역시 앞에서 설명한 방법에 따라서 □Vision에서 Edit project, Build project 등의 작업을 한 후, dScope에서 project 이름을 지정하고 Debug window의 Go에 클릭하고 stop한다. 그런다음 메모리의 내용을 본다.

(7) 課 題

1. 위의 예제에서 결과를 팩 BCD로 변환하라(힌트＞BCD4와 BCD3를 BCD43으로, BCD2와 BCD1을 BCD21로 고치면 된다).

(1) 目 的

2단위의 BCD를 2진수로 변환하고자 한다.

(2) 問題의 例

BCD        BCD=99

결과(2진수)  BIN=63H

(3) 順序圖

BCD는 Binary Coded Decimal code의 약자로서, 8421 코드라고도 한다. BCD에는 존 형식과 팩 형식이 있는데, 존 형식에서는 한 바이트에 10진수 한 자리를 저장하고, 팩 형식에서는 두 자리를 저장한다. 예컨대 43을 존 형식에서는 11110100 11110011로 표시하고, 팩 형식에서는 01000011로 표시한다. 그러므로 팩 형식에서는 상위 4비트가 10단위 BCD이고 하위 4비트가 1단위 BCD이다. 10단위 BCD에는 10을 곱해 주어야 하고, 1단위 BCD에는 1을 곱해 주어야 한다. 10단위 BCD만을 가려내려면 상위 4비트를 4번 우로 시프트해서 하위 4비트로 해야 한다.

그림 4.4  BCD의 2진수 변환 순서도

(4) 프로그램(EX4_8.C)

/*==================================*/

/* PROGRAM EX4_8.C (BCD to BINARY) */

/*==================================*/

#pragma code symbols debug oe

#include  <reg51.h>

unsigned char BCD,bin,BCD_backup,BCD_H,BCD_L,bin_h,bin_l;

void  BCD_bin(void)

{

BCD_backup = BCD;	/*BCD를 BCD_backup에 카피한다*/

BCD_H = BCD >> 4;	/*BCD 상위니블을 하위니블로 고친다*/

bin_h = BCD_H * 10;	/*여기에 10을 곱하여 상위니블에 상당한 */

/* 2진수를 만든다. 위 두 명령은 하나로 할 수 있다*/

BCD_L = BCD_backup;      /*BCD 하위니블에 상당한 2진수를 만든다*/

bin_l = BCD_L & 0x0f;

/*10단위 BCD에 상당한 2진수와 1단위 BCD에 상당한 2진수를 합한다*/

bin = bin_h + bin_l;

}

void main(void)                  /*테스트를 위한 메인루틴*/

{

BCD = 99;                   /*BCD 99를 2진수로 고쳐본다*/

BCD_bin();

}

(5) 프로그램의 解說(C)

BCD_backup = BCD;	/*10단위의 BCD에 상당한 2진수를*/

BCD_H = BCD >> 4;	/*bin_h에*/

bin_h = BCD_H * 10;

BCD_L = BCD_backup;	/*1단위의 BCD에 상당한 2진수를*/

bin_l = BCD_L & 0x0f;	/*bin_l에*/

BCD를 BCD_backup에 넣어둔 것은 BCD>>4, BCD_H*10등의 연산으로 인하여 BCD의 내용이 바꾸어지므로, 하위 BCD의 계산에서 문제가 생길 수 있기 때문이다.

BCD = 99;

BCD_bin();

BCD값을 지정한 후 BCD_bin() 루틴으로 뛰어가서 이를 2진수로 고치라는 것이다. 사실은 BCD_bin() 루틴은 필요없다. BCD=99라고만 해도 C에서는 BCD 번지에는 10진수 99가 들어가지 않고 2진수 63H가 들어가기 때문이다.

(6) 프로그램의 實行

역시 앞에서 설명한 방법에 따라서 □Vision에서 Edit project, Build project 등의 작업을 한 후, dScope에서 project 이름을 지정하고 Debug window의 Go에 클릭하고 stop한다. 그런다음 메모리의 내용을 본다.

(7) 課 題

1. 2단위의 BCD 대신 3단위의 BCD를 2진수로 고치는 프로그램을 작성하라.(힌트, 100단위의 BCD에는 하위 4비트를 상위 4비트로 옮기는 SWAP 조치없이 100을 곱해준다.)

(1) 目 的

부호가 없는 두 단위의 BCD 두 개를 가산하는 프로그램을 작성하고자 한다. 단, 가산할 두 개의 BCD는 각각 NUM_1과 NUM_2에 들어 있고, 가산후 그 결과는 RSLT에 넣어둔다.

(2) 問題의 例

NUM_1 Ａ 99

／   NUM_2 Ａ 99

RSLT  Ａ 198

(3) 順序圖

앞 예제에서도 설명했지만, BCD는 Binary Coded Decimal code의 약자로서, 8421코드라고도 한다.(엄격히 말한다면  8421코드는 BCD의 일종이나, 그 대표적인 것이기 때문에 BCD코드를 흔히 8421코드라고도 한다) 8421코드로서의 BCD는 10진수를 각 자리별로 4단위의 2진수로 나타내므로, 예컨대 10진수 19를 BCD에서는 0001 1001로 표시한다.

BCD 가산에서 유의할 점은 BCD 한 자리로서는 9(1001)를 넘는 것이 없다는 것이다. 1010, 1011, 1100, 1101, 1110, 1111 등은 존재하지 않는다. 그러므로, 가산 결과 9(1001)를 넘는 것이 생기면 1010, 1011, 1100, 1101, 1110, 1111 등 6개를 뛰어 넘어야 하므로 가산 결과에 6(0110)을 플러스해야 한다. 이것을 10진 보정(Decimal Adjust)이라고 한다. 사실은 그 이전의 연산에서 캐리나 보조 캐리가 세트되어 있느냐 그러지 않느냐에 따라 보정과정이 매우 복잡하게 된다. 그래서 PIC16Cxx와 같이 DA 명령이 없는 마이크로콘트롤러에서 이 명령에 상당한 프로그램을 어셈블리어로 작성하면 소스 프로그램이 거의 한 페이지에 달한다. 그러나 8051에는 이 명령이 있으므로, 이 명령을 이용하여 직접 10진 보정을 할 수 있다. DA 명령이 있는 8051에서 BCD 가산에 대한 프로그램은 쉽다. 마치 2진수인 것처럼 BCD 가산을 2진 가산으로 한 다음 DA 명령만 해주면 되기 때문이다.

주의를 요하는 것은 DA 명령은 2진수의 가산 결과를 BCD로 고치는 명령이 아니라는 사실이다. BCD 끼리의 가산 결과가 BCD로 되는 것을 보장받기 위한 것이다. 그러므로, NUM_1에도, NUM_2에도 처음에서부터 BCD가 들어 있어야 한다.

C로 프로그램할 경우에 C에는 DA 명령이 없으므로 다르게 할 수 밖에 없다. C에서는 10진수를 넣어주어도 이것이 2진수로 바꿔져서 기억되므로 10진수로 넣어준 두 수가 2진수로 바꿔졌다는 것을 전제로 하여 두 수를 2진가산을 한 다음 2진수를 10진수(BCD)로 고쳐주면 된다.

(4) 프로그램(EX4_9.C)

/*==================================*/

/* PROGRAM EX4_9.C (BCD ADDITION) */

/*==================================*/

#pragma code symbols debug oe

#include  <reg51.h>

unsigned char BCD1,BCD2,rslt,BCD100,BCD10,BCD1,BCD10_1,remain10;

void  bin_BCD(void)	/*2진수를 BCD로 고치는 루틴*/

{

BCD100 = rslt / 100;

remain10 = rslt % 100;

BCD10 = remain10 / 10;

BCD1 = remain10 % 10;

BCD10 <<= 4;

BCD10_1 = BCD10 □ BCD1;

}

void BCD_add(void)	/*BCD 가산 함수*/

{

rslt = BCD1 + BCD2;	/*2진수로 바뀌진 두 수 BCD1과 BCD2를 2진가산한다*/

bin_BCD();	/*2진수를 BCD로 바꾼다*/

}

void main(void)	/*메인 루틴*/

{

BCD1 = 99;	/*BCD가 2진수로 바꿔져서 BCD1에 들어간다*/

BCD2 = 99;	/* 이곳 BCD도 2진수로 바꿔져서 BCD2에 들어간다*/

BCD_add();	/*BCD_add 함수를 콜한다*/

}

(5) 프로그램의 解說(c)

void  BCD_add(void)

{

rslt = BCD1 + BCD2;

bin_BCD();

}

메인루틴에서 BCD1=99라고 해놓으면 C에서는 이것이 2진수 63H로 바꿔져서 입력되므로 BCD1에는 63H가 기억된다. BCD2도 같다. 그러므로 rslt=BCD1+BCD2가 실행되면 두 개의 2진수가 가산되어 rslt에는 C6H라는 2진수가 들어간다. 이 2진수를 앞에서 다룬 bin_BCD 루틴을 이용하여 BCD로 고치고 있다.

(6) 課 題

제3장에서 설명한 방법에 따라 프로그램 EX4_9.C를 실행(시뮬레이트)시키고, 09H 번지부터 98, C6, 01, …, 63으로 되어 있는지를 확인하라. 그 결과가 위치가 흩어져 있기는 하나 01, 98이라는 결과는 분명히 나온다.

(1) 目 的

다음과 같은 탐색표(look-up table)가 프로그램 메모리의 일정 영역에 저장되어 있다고 하자. 이 표는 BCD를 FND 코드로 변환하기 위한 것인데, 이 표에서 주어진 BCD에 대응하는 FND 코드를 찾아서 RESULT라는 기억번지에 넣는 프로그램을 작성하고자 한다.

□표 4.2  BCD-FND 코드

(BCD)	FND 코드
	2진수 표시	16진 표시
	d.p G F E D C B A
0	0 0 1 1 1 1 1 1	3FH
1	0 0 0 0 0 1 1 0	06H
2	0 1 0 1 1 0 1 1	5BH
3	0 1 0 0 1 1 1 1	4FH
4	0 1 1 0 0 1 1 0	66H
5	0 1 1 0 1 1 0 1	6DH
6	0 1 1 1 1 1 0 1	7DH
7	0 0 0 0 0 1 1 1	07H
8	0 1 1 1 1 1 1 1	7FH
9	0 1 1 0 0 1 1 1	67H

(2) 問題의 例

BCD=2

결과    RESULT=5BH

(3) 順序圖

수차 언급한 바와 같이 8051은 하바드 구조에 속하고, 하바드 구조에서는 프로그램 메모리와 데이터 메모리가 확연히 구분되어 있어서 프로그램 메모리에는 데이터를 넣을 수 없다. 그러나 단 하나의 예외가 있어서 탐색표 데이터만은 프로그램 메모리에 넣을 수 있다.

그림 4.5  FND(common cathode형)

탐색표(look-up table)는 예컨대 BCD를 FND(7-segment LED)에 표시하고자 할 때 그 변환표(BCD-to-FND decode table)와 같은 것이다. 그림 4.5의 윗부분에서 볼 수 있듯이 BCD □0□을 FND에 표시하기 위해서는 LED □G□와 D.P만 불이 켜지지 않고 나머지 모두가 켜져야 하므로, common cathode형 FND의 경우 FND의 각 입력핀에는 논리 □00111111□의 신호가 들어가야 한다. 또 BCD □4□를 표시하기 위해서는 A, D, E와 D.P만 불이 켜지지 않고 나머지 모두가 켜져야 하므로 □01100110□이라는 신호가 들어가야 한다. 이와 같은 이치에 따라 만들어진 표가 BCD-FND 코드에 대한 탐색표인데, 이런 탐색표만은 데이터임에도 불구하고 프로그램 메모리에 저장되는 것이다.

저장된 탐색표를 프로그램 메모리에서 읽어들임에 있어서 핵심이 되는 명령은 어셈블리어의 경우 MOVC A, @A+DPTR 또는 MOVC A, @A+PC이다. 프로그램 메모리에 있는 명령어는 ORG만 정해주면 프로그램카운터가 하나씩 불러오게 되어 있고, 데이터는 MOVC A,@A+DPTR 또는 MOVC A,@A+PC 명령으로 불러온다. 프로그램 메모리에 들어 있는 데이터를 불러오는 이들 명령은 사용 방법에 있어 상당한 차이가 있다.

MOVC A, @A+DPTR는 □프로그램 메모리 [DPTR+A]번지의 내용을 Acc에 로드하라□는 것이고, MOVC A, @A+PC는 □프로그램 메모리 (PC+A)번지의 내용을 Acc에 로드하라□는 것으로 둘 다 TABLE의 시작번지로부터 A만큼 떨어져 있는 표 데이터중 어느 것을 로드하는 데 사용된다. 여기서 A는 DPTR의 값, 또는 PC의 값(표의 시작번지)으로부터 떨어져 있는 정도를 수값으로 나타낸 offset이다.

MOVC A, @A+DPTR와 MOVC A, @A+PC 중 MOVC A, @A+PC는 표에 접근할 때 CALL문을 사용해야 하는 번거로움 때문에 잘 사용되지 않고 MOVC A, @A+DPTR가 주로 사용되는데, 이것은 그림 4.6과 같이 data pointer DPTR가 지시하는 번지(표의 시작번지)에 offset A를 플러스해서 얻는 값의 번지에서 데이터를 가져다가 A에 넣는다. MOVC

그림 4.6  탐색표에서 입력에 대응되는 출력을 찾는 방법

A,@A+DPTR에서 동일한 A라 할지라도 앞의 A와 뒤의 A는 전혀 다른 의미를 갖고 있음에 유의해야 한다. 뒤의 A는 표의 시작번지로부터 떨어져 있는 정도, 즉 offset이고, 앞의 A는 (A+DPTR) 번지의 내용이다.

C에서는 table[n]Ａ{0x3f, 0x06, 0x56 …} 문을 이용한다. 변환표의 각 값을 {}내에 넣어 놓는다. 그런 다음 최초의 값으로부터 떨어져 있는 offset값을 []내에 넣는다. 그러면 offset에 상당하는 변환값이 출력된다. 예컨대 O_dataＡtable[0]라고 하면 0x3f가 O_data에 들어가고, O_dataＡtable[1]이라고 하면 0x0b가 O_data에 들어가며, O_data[2]Ａtable[2]라고 하면 0x56이 O_data에 들어간다.

(4) 프로그램(EX4_10.C)

/*=====================================*/

/* PROGRAM EX4_10.C [LOOKUP TABLE]   */

/*=====================================*/

#include <reg51.h>	/* 8051 헤더파일의 include */

main()	/* 메인 함수 */

{

unsigned char offset, o_data;	/* 변수 정의 */

const unsigned char table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f, 0x67};	/* 표 데이터 */

offset = 0x03;	/* offset */

o_data = table[offset];	/* (table+offset)번지의 내용을 o_data에 */

}

(5) 프로그램의 解說(C)

const unsigned char table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};

변수 table이 table[0], table[1], …, table[7], table[8] table[9], 등 10개의 요소를 가진 일차원 배열임을 선언하고, 그 내용도 밝힌 것이다. 원래 배열은 유사한 형태의 데이터를 취급할 때 사용되며, 1차원 배열의 경우 변수명 끝에 [n]를 지정함으로써 n요소의 배열이 선언된다. 배열요소의 값은 { } 내에 둔다. 배열이 상수임을 표시하기 위해서 unsigned 앞에 □const□를 넣기도 한다.

(6) 課 題

1. 앞에서 설명한 방법에 따라 프로그램 EX4_9.C를 실행시키고, 메모리의 내용이 07H 번지부터 03, 4F임을 확인하라.

프로그램에 의한 지연은 마이크로콘트롤러에서 자주 사용된다. 이것은 어떤 신호를 주고 그 상태를 일정 기간동안 지속시켜야 할 경우에 주로 사용된다. 후술하는 타이머(timer)에 의해서 이 시간지연을 얻을 수도 있으나, 간단한 경우에는 소프트웨어 방식이 더 편하다.

소프트웨어에 의한 시간지연의 기본 원리는 어떤 루프(loop)를 만들어 놓고 그 루프를 일정 횟수만큼 돈 후에 빠져 나가도록 하는 것이다. 에컨대 그림 4.7에서와 같이 R7의 내용을 하나씩 감소하다가 그 내용이 0이 되면 루프에서 빠져 나가도록 한다.

MOV   R7,#0FFH

LOOP＞	DJNZ   R7,LOOP

RET

루프에 들어가서 맴돌다가 빠져 나오기까지의 시간이 지연시간으로 된다. 그러면 구체적으로 얼마만큼의 시간이 지연되는가를 보기로 한다.

그림 4.7  지연루틴

구체적인 지연시간을 계산하기 위해서는 각 명령어의 반복수행 수와 각 명령어의 기계사이클 수를 알아야 한다. 각 명령어의 반복수행 수는 프로그램, 또는 순서도를 보고 따져야 하고, 기계사이클의 수는 명령어 세트를 보아야 한다. 8051 명령어 세트를 보면 각 명령어 형태 옆에 □cycles□라는 것이 있는데, 이것이 기계사이클 수이다.

구체적인 지연시간을 계산하기 전에, 여기서 잠깐 제2장에서 논한 기계사이클에 대해서 보기로 하자.

기계사이클(machine cycle)은 T사이클의 12배에 상당한 시간이다. 하나의 명령어를 호출(fetch)해서 실행(excute)시키는 데 필요한 시간을 命令사이클(instruction cycle)이라고 하는데, 하나의 명령사이클은 8051의 경우 1∼4개의 機械사이클(machine cycle)로 이루어지고, 하나의 기계사이클은 6개의 S사이클로 이루어지며, 하나의 S사이클은 2개의 T사이클로 이

그림 4.8  命令사이클과 機械사이클과 T 사이클

루어진다. 그러므로 하나의 기계사이클은 12개의 T사이클로 이루어진다. T사이클은 시스템의 기본 클록주기, 즉 외부 발진주파수에 상당한 사이클(시간)이다. 그러므로, 외부 발진주파수가 12MHz이면 t =1/f 의 관계에서 T사이클은 1/12□초이고, 기계사이클은 1□초이다.

1 기계사이클Ａ12 T사이클Ａ[eqn: 12 × 1 over { 12 × 10^6 }] (초)Ａ1(□초)   (∵[eqn: f = 1 over t])

이제 구체적인 지연시간을 계산하는 본래의 문제로 되돌아가기로 한다. 지연 루프로 지연시간을 얻는 위 프로그램에 있어서 각 명령어의 반복수행 수, 기계사이클 수, 기계사이클 총수, 지연시간 등은 다음과 같다.

명 령	반복수행의 수	기계사이클의 수	기계사이클의 총수	지연시간 (1 기계사이클Ａ1□s인 경우)
MOV R7,0FFH LP＞ DJNZ R7,LP RET	1 FF(=255) 1	1 2 2	2 255□2 2
총 계			513	513(□초)

이처럼 지연시간은 기계사이클의 총수에 기계사이클의 시간을 곱한 것이다. 그런데, 기계사이클의 시간, 즉 하나의 기계사이클에 요하는 시간은 외부 발진주파수가 클수록 작다. 예컨대 외부 발진주파수가 12MHz일 때에는 1□초이지만, 24MHz일 때에는 0.5□초이다. 그리고, 22.1184MHz일 때에는 0.5425□초이다. 그러므로, 지연시간은 발진주파수에 따라 달라지고, 발진주파수가 달라지면 지연루틴도 달라져야 한다.

일반적으로 지연루프 하나로 얻을 수 있는 지연시간은 매우 짧다. 12MHz를 사용한다해도 하나의 8비트 레지스터로 얻을 수 있는 최대 지연시간은 고작 515□초(0FFH 대신 00H를 넣는 경우)에 불과하고, 22.1184MHz를 사용하면 279□초에 불과하다. 이 보다도 더 큰 지연시간이 필요한 경우에는 그림 4.9와 같은 다중 루프를 쓴다.

다중 루프에서 밖의 루프는 안의 루프를 몇 번 반복할 것인지를 결정한다. 적산전력계에서 아랫쪽 톱니바퀴가 한바퀴 돌아야 윗쪽 톱니바퀴의 눈금 하나를 돌리듯이 안의 루프가 모두 돌아야 바깥 루프 하나를 돌린다. 예컨대 그림 4.9에서 밖의 루프 수를 지정하는 R6의 값을 4로 해두면 안의 루프를 4번 반복해서 돌린다. 그러므로 지연시간은 대략 513×4(□초)로 된다. 정확한 것은 앞에서 소개한 방법에 따라 계산을 해야 한다.

다중루프에서는 예컨대 0.1초의 지연시간이 필요한데 안의 루프가 0.0005초(500□초) 지연이라면 밖의 루프는 이것을 200배 하도록 하면 대충 맞다. 문제는 안의 루프에서 0.0005초의 지연을 얻기 위해서 레지스터 R7에 얼마의 값을 로드해야 하는가에 있다. 다시 말해

그림 4.9  다중 루프에 의한 지연 시간

서 지금까지의 설명은 지연정수(R7의 값)가 정해지고, 이로 인한 지연시간을 계산하는 방법인데, 이젠 반대로 지연시간이 정해지고, 지연정수를 계산하는 방법이다.

이것은 레지스터 R7에 로드해야 할 값을 □로 놓고 다음과 같이 해서 계산을 한다.

命 令	반복수행의 數	기계사이클의 數	기계사이클의 총수	지연시간 ([eqn: f sub o]=12MHz일 때)
MOV R7, #□ LP＞ DJNZ R7, LP RET	1 □ 1	1 2 2	1 2□ 2
총합계			2□+3	(2□+3)(□s)

그림 4.10  단일 루프에서 지연정수의 계산

∴ 2□+3 = 500

□ = 249

그러므로, 0.1초의 시간지연을 얻는 지연루틴은 다음과 같다. 500×200=10000(□초)=0.1(초)이기 때문이다.

MOV	R6,#200

LP1 ＞	MOV	R7,#249

LP2 ＞	DJNZ	R7,LP2

DJNZ	R6,LP1

RET

이 루틴에 의해서 얻어지는 정확한 시간은 다음과 같이 해서 얻는다.

命 令	반복수행의 數	기계사이클의 數	기계사이클의 총수	지연 시간 ([eqn: f sub o]=12MHz일 때)
MOV R6,#200 LP1＞ MOV R7,#249 LP2＞ DJNZ R7,LP2 DJNZ R6,LP1 RET	1 200 200□249 200 1	1 1 2 2 2	1□1 200□1 200□249□2 200□2 1□2	1 기계사이클 Ａ1□초일 때
합 계			100203	100203 □초 □ 0.1초

그림 4.11  어셈블리어 지연루틴의 계산

이 보다도 더 긴 지연시간, 예컨대 1초의 지연시간이 필요한 경우에는 1초는 0.1초의 10배이므로 이 루프 밖에 또 하나의 루프를 두고, 그 정수를 10으로 하면 대략 맞다. 정확한 것은 역시 위 표와 같은 방법으로 계산을 해야 한다.

MOV	R5,#10

LP1＞	MOV	R6,#200

LP2＞	MOV	R7,#249

DJNZ	R7,$

DJNZ	R6,LP2

DJNZ	R5,LP1

RET

물론 발진주파수가 12MHz가 아니고 예컨대 22.1184MHz이면 지연루틴에서 얻는 지연시간은 달라진다. 예컨대 그림 4.10에서와 같이 0.0005초를 얻기 위한 지연정수는 249가 아니고 459로 된다. 그런데 459는 8비트 레지스터가 수용할 수 없으므로 결국 22.1184MHz에서 단일 지연루틴으로서는 0.0005초를 얻을 수 없으므로 0.00025초를 얻는 것으로 지연시간을 조정할 수 밖에 없다. 그 경우의 지연정수는 229이다.

命 令	반복수행의 數	기계사이클의 數	기계사이클의 총수	지연 시간 ([eqn: f sub o]=22.1184MHz일 때)
MOV R7,#x LP＞ DJNZ R7,LP RET	1 x 1	1 2 2	1 2x 2	1 기계사이클 Ａ 0.5425□초
합 계			2x／3	(2x／3)*0.5425

(2x／3)*0.5425Ａ500

xＡ459

∴ (2x／3)*0.5425Ａ250

xＡ229

C 프로그램에서는 다음과 같은 함수를 사용해서 지연시간을 얻는다.

void delay(int i)

{

while(i--);

}

while( )는 ( ) 내의 값이 0이 되지 않는 한 참이고, 그 값이 참인 한 루프를 맴돌므로, 맴도는 시간만큼 시간지연이 된다. i값은 본문에서 예컨대 다음과 같은 명령으로 지정된다.

delay(0x8000);

이 명령이 실행되면 위 함수로 뛰어가서 i값을 하나씩 감소하되 32,768(8000H)번 반복해서 마침내 그 값이 0이 되면 여기에서 벗어난다. 벗어나기까지의 시간이 지연시간이다. 문제는 이로 인해서 얼마만큼의 시간이 지연되느냐에 있다. 이것은 어셈블리어 단위에서 따져야 한다. 프로그램 초두에서 제어지시어 code가 든 전처리문을 두면 어셈블리어 단위의 프로그램을 볼 수 있으므로 이를 보고 앞에서와 동일한 방법으로 지연시간을 계산해야 한다. pragma에 code가 들어있는 경우, 그리고 delay(0x8000)의 경우 LST 파일을 보면 다음과 같이 되어 있다. 여기서 NOP 두 개는 여러 실험을 통하여 시간조정상 넣은 것이다.

?C0001＞	MOV	A,R7

DEC	R7

MOV	R4,AR6 ;AR6는 현 레지스터 뱅크내 R6의 절대번지

JNZ	?C0009

NOP

NOP

DEC	R6

?C0009＞	ORL	A,R4

JNZ	?C0001

?C0003＞	RET

□

MOV	R7,#00H

MOV	R6,#80H

LJMP	?C0001

이 어셈블리어 프로그램으로 인하여 얻는 지연시간을 계산하면 다음과 같다.

그림 4.12  C에서의 지연 루틴

명 령	반복수행의 數	기계사이클의 數	기계사이클의 총수	지연시간 ([eqn: f sub o]=12MHz일 때)
?C0001＞ MOV A,R7 DEC R7 MOV R4,AR6 NOP NOP JNZ ?C0009 DEC R6 ?C0009＞ ORL A,R4 JNZ ?C0001 ?C0003＞ RET	256×128 256×128 256×128 256×128 256×128 256×128 1×128 256×128 256×128 1	1 1 1 1 1 2 1 1 2 2	32768 32768 32768 32768 32768 65536 128 32768 65536 2	1 기계사이클 Ａ1□초일 때
합 계			327810	327810 (□초) □ 0.33초

그림 4.13  C컴파일러어 지연루틴의 계산(2)

위의 계산에서 역시 발진주파수가 달라지면 지연시간도 달라진다. 예컨대 발진주파수가 22.1184MHz이면 327810*0.5425=177848≒0.18(초)로 된다.

위의 것은 지연정수를 미리 정해놓고 지연시간을 계산하는 방법이고, 역으로 지연시간이 정해지고 지연정수를 계산하기 위해서는 위 표에서 R7값은 00H(256)으로 묶어놓고 R6값, 위의 경우 128을 □로 놓고 원하는 지연시간과 같다고 놓으면 된다. 예컨대 0.03초의 지연이 필요하면 그림 4.13에서 128을 □로 놓을 경우의 지연시간 256×10×□+□+2, 즉 2561□+2를 얻고자 하는 지연시간과 같다고 놓으면 2561□+2=30000이 되고, 여기에서 □=11.7≒12=0CH를 얻으므로 R7=00H, R6=0CH이다. 그러므로 delay(0x0C00)으로 하면 되고, 0.3초의 지연이 필요하면 2561□+2=300000에서 □=117=75H이므로 delay(0x7500);으로 하면 된다.

또 발진주파수가 12MHz가 아니고 22.1184MHz이면 0.03초를 얻기 위한 지연정수는 다음과 같이 계산하여 x=16H이므로 delay(0x1600)으로 하면 된다.

(2561x／2)*0.5425Ａ30000

xＡ22Ａ16H

그리고 0.3초를 얻기 위한 지연정수는 다음과 같이 계산하여 x Ａ d8H이므로 delay(0xd800)으로 하면 된다.

(2561x／2)*0.5425Ａ300000

xＡ216Ａ0xd8

C프로그램에서는 while(i--)문 대신 for(i=1; i<=x; I++)문을 쓰기도 한다. 이를 컴파일한 후 LST파일을 보고, 이를 기초로 지연루틴을 계산하면 그림 4.14와 같다.

void delay (void) {

unsigned int I;

for (i=1; i<=x00; i++);

}

命 令	반복수행의 數	기계사이클의 數	기계사이클의 총수	지연 시간
MOV R7,#01H MOV R6,#00H LP1＞ INC R7 CJNE R7,#00,LP2 INC R6 LP2＞ CJNE R6,#013H,LP1 CJNE R7,#89H,LP1 LP3＞ RET	1 1 256x 256x x 256x 1 1	1 1 1 2 1 2 2 1	1 1 256x 512x x 512x 2 1	발진주파수Ａ12MHz의 경우 1281x+5(□초) 발진주파수Ａ22.1184MHz의경우 (1281x+5)*0.5425(□초_)
합 계	단 R6Ａx R7Ａ256		1281x+5

그림 4.14  for() 문에 의한 지연시간의 계산

그러므로 xＡ0xff일 경우 발진주파수=12MHz이면 지연시간은 1281*255+5Ａ326,660(□초)이고 발진주파수Ａ22.1184MHz이면 (1281*255+5)* 0.5425Ａ177213(□초)이다. 그리고 0.1초를 얻기 위한 x값은 발진주파수Ａ12MHz이면 1281x+5Ａ100000에서 xＡ78Ａ4EH이고, 발진주파수Ａ22.1184MHz이면 (1281x+5)*0.5425Ａ100000에서 xＡ144Ａ90H이다.

1. 마이크로콘트롤러에 의한 제어에 있어서는 탐색표(look-up table)를 사용할 경우가 많다. 이 경우에는 탐색표의 시작번지를 base(DPTR 값)로 하여 이로부터 떨어져 있는 offset을 이에 플러스해서 얻는 번지로부터 데이터를 가져오는 MOVC A,@A+DPTR와 같은 명령을 써서 해당 데이터에 접근한다. C에서는 table[offset] 명령을 쓴다.

2. 지연시간(delayed time)을 얻는 방법에는 지연루틴에 의한 방법과 타이머에 의한 방법이 있다. 지연 루프에서의 지연시간은 기계사이클의 총수에 기계사이클의 시간을 곱한 것과 같다.

4.1 다음 프로그램이 수행된 후에 A에는 어떤 값이 남겠는가? (명령어는 8051 어셈블리어이다.)

MOV MOV ADD ORL ANL ORL REF	A, #44H R0, #44H A, R0 A, #01110111 B A, #44H A, #10111011 B

㉮ FF	㉯ DD	㉰ EE	㉱ BB

4.1 다음 프로그램에서 잘못된 곳은?

MOV    R1, #0FFH

LP＞	DEC    R1

JNZ     LP

RET

4.2 다음 프로그램이 실행된 후 어큐뮬레터의 내용은?

NEXT ＞	MOV JB MOV RET MOV RET	A, #88H ACC.2, NEXT A, #00 A, #0FFH

4.3 다음 프로그램이 실행된 후 어큐뮬레이터의 내용은?

NEXT ＞	MOV ANL JZ MOV RET MOV RET	A, #80H A, #0FH NEXT A, #33H A, #44H

4.4 40H 번지와 41H 번지의 내용을 비교하여 보다 큰 수를 42H 번지에 저장하는 프로그램을 작성하라.

4.5 어큐뮬레이터의 내용을 5배로 하는 프로그램을 MUL AB 명령을 사용하지 말고 작성하라.

4.6 20H 번지에서 7FH 번지까지의 내용을 다음 표와 같이 하는 프로그램을 작성하라.

번 지	내 용
20H 21H 22H □ 7FH	00H 01H 02H □ 5FH

4.7 40H 번지로부터 10개의 번지에 들어 있는 데이터중 가장 큰 수를 골라서 4AH 번지에 넣는 프로그램을 작성하라.

4.8 다음 그림과 같이 TAB으로부터 시작되는 일련의 기억번지에 피보나치 수열을 넣는 프로그램을 작성하라(힌트: 피보나치 수열은 최초의 두 수 1, 1을 제외하고는 앞 수에 뒷 수를 플러스하여 다음 수를 만든다. ex4_fib.c 참조)

TAB	／	／	／	／	／	／
1	1	2	3	5	8	13

4.9 40H 번지에서 6FH 번지까지의 기억번지중 그 내용이 0인 것이 몇 개인지를 계수하여 그 수를 70H 번지에 저장하는 프로그램을 작성하라.

4.10 0.5초의 지연 시간을 얻는 지연 루틴을 작성하라.(단 fosc Ａ12MHz)

4.11 40H 번지에서 6FH 번지까지의 내용중 양의 수는 몇 개나 되는지 그 수를 계수하여  70H 번지에 넣는 프로그램을 작성하라.

4.12 다음 그림은 외부 RAM을 갖춘 8051 시스템의 일부로서 주소 부분만을 표시한 것이다. 프로그램이 실행된 후 각 번지의 내용과 Acc, R0, R1의 값을 기술하라. 단 프로그램은 리셋 후에 실행된다.

LP ＞	MOV MOV MOV MOVX INC INC DJNZ RET	A, #0 R0, #0 R1, #10H @R0, A A R0 R1, LP

5.1 I/O포트의 기능 5.2 I/O포트의 구조 5.3 AT89C2051의 I/O포트	5.3 I/O포트에 관한 실험 5.4 이 장의 간추림

8051에는 P0, P1, P2, P3 등 4개의 I/O포트가 내장되어 있다.

I/O포트(Input/Out Port)는 외부장치와 CPU를 연결해 주는 병렬 입출력 인터페이스(parallel I/O interface)이다.

외부장치를 CPU에 연결할 때 직접 할 수 있으면 좋겠지만, 일반적으로 그럴 수가 없다. 제2장에서 논한 바와 같이 외부장치와 CPU는 동작 속도가 서로 다르고, 전압 레벨도 다르며, 전송 사이클도 다르기 때문이다. 그래서 CPU와 외부장치 사이에는 이들을 조정해주는 회로가 필요한데, 이것이 바로 병렬 입출력 인터페이스이다.

I/O포트는 입출력 인터페이스이므로, CPU에서 외부장치로 데이터를 보낼 때에도 이것을 경유하고, 반대로 외부장치에서 CPU에 데이터를 받아들일 때에도 이것을 경유한다. 예컨데 그림 5.1과 같이 마이크로콘트롤러로 자동차의 엔진을 제어하는 경우, 제어에 필요한 각종 데이터도 이 포트를 통하여 입력되고, 이들 데이터를 기초로 하여 연산된 제어 신호도 이 포트를 통하여 외부장치에 출력된다. 이 때 전자의 경우에는 입력포트(input port)로 동작하고, 후자의 경우에는 출력포트(output port)로 동작한다.

8051에 내장되어 있는 4개의 I/O포트 중 3개는 전술한 바와 같이, 기본적으로는 병렬 입출력 인터페이스이나, 외부에 메모리를 둔다든가, 타이머나 직렬 포트를 사용한다든가, 외부 인터럽트를 사용한다든가 기타 특수한 경우에는 다른 용도로도 사용된다.

그림 5.1  자동차 엔진의 제어

I/O포트의 별도 기능을 포트별로 정리하면 다음과 같다.

포트 0＞외부에 메모리를 둘 경우 주소버스의 상위 바이트와 데이터버스를 번갈아 수행함(multiplex)

포트 1＞8051은 별도기능이 없다. 그러나 8751의 경우에는 프로그램을 기록하는 경우 하위 주소버스로 사용되고, 또 8052의 경우에는 타이머2의 T2, T2EX로서의  기능도 가짐

포트 2＞외부에 메모리를 둘 경우 주소버스의 하위 바이트로 사용됨

포트 3＞직렬포트, 인터럽트, 타이머 등의 입출력 핀 또는 제어선으로도 사용됨

I/O포트에 대한 주소지정(addressing)은 특수기능레지스터(SFR)의 해당 주소를 직접 지정하거나 포트 이름을 지정함으로써 이루어진다. 예컨대 포트 1에 0F0H를 출력하고자 할 경우에는 다음과 같이 한다.

MOV  90H,#0F0H  또는

MOV  P1,#0F0H   (C에서는 P1=0xf0)

그림 5.2  I/O 포트의 주소

I/O포트는 그림 2.28에서 밝힌 바와 같이 비트 주소지정(bit addressing)이 가능하다. 다음은 포트 1의 비트 2를 1로 세트하는 명령과 이를 리셋하는 명령, 그리고 이를 반전하는 명령이다.

SETB	P1.2	(C에서는 P1 □ = 0x04)

CLR	P1.2	(C에서는 P & = 0xfb)

CPL	P1.2	(C에서는 P ^ = 0x04)

I/O포트에서의 입력은 그림 5.3과 같이 상태 5(state 5)에서 이루어지고, 출력은 상태 6(state 6)에서 이루어진다. 동 그림 맨 밑은 직렬포트를 모드 0의 확장 I/O포트로 사용할 경우 RxD로 시프트되는 데이터가 샘플 입력되는 타이밍이다.

그림 5.3  포트 동작의 타이밍

5.2.1  포트 0

포트 0은 8비트 open drain의 양방향성 I/O포트로, 이것을 출력포트로 사용할 경우에는 표준 TTL 2개(LS TTL은 8개)를 직접 구동할 수 있다.

포트 0은 외부 메모리가 있느냐 없느냐에 따라 그 용도가 달라진다.

(1) 주소버스 및 데이터버스로 사용되는 경우

외부에 프로그램 메모리나 데이터 메모리를 두고 MOVC  A,@A+DPTR  MOVX A,@DPTR MOV A,@R1과 같은 명령을 사용하면 포트 0과 포트 2를 통하여 외부 메모리에 접근(access)한다. 이 때 포트 0은 3-상태 출력 구동회로로 되고, 하위 어드레스 A0∼A7과 데이터 D0∼D7을 번갈아 멀티플렉스한다.

그림 5.4는 포트 0의 포트라인 중 어느 하나의 구조이다. 외부 메모리에 접근해야 할 경우에 CPU는 이 회로의 control line을 논리 1로 한다. 그러면 동 그림 맨 오른쪽의 n형 MOSFET는 on되고(n형 MOSFET는 논리 1에서 on되고 논리 0에서 off된다. □n형은 n(negative)에서 망(off)하고, p형은 p(positive)에서 망(off)한다.□고 암기해 두면 편리하다), MUX의 스위치는 윗쪽으로 닫히므로 □어드레스/데이터□ 신호가 출력된다. 그런데, CPU는 어드레스 A0∼A7과 데이터 D0∼D7을 이 라인을 통하여 멀티플렉스하므로, 결국 포트 0는 어드레스 하위 버스로서의 역할과 데이터버스로서의 역할을 하는 것이다.

그림 5.4  포트 0의 비트 구조

(2) 범용의 I/O포트로 사용되는 경우

외부에 프로그램 메모리나 데이터 메모리를 두지 않는 경우에 포트 0은 범용 I/O포트로 동작하여 데이터를 병렬로 입력 또는 출력한다. 이 때 CPU는 그림 5.4의 Control line에 논리 0의 신호를 주므로, 풀업 MOSFET는 off되어 open drain의 상태로 된다. 그러므로 포트 0을 범용의 I/O포트로 사용할 경우에 사용자는 반드시 외부에 풀업저항을 달아 주어야 한다.

① 포트 0으로 출력을 하는 경우＞

CPU가 control line에 논리 0의 신호를 주면 MUX의 스위치가 아래쪽으로 닫혀서 래치의 출력이 Q 를 통하여 아래쪽의 MOSFET로 나간다. 래치의 출력이 Q를 통하여 아랫쪽의 MOSFET로 나가므로 물론 이 경우에도 외부 풀업저항을 달아주어야 한다. 래치의 내용은 두 번 반전되어 정의 위상으로 출력된다.

② 포트 0으로 입력을 하는 경우＞

입력의 경우에는 그림 5.4의 윗쪽과 아래쪽 MOSFET가 모두 off된 상태에서 버퍼를 통하여 입력이 이루어져야 한다. 포트 0을 범용의 I/O포트로 사용하는 경우에는 윗쪽 MOSFET가 off 상태로 된다는 것은 이미 설명하였다. 포트 0을 범용의 I/O포트로 사용할 경우에 CPU는 control line에 논리 0의 신호를 주기 때문에 윗쪽 MOSFET가 off 상태로 된다고 하였다. 문제는 아랫쪽 MOSFET이다. 이것도 off 상태로 하기 위해서 사용자는 반드시 입력 명령에 앞서 래치에 1을 기록(write)해 주어야 한다. 래치의 내용은 Q를 통하여 아랫쪽 n형 MOSFET에 들어가므로, Q=1이면 Q는 0이고 아랫쪽 MOSFET는 off되어, 결과적으로 상하 MOSFET 모두 off이어서 포트 핀은 입력버퍼에만 연결되므로 CPU는 아무런 방해도 받지 않고 포트를 통하여 입력을 할 수 있다. 이에 반하여 만약 어떤 이유로 래치가 0이면 Q는 1이고 아랫쪽 MOSFET는 on되어 포트 핀의 입력 신호가 0이든 1이든 관계없이 항상 0으로 읽어진다.

입력할 때마다 포트라인에 1을 출력해야 한다는 것은 잊기 쉽고 귀찮은 일이지만, 방향 결정 레지스터(Data Direction Register)가 없는 8051에서 부득이한 일이므로, 잊지 말고 입력의 경우에는 반드시 포트래치에 1을 기록해 주어야 한다. 그래야 정상적인 입력이 가능해지는 것이다. 8051 포트 0에서는 이처럼 윗쪽 MOSFET도, 아랫쪽 MOSFET도 off로 된 상태에서 P0 핀과 입력버퍼를 통하여 입력을 한다.

③ read-modify-write 명령을 실행하는 경우＞

일반적으로 입력은 이처럼 P0 핀과 아랫쪽 버퍼를 통하여 직접 이루어지지만, 때로는 래치에 이미 기록된 것을 그림 5.4에서 윗쪽 왼편의 버퍼를 통하여 이루어지는 경우도 있다. 후자의 방법을 특히 read-modify-write라고 하는데, 이것은 소위 read- modify-write 명령어를 실행할 때 이루어진다. read-modify-write 명령어란 종착지 오퍼랜드(destination operand)가 포트 그 자체인 명령어이다. 즉, 8051의 명령어 중에는 아래 명령들과 같이 종착지 오퍼랜드(destination operand)가 포트 그 자체인 경우가 있는데, 이런 명령어를 실행하면 래치에 이미 기록된 것을 읽어서, 이를 수정한 후 그 래치에 다시 기록한다. 입출력 핀(pin)을 읽어들이는 것이 아니고 래치를 읽어 들인다는 점에서 다른 마이크로콘트롤러와 구분된다.

INC	(increment; 예 INC  P0)

DEC	(decrement; 예 DEC P2)

CPL	(complement bit; 예 CPL P1.2)

ANL	(logical AND; 예 ANL P0,#0FH)

ORL	(logical OR; 예 ORL P1,#07H)

XRL	(logical EXOR; 예 XRL P2,#07H)

DJNZ	(decrement Px and jump if not Zero; 예 DJNZ P0,NEXT)

MOV	(move carry bit to bit; 예 MOV P1.3,C)

CLR	(clear bit; 예 CLR P3.2)

SETB	(set bit; 예 SETB P3.2)

(3) 데이터버스로 사용되는 경우

특수한 경우로서 8751에 프로그램을 기록(write)할 때에는 P0가 데이터버스로 사용된다. 이 경우에도 control line에는 논리 0이 출력되므로 풀업 MOSFET가 off되므로 풀업저항을 외부에 달아 주어야 한다.

5.2.2  포트 1

포트 1은 8비트 내부 풀업의 양방향성 I/O포트로서, 이것을 출력포트로 사용하는 경우에는 표준 TTL 1개(LS TTL은 4개)를 직접 구동할 수 있다. 포트 1에도 데이터 방향 레지스터는 없다. 그래도 입력과 출력을 자유자재로 할 수 있다. 다만 입력의 경우에는 포트 0에서와 같이 예컨대 다음과 같은 명령으로 포트래치에 1을 출력해 주어야한다.

MOV	P1,#0FFH	(C에서는 P1=0xff)

이와 같이 데이터방향 레지스터가 없어도 입력의 경우에 포트래치에 1을 출력만 하면 입력이 가능하여 입력 및 출력이 자유자재로 되는 포트 구조를 준양방향성 포트(quasi bidirectional port)라고 한다.

포트 1은 그림 5.5와 같이 내부 풀업저항이 있기 때문에, 포트 1을 범용의 I/O포트로 사용할 경우 외부에 풀업저항을 연결할 필요가 없다.

그림 5.5  포트 1의 비트 구조

8751에 프로그램을 기록(write)하는 동안에 포트 1은 하위의 주소버스 (A7∼A0)로 사용된다. ROM 및 EPROM의 내용을 확인(verify)하는 동안에도 같다.

8032AH나, 8052AH나, 8752BH에서는 포트 1의 P1.0와 P1.1이 각각 T2와 T2EX로서의 기능도 한다.

포트핀	기 능
P1.0 P1.1	T2 (timer/counter2의 외부 입력) T2EX (timer/counter2의 capture/reload trigger)

5.2.3 포트 2

포트 2는 8비트 내부 풀업의 준양방향성 I/O포트로, 이것을 출력포트로 사용하는 경우에는 표준 TTL 1개(LS TTL은 4개)를 직접 구동할 수 있다.

외부에 데이터 메모리 또는 프로그램 메모리를 두고 MOVX A,@DPTR 또는 MOVC A,@A+DPTR와 같은 명령으로 이들 메모리에 접근할 때에는 read 또는 write 사이클 기간중 어드레스의 상위 바이트(A15∼A8)가 이 포트를 통하여 출력되고, 하위 바이트(A7∼A0)는 포트 0를 통하여 출력된다.

그림 5.6  포트 2의 비트 구조

MOVX A,@R1과 같은 명령으로 페이지된 외부 데이터 메모리(paged data memory)에 접근할 때에는 외부 메모리 사이클 기간중 페이지 정보가 이 포트의 P2.2∼P2.0를 통하여 출력된다. 즉 MOV P2,#01H와 같은 명령으로 P2.2∼P2.0에 페이지 정보를 준 상태에서 MOVX A,@R1과 같은 명령을 내리면 외부 메모리 사이클 중에 이 페이지 정보가 P2.2∼P2.0을 통하여 외부 데이터 메모리에 출력되어 외부 데이터 메모리의 번지를 지정한다. 이것을 이용하여 MOVX A,@R1의 명령으로도 16비트 어드레스로만 접근 가능한 외부 데이터 메모리에 접근할 수 있다.

외부에서 8751에 프로그램을 기록(write)할 때에도 포트 2는 상위 어드레스(A15∼A8)로서 사용된다.

외부에 메모리를 연결하지 않는 경우에는 범용의 I/O포트로 사용된다. 이때에는 역시 외부에 풀업저항을 연결할 필요가 없다.

5.2.4 포트 3

포트 3 또한 내부 풀업의 8비트 준양방향성 I/O포트로, 이것을 출력포트로 사용할 경우에는 표준 TTL 1개(LS TTL은 4개)를 직접 구동할 수 있다.

포트 3은 일반의 경우 범용의 I/O포트로 사용된다.

직렬 포트, 외부 인터럽트, 타이머, 외부 메모리 등을 사용할 경우에는 이 포트가 다음과 같은 특수 기능을 수행한다.

포트핀	기 능	주 석
P 3.0 P 3.1 P 3.2 P 3.3 P 3.4 P 3.5 P 3.6 P 3.7	RxD TxD INT0 INT1 T0 T1 WR RD	수신 직렬데이터＞직렬 통신에서 수신 핀으로 사용됨 송신 직렬데이터＞직렬 통신에서 송신 핀으로 사용됨 외부 인터럽트 입력 0＞외부 인터럽트0 요청 핀으로 사용됨 외부 인터럽트 입력 1＞외부 인터럽트1 요청 핀으로 사용됨 타이머 0의 외부 클록 입력＞ 카운터0의 외부 클록 핀으로 사용됨 타이머 1의 외부 클록 입력＞ 카운터1의 외부 클록 핀으로 사용됨 외부 데이터 메모리의 write strobe 신호(AT89C2051에는 없음) 외부 데이터 메모리의 read strobe 신호(AT89C2051에는 없음)

포트 3의 각 핀(pin)이 범용의 I/O포트로 되느냐, 아니면 RxD, TxD, …, WR, RD 등의 특수 입출력 신호 또는 제어신호로 되느냐는 WR, RD를 제외하고는 이들 기능을 사용하는 제어레지스터에 어떤 값을 넣는 명령에 의해서 결정되는데, 이들 제어레지스터를 건드리지 않는 한 I/O포트의 각 핀은 범용 I/O포트로 되므로, 사용자는 현 단계에서 크게 신경 쓸 필요가 없다.

그림 5.7  포트 3의 비트 구조

5.2.5 CHMOS의 준양방향성 포트

앞에서 본 바와 같이 8051의 I/O포트는 준양방향성 포트이다. 준양방향성 포트는 데이터 방향 레지스터의 도움 없이도 어느 때든 입력포트로도 사용될 수 있고, 출력포트로도 사용될 수 있는 포트를 의미한다고 앞에서 언급하였다. 다만 입력포트로 사용하기 위해서는 입력하기 전에 먼저 1을 포트래치에 출력해 주어야 한다는 것도 언급하였다. 문제는 CHMOS의 I/O포트에도 같은 논리가 적용되느냐에 있다. 결론부터 말해서 그렇다. 다만  CHMOS의 준양방향성 포트는 그 구조가 앞에서 소개한 것들과는 퍽 달라서  그 구조를 따로 설명할 필요가 있겠다. 이것은 이해가 어려울 것이므로 하드웨어에 특별히 관심이 있는 학생을 제외하고는 건너뛰어도 된다.

8051 CHMOS 준양방향성 포트는 그림 5.8과 같이 되어 있다. 이것을 준양방향성으로 동작하도록 하는 것은 출력 드라이버의 구조가 특이하게 되어 있어서이다. 즉 CHMOS의 준양방향성 포트에서는 출력드라이버(output driver)가 그림 5.8과 같이 Q1, Q2, Q3, Q4 등으로 구성되어 있는데, □0□을 출력할 때에는 강한 드라이버(strong driver) Q2만 on되어 □강한 0□을 출력하지만, □1□을 출력할 때에는 약한 드라이버(weak driver) Q4만 on되어 □약한 1□을 출력한다. 여기서 □강한 0□이라 함은 0V에 연결된 드라이버의 임피던스가 작아서 많은 전류를 흘릴 수 있음을 뜻하고, □약한 1□이라 함은 +5V에 연결된 풀업저항의 임피던스가 매우 커서 극히 적은 전류만을 흘린다는 것을 의미한다. 준양방향성 포트에 □1□을 출력할 때에는 극히 적은 전류만이 흐른다는 것을 이용하여 방향 데이터 레지스터의 도움 없이도 입력을 자유자재로 할 수 있다. 이 관계를 좀더 자세히 설명하고자 한다.

그림 5.8  준양방향성 포트의 회로도

① 준양방향성 포트에 □0□을 기록(write)하면 좌측의 래치 출력 Q는 □1□로 되어 점 □도 □1□로 되므로, □P형은 P(+5)에서 망(off)하고, n형은 n(0V)에서 망(off)한다□는 것을 감안할 때 PMOS Q1과 Q3는 off되고 NMOS Q2는 on되어, 포트 핀은 □0□이 된다. 이 때에는 PMOS Q4도 off 상태로 된다. 출력 □0□이 인버트되어 Q4의 게이트에 들어가기 때문이다. 한편 Q가 □1□로 되면 □점은 □0□으로 되어 2상태시간 후에는 이것이 OR 게이트에 들어가지만 이것은 출력에 영향을 미치지 않는다. OR 게이트로 0이 들어가기 때문이다. 아무튼 포트에 0를 출력하면 Q2만 on되는데, Q2는 강한 드라이버이므로 준양방향성 포트에 □0□을 출력할 경우에는 강한 0이 출력된다. 즉 많은 전류를 어스선에 흘릴 수 있는 0을 출력한다.

② 포트에 □1□을 출력(기록)하면 래치 출력 Q는 0이 되어 점 B는 □1□로 되지만, 이것이 지연회로에서 2상태시간만큼 지연되므로 그 동안 점 A는 □0□을 유지한다. 그래서 Q1과 Q3는 on되고, Q2는 off되어 포트 핀은 □1□로 된다. 한편 포트 핀이 1일 때 Q4의 게이트는 □0□으로 되므로 Q4는 on 상태로 된다. 2상태시간 후에 점 □는 □1□로 되어 Q1과 Q3는 off되지만, Q4에 의해서 on 상태가 자기유지되어(Q4와 밑의 인버터는 의 관계를 유지함) 포트 핀은 □1□의 상태를 유지한다. 그런데 Q4는 약한 드라이버(weak driver)이므로, 포트는 약한 값(weak value)의 논리 1을 출력한다. 요컨대 포트래치에 □1□을 출력할 경우에는 Q4만 on되어 포트 핀은 1의 상태로 되는데, Q4는 약한 드라이버이므로 그 포트는 약한 값(weak value)이 된다. 약한 값이라 함은 앞에서 언급한 바와 같이, 풀업저항의 임피던스가 매우 커서 전류가 매우 적게 흐른다는 것을 의미한다. 요컨대, 포트에 1을 출력하면 풀업저항의 임피던스가 매우 큰 1을 출력한다.

③ 포트에 □1□을 출력하면 풀업저항의 임피던스가 매우 큰 1을 출력하므로 설사 포트 핀에 □0□의 외부 입력이 들어오더라도 극히 적은 전류만이 흐르게 되어 풀업저항이 타버린다든가 기타 문제점이 전혀 없게 된다. 물론 포트 핀에 □1□의 외부입력이 들어올 경우에는 말할 것도 없이 문제가 없다.

포트에 1을 출력하면 풀업저항의 임피던스가 매우 큰 1을 출력하여 설사 포트 핀에 0의 외부 입력이 들어오드라도 문제점이 없다는 것을 이용해서 입력을 한다.

④ 이처럼 CHMOS의 포트에 있어서도 데이터 방향 레지스터의 도움 없이 입출력을 자유자재로 할 수 있다고는 하지만, 사실은 원래 출력으로만 사용될 수 있도록 되어 있는 것을 입력에도 사용한다고 볼 수 있다. 특이한 3중 구조의 드라이버 때문에 포트래치에 □1□을 출력할 때에는 입력이 0인 경우에도 극히 적은 전류만이 흐르므로, 이것을 이용해서 입력도 하는 것이다.

전술한 바와 같이 AT89C2051은 거의 모든 면에서 8051에 호환적(compatible)이지만, I/O포트는 포트 0과 포트 2가 없다. 그러므로 이에는 외부 메모리를 둘 수 없다. 그렇긴 해도 포트 1과 포트 3만을 사용하는 한 8051과 다를 바 없다. 더구나 프로그램 메모리가 플래쉬메모리이어서 기록된 프로그램을 손쉽게 지우고 다른 프로그램을 다시 기록할 수 있을 뿐아니라 값이 저렴하여 8051을 공부하는 분에게는 매우 유용하다.

5.3.1 포트 1

AT89C2051의 포트 1은 8비트 양방향성 I/O포트이다. P1.2∼P1.7은 내부 풀업이 되어 있으나, P1.0과 P1.1은 그렇지 않아서 반드시 외부에 풀업저항을 연결해 주어야 한다. 이들은 아날로그 입력핀(AIN0, AIN1)으로도 사용된다. 포트 1의 출력버퍼는 20mA를 싱크하여 LED를 직접 구동할 수 있다. 포트 1을 입력으로 사용할 때에는 역시 1을 먼저 출력해야 한다.

5.3.2 포트 3

AT89C2051의 포트 3은 비트 6(P3.6)을 제외하고는 내부 풀업이 되어 있는 양방향성 I/O포트이다. P3.6은 내장 아날로그 비교기 출력에 연결되어 있어서 범용 I/O포트로서는 접근할 수 없다. 포트3의 별도기능은 8051과 같으나, P3.6과 P3.7은 별도 기능이 없다.

5.4.1 LED 점멸(1)

(1) 目 的

그림 5.9와 같이 8051의 포트 1에 LED가 연결되어 있다. 최초에는 P1.0에 연결된 LED가 on되고, 0.3초 후에는 on상태가 좌로 이동하여 P1.1의 LED가 on되며, 다시 0.3초 후에는 P1.2의 LED가 on되고, ..... 이와 같이 하여 P1.7의 LED가 on된 후에는 다시 0.3초 후 P1.0의 LED가 on되는 것을 반복하는 프로그램을 작성하고자 한다.

그림 5.9  LED 점등 시스템

(2) 實 例

LED7                              LED0

○   ○   ○   ○   ○   ○   ● ← ○

(3) 順序圖

그림 5.10  LED 점등 순서도

(4) 프로그램 (EX5_1.C)

/*================================*/

/* PROGRAM EX5_1.C (LED ON-OFF) */

/*================================*/

#pragma code symbols debug oe

#include  <reg51.h>

void  delay(int i) {	/* 지연함수 */

while(i--);

}

void main(void) {	/* 메인함수 */

data unsigned char  led;	/* 변수의 정의 */

led=0xfe;	/* 최초의 출력 데이터 */

do {

P1 = led;

led = ( led << 1 ) □ 1;	/* 좌로 시프트하고 빈자리에는 1을 */

if (led == 0xff) led=0xfe; /* LED7까지 on했으면 최초의 상태로 */

delay(0xd800);	/* 0.3초 지연 */

} while(1);

}

(5) 프로그램의 解說(C)

P1 = led;

led = ( led << 1 )  □ 1;

if ((led) == 0xff) led = 0xfe;

첫 번째 것은 led(번지)의 내용을 포트 1에 출력하라는 것이고, 두 번째 것은 led의 내용을 좌측으로 하나 시프트한 후 01H와 OR함으로써 시프트해 간 맨 오른쪽 비트(LSB)를 1로 채우라는 것이며(C에는 RL A와 같은 명령이 없으므로 시프트해간 자리에 1을 넣어주어야 한다), 세 번째 것은 led값이 FFH이면 FE로 바꿈으로써 최초의 상태로 돌아가라는 것이다.

void delay(int I) {

while(i--);

}

□

delay(0xd800);

외부 발진주파수가 22.1184MHz일 때 0.3초를 얻기 위한 지연루틴이다. 제4장의 마지막에서 논한 바와 같이 C에서의 지연루틴은 어셈블리어 단위의 프로그램에서 계산해야 하는데, 0.3S=300000□S를 얻기 위해서는 발진주파수 22.1184일 때 (2561□+2)*0.5425=300000(제4장 참조)에서 □=216=0d8H이기 때문에 delay(0xd800)로 해야 한다.

(6) 프로그램의 實行

제4장에서 설명한 방법에 따라 소스 파일을 만들고(이 책에 첨부된 디스켓에서 카피해도 됨), □Vision을 가동시켜 open project(project→open→프로젝트 이름(예 8051)에 더블클릭)와 edit project(project→edit project→remove→add→C Source(또는 Assemby Source)선택→프로그램 선택(EX5_1.C에 더블클릭)→close→open→save) 작업을 통하여  프로젝트와 프로그램을 지정한 후, build project(project→build project→ok) 작업을 통하여 컴파일 또는 어셈블 그리고 링크를 함으로써 Hex 파일과 Obj 파일을 만들어낸다. 일단 이들을 만들어내면 이것은 실제 시스템 또는 교육용 트레인 키트에 다운로드해서 직접 실험할 수도 있고, 시뮬레이터 dScope를 이용하여 컴퓨터에서 시뮬레이트할 수도 있다.

컴퓨터로 시뮬레이트를 하고자 할 경우에는 dScope로 들어가서 CPU와 pheripheral(포트 1)을 선택하고 툴바 첫 번째 것에 클릭하고 프로젝트(8051)에 더블클릭함으로써 □Vision에서 택한 프로젝트를 불러온 다음 툴바 4번째 것에 클릭함으로써 실행(GO)을 한다. 포트 1의 공란이 일정 간격으로 이동됨을 발견할 것이다. 만약 제대로 동작하지 않으면 다시 □Vision으로 들어가서 디버깅을 해야 한다.

실제 시스템 또는 트레인키트로 실험하고자 할 경우에는 실제 시스템의 CPU(8751 또는 AT89S51 또는 AT89S2051) 또는 외부 ROM에 □Vision에서 만든 Hex 파일을 기록해야 한다. 기록하는 방법에는, 전술한 바와 같이, 수작업에 의한 것과 컴퓨터에 의한 것이 있으나, 어느 방법이든 간에 다음과 같은 것에 주의를 해야 한다.

(1) 시스템에 따라 ROM 또는 RAM 영역이 다르므로, 어셈블리어 프로그램의 경우에는 반드시 자신이 쓰고 있는 시스템의 메모리 맵(memory map)과 I/O맵을 보고, 이에 따라 ORG 기타 메모리 번지에 관한 것들을 고쳐야 한다. 예컨대 자기 트레인키트의 외부 ROM영역이 2000H∼3FFFH로 되어 있으면 본 프로그램에서 ORG 00H를 ORG 2000H로 해야 한다.

(2) 시스템에 따라서는 어떤 포트에 LED가 이미 연결되어 있어서 프로그램의 실행과정을 쉽게 관찰할 수 있으나 그렇지 못하는 경우에는 외부에 LED를 연결해야 하는데, 그게 그리 쉽지 않을 경우도 있다. 이럴 경우에는 logic tester를 이용하면 편리하다. logic tester는 시중에서 값싸게 구입할 수도 있고, 다음과 같은 회로를 볼펜 껍데기 같은 것에 넣어서 간단히 만들 수도 있다.

디지털제어 산업기사 8051 MICOM 보드로 실행하고자 하면 먼저 □-Vision에서 open project, edit project, build project 등의 과정을 통하여 EX5_1.C에 대한 Hex 파일을 만들고, MICOM_PROGRAMMER의 □열기□에서 그 Hex 파일을 연 후(8051.hex에 더블클릭) □자동□

그림 5.11 logic tester의 회로도

에 클릭하여 기록을 한다. 기록이 끝나면 즉시 P1에 연결된 LED들이 일정 시간 간격으로 점멸하는 것을 볼 수 있을 것이다.

(7) 課 題

1. LED들의 점등이 우측으로 이동되도록 하고, 점등 시간간격이 0.2초가 되도록 하라.

2. LED들이 2진 가산 형태로 증가되도록 하라(힌트 : led의 초기값=0xff, led--)

5.4.2  LED의 점등(2)

(1) 目 的

시중의 자동차 중에는 브레이크를 밟을 때 Z카를 흉내내어 점등상태가 좌우로 진동하는 것이 더러 있다. 그림 5.9와 같은 시스템에서 포트 1에 연결된 LED가 이와 유사하게 좌우로 점등하도록 하고자 한다.

(2) 順序圖

그림 5.12  LED 진동 순서도

(3) 프로그램[EX5_2.C]

/*==============================*/

/* PROGRAM EX5_2.C (Z CAR LED) */

/*==============================*/

#pragma code symbols debug oe

#include  <reg51.h>

void  delay(int  i)	/* 지연루틴 */

{

while(i--);

}

void main(void)

{

data unsigned char  led, j;

led=0xfe;	/* 최초의 출력 데이터*/

do {

for (j=1; j<=7; j++)	/* j=1에서 j=7까지 반복 수행하라*/

{

P1 = led;

delay(0x4800);	/* 0.1초 지연 */

led=( led << 1 )  □ 1;	/* 좌측으로 시프트하고 빈 자리는 1로*/

}

for (j=1; j<=7; j++)	/* j=1에서 j=7까지 반복 수행하라*/

{

P1 = led;

delay(0x4800);	/* 0.1초 지연 */

led=( led >> 1)  □ 0x80;	/* 우측으로 시프트하고 빈자리는 1로*/

}

} while( 1 );	/* 반복하라*/

}

(4) 프로그램의 解說(C)

for (j=1; j<=7; j++)

{

P1 = led;

delay(0x4800);

led=( led >> 1 )  □ 0x80;

}

최초의 것은 안의 루프를 7번 반복하라는 것이고, 마지막의 것은 led의 비트 데이터 중 0의 상태를 우측으로 시프트하고, 가장 우측의 시프트해간 빈 공간에는 1로 채우라는 것이다. 01H가 아니고 80H임에 유의하기 바란다.

문제는 최초의 led값이 얼마냐에 있다. 이전의 루프에서 led는 7FH가 되므로 이것이 바로 이 루프의 최초 led값이 된다. 그러므로 LED7은 전 루프에서 on되지 않고, 이 루프에서 on된다. 마찬가지로 LED0는 이 루프에서 on되지 않고 전 루프에서 on된다.

(5) 프로그램의 實行

역시 제4장에서 설명한 방법에 따라 □Vision에서 open project와 edit project 작업을 통하여 EX5_2.C 또는 EX5_2.A51를 open된 프로젝트에 포함시키고, build project  작업을 통하여 이 프로그램을 컴파일 또는 어셈블하고 링크함으로써 Hex file과 OBJ file을 만든다.

실제 시스템 또는 트레인키트로 실험하고자 하면 Hex 파일을 다운로드하여 실행시키고, 컴퓨터에 시뮬레이트하고자 하면, dScope에서 포트 1을 선택하고 프로젝트를 불러온 다음 GO한다. LED상태가 Z카 전조등처럼 좌우로 흔들림을 볼 수 있을 것이다.

디지털제어 산업기사 8051 MICOM 보드에 실행시키고자 하면 역시□Vision에서 open project, edit project, build project 등의 작업을 통하여 만든 Hex 파일을 MICOM PROGRAMMER에서 열기, 자동 등의 작업을 통하여 MICOM 보드에 기록해 넣음으로써 실행을 시킨다.

(6) 課 題

1. EX5_2.C에서 for(j=1; j<=7; j++) 대신 for(j=1; j<=8; j++)로 하면 제대로 동작하지 않는다. 정말 그런지를 확인한 후 그 이유를 밝혀라.

5.4.3  파일럿 램프

(1) 目 的

그림 5.13과 같이 4개 스위치(푸시 버튼)의 on-off에 대응해서 4개의 LED를 점등하고자 한다.

그림 5.13  파일럿 램프 시스템

(2) 順序圖

그림 5.14  파일럿 램프의 순서도

(3) 프로그램(EX5_3.C)

/*=================================*/

/* PROGRAM EX5_3.C) [ PILOT LAMP ] */

/*=================================*/

#pragma code symbols debug oe

#include <reg51.h>	/* 8051 헤더파일을 include */

delay(short i)   {	/* 지연함수 */

while(i--);

}

void main(void) {	/* 메인함수 */

unsigned char i_data;	/* number = 8비트 변수 */

P1 = 0x0f;	/* P1.3∼P1.0은 입력 포트라인이므로 */

do {

i_data = P1;

i_data = (i_data <<4) □ 0x0f;	/* i_data[3∼0]을 i_data[7∼4]로 */

P1 = i_data;	/* 포트 1에 출력 */

delay(0500);	/* 약간의 지연 */

}while(1);	/* 반복하라 */

}

(4) 프로그램의 解說(C)

P1 = 0x0f;

앞에서 수차 언급한 바와 같이, 8051의 포트는 준양방향성이기 때문에 입력하기전에 반드시 입력포트 라인별로 1을 출력해야 한다.

i_data = P1;

i_data = (i_data <<4) □ 0x0f;

P1 = i_data;

포트 1을 읽어서, 그것을 4번 좌로 시프트함으로써 P1.3∼P1.0을 통하여 입력한 것을 P1.7∼P1.4의 자리에 옮긴 후 하위 4비트에는 1로 채우기 위해서  0FH와 OR한 것이다. □ 은 OR 연산기호로서 앞의 것과 뒤의 것을 OR해 준다.

(5) 프로그램의 實行

앞에서 같은 방법으로 □Vision에서 open project(이미 open되어 있으면 생략)와 edit project 작업을 통하여 프로젝트와 프로그램을 지정한 후 build project 작업을 통하여 어셈블 또는 컴파일 그리고 링크를 한다. 이것이 성공적으로 이루어지지 않으면 error 표시가 되므로 이에 따라 고친 후 build project 작업을 다시 한다. 성공적으로 이루어지면 Obj 파일과 Hex 파일이 생성되었으로, 시뮬레이트의 경우에는 dScope에 들어가서 CPU(이것도 이미 지정되어 있으면 생략)와 peripheral의 포트 1을 지정하고, 툴바 첫 번째 것에서 project를 불러온 후 툴바 4번째 것에서 실행(GO)을 한다. 포트 1의 창에서 포트 핀(pins)의 하위 각 비트에 클릭을 해서 입력 값을 변화시키고 이에 따라 포트 값(P1.7∼P1.4)이 어떻게 바뀌는지를 관찰한다.

트레인키트에 실행시키고자 할 경우에는 Hex 파일을 다운로드한 후 실행시킨다. 실제 시스템 예컨대 그림 5.13과 같은 시스템에 실험하고자 하면 Hex 파일을 ROM 라이터로 8751 또는 AT89S51 또는 AT89C2051에 다운로드한 후 실제 시스템에 꽂는다.

디지털제어 산업기사 8051 MICOM 보드에 실행시키고자 하면 □Vision에서 역시 open project, edit project, build project 등의 작업을 통하여 만든 Hex 파일을 MICOM PROGRAMMER에서 □열기□와 □자동□ 작업을 통하여 MICOM 보드에 기록한다. 기록이 끝나면 즉시 실행된다.

(6) 課 題

1. 위 프로그램 중 i_data=(i_data << 4) □ 0x0f에서 0x0f를 빼고 위 프로그램을 실행해 보라.

5.4.4  신호등 제어

(1) 目 的

교통신호등 제어는 점제어, 선제어, 면제어 등으로 분류된다. 점제어는 교차로 하나만을 제어하는 것이고, 선제어는 하나의 일직선상의 교차로들을 제어하는 것이며, 면제어는 도시 전체의 교차로들을 제어하는 것이다.

교통신호등 제어는 또한 고정시간 제어와 가변시간 제어로 분류된다. 전자는 차량 수에 관계없이 일정 시간간격으로 신호등을 바꾸는 것이고, 후자는 각 로선의 차량 수에 따라 시간을 가변하여 신호등을 바꾸는 것이다.

여기에서는 가장 간단한 형태로서 아래 표에 따라 고정시간으로 교차로 하나만을 제어하고자 한다.

노 선		A	B
상 태	신 호	청 황 적	청 황 적
1 2 3 4		1 0 0 0 1 0 0 0 1 0 0 1	0 0 1 0 0 1 1 0 0 0 1 0

그림 5.15  모델 교차로

그림 5.16  모형 시스템에서 LED의 결선

(2) 順序圖

위 표를 보면 각 노선 당 3가지 색깔의 신호등이 있는데, 이들을 그림 5.16과 같이 포트 1에 연결하기로 한다. LED가 포트 라인 당 2개씩인 이유는 그림 5.15에서 노선당 신호등이 2개씩이기 때문이다.

그림 5.17  신호등 제어 순서도

(3) 프로그램(EX5_4.C)

/*=======================================*/

/* PROGRAM EX5_4.C [TRAFFIC CONTROL]   */

/*=======================================*/

#pragma  code	/* 어셈블리어 리스트를 출력하라 */

#include <reg51.h>	/* 8051 헤더파일의 include */

delay(long i) {	/* 지연함수	*/

while(i--);

}

main() {	/* 메인 함수 */

do {

P1 = 0x21;	/* 최초의 출력 패턴 */

delay(0x43c00);	/* 01.5초 지연 */

P1 = 0x12;	/* 두번째 출력 패턴*/

delay(0x2d000);	/* 1.0초 지연 */

P1 = 0x0c;	/* 세번째 출력 패턴 */

delay(0x43c00);

P1 = 0x0a;	/* 네번째 출력 패턴 */

delay(0x2d000);

}while(1);	/* repeat always */

}

(3) 프로그램의 解說(C)

delay(long i)

□

delay(0x43c00);

제4장의 마지막에서 논한 바와 같이 C에 의한 지연시간은 C 자체에서는 계산할 수 없고, #pragma code라는 전처리 문이 들어간 C 프로그램을 컴파일할 때 생기는 어셈블리어 리스트를 보고 계산해야 한다. 제4장 마지막에서 R7=00H, R6=□로 놓을 때 지연시간은 2561□+2이므로, 발진주파수=22.1184MHz에서 1.5초 즉 1500000□초를 얻기 위해서는 (2561□+2)*0.5425=1500000에서 □=1080=43cH를 얻으므로 delay(0x43c00)로 해야 한다.

(3) 課 題

1. 위 프로그램을 실행(시뮬레이트)시키고, 포트 상태를 확인하라

2. LED(포트)의 변화 및 시간간격을 좀더 복잡한 시스템에 맞추어 바꿔보라.

5.4.5  化學플랜트의 제어

(1) 目 的

그림. 5.18은 원당과 석회유를 우측의 파이프라인을 통해서 공급하면 이것을 적당한 온도, 적당한 압력에서 설탕으로 만드는 화학 플랜트로서, 제어 입력으로는 온도 센서, 압력 센서, 액위 센서 등 3개이고, 출력으로는 모터 A, 히터, 냉각기, 전자밸브 A, 전자밸브 B 등 5개이다. 입력은 모두 디지털量이다. 온도센서, 압력센서, 액위센서 등으로부터 입력되는 량은 원래는 아날로그량이만, 이것이 일정 값 이상이면 논리 1, 일정 값 이하이면 논리 0이 되도록 해서 디지털량으로 한 것이다. 예컨대 온도의 경우 30℃ 이상이면 논리 1(5V), 그 이하이면 논리 0(0V)이 되도록 그러게 만든 것이다. 문제는 入力값과 出力값과의 대응 관계, 즉 포트를 통하여 입력되는 디지털량이 얼마일 때 그 디지털량에 상응하는 출력 값을 얼마로 하느냐에 있다. 이것은 시스템의 성격 및 실험에 의해서 결정되는 바, 그런 성격 및 실험에 따라 작성된 表를 탐색표(look-up table)라고 한다. 지금 문제의 경우에 대한 탐색표가 표5.1과 같다고 하자. 그러면 입력이 000일 때에는 출력이 01101로 되어 히터와 전자밸브 A와 모터 A가 동작하고, 입력이 001일 때에는 출력이 10010으로 되어 냉각기와 전자밸브 B가 동작한다. 8051을 사용하여 이와 같은 탐색표에 따른 제어를 하고자 한다.

그림 5.18  설탕 제조 화학 플랜트

□표 5.1  탐색표

테이블番號	입 력			출 력						출력 데이터가 들어있는 번지
	액 위 센 서 (P1.2)	압 력 센 서 (P1.1)	온 도 센 서 (P1.0)	냉 각 기 (P1.7)	히 터 (P1.6)	전 자 밸 브 A (P1.5)	전 자 밸 브 B (P1.4)	모 터 A (P1.3)	16진 표기의 출력 데이터 (단 P1.2∼P1.0=0)
0 1 2 3 4 5 6 7	0 0 0 0 1 1 1 1	0 0 1 1 0 0 1 1	0 1 0 1 0 1 0 1	0 1 0 1 1 1 0 1	1 0 0 0 1 0 0 0	1 0 0 0 1 1 1 1	0 1 1 0 0 0 0 0	1 0 0 1 0 1 0 0	68 90 10 88 E0 A8 20 A0	table[0] table[1] table[2] table[3] table[4] table[5] table[6] table[7]

(2) 順序圖

탐색표(look-up table)에 의한 제어에서 가장 중요한 것은 앞에서도 언급한 바와 같이 입력값과 출력값의 대응 관계를 정하는 탐색표를 만드는 일이다. 이것은 어떤 법칙에 따라 정하는 것이 아니고, 시스템의 성격상 정한다. 예컨대 온도센서로부터의 신호가 일정치 이상이 되어서 그것이 논리 1(+5V)로 되고, 액위센서 및 압력센서가 논리 0(0V)으로 되면, 즉 입력값이 001이 되면 출력값이 10010으로 되어 냉각기가 동작되고 전자밸브 B가 열려야 하는 것과 같다. 사실은 이러한 시스템 성격을 토대로 수 많은 실험을 통하여 최상의 제품이 나오도록 이것저것 조정해서 탐색표를 만든다.

아무튼 탐색표가 만들어지면 이것을 table 형태로 프로그램 메모리의 일정 번지에서부터 기록해야 한다. 예제의 경우 table[0]에는 68H를, table[1]에는 90H를, ......., table[7]에는 A0H를 기억시켜 둔다.

다음 단계로 할 일은 입력된 값에 대응되는 출력 데이터를 이 표에서 찾아서 포트에 출력시키는 프로그램을 작성하는 것이다. 표 5.1을 보면 입력이 0(000)일 때는 출력데이터가 table[0]에 들어 있고, 입력이 1(001)일 때는 출력데이터가 table[1]에 들어 있으며, ..... 입력이 7(111)일 때는 출력이 table[7]에 들어 있다. 그런데 table[0], table[1], .....table[7] 등은 table[]의 []내에 0, 1, .... 7 등을 넣은 형태이므로, 그림 5.19와 같이 table[0]을 베이스로 하고 여기에 P1.2∼P1.0을 통하여 입력한 값을 table[]의 [ ]내에 넣으면 된다.

그림 5.19  제어표에서 출력데이터를 찾는 방법

그러므로, 센서들로부터의 입력을 i_data에 받아들이고 다음과 같은 명령을 실행시키면 입력에 대응하는 출력 데이터를 포트에 내어준다.

□

i_data = P1;	; P1.2∼P1.0을 통하여 센서 상태를 입력한다

i_data &= 0x07;	; 입력 라인만 남기고 나머지는 마스크시킨다

O_data = table[i_data];	; 탐색표의 해당 번지에서 출력데이터를 찾아서

O_data □ = 0x07;	; P1.2∼P1.0은 입력 라인이므로 07H와 OR을 한 뒤(P1.7∼P1.3은 출력)

P1 = O_data;	; 이것을 포트 1에 출력한다

위 프로그램에서 입력된 값을 2진수 00000111에 AND시켜주는 이유는 포트 1의 하위 3비트 만으로 입력을 하므로, 하위 3비트만 남기고 다른 비트들은 모두 마스크시키기 위함이다. 그리고 O_data □ = 0x07은 P1.2∼P1.0은 입력라인이기 때문이다. 출력라인은 P1.7∼P1.3이므로 07H를 OR해 주어도 출력에는 영향을 주지 않는다. 이것을 근거로 문제의 프로그램에 대한 순서도를 작성하면 그림 5.22와 같다. 이것은 입력 및 출력을 그림 5.20과 같이 연결하였음을 전제로 한다. 그림 5.21은 이에 대한 간단한 실험을 위해서 구성한 시스템이다.

그림 5.20  입력 및 출력의 연결도

그림 5.21  실험용 시스템

그림 5.22  플랜트 제어 순서도

(3) 프로그램(EX5_5.C)

/*=====================================*/

/* PROGRAM EX5_5.C [CHEMICAL PLANT]  */

/*=====================================*/

#include <reg51.h>	/* 8051 해더 파일 */

delay(char i) {	/* 지연 함수          */

while(i--);

}

main() {

unsigned char i_data,o_data;

unsigned char table[8] = {0x68,0x90,0x10,0x88,0xf0,0xa8,0x20,0xa0};

/* 표 데이터 */

P1 □ = 0x07;	/* P1.2∼P1.0은 입력으므로 */

do {

i_data = P1;	/* P1.2∼P1.0을 통하여 센서상태를 입력 */

i_data &= 0x07;	/* 하위 3비트만 남기고 모두 마스크 */

o_data = table[i_data]□ 0x07;  /*표에서 출력 데이터를 불러오고 아래 */

/*3비트에는 다음번 입력을 위해서 111을 넣는다*/

P1 = o_data;	/* 그것을 포트 1에 출력한다. */

delay(0x0050);	/* 잠깐 지연 */

}while(1);	/* 반복하라 */

}

(4) 프로그램의 解說(C)

unsigned char table[8] = {0x68,0x90,0x10,0x88,0xf0,0xa8,0x20,0xa0};

1차원 배열 table을 정의한 것이다. 앞에서 언급한 바와 같이 하나 하나의 요소가 부호 없는 8비트 정수임을 선언하는 □unsigned□ 앞에 □const□를 붙일 수 있다.

o_data = table[i_data] □ 0x07;

배열 table[i_data]에 07H를 OR해서 o_data에 넣으라는 것이다. i_data는 포트 1(P1.2∼P1.0)을 통하여 입력한 값으로서 0에서 7까지의 수이다. 그러므로 입력한 값이 0이면 배열 table[0] 즉 0x68을, 1이면 table[1] 즉 0x90을 가져와서 07H에 OR한 후 o_data에 넣는다.

(5) 프로그램의 實行

역시 □Vision에서 open project(이미 open되어 있으면 생략)와 edit project작업으로 프로젝트와 프로그램을 지정하고, build project 작업으로 어셈블 또는 컴파일을 하고 링크를 함으로써 Hex 파일과 Obj 파일을 만든다.

컴퓨터로 시뮬레이트를 하고자 하면 dScope에서 pheripheral(포트 1)을 지정하고(이미 지정되어 있으면 생략함) 프로젝트를 불러온 후 실행(GO)을 한다. P1.2∼P1.0을 통하여 입력을 하도록 되어 있으므로, 시뮬레이터에서는 peripheral의 port1에서 pins의 비트2-0을 크릭하고 이때 비트 7∼3의 변화를 본다. 제어표의 값대로 P1.7∼P1.3에 출력되는지를 확인한다.

트레인키트로 실험하고자 할 경우에는 ROM 라이터로 Hex file을 트레인키트에 다운로드하고 실행시킨다.

실제 시스템, 예컨대 그림 5.21과 같은 시스템에 실험하고자 하면 □Vision에서 얻은 Hex 파일을 ROM 라이터를 사용하여 8751 또는 AT89C2051 또는 AT89S51에 다운로드하여 실제 시스템에 꽂는다.

디지털제어 산업기사 8051 MICOM 보드에 실험코자 하면 역시 □Vision에서 얻은 Hex 파일을 MICOM PROGRAMMER에서 열기와 자동을 통하여 MICOM 보드에 다운로드한다.

(6) 課 題

1. P1.4∼P1.0으로는 입력을 받고, P2.7∼P2.0으로는 제어표에서 얻은 8비트 데이터를 출력하는 프로그램을 작성하라. 단 5개의 □입력□과 8개의 □출력□과의 관계에 대한 소위 제어표는 학생 스스로 적당히 만드는 것으로 한다.

1. I/O포트는 외부장치와 CPU를 연결해 주는 병렬 입출력 인터페이스이다.

2. 8051의 포트 0는 기본적으로는 범용 I/O포트이나, 외부에 메모리를 둘 경우에는 주소버스(A7∼A0)와 데이터버스(D7∼D0)의 기능을 번갈아(multiplex) 수행한다.

3. 포트 0를 범용 I/O포트로 사용할 경우에는 반드시 풀업저항을 외부에 달아 주어야 한다.

4. 8051의 명령어 중에는 INC P0와 같이 종착지 오퍼랜드가 포트 그 자체인 경우가 있는데, 이런 명령어를 실행하면 포트 래치에 기록된 데이터를 먼저 읽어서(read), 수정(modify)한 후, 다시 기록(write)한다. 이러한 명령어를 read-modify-write 명령어라고 한다.

5. 포트 1은 범용의 I/O포트로만 사용된다. 단, 8052AH에서는 P1.0와 P1.1이 T2와 T2EX로서의 기능도 한다.

6. 포트 1은 내부 풀업저항이 있으므로 외부에 풀업저항을 붙일 필요가 없다.

7. 포트 2는 기본적으로는 범용 I/O포트이나, 외부 메모리를 둘 경우에는 상위 주소버스(A15-A8)로서의 기능을 한다.

8. 포트 2를 범용의 I/O포트로 사용할 경우에는 역시 풀업저항을 달 필요가 없다.

9. 포트 3도 기본적으로는 범용의 I/O포트이나, 직렬포트, 외부 인터럽트, 타이머 등을 사용할 경우에는 이들 기능과 관련된 특수 기능을 수행한다.

10. 포트 3도 범용의 I/O포트로 사용할 경우에는 외부 풀업저항을 붙일 필요가 없다.

11. ATmel사의 AT89C2051에는 포트 1과 포트 3만이 있다.

12. 8051 I/O포트에는 입출력 방향을 결정해 주는 레지스터가 없다. 그러므로 I/O포트를 입력포트로 사용할 경우에는 입력하기 전에 반드시 포트라인 별로 1을 출력해 주어야 한다.

5.1 병렬 데이터 전송방식에 대하여 잘못 설명된 것은?

㉮ 직렬 전송방식에 비하여 전송선의 수가 많다.

㉯ 고속프린터와 같은 근거리 주변장치와의 통신에 주로 사용된다.

㉰ 직렬 전송방식에 비하여 데이터 전송 속도가 느리다.

㉱ 한 번에 단위 데이터(보통 1byte)가 병렬로 전송된다.

5.2 입출력 인터페이스에 대한 설명 중 옳지 않은 것은?	(전산기조직응용)

㉮ CPU와 입출력장치 사이에 존재하여 데이터의 전송이 원활하게 이루어지도록 하게 하는 역할을 한다.

㉯ CPU와 입출력장치 간의 동작 속도를 맞춘다.

㉰ 데이터 형식상의 차이도 맞춘다.

㉱ 반드시 CPU 내에 존재한다.

5.3 마이크로컴퓨터의 기본 구성에서 외부의 장치와 신호를 주고받는 요소는?	(전산기조직응용)

㉮ CPU	㉯ ALU

㉰ I/O포트	㉱ 메모리

5.4 마이크로컴퓨터 시스템에서 CPU와 주변장치 사이의 통신이 이루어지는 창구 역할을 하는 것은?

㉮ address bus	㉯ memory map

㉰ system clock	㉱ I/O port

5.5 마이크로컴퓨터의 병렬 입출력 인터페이스가 아닌 것은?

㉮ PIO	㉯ UART

㉰ PPI	㉱ PIA

5.6 마이크로컴퓨터의 입출력 시스템에 있어서 인터페이스(interface) 회로의 기본적인 기능에 해당되지 않는 것은?	(전산기조직응용)

㉮ 데이터 형식의 변환	㉯ 입출력 장치의 상태 조사

㉰ 전송의 동기 제어	㉱ 신호의 레벨 정확

5.7 Z80의 병렬 입출력 제어장치(PIO)의 동작모드는 모두 몇 개인가?	(전자계산기)

㉮ 4개	㉯ 3개	㉰ 2개	㉱ 1개

5.8 입출력장치의 기본적인 특징이 아닌 것은?	(전자계산기)

㉮ 종류가 다양하다.	㉯ 동작 전압이 다양하다.

㉰ 동작 속도의 차가 크다.	㉱ 제어신호 형태가 유사하다.

5.9 마이크로컴퓨터의 입출력부 구성요소가 아닌 것은?	(전산기조직응용)

㉮ 인터페이스 회로	㉯ 입출력 제어 회로

㉰ 채널	㉱ 데이터 전송로

5.10 아래 그림은 마이크로컴퓨터의 키보드 회로이다. 출력 단자 C0, C1, C2에 각각 1, 1,0의 데이터를 내보냈을 때 입력 단자 R0, R1, R2에 1, 1, 0의 데이터가 읽혀졌다. 어느 키가 눌려져 있는가?	(전산기조직응용)

㉮ K1	㉯ K5	㉰ K7	㉱ K9

5.11 컴퓨터와 주변장치 사이에 데이터 전송을 수행할 때 입출력의 준비나 완료를 나타내는 신호가 필요한 비동기식 입출력 시스템에 널리 쓰이는 방식은?	(전산기조직응용)

㉮ polling	㉯ interrupt

㉰ paging	㉱ handshaking

5.12 마이크로프로세서를 위한 I/O인터페이스에서 악수식(Handshaking)이란?	(전자계산기)

㉮ 출력시 자료를 자료버스에 싣는 것과 동시에 스트로브(strobe)를 보내는 것이다.

㉯ 마이크로프로세서의 병렬(parallel) 자료를 I/O장치를 위한 직렬(serial) 자료로 변환시키는 것이다.

㉰ CPU의 간섭 없이 기억장치와 I/O장치들을 직접 자료 교환시키는 것이다.

㉱ 자료 전송 신호와 자료를 보낸 후 수신자로부터 잘 받았음을 알리는 확인 신호를 받는 방식을 말한다.

5.13 handshaking 출력방식으로 올바른 순서는?	(전자계산기)

① CPU는 output request가 1이 될 때까지 기다린다.

② CPU는 output ready로 자료의 출력을 알린다.

③ 주변장치는 CPU에 output request를 보낸다.

④ CPU는 주변장치에 자료를 보낸다.

㉮ ①→②→③→④	㉯ ①→③→②→④

㉰ ③→①→④→②	㉱ ③→①→②→④

5.14 병렬 입출력 인터페이스에서 데이터가 입력되거나 출력되었음을 알려주는 제어를 수행하는 것은?

㉮ control bus	㉯ reset 신호

㉰ latch	㉱ strobe 신호

5.15 Interface의 역할을 설명한 것이 아닌 것은 어느 것인가?	(전자계산기)

㉮ 주변장치에서 컴퓨터로 정보를 보낼 때 이 정보를 컴퓨터에 맞는 형태로 변환한다.

㉯ 컴퓨터에서 주변장치로 정보를 보낼 때 이 정보를 주변장치에 맞는 형태로 변환한다.

㉰ 컴퓨터와 주변장치 사이에 처리 시간이 다른 것을 소화시킨다.

㉱ CPU를 경유하지 않고 메모리와 주변장치간에 정보를 전달한다.

5.16 입출력장치를 기억장치에 직접 연결시켜 입출력할 수 없는 이유는?

㉮ 처리하는 정보의 단위가 다르므로

㉯ 입출력 장치는 자율적으로 동작하므로

㉰ 동작 속도가 다르므로

㉱ 에러(error) 발생률이 크기 때문에

5.17 소프트웨어에 의한 키보드(Key board) 탐색 기법(scanning technique)은 하드웨어에  의해 인코디드(encoded) 기법보다 어느 점이 유리한가?

㉮ 비용이 적게 든다.	㉯ 빠르다.

㉰ 변경이 쉽다.	㉱ 신뢰성이 높다.

5.18 다음 중 입출력 시스템에 들지 않는 것은 어느 것인가?	(전산기조직응용)

㉮ 인터페이스 회로	㉯ 데이터 전송로

㉰ 입출력 제어회로	㉱ 연산제어 시스템

5.19 직렬 입출력 인터페이스에 해당하는 것은?	(전산기조직응용)

㉮ 8251	㉯ 8255	㉰ 8257	㉱ 8259

5.20 직렬 입출력 인터페이스의 응용에 해당되지 않는 것은?	(전산기조직응용)

㉮ 키보드 엔코더	㉯ CRT 단말 기기 인터페이스

㉰ 전화선 인터페이스	㉱ 텔레타이프 인터페이스

5.21 다음은 기억장치와 입출력장치의 동작에 대한 설명이다. 이 중 옳지 않은 것은?	(전산기조직응용)

㉮ 입출력장치는 그 속도가 기억장치에 비하여 상당히 느린 것이 보통이다.

㉯ 기억장치에서 처리하는 정보의 단위는 단어(word)이며, 입출력장치가 다루는 정보의 단위는 보통 문자(Character)로서 1바이트이다.

㉰ 중앙처리장치의 제어기는 자기디스크의 회전속도 제어 등 입출력장치의 모든 동작을 제어한다.

㉱ 중앙처리장치와 입출력장치 사이에 에러(error)가 발생할 가능성은 중앙처리장치보다 크다.

5.22 입출력기기의 준비와 동작이 완료되는 것을 프로그램에 의해 확인한 다음 데이터의 입출력을 행하는 입출력 제어 방식으로 Waiting Loop 방식이라고도 하는 것은?	(전산기조직응용)

㉮ Memory-Mapped I/O	㉯ Isolated I/O

㉰ Programmed I/O	㉱ Interrupt I/O

5.23 IO / MＡ0이면 기억장치에 접근하고, IO / MＡ1이면 입출력에 접근하는 주소 디코더회로는 다음 중 어느 것인가?	(전산기조직응용)

㉮ isolated I/O에서 입출력 포트 주소 해독

㉯ isolated I/O에서 기억 장치 주소 해독

㉰ memory mapped I/O에서 입출력 포트 주소 해독

㉱ memory mapped I/O에서 기억장치 주소 해독

5.24 I/O Mapped I/O(isolated I/O) 구조의 시스템에서 CPU와 주변장치간의 데이터 전송명령은 어느 것인가?	(전산기조직응용)

㉮ 제어 명령	㉯ 연산 명령

㉰ 로더 명령	㉱ 입출력 명령

5.25 CPU가 입출력 데이터 전송을 메모리에서의 데이터 전송과 같은 명령으로 수행할수 있는 입출력 제어방식은 어느 것인가?	(전산기조직응용)

㉮ Interrupt I/O	㉯ Memory Mapped I/O

㉰ Programmed I/O	㉱ Isolated I/O

5.26 다음 중 6800계열에서처럼 I/O회로를 메모리 어드레스 공간에 위치시키려는 방식은?	(전산기조직응용)

㉮ Isolated I/O	㉯ I/O mapped I/O

㉰ I/O mapped memory	㉱ Memory Mapped I/O

5.27 다음 중 입출력 제어부의 기능이라고 볼 수 없는 것은 어느 것인가?	(전산기조직응용)

㉮ 입출력장치의 정합	㉯ 체크 코드의 부가 및 검출

㉰ 데이터 전송 타이밍 정합	㉱ 데이터의 직병렬 변환

5.28 입출력장치에 관한 설명 중 맞지 않는 것은 어느 것인가?	(전산기조직응용)

㉮ 오프라인 상태란 컴퓨터와 독립적으로 작동되는 것을 말한다.

㉯ 온라인 상태라 함은 직접 CPU의 명령으로 메모리의 입출력을 수행할 수 있는 것을 말한다.

㉰ 오프라인으로 컴퓨터와 접속되어 있는 입출력장치가 주변장치이다.

㉱ 온라인으로 컴퓨터와 접속되어 있는 입출력장치가 주변장치이다.

5.1 8051 I/O포트에서 read-modify-write 명령어란 무엇인가?

5.2 8051에 외부 메모리를 둘 경우 포트 0와 포트 2의 기능을 기술하라.

5.3 포트 0를 범용 I/O포트로 사용할 경우에는 반드시 외부에 풀업저항을 달아 주어야 하	는데, 그 이유는 무엇인가?

5.4 8051 I/O포트를 입력포트로 사용할 경우에는 입력에 앞서 포트 라인별로 1을 출력해 주어야 한다. 왜 그래야 하는가?

5.5 포트 1의 P1.0∼P1.3에 연결된 스위치의 상태를 포트 2의 P2.0∼P2.3에 연결된 LED에 표시하는 프로그램을 작성하라.

5.6 포트 1의 P1.0∼P1.7에 연결된 LED를 0.1초 간격으로 하나씩 좌우로 이동시키는 프로그램을 작성하라.

5.7 위 문제에서 LED가 켜지는 순서가 다음과 같이 하도록 하라. 끝까지 가면 역순으로 한다.

5.8 전가산기(full adder)의 기능을 실현하는 프로그램을 작성하라.

6.1 인터럽트 개요 6.2 인터럽트 소스 6.3 외부 인터럽트 6.4 타이머 오버플로 인터럽트와 직렬포트 인터럽트 6.5 인터럽트 벡터 6.6 인터럽트 관련 레지스터	6.7 인터럽트 우선순위 6.8 다중 인터럽트 6.9 인터럽트 처리중 CPU 상태의 보존 6.10 인터럽트 처리 과정 6.11 인터럽트 응답시간 6.12 인터럽트에 관한 실험 6.13 이 장의 간추림

앞에서 언급한 바와 같이, 인터럽트(interrupt)는 외부 또는 내부로부터의 긴급 서비스 요청에 의하여 CPU가 현재 실행중인 일을 일시 중단하고 그 요청에 합당한 서비스를 해주는 기법(technique)이다.

8051의 외부 핀(pin) 중에는 INT0이라는 외부 인터럽트 핀이 있어서 여기에 외부장치로 부터의 긴급 서비스 요청 선이 연결되어 있다. 예컨대 8051을 화재경보기로 사용하는 경우, 핀 INT0에는 화재감지기가 연결되어 있어서, 화재가 나면 이를 감지하고 핀 INT0를 논리 0으로 만든다. 구체적인 예로서 화재감지기로 바이메탈(bi-metal)을 쓰는 경우를 보자. 바이메탈은 열팽창 계수가 서로 다른 두 장의 금속판(황동과 인바르)을 붙여 놓은 것으로, 화재가 나서 온도가 오르면 한쪽(황동판)의 열팽창이 다른쪽보다 커서 구부러지기 때문에 어스선에 연결된 금속판에 접촉된다. 그러므로 금속판은 0V로 되고, 이것이 핀 INT0에 연결되어 있으므로, INT0 핀이 논리 0으로 된다. 이것이 바로 외부로부터의 긴급 서비스 요청이다. 또 내부의 타이머에서 설정된 시간이 지난다든가, 직렬포트에서 송신 또는 수신이 완료된다든가와 같은 일이 일어나도 이 또한 인터럽트 발생 요건이 되는데, 이것이 내부로부터의 긴급 서비스 요청이다.

8051의 CPU는 모든 명령의 마지막 사이클에서 인터럽트의 요청 여부를 체크함으로써 이 요청의 유무를 알아내고, 이 요청을 받은 CPU는 현재 실행중인 명령(경우에 따라서는 그 다음 명령까지)만은 마친 후 일정의 처리순서에 따라 그 요청에 합당한 서비스를 해준 다음, 본래의 프로그램으로 되돌아가서 중단된 프로그램을 중단 지점에서부터 다시 실행한다. 이것이 인터럽트이다.

앞에서 언급한 바와 같이, 인터럽트의 3요소는 인터럽트 소스와 벡터와 우선순위이다. 인터럽트 소스는 누가 인터럽트를 요청할 수 있느냐의 문제이고, 인터럽트 벡터는 인터럽트가 발생할 때 어디로 뛰어가느냐의 문제이며, 인터럽트 우선순위는 동시에 2개 이상의 인터럽트가 요청되는 경우 어느 것부터 인정해 주느냐의 문제이다. 이하 이들에 대해서 하나하나 보기로 한다.

인터럽트 3요소 중 제 1은 인터럽트 소스이다. 앞에서 언급한 바와 같이, 이것은 누가 인터럽트를 요청할 수 있는지, 즉 인터럽트를 요청할 수 있는 권한이 누구에게 있는지의 문제이다.

그림 6.1  인터럽트 소스

8051의 인터럽트 소스(interrupt source)는 도합 5개로서 그 중 2개는 외부장치이고, 다른 2개는 내부 타이머이며, 나머지 1개는 내부 직렬포트이다. 8052에는 이 밖에도 타이머 인터럽트 2가 하나 더 추가된다.

·외부 인터럽트 0(external interrup 0)

·타이머 인터럽트 0(timer/counter overflow interrupt 0)

·외부 인터럽트 1(external interrupt 0)

·타이머 인터럽트 1(timer/counter overflow interrupt 1)

·직렬포트 인터럽트(serial port interrupt)

·타이머 인터럽트 2(8052에만 있음)

외부 인터럽트는 외부 로직이 8051의 INT0(P3.2) 또는 INT1(P3.3)에 하강 에지(falling edge) 또는 L레벨(low level)의 신호를 줌으로써 발생되는 인터럽트인데, 하강 에지를 인터럽트 요청으로 보느냐, 아니면 L레벨을 인터럽트 요청으로 보느냐는 명령으로 선택할 수 있게 되어 있다. 즉, 외부 인터럽트는 그림 6.1의 첫 번째와 세 번째와 같이 하강 에지 트리거와 L레벨 트리거 중 어느 하나로 할 수 있는데, 그 선택은 TCON 레지스터의 비트 0

그림 6.2  TCON 레지스터

과 비트 2로 한다. 그림 6.2의 TCON 레지스터의 비트 0(IT0) 및 비트 2(IT1)가 1이면 하강에지 트리거이고, 0이면 L레벨 트리거이다. 에지 트리거의 경우에는 인터럽트가 발생되면 TCON 레지스터의 비트 1(IE0) 또는 비트 3(IE1)이 세트되고, 인터럽트가 처리되면(정확히 말하면 인터럽트 서비스 루틴이 벡터될 때) 이들 비트는 자동적으로 클리어되지만, 레벨 트리거의 경우에는 인터럽트가 발생되어도, 또 처리되어도 이들 비트는 세트되지도 않고 클리어되지도 않는다. 즉 L레벨 트리거의 경우에는 이들 비트와 아무런 관계가 없다. 다음의 명령어들은 INT0를 에지 트리거, INT1을 레벨 트리거로 하기 위한 것이다.

SETB  TCON.0 (C에서는 IT0=1)

CLR  TCON.2 (C에서는 IT1=0)

8051의 외부 인터럽트를 제어하는 레지스터에는 TCON 외에도 IE 레지스터와 IP 레지스터가 있는데, 이들에 대해서는 후에 다룬다.

8052에서는 INT0와 INT1의 외부 인터럽트 외에도 타이머 2를 보율발생기로 사용할 경우 T2EX(P1.1)를 외부 인터럽트 요청선으로 사용할 수 있다.

타이머 인터럽트는 후술하는 타이머 0 또는 타이머 1에서 오버플로(overflow)가 일어날 때 발생되는 인터럽트이다. 8051의 타이머는 Z80의 타이머와 달리 up-counter이어서, 설정된 값에서부터 up-counting을 하다가 그 내용이 FFFFH가 되고 여기에서 하나 더 카운팅을 하여 0000H가 되면 오버플로가 발생한다.

오버플로가 발생하면 TCON 레지스터의 TF0(timer overflow flag 0) 또는 TF1을 □1□로 세트함으로써 타이머 오버플로가 발생하였음을 나타내는데, 이들 비트는 인터럽트가 서비스될 때, 정확히 말해서 인터럽트 서비스 루틴에 벡터될 때 자동적으로 클리어 된다. 이것은 8051 인터럽트 중 INT0 및 INT1의 에지 플래그 IE0 및 IE1과 함께 예외적인 것이므로 주의를 요한다. 명심할 것은 8052에 있는 타이머2의 TF2와 EXF2 플래그는 인터럽트가 서비스되어도 자동적으로 클리어 되지 않는다는 것이다. 그러므로 타이머2의 이들 플래그는 인터럽트 서비스 루틴에서 명령으로 클리어해 주어야 한다.

직렬포트 인터럽트(RI, TI)는 역시 후술하는 직렬포트에서 수신완료 또는 송신완료를 했을 때 발생되는 인터럽트이다. 직렬포트가 수신완료 또는 송신완료를 하면 CPU는 SCON 레지스터의 해당 비트(RI, TI)를 □1□로 세트함으로써 직렬포트 인터럽트가 요청되어 있음을 나타내고, IE 레지스터의 개별 허용 비트(ES)가 □1□로 세트되고, 전체 허용 비트(EA)가 1로 세트되어 있으면 직렬포트 인터럽트를 발생한다.

SCON 레지스터의 수신 및 송신 플래그  RI 및 TI도 인터럽트가 서비스 될 때 자동적으로 클리어되지 않으므로 역시 인터럽트 서비스 루틴에서 명령으로 클리어해 주어야 한다.

이들 인터럽트에 대한 자세한 것은 타이머 및 직렬포트에서 다룬다.

인터럽트 3요소의 두 번째는 인터럽트 벡터(vector)이다.

앞에서 언급한 바와 같이, 인터럽트 벡터(interrupt vector)는 인터럽트가 CPU에 의해서 인정(acknowledge)될 때 인터럽트 서비스 루틴을 처리하기 위해서 뛰어 가는 주소이다. 좀 더 정확히 말해서 인터럽트 서비스 루틴의 시작번지로 뛰어가라는 JUMP 명령이 들어 있는 번지(address)이다. 예컨대 타이머0 오버플로 인터럽트가 발생하면 프로그램카운터는 0BH로 되어서 프로그램 실행은 0BH 번지로 뛰어가는데, 일반적으로 이 번지에서부터는 실제 인터럽트 서비스 루틴으로 점프하라는 명령이 들어있다. 이때 0BH 번지를 타이머0 오버플로 인터럽트의 인터럽트 벡터라고 한다.

이 관계를 좀 더 자세히 설명하고자 한다. 인터럽트 벡터는 원래 인터럽트 서비스 루틴을 처리하기 위해서 뛰어가는 주소이므로, 이 주소에서부터 인터럽트 서비스 루틴을 두어야 한다. 예컨데 타이머0 오버플로 인터럽트의 경우에는 0BH 번지에서부터 인터럽트 서비

□표 6.1  벡터 주소

인터럽트 소스	인터럽트 벡터	트레인 키트(예) 에서의 벡터 주소
외부 인터럽트 0 타이머 인터럽트 0 외부 인터럽트 1 타이머 인터럽트 1 직렬포트 인터럽트 타이머 인터럽트 2	03H 0BH 13H 1BH 23H 2BH	8003H 800BH 8013H 801BH 8023H 802BH(이것은 8052에만 있음)

스 루틴을 두어야 한다. 그러나 표 6.1과 같이 인터럽트 벡터간의 간격이 8바이트 밖에 되지 않으므로 지극히 간단한 경우를 제외하고는 이곳에 인터럽트 서비스 루틴을 둘 수 없다. 그래서 이곳에는 인터럽트 서비스 루틴으로 뛰어가라는 명령만 두고, 실제 서비스 루틴은 별개의 장소에 둔다. 그러므로, 예컨대 인터럽트 벡터가 0BH이고 실제 서비스 루틴이 8030H부터 있다고 한다면 아래와 같은 명령으로 8030H로 점프하라는 명령을 0BH 번지에서부터 둔다. 이 때 각 번지의 내용은 그림 6.3과 같이 0BH 번지에는 02H(JMP), 그

다음 번지에는 80H, 다시 그 다음 번지에는 30H이다.

ORG  0BH

JMP  TMR0_INT     (단 TMR0_INT라는 라벨은 8030H 번지에 있음)

ROM

0EH	XX
0DH	30
0CH	80
0BH	02(JMP)
0AH	XX

8051의 인터럽트 벡터는 표 6.1과 같이 프로그램 메모리(ROM)의 처음 40 바이트(00H-2BH)에 고정적으로 지정되어 있다. 이들 중 리세트 벡터는 전술한 바와 같이 00H이다. 그러므로 프로그램은 00H번지에서부터 시작된다. 사실은 다음과 같이 이곳에 JUMP 명령을 두어서 실제 프로그램이 들어있는 번지로 뛴다.

ORG	0

JMP	START

＞

START＞	MOV	SP, #70H

그림 6.3  인터럽트 루틴의 시작 번지

03H∼2BH의 이 영역 중 그 프로그램에서 사용되지 않는 부분은 일반 프로그램 메모리 영역으로 사용될 수 있으나, 이 영역에 있는 사용 벡터번지를 덮어쓰는(overwrite) 일이 없도록 주의해야 한다.

마이크로콘트롤러에 따라서는 여러 개의 소스에 하나의 벡터를 할당하는 것도 있지만, 8051에서는 직렬포트 인터럽트, 8052에서는 이것과 타이머 2 인터럽트를 제외하고는 하나의 소스에 하나의 벡터만을 할당한다.

C에서는 인터럽트 벡터를 써 줄 필요없이 예컨대 외부 인터럽트0의 경우 다음과 같이 인터럽트 벡터 번호만 명시해주면 된다.

void  EXT0_int(void) interrupt 0

인터럽트를 제어하는 레지스터에는 앞에서 소개한 TCON 레지스터 외에도 IE 레지스터, IP 레지스터, SCON 레지스터 등이 있는데, 이들 중 TCON과 SCON은 인터럽트 발생 사실을 소스별로 보존하고, IE는 개별 및 전체적으로 인터럽트를 허용(enable)케 하며, IP 레지스터는 각 인터럽트 소스간의 상대적인 우선순위를 규정한다.

그러므로, 인터럽트가 요청되면 요청 발생 사실 그 자체는 TCON 또는 SCON에 기억 보존되고, 이것을 IE 레지스터가 개별 및 전체적으로 허용(enable)시키며, 그 우선순위는 IP 레지스터가 정한다.

그림 6.4는 이들 간의 관계를 나타낸 것이다. 이 그림은 8051 인터럽트의 거의 모든 것을 나타내므로 하드웨어를 이해함에 있어서나 프로그램을 작성함에 있어 필히 참조하기 바란다.

그림 6.4  8051 인터럽트 기능도

6.6.1 IE 레지스터

8051 인터럽트 관련 레지스터들 중 TCON 레지스터는 앞에서 다루었고, IP 레지스터와 SCON 레지스터는 뒤에서 다루므로, 이곳에서는 IE 레지스터만을 설명하기로 한다.

인터럽트 소스로부터 인터럽트가 요청되어도 IE 레지스터(Interrupt Enable Register)의 해당 비트가 클리어되어 있으면 그 인터럽트는 개별적으로 불능(disable)으로 된다. 바꾸어 말해서 이들 인터럽트 소스는 인터럽트가 발생되어도 마치 그것이 발생되지 않은 것처럼 마스크(mask)된다. 이처럼 IE 레지스터의 각 비트는 해당 인터럽트를 개별적으로 허용(enable) 또는 불허(disable)시키는 데 사용된다.

그림 6.5는 IE 레지스터의 내용이다. 8051의 경우 인터럽트 소스가 5개이므로 이들 각각에 해당하는 것이 5개이고(8052에서는 하나가 더 추가된다) 나머지 한개(비트 7)는 EA(Enable All)이다. 이 비트는 CPU가 인터럽트 자체를 받아들일 것인지 그렇지 않을 것인지, 즉 어느 하나라도 인터럽트를 허용할 것인지, 아니면 일체의 인터럽트를 허용하지 않을 것인지를 결정한다. 그러므로, 일체의 인터럽트를 허용하지 않기 위해서는

CLR  IE.7    (C에서는 EA=0)

이라는 명령으로 IE 레지스터의 비트 7을 클리어해야 하고, 단 하나라도 받아들이려면 해당 비트와 함께 이 비트도 세트해야 한다. 예컨대 외부 인터럽트 0를 받아들이려고 한다면 다음과 같이 한다.

그림 6.5  IE 레지스터

SETB  IE.7  (C에서는 EA=1)  ; 전체적으로 허용

SETB  IE.0  (C에서는 EX0=1) ; 개별적으로 허용

이 두 명령은 다음과 같은 하나의 명령으로 대체할 수 있다.

MOV  IE,#10000001B (C에서는 IE=0x81)

IE 레지스터는 앞에서 논한 바와 같이, 어느 인터럽트 소스로부터 인터럽트 요청을 받아드릴 것인지, 아니면 마스크해 버릴 것인지를 결정한다. 이것을 스위치로 표현하면 그림 6.4와 같다. 개별적으로 마스크되면 개별 스위치가 열려 있는 것과 같고, 전체적으로 마스크되면 전체 스위치가 열려 있는 것과 같기 때문이다. 전체 마스크 비트 EA는 모든 인터럽트 소스에 점선으로 연결된 스위치이다.

인터럽트 3요소의 마지막은 우선순위이다. 전술한 바와 같이, 우선순위(priority)란 2개 이상의 인터럽트가 동시에 요청되는 경우 어떤 것부터 서비스를 해 주느냐의 문제이다.

원래 컴퓨터에서 우선순위를 정하는 방법에는 Daisy-chain과 같은 하드웨어 방법과 polling과 같은 소프트웨어 방법이 있는데, 8051에서는 주로 후자의 방법에 의한다.

모든 명령의 마지막 사이클에서 CPU는 인터럽트가 요청되어 있는지 인터럽트 소스를 하나하나 조사한다고 앞에서 언급했는데, 인터럽트 우선순위 문제는 결국 이 때 어느 것부터 조사하느냐의 문제이다.

이들 우선순위를 효과적으로 정의하기 위해서 8051에서는 IP 레지스터(Interrupt Priority register)를 두고 이를 통하여 인터럽트를 높은 레벨 인터럽트와 낮은 레벨 인터럽트로 나눈다. 즉 이 레지스터의 해당 비트를 1로 세트하면 그 인터럽트는 높은 레벨이 되고, 0으로 클리어하면 낮은 레벨이 되는데, 높은 레벨의 인터럽트와 낮은 레벨의 인터럽트가 동시에 요청을 하면 높은 레벨의 인터럽트를 먼저 처리한다. 문제는 같은 레벨의 인터럽트가 동시에 2개 이상 요청되면 어떻게 하는냐에 있다. 이것은 하드웨어에 의해서 그 순위가 정해진다. 같은 레벨의 인터럽트끼리는 하드웨어에 의해서 표 6.2와 같이 정해져 있다. 즉 IP 레지스터의 해당 비트가 1인 것들끼리 또는 해당 비트가 0인 것들끼리의 polling 순서는 다음 표와 같이 외부 인터럽트 0, 타이머 인터럽트 0, 외부 인터럽트 1, 타이머 인터럽트 1, 직렬포트 인터럽트의 순서가 되도록 하드웨어에 의해서 정해져 있다.

□표 6.2  인터럽트 우선순위

인터럽트 소스	우선 순위
외부 인터럽트 0 타이머 인터럽트 0 외부 인터럽트 1 타이머 인터럽트 1 직렬포트 인터럽트 타이머 인터럽트 2	1 2 3 4 5 6(8052의 경우)

그림 6.6은 IP 레지스터의 비트 구성이다. 대체로 IE 레지스터의 순서와 같다. 이 레지스터의 특정 비트를 세트시키는 명령은 역시 SETB이다.

외부 인터럽트 0을 높은 레벨로 하는 명령

SETB  IP.0(C에서는 PX0=1, 또는 IP=0x01)

타이머 인터럽트 1을 높은 레벨로 하는 명령

SETB  IP.3(C에서는 PT1=1, 또는 IP=0x08)

그림 6.6  IP 레지스터

이것은 인터럽트 처리 중에 또다른 인터럽트가 발생하는 경우에 이것을 어떻게 하느냐의 문제이다. 즉 어떤 인터럽트가 발생하여 그 인터럽트를 처리하고 있는 중에 별개의 인터럽트가 발생하는 경우에는 이를 어떻게 처리하느냐의 문제이다.

8051에서는 IP 레지스터의 해당 비트를 1로 세트시킴으로써 높은 레벨의 인터럽트로 할 수도 있고, 0인 상태로 놓으므로써 낮은 레벨의 인터럽트로 할 수도 있다함은 앞에서 논하였다.

① 높은 레벨의 인터럽트, 즉 IP 레지스터의 해당 비트가 1로 되어 있는 인터럽트를 처리하고 있는 중에 또 다른 인터럽트가 발생하면 새로 발생된 인터럽트가 높은 레벨의 인터럽트이든 낮은 레벨의 인터럽트이든 관계없이 새로운 인터럽트는 무시된다.

② 낮은 레벨의 인터럽트를 처리하고 있는 중에 높은 레벨의 인터럽트가 발생하면 그림 6.7과 같이 낮은 레벨의 인터럽트를 일단 중단하고 높은 레벨의 인터럽트를 처리한다. 물론 높은 레벨의 인터럽트를 처리한 후에는 중단된 낮은 레벨의 인터럽트 루틴에 복귀한다.

③ 낮은 레벨의 인터럽트를 처리하고 있는 중에 역시 낮은 레벨의 인터럽트가 발생하면 polling 순서와는 관계없이 무시된다.

결국 8051에 있어서는 낮은 레벨의 인터럽트를 처리하고 있는 중에 높은 레벨의 인터럽트가 발생되는 경우에 한해서 다중 인터럽트가 인정된다.

그림 6.7  다중 인터럽트 처리 과정

8051 인터럽트에 있어서는 인터럽트 처리중 프로그램카운터(PC)의 내용만은 자동적으로 스택에 보존(save)되지만, PSW, ACC, B, DPTR 등의 내용은 그렇지 못하다. 그러므로 이들은 필요한 것만을 골라 명령으로 보존해야 한다. 다음 부분 프로그램은 이들 모두를 보존시키는 부분 프로그램이다.

ORG   00H

JMP   START

ORG	03H

JMP	INT0_SERV

START＞	MOV   A,#0FFH

＞

INT0_SERV＞	PUSH	PSW

PUSH	ACC       ; A가 아니고 ACC임에 유의하기 바란다

PUSH	B

PUSH	DPL

PUSH	DPH

…	……

…	……

POP	DPH

POP	DPL

POP	B

POP	ACC

POP	PSW

RET1

그림 6.8은 PSW, Acc, B, DPTR 등의 내용이 스택에 저장되어 있는 모양이다. 이들 중 Acc의 푸시(PUSH)는 각별한 주의가 필요하다. 경우에 따라서는 이를 사용함으로써 원하

그림 6.8  PSW, ACC, B, DPTR등의 내용이 스택에 저장되어 있는 모양

는 작업이 이루어지지 않기 때문이다. 예컨대 RL A의 작업을 인터럽트 루틴에서 할 때 PUSH ACC를 하면 전번 상태에서부터  RLA가 이루어지지 않기 때문에 실제 RL A가 되지 않는다.

인터럽트 요청이 서비스되기 위해서는 먼저 다음의 조건이 갖추어져 있어야 한다.

·EI 명령에 의해서 인터럽트 처리가 □전체적으로 허용□ 되어 있어야 한다(IE 레지스터)

·해당 인터럽트가 □개별적으로 허용□ 되어 있어야 한다(IE 레지스터)

·동시에 2개 이상의 인터럽트가 요청될 경우를 위하여 해당 인터럽트 레벨의 우선순위가 가장 높아야 한다(IP 레지스터)

이상의 조건이 갖추어져 있는 상태에서 인터럽트 소스로부터 인터럽트 요청에 상당하는 사건이 발생하면 그 요청은 CPU에서 인정(acknowledge)되어, 인터럽트 레벨에 상응하는 인터럽트가 처리중이라는 것을 내부적으로 나타내는 □priority level active□라는 플립플롭을 세트시키고 인터럽트 서비스루틴을 부르기 위한 하드웨어 서브루틴 콜(hardware subroutine call)을 실행한다. 이 하드웨어 서브루틴 콜에 의해서 CPU는 다음과 같은 일련의 인터럽트 처리 과정을 밟는다.

① CPU는 현재 실행중인 명령(경우에 따라서는 그 다음 명령까지)만은 마친후, 에지 트리거 외부 인터럽트의 경우에는 에지 플래그(IE0, IE1), 그리고 타이머의 경우에는 타이머 오버플로 플래그(TF0. TF1)를 클리어 한다(RI, TI, TF2, EXF2 등은 CPU가 클리어하지 않으므로 사용자가 인터럽트 처리루틴에서 명령으로 클리어해 주어야 한다).

② 프로그램카운터의 내용을 스택에 보존한다. 제3장에서 언급한 바와 같이, 보존할 스택의 위치를 지시하는 레지스터를 스택포인터(Stack pointer)라고 하는데, 8051에서는 리세트후에 이 레지스터의 내용이 07H로 되므로(default) 레지스터 뱅크 1을 사용할 경우에는, 예컨데 다음과 같은 명령으로 스택의 위치를 다른 곳으로 옮겨 놓아야 한다. 그러나 C로 프로그램할 경우에는 컴파일러가 적당히 배치하므로 이를 의식할 필요가 없다.

MOV   SP, #70H

③ 이 일을 마친 후에는 인터럽트를 요청한 장치에 서비스하기 위해서 인터럽트 처리 프로그램, 즉 인터럽트 서비스 루틴의 시작 번지가 들어 있는 주소로 점프한다. 앞에서 언급했듯이, 인터럽트 서비스 루틴의 시작 번지로 점프하는 명령이 들어 있는 주소를 인터럽트 벡터 또는 벡터 주소(Vector address)라고 하는데, 8051의 경우에는 인터럽트 소스에 따라 이것이 표 6.1과 같이 고정되어 있다.

인터럽트 벡터는 인터럽트 서비스 루틴의 시작번지로 점프하는 명령이 들어 있는 주소이므로, 그림 6.3과 같이 실제로 인터럽트 서비스 루틴이 시작되는 곳은 벡터주소가 지정하는 곳이다. 예컨대 INT0에 대한 벡터는 03H 번지인데 03H∼05H 번지의 내용이 JMP INT0_INT라고 되어 있으면 INT0_INT라는 라벨이 붙어있는 번지(예컨대 2100H 번지)가 실제 인터럽트 서비스 루틴이 시작되는 곳이다. 이 곳에서부터 인터럽트 서비스 루틴을 수행한다.

④ 인터럽트 루틴의 마지막에는 반드시 인터럽트로 부터의 복귀 명령인 RETI (Returm from Interrupt)가 있고, 인터럽트 처리중 이 명령을 만나면 스택에 push했던 프로그램카운터의 내용을 pop하여 원상 회복시킨다.

⑤ 그런 다음 인터럽트 발생전의 프로그램, 즉 메인 루틴에 복귀하여 중단된 명령어 다음의 명령어부터 프로그램의 수행을 속행한다.

이상에서 설명한 8051 인터럽트 처리 과정을 그림으로 나타내면 그림 6.9와  같다. 독서 중에 전화가 걸려 오면 하는 일과 비교해 놓았으니 참조하기 바란다.

그림 6.9  인터럽트 처리 과정

그림 6.10은 인터럽트 응답시간을 나타내고 있다. INT0 및 INT1에서 인터럽트 요청이 있으면, 즉 이들 핀의 논리레벨이 0으로 바뀌거나(에지) L레벨로 되면 이것은 기계사이클의 IS5P2에서 내부 홀딩레지스터에 래치되고, 다음 기계사이클에서 어느 홀딩레지스터에 래치되어 있는가를 폴링한다. 그리고는 인터럽트 인정에 필요한 조건들이 갖추어져 있으면 요구된 서비스 루틴을 실행하기 위해서 하드웨어 서브루틴 콜(hardware subroutine call)을 실행한다.

그런데 내부 홀딩레지스터에 인터럽트 요청이 래치되고 나서 하드웨어 서브루틴 콜에 들어가기까지는 적어도 14클록 사이클이 필요하다. 그러므로 현재 실행중인 명령의 나머지 시간이 14클록 사이클 이상인 경우에는 현재 실행중인 명령만을 마치고 하드웨어 서브루틴 콜에 들어가지만, 그러지 않는 경우에는 현재 실행중인 명령은 물론 다음 명령까지도 마친 다음에 하드웨어 서브루틴 콜에 들어간다. 하드웨어 서브루틴 콜이 실행되면 앞에서 설명한 순서에 따라 인터럽트 처리 과정을 밟는다.

그림 6.10  인터럽트 응답시간

6.12.1  외부 인터럽트에 의한 LED 이동

(1) 目 的

그림 6.11과 같이 INT0(P3.2)에 푸쉬버튼 스위치가 연결되어 있다. 이 스위치를 누를 때마다 포트 1에 연결된 LED가 하나씩 이동하도록 하고자 한다.

단, 최초로 스위치를 누르기 전에는 P1.0에 연결된 LED에 불이 켜져 있다.

그림 6.11  INT0의 인터럽트 실험

(2) 順序圖

그림 6.12  외부 인터럽트에 의한 LED 이동 순서도

(3) 프로그램(EX6_1.C)

/*==========================================*/

/* PROGRAM EX6_1.C) [EXTERNAL INTERRUPT]    */

/*==========================================*/

#include <reg51.h>	/* 8051 헤더 파일의 include */

unsigned char number;	/* number는 8비트 변수 */

void delay (int i) {	/*지연루틴*/

while (i--);

}

void EXT0_int(void) interrupt 0	/* 벡터넘버 0의 인터럽트 루틴 */

{

EA = 0;	/* 인터럽트 disable*/

P1 = number;	/* number의 내용을 포트1에 출력한다.*/

delay (0xffff);

number = (number << 1 □ 1);

/*number의 내용을 좌로 쉬프트하고, 쉬프트해 간 비트 0에는 1로 채운다.*/

if (number == 0xff) number=0x0fe;/* number=FFH이면 초기 상태로 */

EA =1;	/* 인터럽트 enable */

return;

}

void main(void)	/* 메인 함수 */

{

EX0 = 1;	/* EX0=IE.0, 개별적으로 허용 */

EA = 1;	/* EA=IE.7, 전체적으로 허용 */

PX0 = 1;	/* PX0=IP.0, 우선순위를 high로 */

IT0 = 0;	/* IT0=TCON.0, L-레벨 트리거를 선택 */

number = 0xfe;	/* 최초의 출력 데이터 */

p1 = number;

while(1);	/* 여기서 인터럽트를 기다린다 */

}

(4) 프로그램의 解說(C)

void EXT0_int(void) interrupt 0

EXT0_int라는 함수가 인터럽트 벡터넘버 0의 인터럽트임을 밝히고 있다. 인터럽트 벡터넘버는 표 6.3과 같이 외부인터럽트 0이 0, 타이머 인터럽트 0이 1, 외부인터럽트 1이 2, 타이머 인터럽트 1이 3, …의 값을 가진다.

□표 6.3  인터럽트 벡터넘버

인터럽트 소스	벡터넘버
외부 인터럽트 0 타이머 인터럽트 0 외부 인터럽트 1 타이머 인터럽트 1 직렬포트 인터럽트 타이머 인터럽트 2(8052의 경우)	0 1 2 3 4 5

SETB	EX0 = 1;

SETB	EA = 1;

SETB	PX0 = 1;

SETB	IT0 = 0;

IE 레지스터, IP 레지스터, TCON 레지스터 등을 설정한 것이다. 인터럽트가 발생되기 위해서는 IE 레지스터에 의해서 그 인터럽트가 개별적으로, 전체적으로 허용되어야 하고, IP 레지스터에 의해서 우선순위가 최고가 되어야 하기 때문이다. IT0=0은 INT0이 L레벨에서 동작하도록 하기 위함이다. 이들 명령은 다음과 같이 할 수도 있다.

IEＡ0x81;

IPＡ0x01;

TCONＡ0x00;

EA = 0;

□

EA = 1;

인터럽트 서비스 루틴을 수행하는 중에 또 다른 인터럽트가 발생되는 것을 방지하기 위한 조치이다. 이 조치가 없어도 본 프로그램에 관한한 그런 위험은 없지만 인터럽트 루틴에서는 항상 이런 조치를 하는 습관을 길러 두어야 한다.

if (number == 0xff) number = 0xfe;

변수 number의 내용이 0FFH이면 최초의 상태 0FEH로 되돌아가라는 것이다.

(5) 프로그램의 實行

제4장에서 설명한 방법에 따라 □Vision에서 open proiect와 edit project 작업을 통하여 프로젝트와 프로그램을 지정한 후, build project 작업을 통하여 어셈블 또는 컴파일 그리고 링크를 한다. 이로써 Hex file과 OBJ file이 생기므로, 이를 시뮬레이트할 수도 있고 실제 시스템 또는 트레인키트에 다운로드하여 실행시킬 수도 있다.

시뮬레이트를 하기 위해서는 시뮬레이터 dScope로 들어가서 프로젝트를 지정한 후, pheripheral에서 먼저 포트 1과 포트 3을 택한다. 포트 3 대신 interrupt의 P3.2/INT0#를 택해도 된다. 이제 툴바 4번째에 클릭하고 다시 Go에 클릭한 다음 포트 3의 P3.2에 클릭을 하면 클릭 할 때마다 포트 1의 상태가 바꿔짐을 확인할 수 있을 것이다. 원칙대로 한다면 핀 INT0(P3.2)에 L-레벨 트리거 신호를 외부에서 주어야 하나 시뮬레이터에서는 그것이 불가능하므로 pins P3.2를 클릭하는 것이다.

실제 시스템에서는 □Vision에서 만든 Hex file을 ROM라이터로 8751 또는 AT89S51 또는 AT89C2051에 다운로드한다. 그런 다음 그림 6.11과 같은 시스템에 꽂는다.

디지털제어 산업기사 8051 MICOM 보드에 실행시키고자 하면 □Vision에서 Hex 파일을 만들고, MICOM PROGRAMMER에서 □열기□와 □자동□을 통하여 MICOM 보드에 기록한다.

(6) 課 題

1. 위 프로그램에서는 L-레벨 트리거를 사용하였다. 에지 트리거를 사용하도록 프로그램을 고쳐보라(힌트 IT0=1. 인터럽트 루틴에서는 IE0=0).

2. INT0 인터럽트 대신 INT1 인터럽트로 위에서 같은 일을 하도룩 프로그램을 수정하라.

6.12.2 인터럽트 플래그에 의한 LED 이동

(1) 目  的

앞에서와 동일한 일을 하되, 인터럽트 그 자체를 이용하지 않고 인터럽트 플래그를 사용하여 수행하고자 한다.

(2) 順序圖

그림 6.13  인터럽트 플래그에 의한 LED 이동 순서도

(3) 프로그램 (EX6_2.C)

/*===================================================*/

/* PROGRAM EX6_2.C) [EXTERNAL INTERRUPT BY FLAG]	*/

/*===================================================*/

#include <reg51.h>	/* 8051 헤더 파일 */

unsigned char number;	/* number, flagＡ8비트 변수 */

void delay (long i) {	/*지연루틴*/

while (i--);

}

void main(void)  {	/* 메인 함수 */

EX0 = 1;	/* EX0ＡIE.0, 개별 허용 */

EA = 0;	/* EAＡIE.7, 전체 disable */

IT0 = 1;	/* IT0ＡTCON.0, 에지 트리거 */

P1 = 0xfe;	/* 최초의 LED 상태 */

number = 0xfe;	/* 최초의 출력 데이터 */

do {

while(％IE0);	/* 인터럽트 플래그가 세트되기를 기다린다 */

IE0 = 0;	/* IE0ＡTCON.1, yes이면 플래그를 클리어 */

number = (number << 1) □ 1;         /* 다음 차례의 출력데이터를 준비 */

if(number == 0xff) number = 0xfe;  /*LED7도 on되었으면 초기상태로 */

P1 = number;	/* 출력데이터를 포트 1에 출력 */

delay (0x1ffff);	/* 지연 */

}while(1);

}

(4) 프로그램의 解說

EX0 = 1;

EA = 0;

EX0는 IE.0로서 EX0=1;은 INT0 인터럽트를 개별적으로 허용시키는 명령이다. 인터럽트 플래그를 이용하고 있으므로 이 조치는 필요없지 않겠느냐는 의문이 일 것이다. 인터럽트 플래그는 인터럽트 허용 비트와는 무관하게 세트되기 때문이다. 그러나 8051은 그러지 않지만, 프로세서에 따라서는 개별 허용 비트를 세트시키지 않으면 플래그가 세트되지 않는 마이크로콘트롤러도 있으므로 인터럽트 플래그를 이용하는 경우에도 개별 허용 비트만은 세트시켜 두는 것이 안전하다. 물론 전체 허용 비트는 클리어시킨다. 다시 말하지만 8051에서는 이 명령이 필요없다.

while (％IE0);

＞

IE0 = 0;

IE0는 TCON.1로서 에지 인터럽트 플래그이다. 레벨 플래그는 없다는 것에 유의해야 한다. 아무튼 이 비트가 세트되기를 기다리고 있는 명령이다. 인터럽트 대신 이 플래그를 이용하고 있다.

에지 인터럽트 플래그 IE0가 세트되기를 기다리다가 세트가 되면 이번에는 반드시 그 플래그를 클리어해야 한다. 인터럽트의 경우가 아니므로 자동적으로 클리어되지 않기 때문이다.

(5) 課 題

제4장에서 설명한 방법에 따라 위 프로그램을 □Vision에서 Edit project하고 build project하여 Hex file과 OBJ file을 만든다. 시뮬레이트하고자 할 경우에는 dscope에서 port1과 port3를 열어놓고 첫 번째 툴바에서 project 확인을 하고 4번째 툴바에서 Go한 다음 핀 P3.2에 클릭하든지, pheripheral interrupt의 P3.2/INT0#에서 IE0에 클릭한다. 이 때마다 P1의 상태가 바꿔짐을 확인하라.

6.12.3 자동낚시

(1) 目 的

그림 6.14는 자동 낚시 시스템으로서, 고기가 물어서 릴대가 휘면 리드가 어스선에 접촉되고, 그래서 핀  INT1이 0V로 되면 P1.1에 0.3초 정도의 펄스를 주어서 솔레노이드 밸브의 철심을 잡아당기고 이에 연결된 릴대(또는 낚시줄)를 짧게 채어서 고기를 뀌기 위한 것이다. 이러한 시스템을 동작시키는 프로그램을 작성하고자 한다.

그림 6.14  자동 낚시 시스템

(2) 順序圖

그림 6.15 자동낚시 순서도

(3) 프로그램(EX6_3.C)

/*====================================*/

/* PROGRAM EX6_3.C) [AUTO FISHING]   */

/*====================================*/

#include <reg51.h>	/*8051 헤더파일의 include */

void delay(int i)  {	/* 지연 함수 */

while(i--);

}

void EXT1_int(void) interrupt 2 {	/* 인터럽트 벡터넘버 2의 루틴 */

EA = 0;	/* 인터럽트 disable*/

IE1 = 0;	/* 에지플래그의 클리어*/

P1 □ = 0x02;	/* 솔레노이드 밸브 on*/

delay(0xd800);	/* 0.3초 지연 */

P1 &= 0xfd;	/* 솔레노이드 밸브 off*/

EA =1;	/* 인터럽트 enable */

return;

}

void main(void)  {

EX1 = 1;	/* INT1 인터럽트 개별 enable */

EA = 1;	/* 전체 enable */

PX1 = 1;	/* 우선순위를 high로 */

IT1 = 1;	/* 에지트리거 선택 */

P1 = 0;	/* 초기값 */

while(1);	/* 인터럽트 대기 */

}

(4) 프로그램의 解說

P1 □ = 0x02;

delay(0xd800);

P1 &= 0xfd;

P1.1을 세트시켜 솔레노이드 밸브를 동작시키고, 0.3초 후에 이를 클리어하여 동작 상태를 멈추게 한 것이다. P1=0xfd 대신 P1=0로 해도 되나, 11111101과 AND시켜 줌으로써 다른 비트에는 영향을 주지 않으면서 비트 1만 클리어시켜 준 것이다. 이 프로그램에 관한 한 그러게 하지 않아도 되지만, 복잡한 프로그램에서는 항상 이런 방법으로 다른 비트에 영향을 미치지 않도록 해야 한다.

(5) 프로그램의 實行

역시 □Vision에서 edit project와 build project 작업을 함으로써 Hex file과 Obj file을 만든다.

시뮬레이트를 하고자 하면, dScope에서 pheripheral의 P1과 P3를 열어 둔 다음(이미 열어져 있으면 생략), 프로젝트를 불러오고 GO한다. P3.3에 클릭을 하면 P1.1이 0.3초 동안 on 상태가 됨을 볼 수 있을 것이다.

실제 시스템이나 트레인키트에 실행하고자 하면 OBJ file을 다운로드하여 실행시킨다.

목적과 그림을 보면 거창한데 프로그램이 간단해서 실망하겠지만, 뭐든 아이디어와 원리가 중요하지 그 실현은 쉬울 수도 있다. 물론 이 정도의 것이야 간단한 기계장치로도 가능하고, 또 현재 실용되고 있지만, 마이크로콘트롤러로 구현하는 하나의 예로서 넣은 것이다.

6.12.4 화재 감시 장치

(1) 目 的

그림 6.16은 간이형 화재 감시 시스템으로서, 화재가 나서 온도가 오르면 바이메탈의 리드 핀이 어스핀에 접촉되어 핀  INT1(P3.3)이 0V로 된다. 이것이 8051 CPU에 의해서 감지되면 0.2초 간격으로 집 경보기와 소방서 경보기를 단속적으로 울리고 스프링쿨러의 열선에 전류를 흘려 납을 녹임으로써 탱크 물이 쏟아지도록 되어 있다. 실은 8051이 공급하는 전류로 납을 녹일 수는 없고 제9장에서 소개하는 그림 9.5와 같은 회로에 의해서 8051은 릴레이만을 구동하고 이에 연결된 200V 교류전원이 납(납 주석 함금)을 녹인다.

그림 6.16  화재감시 시스템

(2) 順序圖

그림 6.17  화재감시 순서도

(3) 프로그램(EX6_4.C)

/*==========================================*/

/* PROGRAM EX6_4.C) [FIRE ALARM SYSTEM]    */

/*==========================================*/

#include <reg51.h>	/* 8051 헤더파일의 include */

void delay(int i) {	/* 지연 함수 */

while(i--);

}

void EXT1_int(void) interrupt 2 { /* 벡터넘버 2의 INT1 인터럽트 */

EA = 0;	/* 인터럽트 disable*/

IE1 = 0;	/* 에지플래그를 클리어한다 */

P1 □ = 0x04;	/* 스프링쿨러 on*/

do {

P1 □ = 0x01;	/* 집 부저 on*/

P1 □ = 0x02;	/* 소방서 부저 on*/

delay(0x9000);	/* 0.2초 지연*/

P1 &= 0xfe;	/* 집 부저 off*/

P1 &= 0xfd;	/* 소방서 부저 off*/

delay(0x9000);	/* 0.2초 지연*/

}while(1);

EA =1;	/* 인터럽트 enable */

return;

}

void main(void)

{

EX1 = 1;	/* INT1 인터럽트 개별 enable */

EA = 1;	/* 전체 enable */

PX1 = 1;	/* 우선순위를 high로 */

IT1 = 1;	/* 에지트리거를 선택 */

P1 = 0;	/* 초기값 */

while(1);	/* 인터럽트 대기 */

}

(4) 프로그램의 解說

delay(0x9000);

제4장 마지막에서 다룬 방법에 따라 0.2초의 지연을 얻고 있다. 어셈블리어 단위의 코드에서 0.2초를 얻는 수식은 앞에서도 언급한 바와 같이 발진주파수Ａ22.1184MH일 때 (2561[eqn: x]+2)*0.5425=200,000이고, 여기서 [eqn: x]Ａ90H를 얻는데, 이것이 R6값이고, 이것은 R7Ａ00H (256)임을 전제로 하므로 delay(0x9000)이다.

P1 □ = 0x04;           /* P1.2 = 1 */

do {

P1 □ = 0x01;    /* P1.0 = 1 */

＞

P1 &= 0xfe;     /* P1.0 = 0 */

＞

} while(1);

P1.0과 P1.1은 0.2초 간격으로 on-off를 반복하는데도 P1.2는 계속 on하고 있는데, 이것은 스프링쿨러에 공급하는 전류는 계속해서 공급되어야 하기 때문이다. 어느 비트를 1로 세트하기 위해서는 OR 연산을 하고, 어느 비트를 0으로 클리어 하기 위해서는 AND 연산을 함에 다시 한번 유의하기 바란다.

(5) 프로그램의 實行

□Vision에서 edit project와 build project 작업을 함으로써 Hex file과 Obj file을 얻는다.

시뮬레이트의 경우에는, dScope에서 peripheral의 port1과 port3을 열어 놓은 다음(이미 만들어져 있으면 생략), project를 지정 호출하고 Go한다. P3.3에 클릭하면 화재가 나서 인터럽트가 발생되는 것으로 되어 P1.2∼P1.0에 소정의 긴급조치가 이루어진다.

실제 시스템에서 실험하고자 하면 8751이나 AT89C2051에 Hex 파일을 ROM 라이트로 기입한 후 6.16과 같은 시스템에 꽂은 다음 P3.3을 살짝 어스시킨다.

디지털제어 산업기사 8051 MICOM 보드에 실현시키고자 하면 역시 □Vision에서 만든 Hex 파일을 MICOM PROGRAMMER의 □열기□와 □자동□으로 MICOM 보드에 기록해 넣는다.

(6) 課 題

P1.7에 연결되 푸시버튼을 누르면 인터럽트 루틴에서 빠져 나올 수 있도록 위 프로그램을 수정하라 (힌트 : 인터럽트 루틴에서 포트 1을 읽어서 P1.7=0이면 RETI하도록 한다.)

1. 인터럽트란 외부 또는 내부로부터의 긴급 서비스 요청에 의하여 CPU가 현재 실행중인 일을 중단하고 그 요청에 합당한 서비스를 해주는 기법(technique)이다.

2. 8051의 인터럽트 소스에는 외부 인터럽트 2개, 타이머 인터럽트 2개, 직렬포트 인터럽트 1개 등 5개이다. AT89C2051의 경우에도 같다. 8052에는 타이머 2 인터럽트가 하나 더 추가된다.

3. 인터럽트 벡터는 인터럽트 발생시 뛰어가는 곳으로, 일반적으로 이곳에는 인터럽트 서비스 루틴의 시작번지로 점프하는 명령이 들어 있다.

4. 일반적으로 인터럽트에 관계되는 레지스터에는 TCON, IE, IP, SCON 등이 있다. TCON과 SCON은 인터럽트 발생 사실을 소스  단위로 보존하고,  IP는 각 인터럽트 소스간의 상대적인 우선순위를 규정하고, IE는 각 인터럽트를 개별 및 전체적으로 허용 또는 불허한다.

5. 인터럽트 처리 과정은 독서 중 래전에 유사하다. IE 레지스터에 의해서 인터럽트가 전체적으로 허용되고, 개별적으로 허용되고, IP 레지스터에 의해서 우선순위가 최고인 가운데 인터럽트가 발생하면 에지 트리거 외부 인터럽트의 경우에는 IE0/IE1을, 타이머 인터럽트의 경우에는 TF0/TF1을 클리어 한 후, PC의 내용을 스택에 push한다. 그런 뒤에 인터럽트 벡터로 뛰어가서, 그곳에 있는 JUMP 명령에 따라 인터럽트 서비스 루틴으로 뛰어가서 그 루틴을 수행한다. 수행 중 RETI를 만나면 PC의 내용을 스택에서 POP한 후 메인 프로그램에 복귀하여 중단된 프로그램을 속행한다.

6. 인터럽트 우선순위는 2개 이상의 인터럽트가 동시에 발생하는 경우 어느 것부터 먼저 서비스를 해 주느냐의 문제인데, 8051에서는 그 우선순위를 IP 레지스터를 통하여 정한다. 같은 레벨의 우선순위는 하드웨어에 의해서 정해진다.

7. 다중 인터럽트란 인터럽트 처리 중에 또 다른 인터럽트가 발생하면 어떻게 하느냐의 문제로서, 8051의 경우에는 낮은 레벨의 인터럽트를 처리하고 있는 중에 높은 레벨의 인터럽트가 발생되는 경우에 한해서 일정의 절차를 밟아서 높은 레벨의 인터럽트를 먼저 처리하도록 되어 있다.

6.1 다음 입·출력 방식 중 CPU가 가장 많이 관여해야 하는 방식은?	(전산기조직응용)

㉮ interrupt I/O	□ programmed I/O

□ DMA	㉱ isolated I/O

6.2 입·출력 기기의 준비와 동작이 완료되는 것을 프로그램에 의해 확인한 다음 데이터의 입·출력을 행하는 입·출력 제어방식으로 Waiting Loop 방식이라고도 하는  것은?	(전산기조직응용)

㉮ Memory Mapped I/O	㉯ Isolated I/O

㉰ Programmed I/O	㉱ Interrupt I/O

6.3 System과 외부장치 사이의 데이터 전송이 아닌 것은 어느 것인가?	(전산기조직응용)

㉮ DMA	□ Interrupt I/O

□ Program I/O	㉱ RAM

6.4 마이크로컴퓨터와 입·출력 기기와의 데이터 전송의 제어방식이 아닌 것은?(전산기 조직응용)

□ 프로그램드 I/O	㉯ 가로채기 I/O

㉰ 직접 메모리 액세스(DMA)	㉱ 메모리 맵(MAP)

6.5 CPU가 어떤 작업을 하고 있는 중에 외부로부터의 요구가 있으면 그 작업을 잠시 중단하고 요구된 일을 처리한 후에 다시 원래의 작업으로 되돌아오는 기능을 무엇이라 하는가?(전산기 조직응용)

㉮ DMA	㉯ 인터럽트(interrupt)

㉰ 時分割(time sharing)	㉱ 서브루틴(subroutine)

6.6 한 CPU에 여러 개의 입출력장치가 연결되었을 때 입출력장치가 자기의 상태를 CPU에게 알려주는 방식은?	(전산기 기사)

㉮ Spooling	㉯ Interrupt

㉰ Polling	㉱ Searching

6.7 인터럽트 발생 요인이 아닌 것은?	(전산기조직응용)

㉮ 정전	㉯ 입·출력

㉰ 에러(error)의 발생	㉱ 서브루틴 콜

6.8 컴퓨터가 어떤 프로그램을 수행 중 인터럽트 요구가 발생하면 가장 먼저 취하는 동작은?	(전산기조직응용)

㉮ 즉시 인터럽트 서비스 루틴으로 Jump한다.

㉯ 모든 동작을 일시에 중지한다.

㉰ 현재의 수행 중인 명령을 끝내고 현재 상태를 보관한다.

㉱ 컴퓨터는 Help Sign을 보낸다.

6.9 인터럽트가 발생될 경우 CPU가 반드시 해야 할 일이 아닌 것은?

㉮ 현재 실행중인 명령을 마친다.

㉯ 프로그램카운터의 내용을 스택에 보존한다.

㉰ CPU 내부의 레지스터 내용들을 모두 스택에 보관한다.

㉱ 인터럽트 발생원을 조사한다.

6.10 인터럽트 요청시 마이크로프로세서가 다음에 수행할 명령을 찾는 방법으로 적절하지 못한 것은?

(전산기조직응용)

㉮ 스택에서 명령어의 주소를 가져온다.

㉯ 인터럽트를 요청한 장치에서 명령어의 주소를 가져온다.

㉰ 미리 지정된 일정한 주소에서 명령어를 가져온다.

㉱ 미리 지정된 일정한 주소에서 명령어의 주소를 가져온다.

6.11 인터럽트 서비스 루틴에서 할 필요가 없는 것은?	(전자계산기)

㉮ 모든 processor register의 내용을 기억시킨다.

㉯ 어느 flag가 세트되어 있는지 확인한다.

㉰ 되돌아 갈 주소(return address)를 기억시킨다.

㉱ 기억시켜 둔 processor register의 내용을 복귀시킨다.

6.12 인터럽트 사이클의 마이크로 동작을 설명한 것으로 옳지 않은 것은?	(전자계산기)

㉮ 스택 포인터의 증가

㉯ 프로그램카운터를 스택에 푸시(push)

㉰ 인터럽트 승인 응답의 활성화

㉱ 벡터 번지를 MBR(memory buffer register)에 전송

6.13 인터럽트가 발생될 여지가 없는 것은?

㉮ 입출력 채널(I/O channel)이 끝났을 때

㉯ 서브프로그램에서 에러(error)가 발생했을 때

㉰ 어떤 수를 나누는 과정에서 분모가 0일 때

㉱ 2의 보수의 오버플루(overflow)가 발생했을 때

6.14 다음 중 polling에 대한 바른 설명은?	(전산기조직응용)

㉮ 입·출력 port로부터 interrupt를 처리하는 하드웨어적인 방법이다.

㉯ 인터럽트를 아무 조건 없이 최우선 순위로 할 수 있는 방법이다.

㉰ 주변장치로부터 인터럽트 발생시 어느 곳에서 발생했는지를 조사하는 소프트웨어적인 방법이다.

㉱ daisy chain 방식이라고도 한다.

6.15 인터럽트를 발생한 장치가 CPU에게 분기할 곳의 정보를 제공해 주는 것을 무엇이라고 하는가?

㉮ daisy chain	㉯ polling

㉰ vectored interrupt	㉱ polled interrupt

6.16 인터럽트가 요구되면 인터럽트를 요구한 입·출력 장치에 관계없이 항상 일정한 번지의 인터럽트 서비스 루틴을 처리하는 방식은?	(전자계산기조직응용)

㉮ 우선순위 인터럽트	㉯ 데이지 체인 인터럽트

㉰ 폴링 인터럽트	㉱ 벡터 인터럽트

6.17 인터럽트의 우선순위를 정하는 방법으로서 소프트웨어적으로는 polling방법을 쓰는데, 하드웨어적으로는 어떤 회로를 쓰는가?

㉮ DMA	㉯ daisy chain

㉰ channel	㉱ flip flop

6.18 여러 주변장치에서 동시에 인터럽트가 발생하여 버스에서 신호의 혼돈이 생기는 것을 방지하기 위한 하드웨어적인 방법은?

㉮ polling	㉯ cycle steal

㉰ DMA	㉱ daisy chain

6.19 인터럽트를 발생하는 장치들을 직렬로 연결하는 하드웨어적인 우선순위 제어방식은?

㉮ interface	㉯ daisy chain

㉰ polling	㉮ DMA

6.20 데이지 체인(Daisy chaining) 기법을 바르게 설명한 것은?

㉮ 전압이 높은 입력이 필요한 장치에서부터 낮은 입력의 장치로 순차로 엮는 방식

㉯ 주소가 서로 상충(collision)하는 장치들을 조정하기 위한 기법

㉰ 인터럽트 확인(Interrupt acknowledge) 신호를 우선순위가 제일 높은 장치부터 받게 하는 기법

㉱ 3개 이상의 장치들이 악수식(handshaking) 기법을 사용하는 것

6.21 다음은 daisy chain 인터럽트방식이다. 우선순위가 가장 높은 주변장치는?	(전산기 기사)

㉮ 주변장치 1	㉯ 주변장치 2

㉰ 주변장치 3	㉱ 우선순위는 모두 같다

6.22 인터럽트 요청이 있을 경우 레지스터의 내용을 저장하는 방법 중 옳지 않은 것은?	(전자계산기)

㉮ 메모리의 특정 장소에 저장한다.	㉯ 스택에 저장한다.

㉰ 여분의 레지스터와 내용을 바꾼다.	㉱ 보조기억장치에 저장한다.

6.23 인터럽트 발생시 되돌아 올 주소(return address)를 기억시키는데 사용되는 것은?

㉮ stack	㉯ program counter

㉰ flag	㉱ accumulator

6.24 스택(stack)의 특성을 바르게 설명한 것은?	(전산기조직응용)

㉮ 선입 선출(first in first out) 방식의 구조이다.

㉯ 서브루틴을 호출한 어드레스가 보존된다.

㉰ 레지스터 값의 일시적인 대피 및 복구에도 사용된다.

㉱ 스택 영역은 사용자 프로그램에서 지정할 수 없다.

6.25 Stack과 관계없는 명령어는 어느 것인가.?	(전산기조직응용)

㉮ CALL	㉯ POP

㉰ PUSH	㉱ MOVE

6.26 stack의 번지는 무엇이 지정하는가?	('86 전자계산기 2급)

㉮ Indicator	㉯ Stack Pointer

㉰ Push	㉱ Pop

6.27 8051 stack pointer에 대한 설명 중 올바른 것은?

㉮ CPU 내에 있는 register이다.

㉯ 항상 stack 최하단의 번지를 가리킨다.

㉰ 1 바이트의 데이터를 push할 때마다 1씩 감소한다.

□ 1 바이트의 데이터를 pop할 때마다 1씩 증가한다.

6.28 Z80 마이크로프로세서에서 스택포인터가 200번지를 가리키고 있다. 3바이트의 내용을 스택에 push하면 스택 포인터는 몇 번지를 가리키는가?	(전산기조직응용)

㉮ 197번지	㉯ 198번지

㉰ 199번지	㉱ 202번지

6.29 Program 수행 중 서브루틴(subroutine)으로 돌입한 프로그램의 리턴 번지(return address)를 LIFO(last in first out) 기술로 메모리의 일부에 저장한다. 이 메모리 부분을 무엇이라 하는가?	(전산기조직응용)

㉮ 주기억장치(main memory)	㉯ 보조기억장치

㉰ 스택(stack)	㉱ 어셈블러(assembler)

6.30 가장 나중 기억된 것이 가장 먼저 출력되는 기억장치는?	(전산기조직응용)

㉮ Stack	㉯ Queue

㉰ FIFO	㉱ Register

6.31 마이크로컴퓨터의 전원을 처음 넣었을 경우 이 컴퓨터가 특정한 위치에서부터 인스트럭션을 수행하게 하는 제어신호는?	(전자계산기)

㉮ Set 신호	㉯ DMA 신호

㉰ Reset 신호	㉱ Interrupt 신호

6.32 다음 중 메모리와 외부장치 사이에 직접 데이터를 전송하는 방식은?	(전자계산기)

㉮ Interrupt	㉯ Program 제어 방식

㉰ DMA 방식	㉱ 메모리 맵 I/O 방식

6.33 대부분의 (연산용)마이크로컴퓨터에서는 중앙처리장치의 개입 없이 기억장치와 외부장치간에 직접 자료전달이 가능하다. 이를 무엇이라 하는가?	(전자계산기)

㉮ Interrupt	㉯ DMA

㉰ Polling	㉱ Paging

6.34 중앙처리장치의 제어를 필요로 하지 않는 입·출력 방법은?	(전산기조직응용)

㉮ 메모리 맵에 의한 입·출력	㉯ 디엠에이(DMA)에 의한 입·출력

㉰ 인터럽트 제어에 의한 입·출력	□ 프로그램 제어에 의한 입·출력

6.35 마이크로컴퓨터의 입·출력을 행하는 DMA(direct memory access) 방식에 대한 기술 중 옳지 않은 것은?	(전산기조직응용)

㉮ 프로세서의 제어를 통하지 않고 기억장치와 입·출력장치의 사이에서 직접 데이터 전송을 한다.

㉯ 프로그램 제어 방식에 비해 데이터 전송의 속도는 느리지만 안정한 동작이 된다.

㉰ 주변기기와 기억장치 사이의 데이터 전송에 프로세서의 작업이 필요없다.

㉱ DMA 방식의 입·출력을 실행하기 위해서는 DMA 콘트롤러를 사용한다.

6.36 다음의 입·출력 방식 중 데이터의 전송과 동시에 마이크로프로세서가 다른 처리를 수행할 수 있는 것은?	(전산기조직응용)

㉮ Burst DMA	㉯ Memory mapped I/O

㉰Cycle stealing DMA	㉱ Isolated I/O

6.37 싸이클 스틸링(cycle stealing)과 관계있는 입출력 방식은?

㉮ 인터럽트 방식	㉯ 폴링 방식

㉰ 프로그램 방식	㉱ DMA

6.38 DMA(direct memory access)방식에 대한 설명 중 올바른 것은?	(전산기조직응용)

㉮ 메모리의 내용이 누산기만을 거쳐서 전송된다.

㉯ CPU가 데이터 전송과정을 직접 제어한다.

㉰ 많은 양의 데이터를 고속으로 전송하는 데는 적합하지 않다.

㉱ DMA 제어를 위한 별도의 하드웨어가 필요하다.

6.39 다음 중 시스템 버스의 사용 요청선은?

㉮ HALT	㉯ BUSRQ

㉰ BUSAK	㉱ WAIT

6.40 CPU는 처리속도가 빠르고 주변장치는 늦기 때문에 CPU를 효율적으로 사용하기 위한 방안으로, 주변장치에서 요청이 있을 때만 Service를 해주고 그 외에는 CPU가 다른 일을 하는 방식은 어느 것인가?	(전산기조직응용)

□ Parallel Processing	□ Isolated I/O

□ Interrupt	□ DMA

6.41 다음은 CPU 제어신호에 속한 일반적인 것들이다. 설명이 틀린 것은?

□ HALT는 CPU가 다시 명령을 수행하기 전 인터럽트를 기다리는 상태이다.

□ WAIT 는 CPU에 지정된 주소의 메모리 또는 입출력기가 자료를 전송할 준비가 되어 있지 않음을 나타낸다.

□ INT는 메모리에 의해 발생되며 NMI보다 우선순위가 높다.

□ RESET는 PC를 0000H로 만들며 CPU를 초기화한다.

6.42 컴퓨터와 주변장치 사이에 데이터 전송을 수행할 때 입출력의 준비나 완료를 나타내는 신호가 필요한 비동기식 입출력 시스템에 널리 쓰이는 방식은 어느 것인가?

□ Paging	□ Polling

□ Interrupt	□ Handshaking

6.43 철수는 프로그램 중 모르고 분자를 0으로 나누는 잘못된 내용을 기술했다. 이 때 컴퓨터는 철수에게 잘못됐음을 통고하는 데 이것은 어떤 인터럽트의 분류에 들어가는가?	(전산기조직응용)

□ 외부 인터럽트                    □ 내부 인터럽트

□ 소프트웨어 인터럽트              □ 중앙처리장치간 인터럽트

6.44 마이크로컴퓨터에서 시간(time)을 정확하게 처리하는 기능이 없을 경우 어떻게 하면 좋겠는가?

(전산기조직응용)

□ DMA로 해결한다.	□ 대기(wait) 상태를 넣어 해결한다.

□ Interrupt로 해결한다.	□ stack을 사용한다

6.45 인터럽트 처리 과정이 맞는 것은?	(전산기조직응용)

□ □-□-□-□-□-□	□ □-□-□-□-□-□

□ □-□-□-□-□-□	□ □-□-□-□-□-□

6.46 인터럽트의 원인 중 내부 인터럽트가 아닌 것은 어느 것인가?	(전산기조직응용)

□ 기억장치의 고장(패리티 에러)

□ 정의되어 있지 않은 명령의 실행의 에러

□ 전원의 이상(정전)

□ 출력장치의 종료

6.47 Interrupt시 Save되는 내용이 아닌 것은?

□ Stack 메모리의 내용	□ 상태 조건의 내용

□ 레지스터의 내용	□ 프로그램카운터의 내용

6.48 Interrupt 형태로 분류할 수 없는 것은 어느 것인가?

□ System call	□ 내부 인터럽트

□ 외부 인터럽트	□ Subroutine

6.49 고속의 입출력장치와 메모리간에 CPU를 통하지 않고 직접 데이터를 주고 받는 입출력 제어방법을 무엇이라고 하는가?

□ 시분할(time sharing)	□ DMA

□ 인터럽션(interruption)	□ 인터럽트(interrupt)

6.50 주기억장치와 주변장치 사이에서 비교적 고속, 대용량의 정보를 전달하는 데 적합한 I/O 방식은?

□ 인터럽트 I/O	□ memory mapped I/O

□ Programmed I/O	□ Direct Memory Access

6.51 다음 중 DMA(Direct Memory Access)에 대한 설명이 아닌 것은?

□ 데이터의 전송이 메모리와 입출력 기기 사이에서 직접 행해지도록 한다.

□ DMA를 위한 새로운 클록이 필요한 경우도 있다.

□ 고속으로 데이터 전송이 되므로 많은 양의 데이터 전송에 이용된다.

□ DMA controller는 항상 CPU의 제어 하에 있게 된다.

6.52 다음 일련의 DMA 신호 중 어느 신호가 동작을 해야 DMA 동작을 할 수 있는가?

□ 인터럽트 확인 신호	□ DMA 요구 신호

□ 인터럽트 요구 신호	□ DMA 확인 신호

6.1 인터럽트에 대하여 논하라.

6.2 8051 인터럽트 소스를 열거하고, 간단히 설명하라.

6.3 8051 외부 인터럽트에 대하여 써라.

6.4 인터럽트 벡터에 대해서 아는 바를 써라

6.5 8051 인터럽트 처리 과정을 기술하라.

6.6 다중 인터럽트란 무엇이고, 8051에서는 이를 어떻게 처리하는가?

6.7 8051 인터럽트 우선순위를 논하라.

6.8 외부 인터럽트 INT1에 푸시버튼 스위치가 연결되어 있는 경우 이를 누를 때마다 포트 1(P1.7∼P1.0)에 연결된 LED가 BCD 코드에 따라 바뀌는 프로그램을 작성하라.

7.1 타이머의 개요 7.2 타이머 관련 레지스터 7.3 타이머의 게이트 기능	7.4 타이머의 동작 모드 7.5 타이머에 관한 실험 7.6 이 장의 간추림

8051에는 독립된 2개의 16비트 타이머가 내장되어 있다.

이들 두 타이머는 타이머로 사용될 수도 있고 카운터로 사용될 수도 있는데, 이들이 타이머로 사용 될 경우에는 내부 클록(외부 발진주파수의 1/12)을 이용하여 일정 시간 간격마다 펄스를 만들거나 일정 시간 경과 후에 인터럽트를 발생시키고, 카운터로 사용될 경우에는 외부 핀 T0(P3.4) 또는 T1(P3.5)을 통하여 들어오는 펄스를 계수하는 사건 카운터(event count)로 동작한다.

이 외에도 특히 타이머 1은 직렬포트(serial port)의 비동기 통신에서 보율(baud rate) 발생기로 사용되기도 한다.

이들 타이머의 동작 모드(operating mode)에는 다음과 같은 것들이 있다.

모드 0＞13비트 타이머/카운터 모드

모드 1＞16비트 타이머/카운터 모드

모드 2＞자동 재장전(auto reload)의 8비트 타이머/카운터 모드

모드 3＞2개의 8비트 타이머/카운터 모드, 타이머1은 직렬포트의 비동기 통신 모드에서 보율발생기로 동작함

8051 타이머는 TMOD(Timer MODe register)와 TCON(Timer CONtrol register), 그리고 앞에서 다룬 IE(Interrupt Enable register)와 IP(Interrupt Priority register)로 제어한다. 제2장에서 언급한 바와 같이, 이들 중 TCON, IE, IP 등은 비트 주소지정이 가능하다.

7.2.1 TMOD

TMOD(Timer MODe register)는 타이머를 타이머로 사용할 것인지 카운터로 사용할 것인지, 동작 모드를 어느 것으로 할 것인지, gate 기능을 사용할 것인지 등을 선택하는 데 사용된다.

·타이머/카운터의 선택

·동작 모드의 선택

·gate 기능의 사용 여부

그림 7.1  TMOD 레지스터

이 레지스터의 상위 4비트는 타이머 1에 관한 것이고, 하위 4비트는 타이머 0에 관한 것이다.

리세트 후 TMOD 레지스터는 □00H□로 클리어 된다. 그러므로 리세트 후에 타이머는 타이머로 기능하고, gate 기능은 불능으로 되며, 동작 모드는 모드 0으로 된다.

GATE

TMOD 레지스터의 비트 7과 비트 3(GATE)은 타이머의 gate 기능을 가능케 할 것인지를 결정한다. 이들 비트가 □0□이면 해당 타이머의 gate 기능은 불능(disable)으로 되고, □1□이면 허용(enable)된다. 그러므로 gate 기능을 사용하려면 예컨대 다음과 같은 명령으로 이들 비트 중 어느 것을 □1□로 해야한다.

TMOD = 0b1xxx0xxx

TMOD = 0b0xxx1xxx

여기서 gate 기능이란 동작의 start와 stop을 외부에서 제어하는 기능을 말한다. 마치 stop watch처럼 외부에서 카운팅을 시작시키고 외부에서 카운팅을 스톱시킬 수 있는 기능이다. 그림 7.2 타이머 구조의 왼쪽 아래에서 볼 수 있듯이 TRn(TR1 또는 TR0) =1인 가운데 GATEn=1로 해두면 INTnＡ1일 때에만 카운트 레지스터(THn와 TLn)로 들어가는 □제어□ 스위치가 닫아져서 타이머의 동작이 start되고, INTnＡ0이면 스위치가 열려서 타이머 동작이 stop된다. 바꿔말해서 외부 INTn 핀에 +5V를 인가하면 카운팅이 start되고, 0V를 인가하면 카운팅이 stop된다. 이 기능을 이용하면 외부신호의 펄스폭(펄스 기간)을 계산할 수 있고, 외부신호의 주파수도 계산할 수 있으며 기타 많은 계측을 할 수 있다.

실로 펄스폭이나 주파수만 측정할 수 있으면 거의 모든 계측을 쉽사리 할 수 있다. 그러므로 타이머/카운터의 gate 기능이야말로 거의 모든 계측을 가능케 하는 기능이라고 할 수 있다.

여기서 한가지 집고 넘어 갈 것이 있다. INTn선, 즉 P3.3/ INT1과 P3.2/ INT0는 어느 경우에 포트선으로 되고 어느 경우에 인터럽트선으로 되며, 어느 경우에 gate에 대한 입력핀으로 되느냐이다. IE 레지스터에 의해서 외부 인터럽트가 허용(enable)된 경우에는 인터럽트 입력선으로 되고, TMOD 레지스터에 의해서 gate 기능이 허용된 경우에는 gate 입력선이 되며, 그 밖의 경우에는 일반 포트라인이 된다.

C/T

비트 6과 비트 2(C/T)는 타이머의 클록 소스를 결정한다. 다시 말해서 타이머로 사용되느냐, 카운터로 사용되느냐를 결정한다. 클록 소스로서 내부클록(발진주파수/12)을 선택하면 타이머로 동작하고, 외부 클록을 선택하면 카운터로 동작한다. 그러니까 타이머와 카운터가 따로 있는 것이 아니고, 내부 로직은 동일한데 클록 소스로서 내부클록을 선택하면 타이머로 되고, 외부클록을 선택하면 카운터로 된다.

타이머 0 또는 타이머 1을 타이머가 아니고 카운터로 사용하려면 TMOD 레지스터

그림 7.2  타이머 구조

의 비트 6 또는 비트 2를 □1□로 하는 것 외에도 관련된 입력핀에 카운트할 클록 소스를 연결해야 한다. 타이머 0의 외부 입력핀은 T0(P3.4)이고, 타이머 1의 외부 입력핀은 T1(P3.5)이다. T0/P3.4, T1/P3.5가 어느 경우에 카운터의 입력핀으로 되고, 어느 경우에 포트라인이 되는지는 TMOD 레지스터에 의해서 결정된다. TMOD 레지스터에 의해서 카운터로 설정되면 카운터 입력선이 되고, 그 외의 경우에는 범용 I/O포트라인이 된다.

M1, M0

비트 5와 4, 그리고 비트 1과 0은 타이머/카운터 1 또는 타이머/카운터 0의 동작 모드를 결정한다. 동작 모드 0, 1, 2는 기능적으로 두 타이머가 모두 같지만, 모드 3은 서로 다르다. 이에 대하여는 후에 논한다. 다음은 TMOD 레지스터를 사용하는 하나의 예이다.

타이머 0은 모드 0의 타이머로, 타이머 1은 gate 기능의 모드1 카운터로 사용코자 할 경우

TMOD = 0b11010000

□표 7.1  타이머/카운터 모드

M1	M0	모드	내 용
0 0 1 1	0 1 0 1	0 1 2 3	13비트의 타이머/카운터 16비트의 타이머/카운터 auto reload의 8비트 타이머/카운터 타이머 0＞2개의 8비트 타이머 타이머 1＞직렬포트의 비동기통신에서 baud rate 발생기

7.2.2 TCON

TCON(Timer CONtrol) 레지스터는 외부 인터럽트와 타이머의 동작을 제어한다. 그림 7.3과 같이 상위 4비트는 타이머를 제어하고, 하위 4비트는 외부 인터럽트를 제어한다. 외부 인터럽트에 관한 것은 앞에서 다루었으므로 이곳에서는 타이머에 관한 것만을 논한다.

리세트 후에 이 레지스터는 □00H□로 클리어된다. 그러므로, 타이머는 동작 불능으로 되고, 타이머 오버플로 및 외부 인터럽트는 불능으로 된다.

TR0, TR1

TR0 및 TR1은 timer run 제어 비트로, 타이머의 run/halt를 제어한다. GATE=0의 경우에는 프로그램 수행 중 TR0=1이라는 명령으로 이 비트가 1로 세트되면 즉시 타이머

그림 7.3  TCON

/카운터로서의 동작이 시작(run)되고, TR0=0이라는 명령으로 이 비트가 0으로 클리어되면 즉시 그 동작이 정지(halt)된다. TR1에 대해서도 같다.

GATE=1의 경우에는 전술한 바와 같이 TR0=1인 상태에서도 외부 인터럽트 입력선인 INT0가 논리 1이어야만 비로소 타이머/카운터로서의 동작이 개시된다. TR1에 대해서도 같다.

TF0, TF1

이들은 타이머의 오버플로 플래그이다. 전술한 바와 같이, 8051의 타이머는 up counter이다. 그러므로, 카운터 레지스터(THx, TLx)가 설정된 값으로부터 up counting을 하다가 최고값에 이른 뒤 다시 하나를 더하면 그 값이 0으로 되면서 오버플로가 발생한다. 그러면 해당 플래그 TFx가 하드웨어적으로 1로 세트된다. 그리고 이 비트가 세트되면 인터럽트 허용으로 되어 있는 경우 인터럽트 요청이 인정되어 인터럽트 처리과정에 들어간다. 인터럽트 처리 과정에 들어가면 인터럽트 편에서 언급한 바와 같이,  이들 비트는 자동적으로 클리어된다. 그러므로 이들 비트를 클리어하는 명령을 따로 둘 필요는 없다. 그러나 인터럽트를 사용하지 않고 이들 비트가 세트되어 있는지를 테스트하는 명령을 사용하는 경우에는 자동적으로 클리어되지 않으므로 반드시 명령으로 이들 비트를 클리어시켜 주어야 한다.

TF0 = 0	/*clear TF0*/

＞

while (!TF0);	/*TF0=0인한 여기서 기다린다*/

TF0 = 0;	/*TF0=1인 경우에는 이를 클리어한다*/

7.2.3 IE 레지스터와 IP 레지스터

타이머/카운터의 프로그래밍에 있어서도 인터럽트를 사용할 경우에는 IE(Interrupt Enable register)와 IP(Interrupt Priority register)의 해당 비트를 세트 또는 리셋할 필요가 있으나, 이들에 대하여는 인터럽트 편에서 다루었으므로 이곳에서는 생략한다.

이에 대하여는 TMOD 레지스터의 비트 7과 3(GATE)에서 언급했지만, 이곳에서 좀 더 자세히 논하고자 한다.

포트 3의 두 개 핀(INT0 / P3.2와 INT1/ P3.3)은 타이머 0 및 타이머 1에 대한 게이트 입력으로 사용될 수 있다. P3.2/INT0는 타이머 0의 게이트 입력으로, P3.3/INT1는 타이머 1의 게이트 입력으로 사용된다.

이들 게이트 기능을 가능케 하기 위해서는 다음의 두 조건이 만족되어야 한다.

·TCON 레지스터의 해당 타이머 run 비트(TR0 또는 TR1)가 □1□로 세트되어 있어야 한다.

·TMOD 레지스터의 게이트 사용 허용 비트(GATE)가 □1□로 세트되어 있어야 한다.

게이트 기능을  이용하여 펄스의 주파수(frequency)나 펄스폭(duration)을 측정하는 방법을 강구해 보기로 한다.

앞에서도 잠깐 설명했지만, 그림 7.2의 좌 하단을 다시 보기로 하자. 게이트 사용가능 비트 (GATE)가 □1□이고 타이머 run 비트(TR0 또는 TR1)가 □1□인 상태에서 게이트 핀(INT0 또는 INT1)이 □1□이면 AND 게이트의 출력도 □1□로 되어 연결 스위치가 닫혀져서 카운팅 동작을 한다. 그러나 게이트 핀(INT0 또는 INT1)이 논리 □0□으로 되면 AND 게이트의 출력도 □0□으로 되어 연결 스위치가 열려서 카운팅 동작이 중단된다. 그러므로 게이트 핀(INT0 또는 INT1)에  모양의 구형파를 인가하면 high(논리 1)의 기간에는 카운팅을 하다가 low(논리 0)의 기간에는 카운팅이 중단될 것이다.

그러므로, 예컨대 의 high 기간이 1초인 구형파를 INT0 또는 INT1에 주고, 측정하고자 하는 신호를 T0 또는 T1에 주면 논리레벨이 high인 1초 동안만 카운팅을 하므로 그 동안에 카운트 레지스터(TH0, TL0 또는 TH1, TL1)가 카운트한 값은 그대로 주파수값이 될 것이다. 또 high 기간이 0.1초인 구형파를 줄 경우에는 그 동안에 카운트 레지스터가 카운트한 값을 10배해 주면 주파수값이 될 것이다. 문제는 카운트 레지스터가 카운트한 값, 즉 주파수값을 어떻게 읽어드리냐에 있다. INT0 및 INT1은 외부 인터럽트 입력핀이기도 하므로 의 하강에지에서 인터럽트가 발생되도록 하고, 그 인터럽트 루틴에서 타이머 레지스터값을 읽어드리도록 하면 이 문제는 해결될 것이다. 즉, 외부 인터럽트를 허용시키고, INT0 또는 INT1의 하강에지에서 인터럽트가 발생되도록 TCON 레지스터를 설정해두면 INT0 또는 INT1에 가한 형 구형파의 하강에지에서 외부 인터럽트가 발생되고, 이 인터럽트 서비스 루틴에서 그간 타이머 레지스트가 카운트한 값을 읽어드리면, 이 카운트값과 게이트 핀(INT0 또는 INT1)에 가한 펄스의 high 기간과의 관계에서 외부클록 입력핀(T0/P3.4 또는 T1/P3.5)을 통하여 들어오는 신호의 주파수를 쉽사리 계산할 수 있다.

다음의 부분 프로그램은 아래와 같은 조건에서 타이머 0의 게이트 기능을 이용하여 외부 클록 입력핀 T0/P3.4를 통하여 들어오는 신호의 주파수를 측정하는 방법을 보여주기 위한 것이다.

·발진주파수Ａ22.1184MHz(이 경우에는 타이머 0의 카운트 기능을 이용하므로 발진주파수가 얼마든 상관없음)

·T0(P3.4)에 입력되는 신호의 주파수는 알려져 있지 않음(그 주파수를 측정코자 함)

·게이트 핀(INT0/P3.2)에 입력되는 클록 펄스Ａ62.5□(50% duty)

·외부 인터럽트는 INT0 핀에 들어오는 클록의 하강에지에서 발생됨

프로그램 기능 설명

이 경우 타이머 0은 카운터로 동작한다. 미지의 주파수는 T0/P3.4 핀을 통하여 타이머 0에 입력된다(단, 입력 주파수는 500kHz 이하이어야 함). INT0 핀으로 들어오는 기준 시간 펄스는 62.5Hz이므로, 결국 그림 7.4와 같이 8m초 동안(1/62.5□÷2)만 high 기간이므로 8m초 동안에 T0/P3.4 핀을 통하여 들어오는 미지의 주파수를 그림 7.5와 같이 계수하는 셈이다. 이 값을 8로 나누면 1m초 동안에 카운트한 값이 되는데, 이것을 우선 BUF_H와 BUF_L에 2진수 형태로 저장한다.

앞에서와 같이 8m초 동안에 계수한 값을 8로 나누면 1m초 동안에 계수한  값이 되는데, 1m초를 1초로 환산하면 BUF_H와 BUF_L의 내용은 1초 동안에 계수한 k(키로) 단위의 주파수 값이 된다.

그림 7.4  INT0와 T0의 관계

그림 7.5  INT0의 high 기간에만 카운트하고, 하강에지에서 인터럽트 발생

□

TH0 = 0x00H;	/*타이머0 카운트 레지스터의 초기화*/

TL0 = 0x00;

TMOD = 0x0d;	/*gate 기능, 카운터, 모드 1로 동작*/

TCON = 0x01;	/* INT0는 하강에지에서 인터럽트 발생*/

EX0 = 1;	/*인터럽트 개별 허용*/

EA = 1;	/*인터럽트 전체 허용*/

PX0 = 1;	/*우선순위를 high로*/

TR0 = 1;	/*타이머0 run*/

＞

while(1);	/*인터럽트 발생을 여겨서 기다린다*/

/* 카운트 값을 8로 나누어서 1m초 동안의 카운트값으로 만든다 */

void INT0_int(void) interrupt 1 {

buf_l = TL0;	/*카운트 값을 BUF_H와 BUF_L에*/

bug_h = TH0;

buf_l /= 8;	/*그 값을 8로 나누고 P1과 P0에 표시한다*/

P1 = buf_h;	/*이 값은 KHz 단위의 주파수이다*/

buf_h /= 8;

P0 = buf_h;

TH0 = 0;	/*다음 차례를 위하여 카운트 값을 클리어*/

TL0 = 0;

IE0 = 0;	/*edge interrupt flag의 클리어*/

(자세한 것은 18장에서 설명함)

전술한 바와 같이, 타이머의 동작 모드에는 모드 0, 모드 1, 모드 2, 모드 3 등 4가지가 있는데, 이들은 TMOD 레지스터의 비트 5와 4(M1, M0) 그리고 비트 1과 0(M1, M0)을 통하여 설정된다.

앞에서 언급했듯이 4가지 동작 모드중 모드 0와 모드 1과 모드 2에서는 두 개의 타이머가 기능적으로 동일하지만, 모드 3에서는 서로 다르다.

7.4.1 타이머 모드 0(13비트 타이머/카운트 모드)

타이머가 모드 0으로 설정되면 이것은 그림 7.6과 같이 13비트 타이머/카운터로 된다. 13비트 중 TLx(TL1 또는 TL0)에 속하는 하위 5비트는 32분주의 prescaler로 동작하고, THx(TH1 또는 TH0)에 속하는 나머지 8비트는 TLx에서 32분주된 클록을 카운팅하는 카운터로 동작한다.

리세트 후 타이머는 자동적으로 모드 0으로 된다.

타이머가 모드 0으로 되면 13비트 타이머/카운터로 동작하므로, 가장 긴 카운트의 수는 213Ａ8192이고, 가장 짧은 카운트의 수는 1이다. 그러므로, 외부 발진주파수가 22.1184 MHz이면, 가장 긴 시간은 다음과 같이 계산되어 4444(□초)이고, 가장 짧은 시간은 0.54□초이다. 발진주파수를 12로 나누어 준 이유는 8051 타이머는 하나의 기계사이클마다 증가되는데, 하나의 기계사이클은 12개의 외부 발진주파수로 이루어지기 때문이다.

그림 7.6  타이머 모듈 0의 기능도

22.1184MHz →	[eqn: 1 over 12]	→	[eqn: RM 1 OVER 8192]	Ａ[eqn: 1 OVER t] (□[eqn: f` =`1 OVER t])

22,118,400[eqn: times`1 over 12`times`1 OVER 8192 `=` 1 OVER t]

∴ t Ａ 4444(□초)

8051의 타이머는 up-counting 방식이기 때문에, 예컨대 7373개의 펄스를 카운트하려면 819(8192１7373)에서부터 8192까지 카운트하도록 해야 한다. 819에서 8192까지 카운트하면 7373개 카운트가 된다.

다음 부분 프로그램은 발진주파수가 22.1184MHz인 8051에서 4000□초의 시간 간격으로 타이머0 오버플로 인터럽트가 발생되도록 하기 위한 것이다.

TMOD = 0x00;	/* 타이머0＞ 모드0 */

TCON = 0x00;	/* 타이머0 인터럽트 플래그 TF0의 클리어 */

TH0 = (8192１7373)/32;	/* 타이머0에 시간정수를 로드 */

TR0 = 1;	/* 타이머0 run 시작 */

위 부분 프로그램에서 TH0값을 (8192１7373)/32로 한 이유는 외부 발진주파수 22.1184 MHz에서 4000□초의 시간을 얻기 위해서는 fＡ1/t의 관계에서

22.1184MHz →	[eqn: 1 over 12]	→	[eqn: RM 1 OVER □]	Ａ[eqn: 1 over 0.004000]

22,118,400[eqn: times`1 over 12`times`1 OVER □`=`1 over 0.004000]

□Ａ 7373

그러므로, 7373개의 카운트가 필요하고, 그러기 위해서는 819(8192１7373)에서 8192까지 카운트를 해야 하는데, 프리스케일러 TL0에서 클록을 32분주하므로, TH0에는 32분주된 클록이 들어가고, 그래서 TH0에는 (8192１7373)/32를 로드해야 한다. TH0에 (8192１7373)/32Ａ26이라는 값만 넣어주면 이 값에서 8192/32Ａ256까지 230개의 카운팅을 하고 prescaler인 TL0에서 이 값을 32배하기 때문에 결과적으로 230×32Ａ7373개의 카운트를 한다.

TH0에 대한 이상의 계산은 물론 외부 발진주파수가 달라지면 같은 시간을 얻는데도 그 값이 달라진다.

예컨대 외부 발진주파수가 11.0592MHz이면

11.0592MHz →	[eqn: 1 over 12]	→	[eqn: RM 1 OVER □]	Ａ[eqn: 1 over 0.004000]

11,059,200[eqn: times`1 over 12`times`1 over x`=`1 over 0.004000]

∴   □ = 3686

즉 (8192１7373)/32 대신 (8192１3686)/32를 TH0에 로드해야 한다.

다음의 두 예는 타이머를 모드 0으로 사용하기 위해서 TMOD, THx, IE, IP 등의 레지스터들을 어떻게 설정해야 하는지를 보이고 있다.

타이머 0을 모드 0의 타이머로 사용하되 3000□초마다 인터럽트가 발생되도록 하고자 할 경우 (단, 발진주파수는 22.1184MHz)

TMOD = 0x00;	/* 타이머/카운터 0를 모드 0의 타이머로 */

TH0 = (8192-5530)/32;	/* 5530카운트를 위한 TH0의 값 */

IE = 0x82;	/* 타이머0 인터럽트 허용 */

IP = 0x02;	/* 타이머0 인터럽트를 우선순위 1로 */

TR0 = 1;	/* 타이머 0의 동작 개시 */

＞

타이머 1을 모드 0의 카운터로 사용하되 외부 핀 T1(P3.5)를 통하여 펄스가 2000개 들어오면 인터럽트가 발생되도록 하고자 할 경우

TMOD = 0x40;	/* 타이머 1을 모드 0의 카운터로 */

TH1 = (8192-2000)/32;	/* 펄스 2000개가 들어오면 인터럽트 발생 */

IE = 0x88;	/* 타이머 1 인터럽트 enable */

IP = 0x08;	/* 타이머 1의 우선순위를 최고로 */

TR1 = 1;	/* 타이머 1 동작 개시*/

＞

끝으로 다음의 부분 프로그램은 다음과 같은 조건에서 타이머 1를 모드 0의 타이머로 사용하는 것을 보여주기 위한 것이다.

·타이머 1을 모드 0의 타이머로 사용

·외부 발진주파수Ａ22.1184MHz

·타이머 1 인터럽트는 4m초마다 발생한다.

·타이머 1 인터럽트가 발생하면 P0.0 핀을 반전시킨다.

EA = 0;	/*인터럽트 불능*/

□

TMOD = 0x00;	/*타이머 1 모드 0*/

TH1 = (8192-7373)/32;	/*4m초를 얻기 위한 TH1의 값*/

TR1 = 1;	/*타이머1 run 시작*/

EA = 1;	/*인터럽트 허용*/

□

while(1);                         /*인터럽트 대기*/

void TMR1_int(void) interrupt 3 {

TH1 = (8192-7373)/32;	/*TH값의 재 로드*/

P0 ^= 0x01;	/*P0.0의 반전*/

TF1 = 0;	/*TF1의 클리어, 없어도 상관없음*/

}

위 프로그램에서 특히 유의할 점은 TL1의 값을 지정할 필요가 없다는 것이다. 이유는 TL1이 prescaler로서의 역할만을 하기 때문이다. 다시 말해서 TL1은 TH1을 32(25 )배로 해주는 역할만을 하기 때문이다. 엄격히 따진다면 (8192１7373)/32의 계산을 할 때 나머지가 있으면 그것을 넣어주는 다음과 같은 명령이 있어야 할 것이다.

TL0 Ａ (8192１7373) %32

그러나 대개의 경우에 그 값은 0이 되고, 그렇지 않더라도 의미가 거의 없다.

7.4.2 타이머 모드 1 (16 비트 타이머/카운트 모드)

이 모드의 기본 동작은 모드 0과 같지만, 비트 수가 다르다. 즉, 모드 0은 13비트 타이머

그림 7.7  모드 1 기능도

/카운터로 동작하지만, 모드 1은 THx와 TLx이 그대로 직렬 연결되어 그림 7.7과 같이 16비트 타이머/카운터로 동작한다. THx에서 오버플로가 발생되면 TCON 레지스터의 인터럽트 플래그 TF1 또는 TF0가 자동적으로 세트되고, 역시 IE 레지스터의 타이머 인터럽트 허용 비트 ET1 또는 ET0와 EA가 □1□로 세트되어 있으면 타이머1 또는 타이머0 overflow 인터럽트가 발생한다.

모드 1에서는 16비트의 타이머/카운터로 동작하므로, 카운트할 수 있는 최대의 수는 216 Ａ 65536개이고, 최저 수는 1개이다. 그러므로 외부 발진주파수가 22.1184MHz일 때 얻을 수 있는 가장 긴 시간은 아래와 같이 계산되어 35556□초이고, 가장 짧은 시간은 0.54(□)이다.

22.1184MHz →	[eqn: 1 over 12]	→	[eqn: RM 1 OVER 65536]	Ａ[eqn: 1 OVER t]

22,118,400[eqn: `times`1 over 12`times`1 OVER 65536`=` 1 OVER t]

tＡ35556(□초)

위 식에서 발진주파수를 12로 나눠주는 이유는 타이머 0과 1을 타이머로 사용할 경우도 앞에서 언급했듯이 기계사이클에 동작하도록 구조가 되어 있기 때문이다.

타이머 0을 모드 1의 타이머로 사용하되 25,000□초(0.025초)마다 인터럽트가 발생되도록 하고자 할 경우(단, 발진주파수는 22.1184MHz이다)

TMOD = 0x01;	/*타이머0＞ 모드 1*/

TF0 = 0;	/*타이머0 인터럽트 플래그의 클리어*/

TH0 = 0x4c;	/*시간 정수의 로드*/

TL0 = 0x00;

IE = 0x82;	/*타이머0 인터럽트 enable*/

IP = 0x02;	/*고위 우선순위로*/

TR0 = 1;	/*타이머0  run*/

위에서 TH0, TL0의 값이 4C00H인 것은 외부 발진주파수가 22.1184MHz일 때 25000(□초)를 얻기 위해서는 역시 [eqn: t=1/f] 의 관계에서

22.1184MHz →	[eqn: 1 over 12]	→	[eqn: RM 1 OVER □]	Ａ[eqn: 1 over 0.025000]

□Ａ46,080

그러므로 TH0와 TL0에 (65536-46080)=19456을 로드해야 하는데, 19456은 16진수로 4C00H이기 때문이다.

7.4.3 타이머 모드 2 (8비트 자동 재장전 모드)

이 모드가 다른 모드와 크게 다른 것은 자동적으로 다시 로드(auto reload)가 된다는 것이다. 모드 2에서는 그림 7.8과 같이 카운트 레지스터의 하위 바이트 TLx(TL0 또는 TL1)가 카운팅을 하고, 여기에서 overflow가 발생하면 상위 바이트 THx(TH0 또는 TH1)에 미리 로드되어 있던 값이 하드웨어적으로 다시 TLx에 로드된다. 이 때 애초에 THx에 로드되어 있던 값은 변하지 않는다. 그러므로, 다른 모드에서와는 달리 인터럽트 루틴에서 TLx 값을 다시 설정할 필요가 없다.

그림 7.8  모드 2의 기능도

모드 2에 있어서는 모드 0이나 모드 1과는 달리 THx가 오버플로할 때가 아니고, TLx이 오버플로할 때 TCON 레지스터의 해당 인터럽트 플래그(TF0 또는 TF1)가 □1□로 세트되고, 그러면 즉시 THx에 저장되어 있던 값이 TLx에 다시 장전(load)되며, 이어서 바로 카운팅 동작을 다시 시작한다. 또한 인터럽트 플래그(TF0 또는 TF1)가 세트되어 있고, IE 레지스터의 개별 허용 비트(ET0 또는 ET1)와 전체 허용 비트(EA)가 세트되어 있으며, 우선순위가 가장 높은 경우에는 타이머1 또는 타이머0 overflow 인터럽트가 발생한다.

타이머 1을 모드 2의 타이머로 사용하되 매 100□초마다 인터럽트가 발생되도록 하고자 할 경우의 부분 프로그램

TMOD = 0x20;	/*타이머 1의 동작 모드＞모드 2*/

TF1 = 0;	/*타이머 1 인터럽트 플래그의 클리어*/

TH1 = (256１184);	/*200□s를 얻기 위한 시간정수*/

TL1 = (256１184);	/*최초의 경우를 위한 것임*/

IE = 0x88;	/*또는 EA=1, ET1=1*/

IP = 0x08;	/*또는 PT1=1*/

TR1 = 1;

위에서 TH1의 값이 (256１184)인 것은 외부 발진주파수가 22.1184MHz일 때 100□초를 얻기 위해서는 f Ａ1/t의 관계에서 다음과 같이 184 카운트가 필요하므로 256１184Ａ72을 로드해야 하기 때문이다.

22.1184MHz →	[eqn: 1 over 12]	→	[eqn: RM 1 OVER □]	Ａ[eqn: 1 over 0.000100]

22,118,400[eqn: times`1 over 12`times`1 over x`=`1 over 0.000100]

□Ａ184

다음의 부분 프로그램은 아래와 같은 조건에서 타이머 0을 모드 2의 카운터로 사용하는 방법을 보여 주기 위한 것이다.

·T0/P3.4핀의 클록 입력 펄스 Ａ 60□(구형파)

·타이머 0은 외부 클록 입력을 사용하는 자동 재장전 모드로 동작함

·타이머 0 인터럽트는 2초 간격으로 발생됨

·인터럽트가 발생될 때마다 P1.2의 레벨을 반전(toggle)함

EA = 0;

□

TMOD = 0x06;	/*타이머0＞ 모드2의 카운터*/

TL0 = (256-120);	/*TL0 및 TH0의 시간정수 로드*/

TH0 = (256-120);

TCON = 0x00;	/*또는 CLR TF0*/

IE = 0x82;	/*또는 SETB ET0, SETB EA개별 및 전체enable*/

IP = 0x02;	/*또는 SETB PT0*/

TR0 = 1;	/*타이머 0 run*/

□

while(1);

void TMR0_int(void) interrupt 1 {

P1 ^= 0x04;	/*P1.2의 반전*/

□

}

위에서 TL0 및 TH0 값이 (256１120)인 이유는 60Hz(1/60초)의 구형파가 120개 들어와야 2초가 되는데, up-counting을 하기 때문에 8비트 카운터의 최고값 256에서 이 값을 빼준 것이다.

7.4.4 타이머 모드 3(분리된 2개의 8비트 타이머/카운터 모드)

다른 모드와는 달리 모드 3에서 타이머 0과 타이머 1은 서로 다르게 동작한다. 타이머 0은 2개의 독립된 8비트 타이머/카운터로 동작하고, 타이머 1은 일반적으로 직렬포트의 보율발생기(baud rate generator)로 동작한다.

모드 3을 선택하기 위해서는 TMOD 레지스터의 M1과 M0를 □11B□로 해야한다. 그리하면 타이머0 카운트 레지스터 중 TL0은 8비트 타이머 또는 카운터로 동작하고, TH0은 8비트 타이머로서만 동작한다. 이때 TL0로 구성되는 8비트 타이머/카운터는 타이머 0의 제어에 사용되는 ET0, PT0, TR0로 제어되고, TH0로 구성되는 8비트 타이머는 타이머 1의 제어에 사용되는 ET1과 PT1, TR1으로 제어된다. 그러므로 타이머 0의 오버플로 인터럽트는 타이머 0의 TL0에 의해서 발생되지만, □타이머 1의 오버플로 인터럽트는 타이머 1의 TH1이 아니라 타이머 0의 TH0에 의해서□ 발생된다.

타이머 0이 모드 3으로 동작되고 있는 동안 타이머 1은 인터럽트 기능이 없는 모드 0, 1, 2로 동작하고, 직렬포트를 사용하는 경우에는 직렬포트에 대한 보율생성기(baud rate generator)로 사용할 수 있다(8052에서는 타이머2를 보율생성기로 사용할 수 있음). 타이머

그림 7.9  모드 3 기능도

0이 모드 3으로 동작하는 동안 타이머 1은 보율생성기로 동작한다는 것은 그렇게 사용하는 것이 유리해서 일반적으로 그리 한다는 것일 뿐 반드시 그래야 하는 것은 아니다. 타이머 0가 모드 3으로 사용되면 타이머 1은 인터럽트 기능이 없어지므로, 인터럽트 기능이 필요없는 보율생성기로 사용함이 유리하다는 것이다.

다음 부분 프로그램은 아래와 같은 조건에서 타이머 0을 모드 3으로 사용하는 방법을 보이기 위한 것이다.

·발진주파수Ａ22.1184MHz

·T0/P3.4 핀의 클록Ａ60Hz(구형파; 50% 듀티비)

·타이머 0의 TL0는 인터럽트 기능이 있는 8비트 카운터로 동작하는데, 4초마다 인터럽트 발생하고, 그 루틴에서는 P1.0을 반전한다.

·타이머 0의 TH0는 인터럽트 기능이 없는 8비트 타이머로 동작하여 100□초마다 P0.0을 반전한다.

·타이머 1은 인터럽트 기능이 없는 자동 재장전 모드로 동작하고 UART에 대한 보율생성기(보율 9.6KHz)로서 기능한다.

프로그램 기능 설명

TL0은 T0를 통하여 60□의 펄스를 입력 카운트하여 4초 간격으로 인터럽트를 발생하여 P1.0을 반전한다.

TH0은 발진주파수 22.1184MHz를 12로 나눈 주파수로 카운트하여 100□초마다 인터럽트를 발생하여 P0.0을 반전한다.

타이머 1는 UART에 대한 보율생성기로 작용한다. 보율은 9.6kHz이고, 이 때 타이머 1은 인터럽트를 발생하지 않는다.

EA = 0;

□

TMOD = 0x27;	/*타이머1(보율생성기)＞자동 재장전 모드*/

/*타이머0＞ 모드 3, TL0는 카운터*/

TL0 = (256-240);	/*60Hz, 즉 0.016667초를 240배해야 4초가 되므로*/

TH0 = (256-184);	/*TH0는 100[eqn: mu]초마다 인터럽트 발생의 타이머*/

TH1 = 0xfa;	/*22.1184MHz에서 보율Ａ9.6kbps*/

TL1 = 0xfa;

TCON = 0x00;	/*타이머 플래그 클리어*/

SCON = 0x50;	/*후술하는 SCON 설정, 직렬포트 모드 1*/

IE = 0x8a;	/*TL0 및 TH0 인터럽트 enable*/

IP = 0x0a;	/*우선순위를 high로*/

TR1 = 1;	/*타이머 run*/

TR0 = 1;

while(1);	/*인터럽트 대기*/

void TMR1_int(void) interrupt 3 {	/*타이머 1 인터럽트는 TH0에 의해 발생*/

TF1 = 0;	/*TF1을 클리어하고(반드시 필요한 것은 아님)*/

P0 ^= 0x01;	/*P0.0을 반전한다.*/

TH0 = (256-184);	/*시간정수의 재정의*/

}

void TMR0_int(void) interrupt 1 {	/*타이머0 인터럽트는 TL0의*/

TF0 = 0;	/*overflow(4초 간격)에 의해서 발생된다.*/

TL0 = (256-240);	/*시간정수의 재정의*/

P1 ^= 0x01;	/*P1.0 반전*/

}

7.5.1 타이머 모듈 0의 인터럽트 기능 실험

(1) 目   的

제5장의 5.3.1에서는 일정시간마다 그 상태가 변하는 LED 점멸을 다루었다. 그 곳에서는 점멸 시간간격을 지연루틴으로 얻었으나, 이 곳에서는 타이머의 오버플로 인터럽트 기능으로 얻고자 한다.

·발진주파수＞22.1184MHz

·4000□초 간격으로 타이머 0은 오버플로 인터럽트를 발생

·P1에 연결된 LED는 하나씩 좌회전

그림 7.10 타이머 인터럽트

그림 7.11  모드0 실험 시스템

(2) 順序圖

그림 7.12  타이머 0 overflow 인터럽트 실험 순서도

(3) 프로그램(EX7_1.C)

/*====================================*/

/* PROGRAM EX7_1.C) (TIMER0 MODE 0) */

/*====================================*/

#include <reg51.h>	/* 8051 헤더 파일의 include */

unsigned char number;	/* number=8비트 변수 */

void TMR0_int(void) interrupt 1	/*벡터넘버 1의 인터럽트 루틴*/

{

EA = 0;	/* 인터럽트 불능 */

TF0 = 0;	/* TF0=TCON.5, 인터럽트 플래그의 클리어 */

P1 = number;	/* number값을 P1에 출력 */

number = (number << 1 □ 1);	/* 다음 차례의 출력데이터를 준비 */

if (number == 0xff) number=0xfe; /* 모든 LED가 on되었으면 초기상태로*/

TH0 = 0x1a;	/* 시간정수의 재정의, 26=(8192-7373)/32 */

EA =1;	/* 인터럽트 허용 */

return;

}

void main(void)	/* 메인 함수 */

{

TMOD = 0x00;	/* 타이머0는 모드0의 타이머 */

TH0 = 0x1a;	/*1aＡ(8192-7373)/32, 4000□초를 위한 타이머 시간정수*/

ET0 = 1;	/* 개별 허용 */

EA = 1;	/* 전체 허용 */

PT0 = 1;	/* 우선순위를 high로 */

TR0 = 1;	/* 타이머0 run */

number = 0xfe;	/* 최초의 출력데이터 */

while(1);	/* 여기서 인터럽트 발생을 대기한다 */

}

(4) 프로그램의 解說

TMOD = 0x00;

TH0 = 0x1a;

그림 7.1을 보면  TMOD의 값이 00H이면 타이머 1도, 타이머 0도 게이트 기능이 없는 모드 0의 타이머로 된다. 문제는 두 타이머 중 타이머 0만 사용하는데, 타이머 1까지도 정의해야 하느냐에 있다. TMOD 레지스터의 구조상 뭔가 채워넣지 않으면 안되어서 0을 넣었을 뿐 TR1=1의 명령이 없으므로 타이머1은 실제로는 동작하지 않는다.

4000□초를 얻기 위해서 TH0=(8192１7373)/32를 한 이유는 다음과 같다. 22.1184MHz가 12분주되어 타이머에 들어오고, 여기서 타이머 정수(x)만큼 분주된 것이 얻고자 하는 시간의 역수(f Ａ1/t )이므로 다음 식이 성립한다.

22.1184MHz →	[eqn: 1 over 12]	→	[eqn: RM 1 OVER □]	Ａ	[eqn: 1 over 0.004000]

22118400×[eqn: 1 over 12]×[eqn: 1 over x]Ａ[eqn: 1 over 0.004000]

∴ [eqn: x] = 7373

그래서, TH0의 값은 7373이어야 하나, 8051 타이머는 up-counter이므로 13비트 타이머로서 최고의 값 213Ａ8192에서 이 값을 빼주어야 하고, 이 값이 prescaler에서 25Ａ32 분주되므로 32로 나누어야 한다. 그러면 26이 되는데, 이것을 16진수로 표시하면 1a가 된다.

여기서도 반드시 명심할 것이 있다. 앞에서 TH0=(8192１7373)/32라고 한 것은 어디까지나 발진주파수가 22.1184MHz일 때의 값이라는 사실이다. 발진주파수가 11.0592MHz이면

[eqn: 11059200`times`1 over 12]×[eqn: 1 over x`=`1 over 0.004000]

∴ □=3686

가 되어 TH0의 값은 (8192１3686)Ａ0x8d이어야 한다.

void TMR0_int(void) interrupt 1 {

EA = 0;

TF0 = 0;

＞

EA = 1;

인터럽트 처리 중에 또다른 인터럽트가 발생할까봐 interrupt disable 명령을 인터럽트 초두에 두고, 마지막에 다시 인터럽트를 허용하는 것이 일반이다.

TF0=0은 사실상 불필요하다. 인터럽트 편에서 논한 바와 같이, 타이머 인터럽트의 경우에는 인터럽트 발생시 자동적으로 클리어되기 때문이다. 인터럽트를 사용하지 않고 인터럽트 플래그 (TF0 또는 TF1)를 사용하는 경우에는 반드시 필요하고, 또 다른 마이크로콘트롤러의 인터럽트와의 관계상 잊기 쉬우므로 인터럽트가 발생하면 무조건 그 플래그를 클리어시키는 습관을 가짐이 안전하다.

TH0 = 0x1a

인터럽트 루틴에서도 시간정수를 다시 정의해 주었는데, 만약 이 조치를 해주지 않으면 모드 0의 경우 13비트 타이머로서 최대의 시간이 지난 후에야 인터럽트가 발생된다.

(5) 프로그램의 實行

제4장에서 설명한 방법에 따라 □Vision의 open Project에서 프로젝트를 지정하고(이미 open되어 있으면 생략), edit project에서 프로그램(ex7_1.C)을 지정한 후 build project에서 컴파일과 링킹을 함으로써 Hex file과 Obj file을 만든다.

이것으로 시뮬레이트를 하고자 하면 dScope에 들어가서 CPU를 선택하고(이미 선택되어 있으면 역시 생략함) pheripheral에서 포트 1과 인터럽트 timer0를 선택한 후 □File□밑 툴바에 클릭하여 □Vision에서 open된 프로젝트를 불러온다. 그런 뒤 Go에 클릭하면 4000□초마다 포트 1의 상태가 바뀌짐을 확인할 수 있을 것이다. 사실은 4000□초는 너무 작은 시간이어서 희미하게 켜진 상태로 보인다.

트레인키트에 실행시키고자 하면 □Vision에서 만든 Hex file을 이에 다운로드하여 실행시키고, 그림 7.11과 같은 실제 시스템에 실행시키고자 하면 ROM 라이터를 이용하여 Hex 파일을 8751 또는 AT89S51 또는 AT89C2051에 다운로드 한 후 동 그림과 같은 시스템에 꽂는다. 8051은 mask ROM이기 때문에 실현이 어렵다.

디지털제어 산업기사 8051 MICOM 보드에 실행시키고자 하면 □Vision에서 Hex 파일을 만들고, MICOM PROGRAMMER에서 □열기□와 □자동□작업을 통하여 Hex 파일을 MICOM 보드에 기록한다. 기록이 이루어지면 즉시 실행되어 LED가 점멸할 것이나, 시간 간격이 너무 짧아서 구별하기 힘들 것이다.

(6) 課 題

1. 프로그램이 시작되면 LED가 00H에서 FFH까지 2진수 형태로 4000□초간격으로 증가하는 프로그램을 작성하라.(단, 발진주파수는 22.1184MHz이다.)

7.5.2 오버플로 플래그의 기능

(1) 目 的

경우에 따라서는 인터럽트를 이용하지 않고 일정의 시간을 얻어야 할 경우가 있다. 그런 경우에는 인터럽트 플래그(TF0 또는 TF1)를 이용한다. 그 구체적인 예로서 앞에서와 동일한 일을 타이머 0를 사용하여 하되, 인터럽트를 이용하지 말고 TCON 레지스터의 인터럽트 플래그 비트(TF0)를 이용하고자 한다. 그리고 시간간격도 4000□초 대신 40000□초(0.04초)로 하고자 한다.

(2) 順序圖

그림 7.13  오버플로 플래그에 의한 지연 순서도

인터럽트를 이용하지 않으므로 인터럽트 벡터 번호의 선언도, IE 레지스터 및 IP 레지스터의 설정도 필요없다. 모드 0의 카운트 레지스터(TH0)가 255에서 0으로 바뀌어지면 TCON 레지스터의 인터럽트 플래그 비트(TF0)는 인터럽트 발생 여부와는 관계없이 세트되므로, 이 비트가 세트되기를 기다렸다가, 세트되면 소정의 시간이 지난 것이기 때문에 인터럽트 루틴에서 했던 일을 Main 루틴에서 직접한다. 일을 마치면 플래그 비트를 클리어시키는 일을 잊지 않도록 해야 한다. 타이머 인터럽트의 경우에는 자동으로 클리어되지만, 플래그를 이용하는 경우에는 자동적으로 클리어되지 않으므로 인위적으로 클리어시켜야 한다. 만약  클리어시키지 않으면 계속 소정의 시간이 지난 것으로 되어 곧바로 인터럽트에 들어가므로, 뒤죽박죽 엉망이 된다.

(3) 프로그램(EX7_2.C)

/*===================================================*/

/* PROGRAM EX7_2.C) (TIMER0 MODE 0 overflow function)	*/

/*===================================================*/

#include <reg51.h>	/* 8051 헤더 파일의 include */

unsigned char number,count	/* 변수 정의 */

void delay(void)  {	/* 지연함수 */

count = 10;	/* 총 지연시간을 4000u초의 10배로 하기 위함임*/

do {

while( !TF0);	/* TF0=1인가? 4000□초가 지났는가? */

TF0 = 0;	/* yes이면 TF0의 클리어 */

TH0 = 0x1a;	/* 시간정수의 재정의, 0x1a=(8192-7373)/32 */

count--;	/* TF0=1일 때마다 COUNT 값을 하나씩 감소*/

}while(count);	/* 10*4000□초가 경과되었는가?*/

}

void main(void)  {	/* 메인 함수 */

TMOD = 0x00;	/* 타이머0를 모드 0의 타이머로 */

TH0 = 0x1a;	/* 0x1a=(8192-7373)/32, 지연 루틴의 시간정수 */

ET0 = 1;	/* ET0=IE.1, 인터럽트 개별 허용 */

EA = 0;	/* 전체 허용, 이 두 명령은 없어도 됨 */

number = 0xfe;	/* 최초의 출력데이터 */

TR0 = 1;	/* 타이머0 run */

do {

P1 = number;	/* 포트 1에 준비된 데이터를 출력 */

delay();	/* 8000×5[eqn: mu]초 지연 */

number = (number << 1) □ 1;	/* 다음 차례의 출력데이터를 준비 */

if (number == 0xff) number=0xfe;	/* LED7까지 on했으면 최초의 상태로*/

}while(1);	/* 반복하라 */

}

(4) 프로그램의 해설

while(％TF0 );

while(!TF0)는 TCON 레지스터의 비트 5, 즉 TF0가 0인한 이 루프를 반복한다. 4000□초가 지나면 TF0가 1로 세트되므로 그때까지 기다린다. 원래 while 문은 while( )의 ( )내 값이 논리 1인 한 그 루프를 맴돈다. 여기서 논리 1은 0이 아닌 한 모두 논리 1이다. 이 명령의 경우 ( )내가 !TF0이므로, TF0가 0이어야 !TF0가 1이 되므로 결국 TF0가 0인한 이 루프를 맴돈다. 이 명령은 다음과 같이 해도 된다.

do {

flag = TCON;

} while ((flag & 0x20) == 0);

앞에서 언급한 바와 같이 이 경우는 인터럽트에 의존하는 경우가 아니므로 조건이 성립된 후 TF0를 반드시 클리어시켜야 한다.

count = 10;

＞

TH0 = (8192-7373)/32

count --;

앞의 조치로 4000□초마다 TF0가 세트되는데 이것을 10번 반복하라는 것이다. 결국 4000×10=40000□초의 지연을 얻기 위함이다. 한번 TF0를 세트할 때마다 TH0 시간정수를 재 정의함을 잊지 말아야 한다.

do {

＞

count--;

}while(count);

여기에서도 while(count)는 while(count !=0)과 같다. count값이 0이 될 때까지 {}내의 명령들을 반복 수행하라는 것이다. 원래 count값은 10이었으나 4000□초마다 하나씩 감소되어 마침내 0이 되면 이 루프를 벗어난다.

TR0=1;

원칙으로 한다면 이 명령이 DELAY 루틴의 맨 처음에 들어가고, TR0=0는 마지막에 들어가야 하나, DELAY 루틴 외의 명령이 4000[eqn: mu]초 이내에 끝나므로 메인루틴에 두어도 상관 없다.

number = (number << 1) □ 1;

number의 내용을 좌로 1비트 시프트하고 그 빈자리에는 1로 채우라는 것이다.

(5) 프로그램의 實行

앞 문제를 실행한 뒤라면 이미 project open은 되어 있으므로 곧바로 □Vision의 edit project로 들어가서 위 프로그램을 open된 프로젝트에 포함시키고 Build Project에서 어셈블 또는 컴파일을 하고 링킹을 함으로써 Hex file과 Obj file을 만든다.

시뮬레이트하고자 하면, dScope에서 프로젝트 지정을 다시 해서 그 프로젝트를 불러오고 (CPU 및 pheripheral은 앞에서 선택된 것을 그대로 씀), 4번째 툴바에서 Go에 클릭함으로써 프로그램을 실행시킨다. 4000□초의 10배(0.04초)마다 포트의 상태가 바꿔짐을 관찰할 수 있을 것이다.

디지털제어 산업기사 8051 MICOM보드에 실행시키고자 하면 □Vision에서 얻은 Hex파일을 MICOM PROGRAMMER에서 □열기□와 □자동□을 통하여 MICOM 보드에 기록해 넣는다. MICOM 보드의 아래 공간을 이용해서 포트 1에 연결할 LED들을 미리 만들어 놓는 게 좋다.

(6) 課 題

1. 위 프로그램에서 0.04초 대신 1초마다 LED 상태가 쉬프트되도록 하라.

7.5.3 타이머 모드 1 실험

(1) 目 的

역시 위에서와 같은 일을 하되 타이머 1의 모드 1을 이용하고, 시간 간격은 0.025초(25000□초)가 되도록 하고자 한다.

(2) 順序圖

그림 7.14  타이머 1의 모드 1 실험 순서도

(3) 프로그램(EX7_3.C)

/*====================================*/

/* PROGRAM EX7_3.C) (TIMER1 MODE 1) */

/*====================================*/

#include <reg51.h>	/* 8051 헤더파일을 include */

unsigned char number;	/* number=8비트 변수 */

void TMR1_int(void) interrupt 3 {  /* 벡터 넘버=3의 인터럽트 루틴 */

EA = 0;	/* 인터럽트 disable */

TF1 = 0;	/* TF1=TCON.7, 인터럽트 플래그의 클리어 */

P1 = number;	/* 준비된 데이터를 포트 1에 출력*/

number = (number << 1 □ 1);	/* 다음차례의 출력데이터를 준비 */

if (number == 0xff) number=0xfe;	/* LED7이 on되었으면 초기상태로 */

TH1 = 0x4c;	/* 25000□초를 얻기 위한 시간정수의 재정의 */

TL1 = 0x00;

EA =1;	/* 인터럽트 enable */

return;

}

void main(void)  {	/* 메인 함수 */

TMOD = 0x10;	/* 타이머 1을 모드 1의 타이머로 */

TH1 = 0x4c;	/* 25000u초를 얻기위한 시간정수 */

TL1 = 0x00;

ET1 = 1;	/* ET1=IE.3, 인터럽트 개별 허용 */

EA = 1;	/* EA=IE.7, 전체 허용 */

PT1 = 1;	/* PT1=IP.3, 우선순위를 high로 */

TR1 = 1;	/* 타이머1 run */

number = 0xfe;	/* 최초의 출력데이터 */

while(1);	/* 인터럽트가 발생되기를 기다린다 */

}

(4) 프로그램의 解說

TMOD = 0x10;

TH1 = 0x4c;

TL1 = 0x00;

TMOD=0x10;이므로, 타이머 1은 모드 1의 타이머로 된다.

이런 조건에서 0.025초의 시간간격을 얻기 위해서는 타이머 카운트레지스터의 TH1와 TL1의 값을 얼마로 해야 하는가가 문제이다. 모드 1에서 타이머 1은 16비트 타이머/카운터로 되므로 최대 카운트 값은 216Ａ65536이다. 발진주파수가 22.1184MHz라면 타이머로 동작할 때에는 이것이 12로 분주된 것이 카운트 레지스터에 들어가므로, 25000□초(0.025초)를 얻기 위해서는 f =1/t 의 관계에서

22.1184MHz →	[eqn: 1 over 12]	→	[eqn: RM 1 OVER □]	Ａ	[eqn: 1 over 0.025]

x = 46080

그런데 8051 타이머는 up-counting을 하므로 모드 1의 최대값 65536에서 이 값을 빼주어야 하므로 19456(65536-46080)을 TH1와 TL1에 넣어 주어야 한다. 19456에서 65536 (FFFFH+1)까지 46080개의 카운트를 해야 하기 때문이다. 그런데 19456=4C00H이므로, TH1에는 4CH를 TL1에는 00H를 넣어준다.

(5) 프로그램의 實行

프로그램 작성이 끝나면 □Vision의 edit project에서 프로그램을 지정하고 build project로 어셈블 또는 컴파일 그리고 링킹을 함으로써 Hex file과 Obj file을 만든다.

시뮬레이트하고자 하면 dScope에서 먼저 File 밑의 툴바에 클릭하여 프로젝트를 다시 지정 호출한다. 그리고 peripheral에서 인터럽트 타이머 1과 포트 1을 택하고 타이머 1의 창을 연 다음 (타이머의 경우에는 인터럽트 창과 타이머 창은 반드시 필요한 것은 아님) 실행시키면 0.025초마다 포트 1의 상태가 바뀌는 것을 볼 수 있을 것이다.

실제 시스템 또는 트레인키트에 실행시키고 싶으면 □Vision에서 얻은 Hex파일을 ROM라이터로 8751 또는 AT89S51 또는 AT89C2051에 기록한 뒤 그림 7.11과 같은 회로에 꽂는다.

디지털제어 산업기사 8051 MICOM 보드에 실행시키고자 하면 MICOM PROGRAMMER에서 □열기□와 □자동□작업으로 □Vision에서 얻은 Hex파일을 기록한다.

(6) 課 題

1. 동일한 일을 타이머 0으로 해 보라.

2. 0.025초 대신 0.5초마다 LED 상태가 바꿔지도록 해라(힌트, count=20으로 한 다음 인터럽트 발생시마다 count--를 해서 그것이 0일 때에만 p1=number; (number<<1)  □  0x01; count=20 등의 일을 하도록 하면 된다).

7.5.4 로켓 발사 카운트

(1) 目 的

로켓 발사시에는 9부터 매초 다운 카운트를 하다가 0이 되면 발사가 되는 것을 볼 수 있다. 이것을 모의하는 프로그램을 작성코자 한다. 단 숫자 표시는 포트 1에 2진수 형태로 하기로 한다.

(2) 順序圖

그림 7.15  로켓 발사 카운트 순서도

(3) 프로그램(EX7_4.C)

/*==================================*/

/* PROGRAM EX7_4.C) (ROCKET FIRE)   */

/*==================================*/

#include <reg51.h>	/* 8051 헤더파일의 include */

unsigned char number,count;	/* 변수의 정의 */

void delay2(int i)  {	/* 약간의 지연 */

while(i--);

}

void delay(void)   {	/* 1초 지연 함수 */

count = 40;	/* 시뮬레이팅에서는 count=2*/

do {

while(!TF1);	/* 0.025초 경과되었는가? */

TF1 = 0;	/* 플래그의 클리어, 이 때에는 반드시 필요함 */

TH1 = 0x4c;	/* 시간정수를 다시 정의한다. */

TL1 = 0x00;

count--;	/* counter를 감소 */

}while(count);	/* count=0인가?, 1초가 되었는가? */

}

void main(void)

{

TMOD = 0x10;	/* 타이머1을 모드1의 타이머로 */

ET1 = 1;	/* ET1=IE.3, 인터럽트 개별 enable */

EA = 0;	/* 전체 enable */

TR1 = 1;	/* 타이머 1 run */

number = 10;	/* 최초의 출력 데이터 */

do {

number--;

P1 = number;	/* number를 P1에 출력 */

delay();	/* 0.025*40=1초 지연 */

}while(number);	/* number=0이면, 루프에서 벗어나라 */

do {

P1 = 0xff;	/* 로켓 발사 모양을 흉내낸다. */

delay2(8000);

P1 = 0;

delay2(8000);

}while(1);

}

(4) 프로그램의 解說

void delay(void) {

count = 40;

do {

while (!TF0);

TF1 = 0

TH1 = 0x4c;

TL1 = 0x00;

count--;

} while(count);

}

앞에서 밝힌 바와 같이 지연루틴의 최초와 최후에 TR1=1과 TR1Ａ0을 넣어야 하나, TR1=1을 메인 루틴에 넣어놓고 있어서 타이머1은 계속해서 동작한다. 그러므로 DELAY 루틴의 마지막에 있는 TH1Ａ0x4c;와 TL1Ａ0x00;가 실행되면 타이머1의 카운트 레지스터(TH1, TL1)가 이 값으로 바꿔진 후 up counting을 계속하다가 FFFFH에서 0으로 되면서 TF1을 세트시킨다.

number = 10;

do {

number--;

P1 = number;

delay();

}while(number);

numberＡ9에서 하나씩 감소하다가 마침내 0이 되면 이 루프에서 벗어나도록 한 것이다. 그 사이에 number의 내용을 포트 1에 표시하고 1초를 기다리는 일을 반복한다. while(number)로 numberＡ0가 될 때까지 루프를 반복하도록 하고 있다. number--; P1Ａnumber 대신 P1=number--로 하면 10부터 표시되나 0이 표시되지 않는다.

(5) 프로그램의 實行

역시 제4장에서 설명한 방법에 따라 □Vision에서 open project와 edit project 작업을 통하여 open된 프로젝트에 본 프로그램을 포함시키고, build project 작업을 통하여 이 프로그램을 어셈블 또는 컴파일하고 링크함으로써 Hex file과 Obj file을 만든다.

시뮬레이트를 하고자 하면 dScope의 pheripheral에서 port의 포트 1, interrupt의 time 1, timer의 timer 1의 창을 만들어 놓고(interrupt와 timer창은 반드시 필요하지는 않는다), 4번째 툴바에 클릭함으로써 프로젝트를 지정한 후 GO한다.

트레인키트에 실행시키고자 하면 □Vision에서 만든 Hex file을 다운로드해서 실행시킨다.

실제 시스템에 실행시키고자 하면 Hex 파일을 8751 또는 AT89S51 또는 AT89C2051에 ROM 라이터로 기록한 후 그림 7.11과 같은 시스템에 꽂는다.

디지털제어 산업기사 MICOM보드에 실행시키고자 하면 역시 □Vision에서 얻은 Hex 파일을 MICOM PROGRAMMER에서 □열기□와 □자동□을 통하여 기록한다.

(6) 課 題

위에서는 1초의 지연을 얻는 데 타이머 오버플로 플래그 TF1이 세트되는 것을 이용하고 있는데, 이것을 인터럽트 루틴으로 실현하라.

7.5.5 카운터 기능

(1) 目 的

그림 7.16  카운터 실험 시스템

타이머 1을 카운터로 사용하는 방법을 익히기 위해서 그림 7.16과 같은 시스템에서 T1(P3.5)에 연결된 스위치를 누를 때마다 포트 1의 LED가 하나씩 증가하는 형태로 on되는 프로그램을 작성하고자 한다.

(2) 順序圖

그림 7.17  카운터 실험 순서도

(3) 프로그램(EX7_5.C)

/*============================================*/

/* PROGRAM EX7_4.C) (TIMER1 COUNTER MODE)  */

/*============================================*/

#include <reg51.h>	/* 8051 헤더 파일의 include */

unsigned char counter;	/* number=8비트 변수 */

void delay (long i) {

while (i--);

}

void TMR1_int(void) interrupt 3 {	/* 벡터 넘버=3의 인터럽트 발생시 TMR1_int로 */

EA = 0;	/* 인터럽트 불능 */

counter++;	/* counter의 내용을 하나 증가 */

P1 = ∼counter;	/* LED에 출력*/

TH1 = 0xff;	/* TH1과 TL1 값을 다시 정의 */

TL1 = 0xff;

delay (0x10000);

EA =1;	/* 인터럽트 enable */

return;

}

void main(void) {	/* 메인 함수 */

TMOD = 0x50;	/* 타이머1을 모드 1의 카운터로 */

TH1 = 0xff;	/* T1에 펄스 하나만 들어오면 인터럽트가 발생되도록*/

TL1 = 0xff;

ET1 = 1;	/* 인터럽트 개별 허용 */

EA = 1;	/* 전체 허용 */

PT1 = 1;	/* 우선 순위를 high로 */

TR1 = 1;	/* 타이머1 run */

counter = 0xff;	/* 초기 LED를 클리어 */

P1 = counter;

while(1);	/* 인터럽트 대기 */

}

(4) 프로그램의 解說

TMOD = 0x50;

TH1 = 0xff;

TL1 = 0xff;

처음 명령은 타이머 1을 모드 1의 카운터로 사용하기 위한 조치이고(그림 7.1 참조), 두 번째와 세 번째 명령은 T1을 통하여 펄스가 하나만 들어오면 FFFFH→0000H로 되어 인터럽트가 발생되도록 하기 위함이다.

void TMR1_int(void) interrupt 3 {

＞

counter++;

＞

delay (0x10000);

EA = 1;

P1 = ~counter;

인터럽트 루틴에서는 인터럽트 발생수를 counter에 누적하여 포트 1에 표시함으로써 실질적으로는 T1을 통하여 들어오는 펄스의 수를 나타나게 된다. counter 값을 직접 P1에 출력하지 않고 보수를 취한 것은 LED 연결이 전류흡입형로 되어 있기 때문이다. 인터럽트 루틴에서도 TH1과 TL1의 값을 동일하게 FFFFH로 하고 있는데, 이 조치가 없다면 65536개의 펄스가 들어와야 LED가 하나 증가될 것이다. 그리고 EA=1 이전에 delay 루틴을 가진 것은 다음번 인터럽트가 가능하기 전에 지연시간을 두어서 스위치를 한번 누르면 여러번 카운트되는 것을 막기 위함이다.

(5) 프로그램의 實行

□Vision에서 프로젝트와 프로그램을 지정하고 어셈블 및 컴파일 그리고 링킹을 함으로써 Hex file과 Obj file을 만든다.

시뮬레이션을 하고자 하면 dScope의 peripheral에서 포트 1과 포트 3을 선택하고, 프로젝트를 지정한 후 프로그램을 실행(시뮬레이트)시킨다. 창이 2개나 되므로 이들을 적당한 위치에 옮긴후 실행에 들어가야 한다. P3.5에 두 번 클릭을 할 때마다 T1에 연결된 스위치를 한번 누르는 것으로 되므로 그때마다 포트 1의 공란 값이 하나씩 증가됨을 관찰할 수 있을 것이다. 거듭 밝히지만 카운터값을 증가해야 함에도 불구하고 감소한 것은 LED의 연결 상태가 전류흡입형으로 되어 있기 때문이다. 8051은 PIC 제품과는 달리 공급 전류량이 LED를 구동하기에 부족하므로(제5장에서 논한 약한 1, 강한 0 때문임) 전류흡입형으로 LED를 연결할 수 밖에 없다. 시뮬레이터에서는 counter-- 대신 counter++로 바꾸든지, 아니면 ∨대신 공란의 변화를 보면 된다.

시뮬레이트 대신 트레인키트로 실험을 하고자 할 때에는 □Vision에서 만든 Hex file을 다운로드한다.

그림 7.16과 같은 실제 시스템으로 실험하고자 하는 경우에는 8051 대신 8751 또는 AT89S51 또는 AT89C2051에 ROM 라이터를 써서 Hex file을 다운로드한다.

디지털제어 산업기사 8051 MICOM 보드에서 실행시키고자 하면 MICOM PROGRAMMER에서 □열기□와 □자동□을 통하여 Hex파일을 다운로드한다.

(6) 課 題

1. 위에서는 소프트웨어 카운터를 이용하였다. 동일한 일을 하드웨어 카운터를 이용하여 하라.(힌트 : TH1ＡTL1Ａ0, P1ＡTL1)

7.5.6 타이머1 모드 2 실험

(1) 目 的

이것 역시 그림 7.11과 같은 시스템에서 LED가 2진 가산 형태로 점멸하는 일을 하되 타이머 1의 모드 2를 이용하고, 시간 간격은 0.0325초로 하고자 한다.

(2) 順序圖

그림 7.18  모드 2(auto-reload)의 순서도

(3) 프로그램(EX7_6.C)

/*====================================*/

/* PROGRAM EX7_6.C) (TIMER1 MODE 2)  */

/*====================================*/

#include <reg51.h>	/* 8051 해더 파일의 include */

unsigned char number,count;	/* number, count=8비트 변수 */

void TMR1_int(void) interrupt 3	/* 벡터 넘버=3의 인터럽트 루틴 TMR1_int */

{

EA = 0;	/* 인터럽트 불능 */

TF1 = 0;	/* 인터럽트의 경우에는 없어도 상관없음 */

count --;

if ( count == 0 )	/* 250번 반복한 후에야 LED 상태를 바꾼다 */

{

P1 = ∼number;	/* 포트 1에 표시 */

number++;	/* 다음번 출력 데이터를 준비 */

count = 250;	/* 반복수의 재정의 */

}	/* 시간정수 재정의는 필요치 않음 */

EA =1;	/* 인터럽트 enable */

return;

}

void main(void)	/* 메인 함수 */

{

TMOD = 0x20;	/* 타이머1을 모드 2의 타이머로 */

TH1 = 0x07;	/* 시간정수=130uS; 22118400÷12*0.00013÷32 */

TL1=0x07;

ET1 = 1;	/* 인터럽트 개별 허용 */

EA = 1;	/* 전체 허용 */

PT1 = 1;	/* high 우선순위 */

number = 0;	/*최초의 출력데이터, LED를 클리어하기 위해서*/

TR1 = 1;	/* 타이머1 run */

count = 250;	/* 반복 수 */

while(1);	/* 인터럽트 대기 */

}

(4) 프로그램의 해설

count = 250;

＞

counter--

if (counter == 0) {

P1 = ~number;

number++;

count = 250;

}

EA = 1

모드 2에서 타이머 1은 8비트 타이머/카운터로 되므로, 22.1184MHz의 발진주파수에서 얻을 수 있는 최대 시간은 다음과 같이 계산하여 139□초 밖에 되지 않는다.

[eqn: 22118400* 1 over 12 * 1 over 256 = 1 over t]	∴ t Ａ139

본 프로그램에서는 그중 130□초만 얻고 있는데, 문제에서 요구한 것은 130□초가 아니고 32500□초(250×130□초)이므로, 인터럽트가 250번 들어와야만 LED가 바꿔지도록 하면 결과적으로 32500□초(0.0325초)마다 LED가 변하게 된다. P1=number로 하지 않고 PＡ~number로 한 것은 역시 LED 연결 상태가 전류공급형이 아니라 전류흡입형(sink)으로 되어 있기 때문이다.

(5) 프로그램의 實行

소스파일이 작성되었으면 역시 □Vision의 edit project에서 프로그램을 open된 프로젝트에 포함시키고, Build project 작업에서 어셈블 또는 컴파일과 링크를 함으로써 Hex file과 Obj file을 얻는다(4장 참조).

시뮬레이트를 하고자 하면 □Vision에서 앞에서와 같이 하고, dScope에서 프로젝트를 지정 호출한 후 실행을 시킨다. 0.0325(130×250□초)초마다 포트 1의 상태가 바꾸어 짐을 볼 수 있을 것이다. 시뮬레이터에서 공란으로 보면 증가되는 형태이다.

트레인키트에 실행시키고자 하면 Hex file을 다운로드하여 쓰고, 그림 7.11과 같은 실제 시스템에 실행시키고자 하면 ROM 라이터로 Hex file을 89S51 또는 89C2051에 다운로드하여 쓴다.

디지털제어 8051 MICOM보드에 실행시키고자 하면 역시 □Vision에서 얻은 Hex파일을 MICOM PROGRAMMER에서 □열기□와 □자동□을 통하여 8051 MICOM 보드에 기록해 넣는다.

(6) 課 題

1. 위의 일을 인터럽트 대신 오버플로 플래그를 이용해서 실현하라.

7.5.7 타이머 0의 모드 3 실험

(1) 目 的

위 프로그램과 같이 일정 시간간격으로 P1에 연결된 LED 상태가 앞에서와는 반대로 2진감산 형태로 바뀌되, 타이머 0의 모드 3을 사용하고 인터럽트 기능을 이용하지 말고, 시간간격을 0.03초가 되도록 하고자 한다.

(2) 順序圖

그림 7.19  모드 3 실험 순서도

(3) 프로그램(EX7_7.C)

/*====================================*/

/* PROGRAM EX7_7.C) (TIMER1 MODE 3)  */

/*====================================*/

#include <reg51.h>	/* 8051 헤더파일의 include */

unsigned char number,count;	/* 변수의 정의 */

void delay(void) {

count = 240;	/* 내부 루프를 240번 반복하기 위함임*/

do {

while(％TF0 );	/* 200□초 지연*/

TF0 = 0;	/* 플래그의 클리어*/

TL0 = 26;	/* 시간정수 26=256-230*/

count--;

}while(count);	/* 240*0.000125□초가 경과되었는가?*/

}

void main(void)	/* 메인 함수 */

{

TMOD = 0x03;	/* 타이머0 모드 3*/

TL0 = 26;	/* 최초의 시간정수, 26=(256-230) */

ET0 = 1;	/* ET1=IE.3, 개별적으로는 enable */

EA = 0;	/* 전체적으로는 disable, 두 명령은 없어도 됨 */

number = 0xff;	/* 최초의 출력데이터 */

TR0 = 1;	/* 타이머0 run */

do {

P1 = ∼number;	/* 포트 1에 출력 */

delay();

number++;	/* 다음번 출력데이터를 준비 */

}while(1);

}

(4) 프로그램의 解說(C)

void delay (void) {

count = 240;

do {

while( !TF0 );	/* 125□초가 지났는가? */

TF0 = 0;	/* 플래그 클리어 */

TL0 = 26;	/* 시간정수 재정의 */

count--;	/* 250에서부터 하나씩 감소 */

} while(count)	/* 200×250□초가 지났는가 */

}

TF0=1인지를 체크하는 내부의 지연루틴을 count=240번 반복하게 하는 지연루틴이다. 앞에서 수차 언급한 바와 같이 타이머 0나 1의 인터럽트에 있어서는 이를 클리어할 필요는 없다. 그러나 이 경우에는 인터럽트가 아니므로 반드시 클리어시켜야 한다.

while(!TF0)는 앞에서와 같이 TF0가 0인 한 루프를 반복수행하고, TF0=1이면 여기에서 빠져나오라는 것이다. while(count)도 count가 0이 아닌 한 반복 수행하라는 것이다.

TL0=26인 이유는 발진주파수Ａ22.1184MHz에서 0.000125초를 타이머 모드3으로 얻기 위해서는 다음의 계산에서 TL0에 26을 넣어주어야 하기 때문이다.

[eqn: 22118400 * 1 over 12 * 1 over x = 1 over 0.000125]	x =230	∴ TL=256-230=26

(5) 프로그램의 實行

역시 □Vision에서 open project(최초의 경우에만) edit project, build project 등의 작업을 하고, 시뮬레이트의 경우에는 dScope로 넘어간다. 여기에서는 프로젝트 이름을 다시 지정호출하고 pheripheral에서 포트 1과 인터럽트(타이머0)를 지정한 후 Go(실행)한다. 전류흡입형 연결의 LED에서는 2진감산 형태가 되나, 시뮬레이터에서는 2진가산 형태가 된다. 공란으로 보면 2진감산 형태가 된다.

트레인키트나 그림 7.11과 같은 실제 시스템에 실행시킬 경우에는 □Vision에서 만든 Hex file을 8751 또는 AT89S51 또는 AT89C2051에 다운로드해서 쓴다.

디지털제어 산업기사 8051 MICOM보드에 실행시킬 경우에는 역시 □Vision에서 Hex파일을 얻고, 이것을 MICOM PROGRAMMER에서 □열기□와 □자동□ 작업으로 MICOM 보드에 기록해 넣는다.

(6) 課 題

위의 일을 모드 3의 TH0 타이머로 하되 상태변환 시간은 0.03125초가 되도록 하라(힌트＞ 0.000125*250=0.03125).

7.5.8 타이머에 관한 종합 실험

(1) 目 的

타이머/카운터 0은 모드 0으로 4m초마다 인터럽트를 발생하여 1초마다 포트 1에 연결된 LED3∼0을 깜박이고, 타이머/카운터 1은 25m초마다 인터럽트를 발생하여 3초마다 LED7∼4를 깜박이도록 하고자 한다. 단 인터럽트 우선순위는 타이머 1 오버플루 인터럽트가 더 높도록 한다.

(2) 順序圖

타이머 0는 모드 0으로 4m초마다 인터럽트를 발생해야 하므로 다음의 계산에서 TH0에 넣어야 할 값은 0x1a이다.

[eqn: 22118400*1 over 12 * 1 over x = 1 over 0.004]   ∴ x = 7373

∴ TH0=(8192-7373)/32=26=0x1a

또 0.004초를 250번 반복해야 1초가 되므로 반복횟수 count0은 250이다. 반면 타이머 1은 모드 1로 25m초마다 인터럽트를 발생해야 하므로 다음의 계산에서 TH1과 TL1에 넣어야 할 값을 TH1=0x4c, TL1=0x00이다.

[eqn: 22118400* 1 over 12 * 1 over x = 1 over 0.025]   ∴x = 46080

TH1＞TL1 Ａ (65536１46080)Ａ19456Ａ0x4c00

또 0.025초를 120번 반복해야 3초가 되므로 반복횟수 count1은 120이다.

그림 7.20 종합실험에 대한 순서도

(3) 프로그램(EX7_8.C)

/*=============================================*/

/* PROGRAM EX7_8.C) (TIMER0 & TIMER1 interrupt) */

/*=============================================*/

#include <reg51.h>	/* 8051 header file의 include */

unsigned char count0,count1;

void TMR0_int(void) interrupt 1	/* TMR0 인터럽트 루틴 */

{

EA = 0;

TF0 = 0;	/* TF0=TCON.5, interrupt flag의 클리어*/

count0--;

if (count0 ==0){

P1 ^= 0x0f;	/* LED3-LED0 on/off*/

count0 =250;

}

TH0 = 0x1a;	/* 4m초 시간정수의 재정의 */

EA =1;

return;

}

void TMR1_int(void) interrupt 3	/* TMR1 인터럽트 루틴 */

{

EA = 0;

TF1 = 0;	/* TF1=TCON.7, interrupt flag의 클리어*/

count1--;

if (count1 ==0){

P1 ^= 0xf0;	/* LED7-LED4 on/off*/

count1 =120;

}

TH1 = 0x4c;	/* 25m초를 위한 시간정수*/

TL1 = 0x00;

EA =1;

return;

}

void main(void)

{

TMOD = 0x10;	/* timer1 mode 1; timer0 mode 0*/

TH0 = 0x1a;	/* 1aH=(8192-7373)/32; 4mS를 위한 시간정수 */

TH1 = 0x4c;	/* 4c00H=(65536-460801);25mS를 위한 시간정수 */

TL1 = 0x00;

count0 =250;	/* repeat times of interrpt 0*/

count1 =120;	/*   "      "         "     1*/

ET0 = 1;	/* ET0=IE.1, enable timer interrupt 0 */

ET1 = 1;	/* ET1=IE.3, enable timer interrupt 1 */

EA = 1;

PT1 = 1;	/* PT1=IP.3 */

TR0 = 1;	/* run timer0*/

TR1 = 1;	/* run timer1*/

while(1);

}

(4) 프로그램의 解說

count0--;

if (count0 ==0){

P1 ^= 0x0f;

count0 =250;

}

인터럽트가 발생할 때마다 count0값을 하나씩 감소하다가 마침내 0이 되면 LED3∼LED0 값을 바꾸고, count0값을 본래의 값으로 하라는 것이다. 4(m초)*250=1(초)이기 때문이다.

(5) 프로그램의 實行

제4장에서 설명한 방법에 따라 □Vision의 open Project에서 프로젝트를 지정하고(이미 open되어 있으면 생략), edit project에서 프로그램(ex7_8.C)을 지정한 후 build project에서 컴파일과 링킹을 함으로써 Hex file과 Obj file을 만든다.

이것으로 시뮬레이트를 하고자 하면 dScope에 들어가서 CPU를 선택하고(이미 선택되어 있으면 역시 생략함) pheripheral에서 포트 1과 인터럽트 timer0와 timer1을 선택한 후 □File□밑 툴바에 클릭하여 □Vision에서 open된 프로젝트를 불러온다. 그런 뒤 Go에 클릭하면 요구된 것대로 포트 1의 상태가 바뀌짐을 확인할 수 있을 것이다.

트레인키트에 실행시키고자 하면 Hex file을 이에 다운로드하여 실행시키고, 그림 7.11과 같은 실제 시스템에 실행시키고자 하면 ROM 라이터를 이용하여 Hex 파일을 8751 또는 AT89S51 또는 AT89C2051에 다운로드한 후 그림 7.11과 같은 시스템에 꽂는다. 8051은 mask ROM이기 때문에 실현이 어렵다.

디지털제어 산업기사 8051 MICOM 보드에 실행시키고자 하면 □Vision에서 Hex 파일을 만들고 MICOM PROGRAMMER에서 □열기□와 □자동□작업을 통하여 Hex 파일을 MICOM 보드에 기록한다. 기록이 이루어지면 즉시 실행되어 LED가 점멸한다.

(6) 課 題

이 프로그램에 타이머0의 우선순위를 더 높게 하고, 타이머1은 5초마다 깜박이도록 하라.

1. 8051은 독립된 두 개의 16비트 타이머/카운터를 내장하고 있다.

2. TMOD는 GATE, C/ T, M1, M0 등을 제어한다. GATE는 외부에서 start/stop을 제어할 때 사용되고, C/ T는 카운터로 사용할 것인지 타이머로 사용할 것인지를 결정하며, M1과 M0는 동작모드를 결정한다.

3. TCON은 타이머/카운터와 외부 인터럽트를 제어한다. 상위 4비트 중 TF1과 TF0는 오버플로 플래그이고, TR1과 TR0는 타이머/카운터의 run/halt를 제어한다. 그리고 하위 4비트 중 IE1과 IE0는 외부 인터럽트의 edge flag이고, IT1과 IT0는 edge trigger인지 level trigger인지를 결정한다.

4. 타이머/카운터가 모드 0으로 되면 13비트 타이머/카운터로 동작한다. 13비트 중 TLx의 5비트는 prescaler로서 동작하므로, THx의 값만 정해주면 된다.

TH0=(8192１5000)/32

5. 타이머가 모드 1로 되면 16비트 타이머/카운터로 동작한다.

TH0=>(65536１50000)  (단 >는 16진 표시의 상위 2단위라는 뜻임)

TL0=<(65536１50000)  (단 <는 16진 표시의 하위 2단위라는 뜻임)

6. 8051 타이머가 모드 2로 되면 8비트 자동 재장전의 타이머/카운터가 된다. 모드 2에서는 TLx가 카운트 레지스터로 사용되고, 여기에서 오버플로가 발생하면 THx의 내용이 TLx에 자동으로 다시 로드된다.

7. 모드 3에서 타이머 0은 독립된 2개의 8비트 타이머/카운터로 동작하고, 타이머 1은 보율생성기로 동작한다.

8. 타이머 0와 1에는 게이트 기능이 있어서 게이트 핀(INT0 또는 INT1)에 입력되는 펄스의 high 부분에서만 카운트 동작을 하도록 프로그램 할 수 있다. 이 기능을 이용하여 주파수를 측정할 수도 있고, 펄스의 기간도 측정할 수 있다(제18장 참조).

9. 타이머 0 또는 타이머 1을 사용할 때 주의할 것은 모드 2 외에는 자동 재정전이 되지 않는다는 것이다. 그러므로 모드 2 외에는 인터럽트 루틴 내에서 시간정수를 다시 로드해 주어야 한다.

7.1 8051의 타이머 0을 모드 0의 타이머로 사용하기 위한 명령을 쓰라.

7.2 타이머 0를 모드 1의 카운터로 사용하되 20개의 펄스가 T0에 들어오면 인터럽트가 발생되는 부분 프로그램을 쓰라.

7.3 타이머 1을 모드 2의 타이머로 하되 22.1184MHz에서 100□초마다 인터럽트가 발생되도록 하는 부분 프로그램을 쓰라.

7.4 타이머 0를 모드 3의 타이머로 사용하되 22.1184MHz에서 100□초마다 인터럽트가 발생되도록 하는 부분 프로그램을 쓰라.

7.5 외부 발진주파수가 22.1184MHz일 때 타이머 1을 이용하여 120□초마다 인터럽트가 발생되도록 하고, 이것을 이용하여 12m초마다 포트 1에 연결된 LED가 이동되도록 하라.

8.1 직렬포트 개요 8.2 직렬포트 관련 레지스터 8.3 직렬포트의 인터럽트 8.4 직렬포트의 동작 모드 8.5 비동기식 통신모드의 송수신 시퀀스	8.6 다중 프로세서 직렬 통신 8.7 직렬포트의 인터페이스 8.8 직렬포트에 관한 실험 8.9 이 장의 간추림

8051은 직렬포트(USART)를 하나 내장하고 있는데, 이것은 그림 8.2와 같이 8비트 병렬 데이터를 직렬 형태로 바꾸어서 외부에 송신하고, 반대로 외부로부터 수신된 직렬 데이터를 8비트 병렬 데이터로 바꾸어서 CPU에 입력하는 역할을 한다.

8051의 직렬포트는 제2장에서 언급한 바와 같이, 전이중(full duplex) 방식으로서, 이것은 송신과 수신을 동시에 할 수 있다는 점에서 송신과 수신을 번갈아 하는 반이중(half duplex) 방식과 구분된다. 또 8051의 직렬포트는 수신버퍼(receive buffered) 방식으로 되어 있는데, 이 방식에서는 수신부의 데이터 버퍼가 2중 구조로 되어 있어서 앞에서 수신한 바이트가 수신레지스터(SBUF)로부터 읽혀지기 전에 두 번째 바이트가 수신되어도 오버플로 착오(overflow error)가 발생되지 않는다. 단, 두 번쨰 바이트가 수신 완료될 때까지 첫 번째 바이트가 판독되지 않으면 두 바이트 중 어느 하나가 상실된다.

8051의 직렬포트는 인텔 80C186 및 자이로그의 Z88C00(Super-8)의 직렬포트와 기능적으로 매우 흡사하다.

직렬포트의 송신 및 수신은 SBUF을 통하여 이루어지는데, SBUF의 주소는 송신과 수신의 경우 모두 같지만(88H 번지), SBUF에 기록(write)을 하는 것은 물리적으로 전혀 다른 송신 레지스터에 기록하는 것이고, SBUF를 읽어드리는 것은 물리적으로 전혀 다른 수신

그림 8.1  직렬포트가 8051에서 차지하는 위치

그림 8.2 직렬포트의 역할

레지스터의 내용을 읽어드리는 것이다. 다시 말해서 SBUF라 하더라도 수신과 송신의 경우에 주소는 같아도 실제 사용되는 레지스터는 전혀 다르다.

직렬포트의 보율(baud rate)은 동작 모드에 따라 다르다. 모드 0과 2는 외부 발진주파수(oscillator frequency)에 고정적이고, 모드 1과 3에서는 타이머 1(8052의 경우에는 타이머 2)의 오버플로 율(overflow rate)에 따라 가변적이다.

직렬포트에는 4개의 동작 모드가 있어서 사용자는 그 중 어느 것을 택하여 사용한다. 각 모드의 요점은 다음과 같다.

모드 0 : I/O 확장용의 동기식 통신 모드이다. 보율(baud rate)은 발진주파수의 1/12에 고정된다.

모드 1 : 10비트 프레임의 표준 비동기식 통신 모드이다. 보율은 가변적이다.

모드 2 : 11비트 프레임의 비동기식 통신 모드이다. 보율은 발진주파수의 1/32 또는 1/64에 고정된다.

모드 3 : 11비트 프레임(frame)의 비동기식 통신 모드로, 보율이 가변적이라는 것을 제외하고는 모드 2와 같다. 일반적으로 모드 2와 모드 3은 다중 프로세서 통신에 사용된다.

어느 모드에서도 송신은 MOV SBUF, A(C에서는 SBUF=tx_data)와 같은 명령으로 SBUF(TX)에 기록(write)을 함으로써 시작된다.

반면 수신은 모드 0에서는 SCON 레지스터의 REN=1인 상태에서 역시 SCON 레지스터의 RI를 클리어함으로써 시작되고, 다른 모드에서는 SCON의 REN=1인 상태에서 start 비트가 수신되면 시작된다.

직렬포트에 관한 레지스터에는 SBUF, SCON, PCON 등이 있다. 이 외에도 인터럽트 편에서 다룬 IE, IP 등의 레지스터가 직렬포트 인터럽트에도 관여된다.

(1) SBUF

SBUF(Serial port BUFfer register)는 송신할 데이터와 수신한 데이터를 일시 보존하는 역할을 한다. 전술한 바와 같이, 물리적으로 SBUF는 데이터를 읽어(read)드릴 때와 기록(write)할 때 각각 다르다. 즉 SBUF에 데이터를 기록할 때에는 송신 레지스터로서의 SBUFTX에 접근되고, SBUF를 읽어드릴 때에는 주소는 동일하나 물리적으로 전혀 다른 수신 레지스터로서의 SBUFRX에 접근된다.

역시 앞에서 언급한 바와 같이, 수신부의 수신 레지스터(SBUF)는 2중 구조로 되어 있어서 첫 번째 수신 데이터가 읽혀지기 전에 두 번째 데이터가 들어와도 overrun error를 발생하지 않는다.

(2) SCON 레지스터

SCON(Serial port CONtrol register)은 직렬포트의 제어와 상태의 표시를 위한 것으로, 구체적으로는 다음과 같은 것들을 제어한다.

·동작 모드의 선택(SM0, SM1)

·모드 2 또는 3에서 송수신 8번째 데이터 비트(TB8, RB8)

·다중 프로세서 통신을 위한 인터럽트 제어(SM2)

·수신 가능 제어(REN)

·송수신 완료 플래그(RI, TI)

그림 8.3  SCON 레지스터

SM0, SM1 : 직렬포트의 동작 모드를 결정한다. 이들 비트의 내용이 □00□이면 모드 0으로 되고, □01□이면 모드 1로 되며, □10□이면 모드 2로 되고, □11□이면 모드 3으로 된다.

SM2 : 모드 2나 3에서 이 비트는 다중 프로세싱을 가능케 하는 데 사용된다. 모드 2나 3에서 이 비트를 □1□로 세트해 두면 수신된 데이터의 8번째 비트(RB8)가 □1□인 경우에만 데이터를 수신하고 벡터 23H의 직렬포트 인터럽트(受信 인터럽트)를 요청한다. 그리고 이 비트를 □0□으로 해두면 수신 데이터를 받아드리지도 않고 RI가 동작하지 않아서 인터럽트를 요청하지도 않는다. 이 기능을 이용하면 다중 프로세서 시스템에서 프로세서 상호간에 직렬통신을 하게 할 수 있다. 모드 0에서는 이 비트를 클리어해 두어야 하고, 모드 1에서는 SM2=1이면 유효한 stop 비트가 수신되지 않는한 RI가 동작하지 않는다.

REN(Receive Enable) : 이 비트는 수신 가능 여부를 결정한다. 소프트웨어로 이 비트를 세트시키면 수신 가능으로 되고, 리세트시키면 수신 불능으로 된다.

TB8(Transmit Bit 8) : 모드 2 또는 3에서 송신될 8번째 비트이다. 다음과 같은 명령으로 SCON 레지스터의 비트 3을 세트 또는 클리어함으로써 이 비트를 세트 또는 클리어시킬 수 있다.

SCON=0bxxxx1xxx	// TB8=1

SCON=0bxxxx0xxx	// TB8=0

RB8(Receive Bit 8) : 모드 2 또는 3에서 수신된 8번째 비트 TB8이 자동적으로 이 비트로 된다. 모드 1에서는 SM2=0이면 stop 비트가 이 비트로 된다. 모드 0에서는 이 비트를 사용하지 않는다.

RI(Receive Interrupt flag), TI(Transmit Interrupt flag): TI 플래그는 하나의 바이트 데이터 중 마지막 비트(모드 0에서는 8번째 비트, 기타 모드에서는 stop 비트)가 전송될 때, 즉 데이터의 송신이 끝나서 송신버퍼(SBUFTX)가 빌(empty)때 자동적으로 세트된다. 그리고 이 비트가 세트되면 직렬포트 인터럽트가 요청된다. 이 비트는 인터럽트 발생시 자동적으로 클리어되지 않으므로 소프트웨어로 클리어해 주어야 한다.

RI 플래그는 마지막 데이터 비트를 수신할 때(모드 0에서는 8번째 비트가 수신될 때, 그리고 다른 모드에서는 STOP 비트가 수신될 때), 다시 말해서 수신버퍼(SBUFRX)가 찰(full)때 하드웨어로 세트된다. 이 플래그도 인터럽트 발생시 자동적으로 클리어되지 않으므로 반드시 소프트웨어로 클리어해 주어야 한다. 다음 부분 프로그램들은 RI와 TI를 이용하여 수신 및 송신을 하는 것이다.

(RI를 이용한 수신 루틴)

while(!RI);	/* RI 플래그가 셋트될 때까지 기다린다 */

RI=0;	/* RI를 clear */

rx_data=SBUF;	/* SBUF에 수신된 데이터를 rx_data에 */

return;

(TI를 이용한 송신 루틴)

SBUF=tx_data	/* Acc의 내용을 송신 */

while(!TI);	/* TI 플래그가 셋트될 때까지 기다린다 */

TI=0;	/* TI를 clear */

return;

(3) PCON 레지스터

PCON(Power Control register)은 보율을 제어하고, idle 모드와 power down 모드를 제어

그림 8.4  PCON

하는데, 직렬포트에서 필요한 것은 보율을 제어하는 SMOD뿐이다. SMOD를 1로 세트해 두면 모드 1, 2, 3에서 보율이 2배로 된다.

앞에서 언급한 바와 같이, 직렬포트는 수신 레지스터([eqn: rm SBUF sub RX])가 찬다(full)든가 송신 레지스터(SBUBTX)가 빌(empty) 경우에는 RI 또는 TI를 세트시키고, 그 이전에 IE 레지스터의 비트 4(ES)와 비트 7(EA)이 세트되어 있으면 벡터 23H의 직렬포트 인터럽트를 발생한다. 그런데, 직렬포트의 인터럽트 요청선은 한 개 밖에 없어서 RI와 TI는 OR되어 있다. 따라서 인터럽트 요구를 받은 CPU는 프로그램에 의해서 SCON 레지스터의 RI와 TI의 플래그를 조사해서 그것이 수신 레지스터 full인지 송신 레지스터 empty인지를 판단해서 이에 상응하는 서비스를 해주어야 한다. 인터럽트의 소스를 찾은 후에는 RI=0 또는 TI=0과 같은 명령에 의해서 이들 플래그를 클리어해 주어야 한다. 그렇지 않으면 동일한 인터럽트가 계속 다시 발생한다.

그림 8.5 직렬포트 인터럽트

8.4.1 동작 모드 0

전술한 바와 같이, 이 모드는 I/O확장용의 동기식 통신 모드로서, 직렬포트가 이 모드로 설정되면 동기 클록은 TxD(P3.1)를 통하여 나가고, 송신 및 수신 데이터는 RxD(P3.0)를 통하여 주고 받는다.(송수신은 LSB부터 이루어진다).

보율(baud rate)은 발진주파수(Oscillator frequency)의 1/12에 고정된다. 모드 0에서는 CPU의 기계사이클에 동기하여 송수신이 이루어지기 때문이다.

모드 0의 보율Ａ[eqn: 발진주파수 over 12]

그림 8.6은 그 기능도이고, 그림 8.7은 그 타이밍圖이다.

모드 0에 있어서는 단지 시프트레지스터를 외부에 추가함으로써 8051의 병렬 I/O포트 능력을 확장할 수 있다.

이 관계를 좀더 자세히 보기로 하자. 8051 직렬포트의 모드 0은 전통적인 동기식 직렬통신을 위한 것이라기 보다는 I/O 확장을 위한 것이다. 모드 0의 I/O 확장 기능을 이용하면 직렬포트를 마치 병렬 I/O포트처럼 사용할 수 있어서 병렬 I/O포트가 부족한 경우에 매우 긴요하게 사용할 수 있다. 이 경우에 클록은 핀 TxD를 통하여 나가고, 송신 또는 수신 데이터는 핀 RxD를 통하여 송수신된다. 그림 8.8에서 MOV SBUF, A(C에서는 SBUF= tx_data)와 같은 송신 명령을 내리면 Acc의 병렬 데이터가 직렬포트에서 직렬데이터로 바꿔져서 외부 시프트레지스터에 직렬 송신되고, 송신된 직렬데이터는 하나의 바이트를 단

그림 8.6  모드 0의 기능도

그림 8.7  모드 0의 타이밍圖

그림 8.8  시프트레지스터에 의한 I/O 확장도

위로 하여 외부 시프트레지스터에서 병렬 데이터로 바꿔져서 병렬 출력된다. 한편 REN=1이고 RI=0인 가운데 MOV A, SBUF(C에서는 Rx_data=SBUF)와 같은 수신 명령을 내리면 외부 시프트레지스터에 들어있는 병렬데이터가 직렬데이터로 바꿔져서 역시 RxD를 통하여 수신되고, 이것이 직렬포트에서 다시 병렬데이터로 바꿔져서 Acc에 입력된다. 래치 펄스 및 로드 펄스는 별도의 I/O라인을 통하여 나간다. 자세한 것은 8.9.4와 8.9.5에서 논한다.

(1) 모드 0 송신 과정

① SCON의 비트 7과 6을 □00B□로 함으로써 모드 0을 선택한다.

② SBUF(88H)에 송신 데이터를 기록(write)한다.

③ 이제 클록은 TxD(P3.1)로 출력되고, 데이터는 RxD(P3.0)를 통하여 외부 시프트레지스터(직렬입력 병렬출력(serial-in, parallel-out)의 시프트레지스터)에 송신된다.

④ 하나의 바이트가 모두 송신되면 TI=1이 되고, 이 때 별도의 I/O포트 라인을 통하여 형의 latch lock 펄스를 외부 시프트레지스터에 보내면 시프트되어 나간 바이트 데이터가 외부 시프트레지스터에서 병렬 출력된다.

(2) 모드 0 수신 과정

① SCON의 비트 7과 6을 □00B"로 함으로써 모드 0을 선정한다.

② 수신 인터럽트 허용 비트(REN)을 □1□로 하고 수신 플래그 RI를 클리어 해둔다.

③ 병렬입력 직렬출력(parallel-in, serial-out)의 외부 시프트레지스터의 strobe선에 형의 load 펄스를 별도의 I/O포트 라인을 통하여 주면 외부 시프트레지스터의 병렬데이터가 직렬로 바꿔져서 직렬포트에 RxD를 통하여 들어온다.

④ RxD(P3.0)를 통하여 들어오는 직렬 데이터는 동기 클록의 상승에지에서 직렬포트의 시프트레지스터에 차례로 들어온다. 8개 비트가 다 들어오면 RI=1로 되므로, 이것을 탐지하고 있다가 RI=1로 되면 MOV A,SBUF(C에서는 Rx_data=SBUF)와 같은 명령으로 Acc로 옮긴다.

8.4.2 동작 모드 1

이는 10비트 프레임의 표준 비동기식 통신 모드로, 모드 0과는 달리 TxD(P3.1)는 데이터의 송신에 사용되고, RxD(P3.0)은 데이터의 수신에 사용된다. 10비트 프레임은 다음의 3 요소로 구성된다.

·start 비트(□0□)

·8개의 데이터 비트(LDS부터 송수신)

·stop 비트(□1□)

데이터를 수신할 때 stop 비트는 SCON 레지스터의 RB8에 들어간다.

모드 1의 보율(baud rate)은 타이머 1의 오버플로 율(overflow rate)과 보율선택 비트(SMOD.7)의 값에 따라 다음 식과 같이 결정된다. 후술하는 모드 3의 보율도 이와 같다.

보율[eqn: =`rm 2 sup SMOD over 32]×(타이머 1의 오버플로 율)

타이머 1을 보율생성기로 하기 위해서는 타이머1 인터럽트 허용 비트(IE.3)를 불허(disable)로 해야한다. 또 타이머 또는 카운터 어느 것으로 해도 되고, 3개의 동작 모드 중 어느 것으로 해도 되나, 일반적으로는 8비트 자동 재로드(auto-reload)의 타이머 모드(TMOD=00100000B)로 한다.

이 경우 타이머 0는 전장에서 언급한 바와 같이 타이머 모드 3으로 해두는 것이 일반적이다. 타이머 1을 보율생성기로 사용할 경우에는 인터럽트를 불허해야 하기 때문에 타이머 0을 모드 3으로 해두면 TL0와 TH0 각각에 인터럽트를 사용할 수 있기 때문이다. 그러나 두 개의 타이머 인터럽트가 필요하지 않을 경우에는 어느 모드로 해도 상관없다.

타이머 1을 자동 재로드의 타이머 모드로 할 경우의 보율은 다음식으로 표시된다.

보율[eqn: =`rm 2 sup SMOD over 32^`]×[eqn: rm 발진주파수_` over {12×(256-TH1)}^`]

표 8.1은 보율과 SMOD와 발진주파수가 주어졌을 경우 이 수식에 따라 타이머 1의 TH1

□표 8.1  보율과 TH1 값과의 관계

(타이머1을 자동 재로드의 타이머로 사용할 경우)

보율 (Baud Rate)	발진주파수 (Fosc)	SMOD	Timer 1
			C/ T	타이머 모드	TH1의 값
Mode 0 Max : 1 MHz Mode 2 Max : 375K Mode 1, 3 : 62.5K 19.2K 9.6K 4.8K 2.4K 1.2K 127.5 110 110	12 MHz 12 MHz 12 MHz 11.0592 MHz 22.1184MHz 11.0592 MHz 22.1184MHz 11.0592 MHz 22.1184MHz 11.0592 MHz 22.1184MHz 11.0592 MHz 22.1184MHz 11.0592 MHz 6 MHz 12 MHz	× 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0	× × 0 0 0 0 0 0 0 0 0 0 0 0 0 0	× × 2 2 2 2 2 2 2 2 2 2 2 2 2 1	× × FFH FDH FDH FDH FAH FAH F4H F4H E8H E8H D0H 1DH 72H FEEBH

값을 얼마로 해야 하는지를 나타내고 있다. 발진주파수가 22.1184MHz의 경우에 대한 TH1 값은 발진주파수가 11.059MHz일 때의 보율이 절반인 경우와 같다. 예컨대 발진주파수=22.1184MHz일 때 보율을 9.6KHz로 하려면 발진주파수Ａ11.059MHz일 때 보율Ａ4.8KHz로 하고자 할 때의 TH1 값(FAH)을 쓰면 된다.

모드 1 송신 과정

① TMOD, PCON 등을 설정함으로써 타이머 1에 의해서 생성되는 보율을 선택한다.

TMOD=0x23;	/* 타이머1을 자동 재장전 모드로 한다 */

PCON &=0x7f;	/* PCON.7=SMOD를 0으로 한다 */

TH1=0xfa;	/* 발진주파수=22.1184Mhz에서 보율=9.6K */

② SCON의 비트 7과 6을 □01B□로 함으로써 직렬포트 모드 1을 선택한다.

SCON=0x40;	/* 모드 1의 선택 */

③ SCON 레지스터의 송신 인터럽트 플래그 TI를 클리어해둔다.

TI=0;	/* SCON의 비트3 TI를 클리어 */

④ SBUF=tx_data와 같은 명령으로 SBUF에 송신 데이터를 기록한다.

start 비트와 stop 비트는 하드웨어에 의해서 자동적으로 만들어진다.

SBUF=tx_data

⑤ 하나의 바이트를 모두 송신하면 TI 플래그가 세트되므로, 그것을 기다렸다가 이를 클리어함으로써 다음 바이트를 송신할 준비를 한다

while(!TI);

TI=0;

모드 1 수신 과정

① 타이머 1에 의해서 생성되는 보율을 선택한다.

TMOD=0x23;

PCON &=0x7f;

TH1=0xfa;

② SCON 레지스터에서 모드 비트와 REN 비트를 □1□로 세트하고 RI를 클리어한다.

SCON=0x50;	/* 모드 1, REN=1, RI=0 */

그림 8.9  비동기 통신 모드의 기능도

그림 8.10  모드 1의 타이밍도

③ RxD 핀에 start 비트(□0□)가 감지되면 직렬포트가 수신 동작을 시작한다. 이 때 SBUF의 내용을 읽어들인다.

while( !RI);

RI=0;

rx_data=SBUF;

8.4.3 동작 모드 2와 3

모드 2와 3은 11비트 프레임의 비동기식 통신 모드이다. 11개 비트 프레임은 다음과 같이 4개의 구성 요소로 이루어진다.

·start 비트 (□0□)

·8개의 데이터 비트(LSB부터 송수신)

·프로그램 가능한 8번째 비트(TB8)

·stop 비트 (□1□)

모드 2와 3은 하나의 프로그래머블 8번째 데이터가 더 있다는 점에서 모드 1과 구분된다. 송신될 8번째 데이터 비트는 SCON 레지스터의 비트 3(TB8)에 □0□ 또는 □1□을 기록함으로서 생성된다. 수신시에는 수신 데이터의 8번째 데이터 비트(TB8)가 SCON의 RB8 비트(SCON.2)에 들어간다.

모드 2와 3은 보율을 만드는 방법이 다르다. 모드 2의 경우는 보율이 발진주파수에 고정적이고, 모드 3의 경우는 보율이 모드 1에서와 같이 타이머 1의 오버플로 율에 따라 가변적이다.

모드 2의 보율은 발진주파수의 1/32 또는 1/64에 고정된다.

보율[eqn: =`rm 2 sup SMOD over 64]×(발진주파수)

모드 3의 보율은 모드 1에서와 같다.

보율[eqn: =`rm 2 sup SMOD over 32 × 발진주파수_` over {12×(256-TH1)}^`]

모드 2, 3의 송신 과정

① SCON의 비트 7과 비트 6을 □10B□ 또는 □11B□로 함으로써 모드 2 또는 모드 3을 선택한다. 또한 SCON 레지스터의 비트3 TB8에 □0□ 또는 □1□을 기록함으로써 송신될 8번째 데이터 비트를 지정한다.

SCON=0b1x1x1000;	/* 모드 2,3 TB8=1 또는 0 */

② PCON 레지스터의 SMOD 비트를 □0□ 또는 □1□로 하고 모드 3의 경우에는 타이머 1의 TH1값을 로드함으로써 전송속도를 선택한다.

TMOD=0x23;	/* 타이머1을 자동 재장전 모드로 */

PCON &=0x7f ;	/* SMOD=0 */

TH1=0xfa;	/* 발진주파수=22.1184MHz에서 보율을 9.6K로*/

③ SCON 레지스터의 TI 플래그를 클리어해 둔다.

TI=0;	/* TI=0 */

④ SBUF=trans_data와 같은 명령으로 송신 데이터를 SBUF에 기록함으로써 송신 동작을 시작시킨다.

SBUF=trans_data;	/* 송신 */

⑤ 하나의 바이트가 송신 완료되면 송신 인터럽트 플래그 TI가 1로 세트되므로 이것이 확인되면 다음 바이트의 송신을 위해서 이를 클리어한다.

while(!TI);	/* TI=1인가, no이면 계속 체크하고 */

TI=0;	/* yes이면 이를 클리어한다 */

모드 2 및 3의 수신 과정

① PCON 레지스터의 SMOD 비트와 타이머 1의 TH1값에 의해서 전송 속도를 지정한다.

TMOD=0x23;	/* 타이머 1을 자동재장전 모드로 */

PCON &=0x7f;	/* SMOD=0 */

TH1=0xfa;	/* 보율을 9.6K로 */

② 동작모드 2 또는 3을 선택하고, SCON 레지스터의 수신 가능 비트(REN)를 □1□로 세트한다.

SCON=0b1x11x000B;	/* 모드 2,3 SM2=1 REN=1 */

③ SCON 레지스터의 수신 인터럽트 플래그 RI를 클리어해 둔다.

RI=0;  (앞 동작에 의해서 클리어되지만, 강조하기 위해서 넣어두었다)

④ 수신 동작은 RxD 핀의 신호가 논리 0(start 비트)으로 될 때 시작된다.

하나의 바이트가 수신 완료되면 수신 인터럽트 플래그 RI가 1로 세트되므로 이를 기다렸다가 세트가 되면 이를 수신하고 다음 수신을 위해서 RI를 클리어한다.

while( !RI);	/* RI=1? no이면 체크 계속 */

RI=0;	/* yes이면 클리어 */

모드 2 또는 3의 일반적인 송수신 과정은 이상과 같지만 이것이 다중 프로세서 시스템으로 사용되는 경우에는 인터럽트 관계라든가 매우 복잡한 관계가 있어 위와는 약간의 차이가 있다. 이에 대해서는 뒤에서 논하기로 한다.

(1) 수신 시퀀스

모드 1∼3의 비동기식 통신 모드에서 수신은 REN=1인 가운데 start 비트, 즉 RxD(P3.0)가 1에서 0으로 바뀌는 것을 검출(detect)함으로써 시작된다. start 비트를 검출하기 위해서 직렬포트는 RxD를 설정된 보율의 16배 속도로 샘플링한다. 샘플링해서 RxD가 1에서 0으로 바뀌는 것이 검출되면 16분주 카운터는 즉시 리셋되고, 수신 시프트레지스터는 자동적으로 모두 1로 채워지며, 16분주 카운터는 들어오는 bit time의 경계에 맞춰서 다시 배열된다.

start 비트가 수신되면 16분주 타이머는 그림 8.11과 같이 하나의 비트 타임을 16으로 분주하고, 분주된 클럭의 7∼9번째에 RxD를 3번 샘플링해서 그 중 2번 이상 같은 값을 올바른 데이터 비트로 인정하고 이를 받아들인다. 잡음의 영향을 제거하기 위함이다. 받아들이는 데이터 비트는 수신 시프트레지스터의 오른쪽으로 shift in되고, 왼쪽으로는 미리 저장되어 있는 1이 shift out된다.

그러다가 모드 1에서는 프레임의 8번째 비트를, 모드 2, 3에서는 10번째 비트를 수신하면 수신 시프트레지스터의 내용은 SBUF와 RB8(모드 2, 3만)에 옮겨지고, RI 플래그는 1로 세트된다.

세트된 RI 플래그는 자동적으로 클리어되지 않으므로 소프트웨어로 클리어해야 한다. 다음 프레임의 수신이 완료되기까지 RI 플래그가 클리어되지 않으면 overrun error가 발생된다.

그림 8.11 비동기식 통신모드의 수신 타이밍

(2) 송신 시퀀스

모드 1∼3의 비동기식 통신 모드에서 송신은 MOV SBUF,A(C에서는 SBUF=tx_data)와 같이 SBUF를 목적지로 하는 명령으로 SBUF에 데이터를 기록함으로써 시작된다. SBUF에 데이터를 기록하면 송신 시프트레지스터의 8번째 비트에 (SCON TB8의 내용에 따라) 1 또는 0이 로드되고, TX제어장치에 송신의 시작을 알린다. 송신이 시작되면 start 비트부터 TxD(P3.1)를 통하여 데이터가 출력된다. 데이터 비트들은 송신 시프트레지스터에 하나씩 오른쪽으로 시프트되고 그 빈자리에는 0으로 채워진다. 모드 1에서는 8번째 데이터 비트(stop bit)가 송신될 때 TI 플래그가 세트되고, 모드 2, 3에서는 10번째 데이터 비트(stop bit)가 송신될 때 TI 플래그가 세트된다.

그림 8.12는 비동기 통신모드(모드 2, 3)의 송수신 타이밍도이다.

그림 8.12  비동기 통신 모드(모드 2, 3)의 송수신 타이밍

모드 2나 3에서는 다중 프로세서의 데이터 통신을 위하여 특별히 준비한 비트가 있다. 이들 모드에서는 하나의 프레임에서 데이터 비트를 7개 대신 8개를 쓰는데, 이들 중 8번째 비트 TB8은 수신시에 수신측 SCON의 RB8에 들어간다. 8번째 데이터 비트 바로 뒤에는 stop 비트가 있고, 직렬포트가 이 stop 비트를 받으면 SCON의 RB8을 조사해서 그것이 □1□인 경우에 한하여 인터럽트를 발생하도록 미리 프로그램해 둘 수 있다. SCON의 SM2 비트를 □1□로 세트해두면 그리 된다. 8번째 비트가 □1□인 것은 주소정보이다. 그러므로 SM2=1인 경우에 주소정보가 들어와야만 인터럽트가 발생되는 것이다.

모드 2나 3의 이러한 기능을 이용하면 그림 8.13과 같이 여러개의 프로세서를 직렬 버

그림 8.13  다중 프로세서 시스템

스로 연결해 두고, 주 프로세서(master processor)가 여러 종 프로세서(slave processor) 중 어느  것에 직렬 데이터를 보낼 수 있는 소위 다중 프로세서 시스템을 구성할 수 있다.

주 프로세서가 여러 종 프로세서 중 어느 것에 한 블록의 데이터를 전송하려면

① 모든 프로세서(주와 종 프로세서)의 동작모드를 2와 3중 어느 하나로 설정한다.

② 모든 종 프로세서는 스스로의 프로그램에 의해서 동작 모드를 주 프로세서와 같이 해두고 자신의 SM2(SCON.5)를 □1□로 세트해 둔다. SM2를 □1□로 해두면 주 프로세서가 종 프로세서에게 보내는 바이트 데이터중 8번째 비트(TB8)가 □1□일 때에 한하여 종 프로세서는 직렬포트 인터럽트를 발생한다. 그런데 8번째 비트가 □1□이면 그림 8.14와 같이 주소정보이고, 이것이 □0□이면 데이터정보이다. 그러므로 모든 종 프로세서들은 자신의 SM2를 □1□로 세트해 둠으로써 주 프로세서가 주소정보를 보낼 경우에 한해서 인터럽트를 발생하도록 한다.

그림 8.14  멀티프로세서 통신 제어 프로토콜(모드 2, 3)

□ 주 프로세서가 SCON=0bxxxx1xxx와 같은 명령으로 자신의 TB8을 1로 하고 주소정보를 보낸다.

□ 주소정보를 받은 (SM2=1의) 모든 종 프로세서는 인터럽트를 발생하고, 그 루틴에서 수신된 주소정보가 자신을 지정한 것인지를 판단한다. 판단은 자신의 고유 주소와 수신된 주소를 비교하는 방법에 의한다.

□ 수신된 주소정보가 자신을 지정하였다고 판단하는 종 프로세서(target slave)는 자신의 SCON의 SM2를 □0□으로 함으로써 데이터정보를 받아드릴 준비를 한다. 지정되지 않은 종 프로세서들은 SM2 비트가 □1□인 상태 그대로 있기 때문에 주 프로세서가 뒤이어 보내는 데이터정보를 받아드릴 수 없게 된다.

□ 주 프로세서는 자신의 TB8을 □0□으로 클리어함으로써 8번째 비트를 □0□으로 하고, 데이터 한 바이트를 송신한다.

□ 이 데이터 바이트는 모든 종 프로세서에 들어가지만, 지정된 종 프로세서(target slave) 만이 SM2=0으로 되어 있으므로 이를 받아드리고 다른 종 프로세서들은 이를 받아들일 수 없다.

□ 양측에 미리 정해진 수의 바이트로 이루어진 한 블록의 데이터 통신이 종료되면 주 프로세서는 자신의 TB8을 1로 세트하고, 지정된 종 프로세서도 스스로 SM2를 □1□로 함으로써 처음의 상태로 되돌아가서 주소정보가 들어오기를 기다린다.

8051과 IBM PC가 데이터 통신을 하기 위해서는 그림 8.15와 같이 RS-232C 케이블로 이들을 연결해야 한다. 8051 트레인키트에서는 MAX232가 TxD 및 RxD에 연결되어 있으므로 8051 자체로 볼 때 실제 결선 모양은 그림 8.16과 같다. 여기서 MAX232는 TTL 레벨을 RS-232C 레벨로, 또는 RS-232C 레벨을 TTL 레벨로 변환하는 것이다. TTL 레벨은 +5V이고, RS-232C 레벨은 5∼12V이다.

RS-232C는 원래 MODEM과 터미널 간의 인터페이스 방법에 대한 EIA(미국전자공업협회)의 RS(Recommanded Standard) 규격으로서, 비동기식 데이터 통신에서 널리 사용되고 있다.

RS-232C는 인터페이스 신호선의 전기적 사양, 신호선의 종류 및 기능, 전기적 특성, 콘넥터의 사양 등에 일정의 규격이 있다. 표 8.2는 그 전기적 특성이고, 표 8.3은 8핀의 경우 그 신호선의 종류와 내용이다.

그림 8.15  RS_232C 케이블 연결 방법

그림 8.16  RS_232C 연결방법(2)

□표 8.2  RS_232C의 전기적 특성

드라이버 출력 로직 레벨(부하 3K∼7K□때)	／15V > 0h > ／5V １5V > 01 > １15V
드라이버 출력 전압(개방시)	V01 < 25V
드라이버 출력 임피던스(전원 단락시)	R0 > 300□
출력회로 전류(단락시)	010 < 0.5A
드라이버 슬레이트(slate) : 상승 에지 특성	dv/dt < 30V/□s
리시버 입력 임피던스	7K□ > Rin > 3K□
리시버 입력 전압	±15V(드라이버와 같음)
입력 개방때 리시버 출력	mark(□1□)
+3V 입력때의 리시버 출력	space(□0□)
-3V 입력때의 리시버 출력	mark(□1□)
로직 □0□=스테터스=제어 ON	／15V∼／5V
잡음 여유	／5V∼／3V
과도 영역	／3V∼１3V
잡음 여유	１3V∼１5V
로직 □1□=마크=제어 OFF	１5V∼１15V

□표 8.3  RS_232C 신호선의 종류(8핀의 경우)

명 칭	신호명	핀번호	비 고
Carrier Detect Receive Data Transmitted Data Data Terminal Ready Signal Ground Data Set Ready Request to Send Clear to Send Ring Indicatior	CD RxD TxD DTR GND DSR RTS CTS RI	1 2 3 4 5 6 7 8 8	캐리어 검출 수신 데이터 송신 데이터 단말장치의 송수신 가능 접지 모뎀의 송수신 가능 송신 요구 송신 가능 호출 표시

8.8.1 RI와 TI 기능에 의한 USART 실험

(1) 目 的

8051 시스템의 TxD와 RxD를 그림 8.18과 같이 직접 연결해 두고, TxD를 통하여 FFH에서 0까지의 숫자 데이터를 0.05초 간격으로 차례로 전송한다. TxD와 RxD는 같은 8051에

그림 8.17  UART 실험 시스템

직접 연결되어 있으므로 REN=1로 해 둔 상태라면 TxD를 통하여 송신된 데이터는 곧바로 전송되어 RxD를 통하여 같은 8051에 수신된다. 수신된 데이터를 포트 1에 연결된 LED에 출력함으로써 수신결과를 확인하고자 한다.

(2) 順序圖

그림 8.18  UART 실험 순서도

(3) 프로그램(EX8_1.C)

/*================================================*/

/* PROGRAM EX8_1 (UART, Display Sent Data to LED) */

/*================================================*/

#include <reg51.h>

char tx_data;

void delay(void)	/*지연 함수*/

{

TH0 = 0x28;	/* 0.03초를 얻기 위한 시간정수 */

TL0 = 0x00;

TR0 = 1;	/* 타이머0 run */

while( !TF0);	/* TF0 = 1? 0.03초가 경과했는가? */

TF0 = 0;	/* TF0를 클리어 */

TR0 = 0;	/* 타이머0 stop */

}

void transmit(void)

{

SBUF = tx_data;	/* SBUF(TxD)를 통하여 송신한다 */

while(％TI);	/* 송신 완료시까지 기다린다 */

TI = 0;

}

void receive(void)

{

// RI = 1;	/* SIMULATION의 경우에만 필요함 */

while(％RI);	/* RI=1인지를 체크 */

RI = 0;	/* RI 플래그를 클리어 */

P1 = ∼SBUF;	/* 수신된 데이터를 포트 1에 표시 */

}

/* 메인 함수 */

void main(void)

{

TMOD = 0x21;	/* 타이머1의 모드=2, 타이머0의 모드=1 */

PCON &= 0x7f;	/* SMOD=0 */

TH1 = 0xfa;	/* 발진주파수=22.1184MHz에서 보율=9600bps */

TR1 = 1;	/* 타이머1 run */

SCON = 0x50;	/* 직렬 모드=1, REN=1, TI=0 */

do {

for (tx_data =0xff; tx_data <=0; tx_data--)

{

transmit();	/* 하나의 바이트를 송신하고 */

receive();	/* 그것을 되돌려 수신한다 */

delay();	/* 0.03초 지연 */

}

}while(1);

}

(4) 프로그램의 解說

TMOD=0x21;

PCON=0x7f;

앞의 명령은 타이머 1을 모드 2의 타이머로, 타이머 0을 모드 1의 타이머로 사용한다는 것이고, 뒤의 것은 보율 결정에 사용되는 PCON 레지스터의 비트 7인 SMOD를 0으로 한다는 것이다. keil software를 사용하지 않고 다른 translator를 사용할 경우에는 PCON 대신 87H라고 하는 것이 좋을 경우가 있다. translator에 따라서는 PCON이 무엇인지를 모르는 것이 있기 때문이다.

TMODＡ0x21라고만 한다면 타이머 1이 일반 타이머로 사용되는지 보율생성기로 사용되는지 알 수 없다. 타이머 1이 어느 경우에 일반 타이머로 되고 어느 경우에 보율생성기로 되는가? SCON 레지스터의 SM0와 SM1에 의해서 직렬포트 모드 1 또는 3으로 되면 보율생성기로 되고, 그 외의 경우에는 일반 타이머로 된다.

SCON=0x50;

직렬포트의 동작모드=1, REN=1, TI=0로 하기 위함이다.(그림 8.2 참조)

RI=1

TxD를 통하여 보내는 데이터를 자신의 RxD로 받아드리므로 TxD와 RxD를 외부에서 연결해 주어야 하는데, 시뮬레이터에서는 그것이 되지 않으므로 마치 연결해 준 것처럼 하기 위해서는 RI 플래그를 강제로 세트시켜 주는 수 밖에 없다. 시뮬레이터에서는 이렇듯 외부 연결과 관계되는 것은 연결된 것처럼 조정해 주어야 한다. 그러므로 실제 시스템에서는 이들 명령을 없애버리든지 주석처리해야 한다.

void delay(void)

{

TH0 = 0x28;

TL0 = 0x00;

TR0 = 1;

while( !TF0);

TF0 = 0;

TR0 = 0;

}

앞에서도 몇차례 나온 0.03초 지연 함수이다. 타이머0에 대한 TMOD를 모드 1로 하는 것은 메인 함수에서 정의하고 있다. while(!TF0)에 유의하기 바란다. TF0가 1일 때까지 기다리라는 것이다. TF0가 1이면 !TF0는 0으로 되므로 여기에서 벗어난다.

TH0:TL0의 값이 0x2800인 이유는 발진주파수Ａ22.1184MHz에서 0.03초를 얻기 위한 카운트 값은 55296인데, 8051의 타이머는 업카운터이기 때문에 65536에서 이를 빼준 값을 넣어주어야 하기 때문이다.

[eqn: 22118400* 1 over 12 * 1 over x = 1 over 0.03] ∴ [eqn: x`=]55296

TH0:TL0Ａ65536１55296Ａ10240Ａ0x2800

만약 0.03초가 아니라 0.3초의 지연이 필요하면 다음과 같이 한다. 안의 { }에는 위의 0.03초 지연 루틴을 넣는다. 이 루틴을 10번 수행하는 것이다.

void delay(void)

{

for (i=1; i<=10; i++)

{

:

}

}

(5) 프로그램의 實行

제4장에서 설명한 방법에 따라 □Vision에서 Open project 작업을 하고(이미 open되어 있으면 생략), Edit project 작업을 한 다음 Build project 작업을 한다. 이로써 EX8_1.A51 또는 EX8_1.C라는 소스파일이 open된 프로젝트에 편입되고, 어셈블 또는 컴파일되고 링크되어 Obj 파일과 Hex 파일이 생성된다.

이 프로그램을 시뮬레이트하고자 하면 dScope에서 제4장에서 설명한 방법에 따라 CPU를 선택한다(물론 이미 CPU가 선택되어 있으면 생략한다). 그런데 앞에서와 달리 이 경우에는 문제점이 하나 있다. 앞에서도 언급했듯이 이 프로그램을 실행시키려면 8751 또는 AT89C2051의 TxD핀과 RxD핀을 직접 연결해야 하는데 시뮬레이터에서는 이를 연결할 방법이 없다. 할 수 없이 RI가 세트되어 있는지의 명령 앞에 SETB RI라는 명령을 두어서 강제 세트시켜야 한다. CPU 선택이 되면 다음으로 할 일은 주변장치들을 지정하는 일이다. peripheral에서 포트 1과 serial을 택한 후 serial의 Mode란에서 □8 bit variable Baudrate"에 클릭한다. 그런 다음 □Vision에서 지정한 project를 지정 호출한 후 Go에 클릭하여 프로그램을 실행(simulate)시킨다. serial 창의 SBUF가 하나씩 바꿔짐을 확인할 수 있을 것이다. 포트 1의 창이 변화되지 않는 이유는 TxD와 RxD가 연결되어 있지 않으므로 송신된 데이터가 수신이 되지 않아서 수신버퍼 레지스터 SBUF가 바꿔지지 않기 때문이다. 굳이 포트 1의 창에 송신된 데이터가 표시되도록 하고 싶으면 MOV P1, A 앞에 □MOV A, R0□라는 명령을 넣으면 된다.(C에서는 P1Ａtx_data로) 거듭 밝히지만 시뮬레이터에서는 외부 연결을 실제 연결된 것처럼 그와 관계되는 것들을 고쳐주어야 한다.

실제 시스템에 실행시키고자 하면 □Vision에서 얻은 Hex 파일을 8751 또는 AT89S51 또는 AT89C2051에 ROM 라이터로 기록한다.

디지털제어 산업기사 8051 MICOM 보드에 실행시키고자 하면 역시 □Vision에서 얻은 Hex 파일을 MICOM PROGRAMMER에서 □열기□와 □자동□ 작업을 통하여 MICOM 보드에 기록해 넣는다. RS_232C 커넥터의 2번과 3번을 연결해 두는 것을 잊지 말아야 한다.

8.8.2 인터럽트에 의한 UART 실험

(1) 目 的

앞의 예제를 인터럽트 기능에 의하여 실현하고자 한다.

(2) 順序圖

그림 8.19  인터럽트에 의한 UART 실험 순서도

(3) 프로그램(EX8_2.C)

/*==========================================================*/

/* PROGRAM EX8_2 (UART, Display Sent Data to LED by interrupt)  */

/*==========================================================*/

#include <reg51.h>

char tx_data;	/* 변수의 정의 */

void delay(void)	/* 지연 함수 */

{

TH0 = 0x28;	/* 0.03초 시간정수 */

TL0 = 0x00;

TR0 = 1;	/* 타이머0 run */

while(％TF0);	/* TF0=1인가, 0.03초가 경과되었는가? */

TF0 = 0;	/* TF0 = 0 */

TR0 = 0;	/* 타이머0 stop */

}

void transmit(void)

{

SBUF = tx_data;	/* 전송할 데이터를 SBUFTX에(송신) */

while(％TI);	/* 하나의 바이트에 대한 송신 완료 */

TI = 0;	/* TI 플래그의 클리어 */

//  RI = 1;	/* SIMULATION만을 위한 것임*/

}

/* 수신 인터럽트 루틴 */

void serial_int(void) interrupt 4	/* 인터럽트 벡터넘버=4 */

{

P1 = ∼SBUF;	/* 수신된 데이터를 포트 1에 표시한다 */

RI = 0;	/* RI 플래그를 클리어 */

}

/* 메인 함수 */

void main(void)

{

TMOD = 0x21;	/* 타이머1의 모드는 2, 타이머0의 모드는 1 */

PCON = 0;	/*SMOD=0 9600보 (22.1184MHz에서) */

TH1 = 0xfa;

TR1 = 1;	/* 타이머1 run */

SCON = 0x50;	/* 직렬 모드=1, REN=1, TI=0 */

ES = 1;	/* 직렬포트 인터럽트 enable */

EA = 1;

PS = 1;	/* 우선순위를 high */

do {

for (tx_data=0xff; tx_data <=0; tx_data--) /* ff에서 00까지 하나씩 */

{

transmit();	/* 하나의 바이트를 송신한다 */

delay();	/* 0.05초 지연 */

}

}while(1);

}

(4) 프로그램의 解說(C)

void serial_int(void) interrupt 4

{

P1 = ∼SBUF;

RI = 0;

}

처음 명령은 인터럽트 벡터 넘버 4인 인터럽트 루틴이라는 것을 선언한 것이다. 벡터 넘버 4는 직렬포트 인터럽트이다. 직렬포트 인터럽트가 발생하면 SBUFRX에 수신된 데이터를 읽어서 포트 1에 표시하고, 수신 플래그 RI를 클리어하라는 것이 그 내용이다.

(5) 프로그램의 實行

□Vision에서는 역시 Open project 작업과 Edit project 작업을 통하여 프로젝트와 프로그램을 지정하고, Build project 작업에서 어셈블 또는 컴파일을 하고 링킹을 한다. 이로써 Hex file과 Obj file이 생성된다.

시뮬레이트를 원할 경우에는 dScope에서 CPU를 선택하고(이미 되어 있으면 물론 생략한다) peripheral에서 port1과 interrupt Ser.Receive와 serial의 8 bit var. Baudrate를 선택하고 Go한다. serial창의 SBUF가 0FFH에서 0.03초마다 하나씩 감소됨을 확인할 수 있을 것이다. 포트 1의 값이 SBUF와 같이 변화하지 않는 것은 역시 RxD와 TxD가 직접 연결되어 있지 않기 때문이다.

실제 시스템에 실행하고자 하면 □Vision에서 만든 Hex 파일을 8751 또는 AT89S51 또는 AT89C2051에 ROM 라이터로 기록하여 그림 8.18과 같은 회로에 꽂는다.

디지털제어 산업기사 8051 MICOM 보드에 실행하고자 하면 역시 MICOM PROGRAMMER에서 □열기□와 □자동□작업을 통하여 Hex 파일을 기록해 넣는다.

(6) 課 題

위에서는 수신 루틴만을 인터럽트로 처리하였다. 송신 루틴마저도 인터럽트로 처리토록 하라.

8.8.3 키값에 따라 다른 문자 전송하기

(1) 目 的

그림 8.20과 같이 포트 1에는 단순 키가 연결되어 있고, 포트 3에는 LED가 연결되어 있으며, TXD와 RXD가 직접 연결되어 있다. 키 K0를 누르면 □0"자가 TXD를 통하여 RXD로

그림 8.20 누른 키 값에 따라 다른 문자를 보내는 시스템

들어와서 포트 3의 P3.5∼P3.2에 표시되고, 키 K3를 누르면 □3□이 송신, 수신되어 P3.5∼P3.2에 표시되며, 키 K4를 누르면 □A□자가 송신. 수신되어 P3.5∼P3.2에 표시되고 … 키 K7을 누르면 □Z□자가 송신. 수신되어 P3.5∼P.32에 표시되도록 하고자 한다.

(2) 順序圖

이것은 앞에서 다룬 프로그램 ex8_1.C와 뒤에서 다룰 프로그램 ex11_1.C를 합한 형태이다.

그림 8.21  누른 키 값에 따라 다른 문자를 보내는 순서도

(3) 프로그램

/*===============================================*/

/* PROGRAM EX8_3 (UART, Display key Data to LED)   */

/*===============================================*/

#include <reg51.h>

char tran_data,flag,i;

unsigned char i_data,key_number,j,trans_data,recv_data;

void transmit(void) {

SBUF = trans_data;	/* 송신 데이터를 SBUF(TxD)에*/

while(％TI);	/* TI=1?; 송신완료?*/

TI = 0;

}

void receive(void) {

// RI = 1;	/* SIMULATION을 위해서만 필요함*/

while( !RI);	/* RI=1일 때까지*/

RI = 0;	/* clear RI flag*/

recv_data = SBUF;	/* 수신 SBUF의 내용을 recv_data에*/

}

void display(void) {	/* 수신 데이터를 P3.5-P3.2에 출력*/

recv_data <<=2;

P3 = ∼recv_data;

}

void check_key_number(void) {	/* 어느 키를 눌렀는지를 찾는 루틴*/

P1 = 0xff;	/* P1은 입력포트*/

key_number = 0xff;	/* 최초의 key_num; key_num=-1*/

do {

i_data =P1;

}while( i_data==0xff);	/* 어느 것이든 키를 눌렀는가?*/

for (j=0; j<=7; j++) {	/* yes이면 어느 키인가?*/

key_number++;

i_data =i_data >>1 □ 0x80;  /* shift right */

if(i_data==0xff) break;	/* 누른 키를 찾았으면 break */

}

}

/* 메인루틴*/

void main(void)

{

TMOD = 0x20;	/* timer1 mode=2*/

PCON &= 0x7f;	/* SMOD=0. 보율=9600*/

TH1 = 0xfa;

TR1 = 1;	/* run timer1*/

SCON = 0x50;	/* serial mode=1,REN=1,TI=0*/

do {

check_key_number();	/* 누른 키에 따라 다른 값을 송신*/

if (key_number ==0) trans_data ='0';

else if (key_number ==1) trans_data ='1';

else if (key_number ==2) trans_data ='2';

else if (key_number ==3) trans_data ='3';

else if (key_number ==4) trans_data ='A';

else if (key_number ==5) trans_data ='B';

else if (key_number ==6) trans_data ='C';

else trans_data ='Z';

transmit();	/*transmit a byte*/

receive();	/*receive a byte*/

display();	/*display received data to P3.5-P3.2*/

} while(1);

}

(4) 프로그램의 解說

void check_key_number(void) {

P1 = 0xff;	/* 포트 1은 입력포트*/

key_number = 0xff;	/* key_num=-1*/

do {

i_data =P1;	/* P1을 읽어서 어느 비트든 0인가?*/

}while( i_data==0xff);	/* 누른 키가 있는가? */

for (j=0; j<=7; j++) {	/* 있으면 어느 것인가? */

key_number++;	/* key_number를 증가한다 */

i_data =i_data >>1 □ 0x80;	/* 하나씩 옮겨가면서 0인 비트를 찾는다*/

if(i_data==0xff) break;	/* 찾으면 루틴에서 빠져나온다*/

}

}

누른 키가 있는지, 있다면 그 key_number는 얼마인지를 알아내는 루틴이다. P1=0xff;는 포트 1을 입력포트로 하기 위함이고, i_data=P1을 i_data=0xff인 한 계속하는 것은 어느 것이든 키를 누를 때까지 여기서 맴돌으라는 것이다. i_data=0xff가 아니면 어느 것이든 누른 키가 있다는 증거이기 때문이다. 이 경우에는 i_data를 하나씩 우측으로 시프트해가면서 key_number를 증가한다. 원래 key_bumber는 0xff이기 때문에 하나 증가하면 0이 되고, 다시 증가하면 1이 되고 … 이렇게 증가한다. 이 루틴은 제11장에서 다시 다룬다.

if (key_number ==0) trans_data ='0';

else if (key_number ==1) trans_data ='1';

else if (key_number ==2) trans_data ='2';

else if (key_number ==3) trans_data ='3';

else if (key_number ==4) trans_data ='A';

else if (key_number ==5) trans_data ='B';

else if (key_number ==6) trans_data ='C';

else trans_data ='Z';

key_number에 따라 송신할 데이터를 달리하는 과정이다.

(5) 프로그램의 實行

제4장에서 설명한 방법에 따라 □Vision에서 Open project 작업을 하고(이미 open되어 있으면 생략), Edit project 작업을 한 다음 Build project 작업을 한다. 이로써 EX8_3.C라는 소스파일이 open된 프로젝트에 편입되고, 어셈블 또는 컴파일되고 링크되어 Obj 파일과 Hex 파일이 생성된다.

이 프로그램을 시뮬레이트하고자 하면 dScope에서 제4장에서 설명한 방법에 따라 CPU를 선택한다(물론 이미 CPU가 선택되어 있으면 생략한다). 그런데 앞에서와 같이 이 경우에도 문제점이 있다. 앞에서도 언급했듯이 이 프로그램을 실행시키려면 8751 또는 AT89C2051의 TxD핀과 RxD핀을 직접 연결해야 하는데 시뮬레이터에서는 이를 연결할 방법이 없다. 할 수 없이 RI가 세트되어 있는지의 명령 앞에 RI=1라는 명령을 두어서 강제 세트시켜야 한다. CPU 선택이 되면 다음으로 할 일은 주변장치들을 지정하는 일이다. peripheral에서 포트 1과 serial을 택한 후 serial의 Mode란에서 □8 bit variable Baudrate□에 클릭한다. 그런 다음 □Vision에서 지정한 project를 지정 호출한 후 Go에 클릭하여 프로그램을 실행(simulate)시킨다. serial 창의 SBUF가 하나씩 바꿔짐을 확인할 수 있을 것이다. 포트 1의 창이 변화되지 않는 이유는 TxD와 RxD가 연결되어 있지 않으므로 송신된 데이터가 수신이 되지 않아서 수신버퍼 레지스터 SBUF가 바꿔지지 않기 때문이다. 굳이 포트 1의 창에 송신된 데이터가 표시되도록 하고 싶으면 P1=tx_data라는 명령을 넣으면 된다.

실제 시스템에 실행시키고자 하면 □Vision에서 얻은 Hex 파일을 8751 또는 AT89S51 또는 AT89C2051에 ROM 라이터로 기록한다.

디지털제어 산업기사 8051 MICOM 보드에 실행시키고자 하면 역시 □Vision에서 얻은 Hex 파일을 MICOM PROGRAMMER에서 □열기□와 □자동□작업을 통하여 MICOM 보드에 기록해 넣는다. 그 이전에 LED들을 P3에 연결하고 P1은 키(key)로 쓸 수 있도록 해야 한다.

(6) 課 題

key_number에 따라 송신되는 문자가 자기 이름이 되도록 하라.

8.8.4 I/O포트 확장(출력)

(1) 目 的

모드 0의 I/O 확장기능을 이용하면 직렬포트를 병렬포트처럼 사용할 수 있다고 앞에서 언급하였다. 지금 그림 8.22와 같이 2중 버퍼형 직렬입력-병렬출력(serial-in parallel-out) 시프트레지스터 4084(또는 74HC585)를 8051에 연결하고 0FF에서 0까지의 데이터를 RxD를 통하여 일정 시간간격으로 직렬 전송하면 이들 데이터가 4084 또는 74H595에 연결된 LED에 병렬 표시되도록 하고자 한다. 4084 또는 74HC585는 2중 버퍼로 되어 있으므로 데이터를 시프트하는 동안 출력이 바뀌는 것을 방지하고 있다. 즉 SBUF에 송신될 데이터를 주면 직렬포트는 RxD를 통하여 한 비트씩 전송되는데, 한 바이트의 전송이 모두 끝나서 TI=1일 때 P3.3을 통하여 latch lock 신호를 보내면 그때에야 시프트되어온 데이터가 출력에 나타난다. 참고로 직렬포트의 확장 기능은 단 하나의 시프트레지스터에만 사용할 수 있

그림 8.22  직렬포트 I/O 확장도(출력)

그림 8.23  2개 이상의 I/O 확장도

는 것은 아니고 그림 8.23과 같이 또 하나의 포트라인 P3.2에 latch lock을 연결해 주면 상위의 시프트레지스터와는 별개로 또 하나의 시프트레지스터를 범용 I/O포트처럼 사용할 수 있다. 이런 식으로 몇 개고 간에 확장사용할 수 있다.

직렬포트를 사용하여 I/O포트를 확장하려면 8051 외에도 시프트레지스터가 필요하고 이것을 8051과 외부에서 연결해야 하기 때문에 실험이 어렵다. 그러나 실제로 8051을 이용하여 외부장치를 제어하다 보면 8051 자체의 I/O포트 만으로는 포트라인이 부족해서 망연자실하는 경우가 왕왕 있으므로 직렬포트의 I/O확장 기능은 반드시 설명해야 한다는 생각에서 여기에 소개한다.

(2) 順序圖

직렬포트의 I/O포트 확장 기능은 모드 0에서 가능하므로 먼저 모드 0을 설정한다. 모드 0이 설정되면 TxD를 통해서는 클록신호 CLK가 나가고, RxD를 통해서는 출력 데이터가 직렬 전송된다. STRobe 신호는 P3.3을 통하여 나가고 있다. 데이터를 송신하기 전에 이것을 Low로 함으로써 시프트가 가능하도록 하고, 송신이 완전히 끝나서 SCON 레지스터의 비트 1(TI)이 1로 될 때 4084의 수신 데이터를 래치시키기 위해서 이것을 High로 한다.

그림 8.24 모드 0의 I/O확장 기능(출력) 순서도

(3) 프로그램(EX8_4.C)

/*===========================================*/

/* PROGRAM EX8_4 (I/O EXPANSION(OUTPUT))	*/

/*===========================================*/

#include <reg51.h>

char i,tx_data;

void delay(void)	/* 지연 함수 */

{

TH0 = 0x28;	/* 0.03초를 위한 시간정수 */

TL0 = 0x00;

TR0 = 1;	/* 타이머0 run*/

while(％TF0);	/* TF0=1이 될 때까지 기다린다 */

TF0 = 0;	/* TF0를 클리어 */

TR0 =0;	/* 타이머0 stop */

}

void transmit(void)

{

SBUF = tx_data;	/* 송신; SBUFTX에 송신 데이터를 */

while(％TI);	/* 송신이 완료되었는가? */

TI = 0;	/* TI를 클리어 */

// P1 = tx_data;	시뮬레이션을 위한 것임

}

/* 메인 함수 */

void main(void)

{

EA = 0;	/* 인터럽트 disable */

TMOD = 0x01;	/* 타이머0의 모드=1 */

SCON = 0x00;	/* 직렬 모드=0, REN=0, TI=0 */

/* 보율=발진주파수/12 */

do {

for (tx_data=0; tx_data <=0xff; tx_data++)

{

P3 &= 0xf7;	/* P3.3=0 래치 펄스 */

transmit();	/* 하나의 바이트를 송신한다 */

P3 □ = 0x08;	/* P3.3=1 래치 펄스 */

delay();

}

}while(1);

}

(4) 프로그램의 解說

while( !TI);

TI=0

SCON 레지스터의 비트 1은 TI 플래그이다. 1 바이트 데이터의 전송이 완료되면 이 비트가 1로 세트되므로, 그것을 체크하는 것이다. SBUFＡtx_data에 의해서 전송이 완료되면 고장이 아닌한 당연히 TI가 세트되므로, 전송완료를 확인하는 것에 불과하다.

TI나 RI 플래그는 인터럽트가 발생되어도 자동적으로 클리어되지 않으나, SCON 레지스터를 읽어드리는 경우에는 자동적으로 클리어된다.

(5) 프로그램의 實行

이 프로그램도 다른 것과 같이 □Vision에서 Open project와 Edit project 작업을 하고 Build project 작업을 한다.

시뮬레이트를 하고자 하면 dScope에서 CPU와 project와 peripheral들을 선택을 한 후 Go한다. serial 창의 SBUF와 포트1의 내용이 하나씩 바꾸어짐을 확인할 수 있을 것이다. serial창에서는 8bit shift register를 선택한다.

이 문제를 실제 시스템에서 실험고자 한다면 외부에 그림 8.22와 같은 회로를 만들고, Hex 파일을 ROM 라이터로 8751 또는 AT89C2051 또는 AT89S51에 기록해 넣고 시스템에 꽂아 넣어야 한다.

트레인키트를 사용할 때에는 주소지정에 유의해야 한다. 트레인키트에 따라 시작번지를 8000H로 되어 있는 것도 있고, 4000H로 되어 있는 것도 있고, 2000H로 되어 있는 것도 있고, 0000H로 되어 있는 것도 있기 때문이다. 대개의 경우 트레인 키트에는 그림 8.22와 같은 회로를 만들어 넣을 만한 공간이 없으므로, 별도의 기판에 만들어 넣고 전원도 별개 전원을 쓰는 것이 편하다. 이때 어스선은 반드시 공통되어야 한다. 별도 기판의 어스선을 트레인 키트의 어스선에 연결해 주어야 한다. 그리고 프로그램도 지연루틴을 4배 정도 크게 해주어야 보기에 편하다.

디지털제어 산업기사 8051 MICOM 보드에 실현할 때에도 외부에 그림 8.22와 같은 회로를 만들고 이들을 연결한 후 □Vision에서 만든 Hex 파일을 MICOM 보드에 기록해 넣어야 한다.

(6) 課 題

CD4084 대신 74HC585를 이용하여 위의 일을 하도록 하라.

8.8.5 I/O 포트 확장(입력)

(1) 目 的

그림 8.25와 같이 병렬입력-직렬출력의 시프트레지스터(Parallel-in Serial-out shift register)

그림 8.25  직렬포트의 I/O 확장(입력)

74LS165를 직렬포트의 TxD와 RxD에 연결하고, b7∼b0를 통하여 외부로부터 들어오는 병렬 데이터를 직렬로 바꿔서 Serial output(QH)를 통하여 8051의 RxD에 보내면 8051은 이를 직렬 입력하여 포트 1에 나타내고자 한다.

(2) 順序圖

래치와 시프트를 위하여 strobe에 연결된 P3.3을 High-Low-High로 한 뒤에 SCON의 RI 플래그를 조사한다. 이것이 1이면 하나의 바이트 데이터가 입력 종료되었음을 뜻하므로 SBUF를 읽어서 P1에 출력한다.

그림 8.26  I/O 확장(입력)의 순서도

(3) 프로그램(EX8_5.C)

/*=========================================*/

/* PROGRAM EX8_5 (I/O EXPANSION(INPUT))    */

/*=========================================*/

#include <reg51.h>

char rx_data;	/* 변수의 정의 */

void delay(char i)  {	/* 지연 함수 */

while(i--);	/* i=0일 때까지 루프 계속 */

}

void receive(void) {	/* 수신 함수 */

//  RI = 1;	/* 시뮬레이트를 할 때 필요하다 */

while( !RI);	/* RI=1인가? */

RI = 0;	/* yes이면 RI를 클리어 */

rx_data = SBUF;	/* 수신된 데이터를 recv_data에 */

}

void main(void)	{	/* 메인 함수 */

EA = 0;	/* 인터럽트 불능 */

SCON = 0x10;	/* 직렬모드=0, REN=1, TI=0 */

do {

P3 □ = 0x08;	/* 로드 펄스 (형) */

P3 &= 0xf7;

P3 □ = 0x08;

receive();	/* 하나의 바이트를 수신 */

//  rx_data = 0x77;	/* 시뮬레이트를 할 때 필요하다 */

P1 = rx_data;

delay(0x10);

}while(1);

}

(4) 프로그램의 解說

while( !RI);

RI=0

SCON 레지스터의 비트 0은 수신이 끝났음을 나타내는 RI 플래그이다. 이 비트가 1인지를 체크하는 것이다. 전술한 바와 같이, SCON 레지스터를 읽어들이면 RI 플래그는 자동적으로 클리어되나, 즉시 클리어시킴이 좋다.

P3 □ = 0x08;

P3 & = 0xf7;

P3 □ = 0x08;

P3.3에 의 펄스를 주어서 latch lock을 시키기 위함이다.

(5) 프로그램의 實行

이 프로그램도 역시 □Vision에서 Open project와 Edit project 작업을 하고,  Build project 작업을 한다.

시뮬레이션을 하고자 하면, dScope에서 project를 불러와서 Go한다. SBUF에 아무런 변화가 없는데 이것은 시뮬레이터에서는 상대방 시프트레지스터의 Data out이 8051의 RxD를 통하여 데이터를 직렬 전송하는 부분을 만들 수 없기 때문이다. 실행(simulate)시키면 포트 1에는 55H 또는 77H가 표시되는데, 이것은 시뮬레이트를 위해서 특정의 수를 받은 것처럼 명령을 넣었기 때문이다.

앞 문제에서와 같이, 이 프로그램을 그림 8.25와 같은 실제 시스템에 실험하고자 할 경우에는 외부 기판에 회로를 만들고, 별도 전원의 경우에는 어스선을 서로 연결해야 한다. 그리고 프로그램에서는 □JUST FOR SIMULATION"이라는 주석이 들어간 명령은 모두 지워야 한다. 그리고 프로그램 실행에 있어서는 down loading에 들어가기 전에 TxD와 RxD선을 잠시 뽑아 놓든지, 아니면 tri-state 버퍼의 제어선에 논리 0의 신호를 주어 이 기간 중 TxD와 RxD가 고임피던스 상태가 되도록 해야 한다. 물론 실행(GO)에 들어갈 때에는 이들을 연결해 두어야 한다.

(6) 課 題

1. 그림 8.22와 그림 8.25를 하나로 해서 즉 I/O확장 출력회로와 입력회로를 하나로 합쳐서 직렬포트를 범용 I/O포트로 사용할 수 있도록 하라.

1. 8051의 직렬포트는 송신과 수신을 동시에 할 수 있는 전이중방식(Full duplex)으로서, 이는 송신과 수신을 번갈아 하는 반이중방식(Half duplex)과 구별된다

2. 8051 직렬포트는 또한 송신버퍼방식(receive buffered)이어서 앞에서 수신한 바이트가 SBUF에서 읽혀지기 전에 두 번째 바이트가 수신되어도 overrun error를 발생하지 않는다.

3. SBUF는 수신용과 송신용이 따로 있고, 송신할 데이터 및 수신한 데이터를 일시 보존하는 역할을 한다.

4. SCON 레지스터는 직렬포트의 제어와 상태 표시를 위한 것이다. 특히 이 레지스터의 REN(Receive Enable)는 수신 가능 여부를 결정짓는데, 이 비트를 1로 해 놓은 상태에서 RxD(P3.0)을 통하여 데이터가 들어오면 수신 시프트 레지스터는 이를 자동적으로 받아들이고, 하나의 바이트(프레임)가 다 들어오면 그 내용을 수신버퍼 SBUFRX에 옮김과 동시에 RI 플래그를 세트시킨다. TI 플래그는 MOV SBUF, R0(C에서는 SBUFＡtrans_data)와 같은 송신 명령이 실행된 뒤에 세트된다.

5. PCON 레지스터의 비트 7은 SMOD인데, 이것은 보율을 제어한다. 이것이 1로 되어 있으면 모드 1, 2, 3에서 보율이 2배로 된다.

6. 직렬포트의 동작 모드에는 4가지가 있는데, 직렬포트가 모드 0으로 되면 I/O포트 확장용의 동기식 통신 모드로 되고, 보율은 발진주파수의 1/12로 고정된다.

7. 모드 0의 I/O 확장기능을 이용하면 시프트레지스터를 8051의 병렬 I/O포트처럼 사용할 수 있다.

8. 동작 모드 1은 10비트 프레임의 표준 비동기식 통신 모드로서, 보율은 타이머 1의 오버플로율에 따라 달라진다.

9. 동작모드 2와 3은 11비트 프레임의 비동기식 통신 모드로서, 보율은 모드 2에서는 SMOD에 따라 발진주파수의 1/32 또는 1/64에 고정되고, 모드 3에서는 모드 1에서와 같이 타이머 1의 오버플로율에 의한다.

10. 모드 2, 3에서 SCON 레지스터의 SM2를 1로 세트해 두면 SCON 레지스터의 TB8(RB8)이 1인 경우에 한하여 인터럽트를 발생한다. 모드 2, 3의 이러한 기능을 이용하면 여러개의 8051 시스템을 직렬버스에 연결해 놓고 주 프로세서가 여러 종 프로세서 중 어느것에 직렬 데이터를 보낼수 있는  다중 프로세서 시스템을 구성할 수 있다.

11. 8051과 IBM PC는 보통 RS-232C 케이블을 통하여 연결된다. 원래 RS-232C는 MODEM과 터미널간의 인터페이스 방법에 대한 EIA의 RS규격이다.

8.1 다음 중 마이크로컴퓨터의 직렬 입출력 인터페이스가 아닌 것은?

㉮ SIO	㉯ USART

㉰ ACIA	㉱ PPI

8.2 마이크로컴퓨터의 병렬 입출력 인터페이스가 아닌 것은?

㉮ PIO	㉯ UART

㉰ PPI	㉱ PIA

8.3 직렬 입·출력 인터페이스에 해당하는 것은?	('84 전산기조직응용 2급)

㉮ 8251	㉯ 8255

㉰ 8257	㉱ 8258

8.4 동기 또는 비동기식으로 마이크로프로세서 간의 원거리 통신을 하려고 한다. 이때 필요하지 않는 장치는?	(전산기조직응용)

㉮ MODEM	㉯ RS 232 Driver/Receiver

㉰ SIO	㉱ PIO

8.5 아래 그림은 음성용 카세트 인터페이스의 개념도이다. 여기에서 UART의 역할은 아래 중 어느 것인가?	(전산기조직응용)

㉮ 카세트 속도 변화에 따라 Click 신호를 재조정하는 역할

㉯ 자료의 직렬, 병렬 변환의 역할

㉰ 자료의 변조 및 복조

㉱ 자료의 비교(0 또는 1의 구분)

8.6 직렬 입·출력 인터페이스의 응용에 해당되지 않는 것은?	(전산기조직응용)

㉮ 키보드 인코더	㉯ CRT 단말기기 인터페이스

㉰ 전화선 인터페이스	㉱ 텔레타이프 인터페이스

8.7 비동기식(asynchronous) 직렬 입·출력 인터페이스를 바르게 설명한 것은?	(전산기조직응용)

㉮ 단위 데이터를 동일 시점에서 전송하는 방식이다.

㉯ 변·복조 장치(MODEM)를 사용한 장거리 데이터 전송은 불가능하다.

㉰ 단위 데이터 전후에 스타트(start)신호와 스톱(stop) 신호가 필요하다.

㉱ 고속 데이터 전송이 필요한 입·출력장치의 인터페이스에 적합하다.

8.8 직렬 데이터 전송 방식에 대한 설명 중 잘못된 것은?

㉮ 데이터를 1비트씩 분해해서 전송하므로 병렬 전송 방식에 비하여 느리다.

㉯ 비동기 방식은 문자 단위로 데이터를 송수신한다.

㉰ 동기 방식은 블록(block) 단위로 데이터를 송수신한다.

㉱ 비동기 방식은 baud rate를 높게 할 수 있어서 동기식에 비해 일반적으로 전송 속도가 빠르다.

8.9 다음 중 한 번에 여러 문자, 즉 block 단위로 데이터를 전송하는 방식은?

㉮ 동기식(synchronous system)	㉯ 비동기식(asynchronous system)

㉰ 조보식(start stop system)	㉱ 정조보식(stepped start stop system)

8.10 동기식 전송 방법에 해당되는 것은 어느 것인가?	(전산기조직응용)

㉮ 한 번에 한 워드(word) 또는 한 문자식을 송·수신한다.

㉯ 송신하는 각 문자의 전후에 스타트 신호와 스톱 신호를 붙인다.

㉰ 어떤 특정의 조합 부호를 여러개 연속하여 보낸 뒤에 데이타를 전송한다.

㉱ 스타트 신호와 스톱 신호가 일정하게 정해진 간격에서 일어난다.

8.11 주변장치와의 데이터 전송이 직렬 형식으로 이루어지지 않는 것은?

㉮ 텔레타이프	㉯ MODEM

㉰ 카세트 테이프	㉱ keyboard

8.12 300 baud의 속도로 600문자의 데이타(문자당 8 bit로 구성)를 조보식으로 전송하려면 시간이 얼마나 걸리겠는가? 단, 1 start bit, 1 parity bit, 1 stop bit를 사용한다.

㉮ 5초	㉯ 11초

㉰ 22초	㉱ 30초

8.13 변·복조 장치(MODEM) 등의 디지탈 데이터를 아날로그 신호로 변환하여 전송하는 변조 방식과 관계가 먼 것은?	(전산기조직응용)

㉮ 시간 변조	㉯ 진폭 변조

㉰ 위상 변조	㉱ 주파수 변조

8.14 데이터 전송에 관한 설명 중 바른 것은?

㉮ 컴퓨터 내부의 데이터 전송은 모두 직렬 형태이다.

㉯ 원거리 데이터 전송은 병렬 방식이 적합하다.

㉰ 변복조 장치(MODEM)는 중고속의 원거리 통신에 적합하다.

㉱ 컴퓨터 내부에서의 데이터 전송 형태는 데이터버스를 통하여 이루어지므로 각기 다른 형태로 이루어진다.

8.15 다음 설명 중 틀리는 항은 어느 것인가?	(전산기조직응용)

㉮ 일반적으로 병렬 전송은 직렬 전송보다 훨씬 높은 비용의 전송선이 요구된다.

㉯ 동기 전송은 각 character당 start bit와 stop bit가 있다.

㉰ 동기 전송은 character block의 고속도 전송을 위해 사용된다.

㉱ code 형태는 사용될 장비에 좌우된다.

8.16 다음 설명 중 잘못된 것은?

㉮ 비트가 정보 표현 단위인데 반하여 baud는 정보 전달 속도의 단위이다.

㉯ baud는 1초 동안의 신호 비트 수로 표시한다.

㉰ BPS(bit per second)는 1초간의 data 비트수로 표시한다.

㉱ baud와 bit time은 같은 값이다.

8.17 UART는 보통 6가지 기능 블럭(block)에 의하여 운영된다. 그중 속하지 않는 것은?

㉮ 자료 버스 버퍼(buffer)	㉯ 상태 레지스터

㉰ 제어 레지스터	㉱ 자료 방향 레지스터(Data Direction Register)

8.18 여러 회선이 하나의 회선을 공유하려면 어떤 회로를 사용하면 좋은가?	(조직응용)

㉮ 멀티플렉서	㉯ 디멀티플렉서

㉰ 인터페이스	㉱ 버스 회로

8.19 다음 용어 중 보조기억장치와 관계가 없는 것은?	(전산기조직응용)

㉮ 섹터(Sector)	㉯ 트랙(Track)

㉰ 볼륨(Volume)	㉱ 모뎀(Modem)

8.20 마이크로컴퓨터의 입·출력 방식에 대한 설명 중 옳지 않는 것은?	(전산기조직응용)

㉮ 입·출력장치에 번호를 붙여 명령 중에 이 번호를 지정함으로써 입·출력하는 대상 장치를 지정할 필요가 있다.

㉯ 입·출력 장치를 지정하는 방법에 따라 채널 입·출력 방식과 기억장치 맵 입·출력 방식의 두 가지가 있다.

㉰ 채널(isolated) 입·출력 방식은 입·출력장치의 번호를 붙여 입·출력 명령중에 이 장치 번호를 지정하는 방식이다.

㉱ 하나 이상의 입·출력이 병렬로 이루어지도록 하는 프로그램 수행 능력을 가진 처리 장치인 채널을 사용한다.

8.21 MODEM이란?

□ 변조장치	□ 복조장치

□ 변조 및 복조장치	□ 동가장치

8.22 다음 중 UART(Universal Asynchronous Receiver Transmitter)에 속하지 않는 것은?

□ Serial Receiver(Rx)	□ Serial Transmitter(Tx)

□ Bidirectional Data Bus Buffer	□ Data Direction Register

8.1 수신에 있어서 SCON 레지스터의 REN 비트의 기능을 기술하라.

8.2 RI과 TI 플래그가 세트되는 과정을 서술하라.

8.3 8051 직렬포트의 보율(baud rate)은 어떻게 결정되는가?

8.4 8051 직렬포트에서 비동기식 송신 및 수신이 이루어지는 과정(sequence)을 기술하라.

8.5 다중 프로세서 시스템에서 주 프로세서와 종 프로세서 간에 직렬통신이 이루어지는 관계에 대하여 논하라.

8.6 직렬포트의 I/O 확장 기능에 대하여 논하라.