8051 평가 컴파일러를 이용한 타깃보드...

30
112 Embedded Systems Special 8051 평가 컴파일러를 이용한 타깃보드 설계 신연재 1. 서론 8051 펌웨어를 개발하기 위해서는 전자부품과 프로세스에 관련된 하드 웨어 설계, 적절히 운용할 수 있는 프 로그램 작성 등 관여해야 할 것이 상 당히 많다. 저자는 그 중에서도 C 언 어를 이용하여 8051 프로그램을 작성 하는 컴파일러 툴(Tool)에 대해 본 잡 지를 통하여 시리즈로 설명하고자 한 다. 본인이 학교에서 전자공학을 전공 할 때에는 기계어 코드를 적어 놓은 니모닉(Mnemonic) Sheet 를 보고 프로그램 했다. 얼마후 어셈블리를 이 용해서 마이크로컨트롤러(마이컴)의 프로그램을 작성하여 코드를 만들었 고, 이제는 하이 레벨 C 언어를 사용 하여 프로그램을 작성하고 컴파일하 게 되었다. 그 당시보다는 좋은 환경 이라 말할 수도 있지만 사실 만들어야 하고 신경 써야 할 것이 많은 것에 비 하면 상대적이기는 하다. 본 원고는 전자기술의 지면을 빌려 독일 카일 (KEIL) C 컴파일러와 구현한 Tar- get Board 를 설명함으로써 개발자 들의 컴파일러 환경에서 부담을 덜어 주고자 노력했다. 마이크로컨트롤러는 0과 1의 조합 으로 구성되어 있는 기계어를 사용한 다. 8 비트 MPU 나 PC에서 사용하는 펜티엄 시리즈도 마찬가지이다. 아무 리 고급언어로 프로그램을 작성하더 라도 최종적으로 마이컴(마이크로컴 퓨터)에서는 해독하기 쉬운 언어에 해 당하는 기계어로 바꿔주어야 한다. 마 이컴 내부에는 0과 1로 구성되어 있 는 명령어의 코드를 차례로 불러 올 수 있는 역할을 하는 프로그램 카운터 (PC : Program Count) 가 있다. PC가 지정한 메모리 위치에서 한번 에 불러올 수 있는 코드는 마이컴의 능력에 따라 4비트, 8 비트, 16 비트, 32비트 등으로 나누어지는데, 코드를 읽고 해석해서 주어진 동작을 실행하 도록 되어있다. 8 비트 마이컴은 한번 에 불러오고 처리할 수 있는 비트수가 8비트인 것이다. 명령의 개수도 256 개(0∼FF) 이하로 되어있는데, 프로 그램을 하는 사람은 여러 개의 코드를 적절히 나열하여 정해진 일을 마이컴 이 하도록 하면 된다. 그러나 여러 가 지 동작을 하는 기계어 코드를 일일이 외우고 적절히 치하기에는 고도의 훈련이 필요하므로 고급수준의 언어 로 일단 만든 후, 컴파일러(Compiler) 와 링커(Linker) 를 통해 기계어 코 드로 바꿔주는 것이다. 엔지니어는 C 언어나 어셈블리언어로 작성한 프로 그램(Source File) 을 기계어 코드 로 바꾼 후에 메모리에 적재하여 마이 컴을 운용한다. 그래서 기계어 코드 로 만들어 주는 컴파일러의 성능에 따 라 코드의 크기가 줄어들기도 하고 명 령어 조합의 식에 따라 마이컴의 실 행 속도가 결정되기도 한다. 현재 일 반적으로 잘 알려지고 통용되는 8051 글/김형태 [email protected]

Upload: others

Post on 03-Jan-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

전자 112CM YK CM YK

CM YK CM YK

112

Embedded Systems Special

8051 평가 컴파일러를 이용한 타깃보드 설계

신연재

1. 서론

8051 펌웨어를 개발하기 위해서는

전자부품과 프로세스에 관련된 하드

웨어 설계, 적절히 운용할 수 있는 프

로그램 작성 등 관여해야 할 것이 상

당히 많다. 저자는 그 중에서도 C 언

어를 이용하여 8051 프로그램을 작성

하는 컴파일러 툴(Tool)에 대해 본 잡

지를 통하여 시리즈로 설명하고자 한

다. 본인이 학교에서 전자공학을 전공

할 때에는 기계어 코드를 적어 놓은

니모닉(Mnemonic) Sheet 를 보고

프로그램 했다. 얼마후 어셈블리를 이

용해서 마이크로컨트롤러(마이컴)의

프로그램을 작성하여 코드를 만들었

고, 이제는 하이 레벨 C 언어를 사용

하여 프로그램을 작성하고 컴파일하

게 되었다. 그 당시보다는 좋은 환경

이라 말할 수도 있지만 사실 만들어야

하고 신경 써야 할 것이 많은 것에 비

하면 상대적이기는 하다. 본 원고는

전자기술의 지면을 빌려 독일 카일

(KEIL) C 컴파일러와 구현한 Tar-

get Board 를 설명함으로써 개발자

들의 컴파일러 환경에서 부담을 덜어

주고자 노력했다.

마이크로컨트롤러는 0과 1의 조합

으로 구성되어 있는 기계어를 사용한

다. 8비트 MPU나 PC에서 사용하는

펜티엄 시리즈도 마찬가지이다. 아무

리 고급언어로 프로그램을 작성하더

라도 최종적으로 마이컴(마이크로컴

퓨터)에서는 해독하기 쉬운 언어에 해

당하는 기계어로 바꿔주어야 한다. 마

이컴 내부에는 0과 1로 구성되어 있

는 명령어의 코드를 차례로 불러 올

수 있는 역할을 하는 프로그램 카운터

(PC : Program Count) 가 있다.

PC가 지정한 메모리 위치에서 한번

에 불러올 수 있는 코드는 마이컴의

능력에 따라 4비트, 8비트, 16비트,

32비트 등으로 나누어지는데, 코드를

읽고 해석해서 주어진 동작을 실행하

도록 되어있다. 8비트 마이컴은 한번

에 불러오고 처리할 수 있는 비트수가

8비트인 것이다. 명령의 개수도 256

개(0∼FF) 이하로 되어있는데, 프로

그램을 하는 사람은 여러 개의 코드를

적절히 나열하여 정해진 일을 마이컴

이 하도록 하면 된다. 그러나 여러 가

지 동작을 하는 기계어 코드를 일일이

외우고 적절히 배치하기에는 고도의

훈련이 필요하므로 고급수준의 언어

로 일단 만든 후, 컴파일러(Compiler)

와 링커(Linker)를 통해 기계어 코

드로 바꿔주는 것이다. 엔지니어는 C

언어나 어셈블리언어로 작성한 프로

그램(Source File) 을 기계어 코드

로 바꾼 후에 메모리에 적재하여 마이

컴을 운용한다. 그래서 기계어 코드

로 만들어 주는 컴파일러의 성능에 따

라 코드의 크기가 줄어들기도 하고 명

령어 조합의 방식에 따라 마이컴의 실

행 속도가 결정되기도 한다. 현재 일

반적으로 잘 알려지고 통용되는 8051

글/김형태[email protected]

전자 113

113월간 전자기술/ 2000년 7월호

CM YK CM YK

CM YK CM YK

8051 평가 컴파일러를 이용한 타깃보드 설계

관련 컴파일러에는 KEIL, PLC, IAR, Tasking, Intel,

Hitech , 2500AD, Avocet 등이 있다.

C 언어 등의 고급언어로 작성한 프로그램은 어셈블리언

어나 니모닉으로 작성한 프로그램에 비해 이해하기 쉬운

것은 당연하다고 하겠다. 표준으로 되어 있는 C 언어를 이

용하여 프로그램하면, 관리적인 측면에서 유리하고 융통

성이 뛰어나는 등의 장점이 있다. 사실 C 언어를 익혀두면

하드웨어나 소프트웨어를 하는 모든 엔지니어에게 플러스

적인 작용을 한다. 현재 통용되고 앞으로 21세기에는 개발

자가 사용해야 하는 Tool이 커지면서 Window에서 운용

되며 상당부분이 C 언어에 기초를 둘 것이라 예상하기 때

문이다. 프로그램 언어에 대해 잘 알지 못하면 대개 개발자

에게 스트레스로 다가온다. 본인이 속해 있는 개발실에서

도 한번 모르면 좀처럼 그 상황을 벗어나기 어려운 경우를

많이 보아왔다. 그렇다고 마이컴 프로그램을 만드는 것이

마지막단계는 아니다. 어쩌면 납땜인두나 PC를 사용하는

공구나 Tool의 한 종류일 수도 있기 때문이다.

2. 8051 요약

원래 8051은 외부 모양이 40핀으로 직사각형 모양을 이

루고 있는 디바이스이다. 표준 형식만 간단히 설명하고자

한다. 핀의 구성은 5V 전원이 인가되는 Vcc(무수히 많은

로직이 내부에 있으므로 공급 전압 리플이 적어야 한다)와

GND가 있다. 그리고 2개의 머신 사이클(One Machine

Cycle=12 Clock)동안 하이(High, 로직 1)가 유지되면

리셋이 되는 RESET 핀이 있다. 포트0은 8비트 오픈 드

레인(I/O로 사용할 경우 외부 풀업)으로 구성되어 있으며

양방향 I/O, A0~A7, D0~D7 로 이용한다. 포트1은 내

부에 풀업이 되어 있는 양방향 I/O이다. 포트2는 내부에

풀업이 되어 있고 양방향 I/O, A8~A15 로 이용한다. 포

트 3은 내부 풀업이 되어 있는 양방향 I/O 이며 Serial 통

신, 외부인터럽트, 타이머, Read, Write 로 사용할 수 있

는 특수 기능도 가지고 있다. X1은 발진기 증폭기의 입력

이 반전되어 들어가는 핀이며 X2는 반전되어 출력되는 핀

이므로 Crystal일 경우는 X1, X2 에 병렬로 연결하지만

Oscillator일 경우는 X1만 연결한다. ALE/PROG

(Address Latch Enable Output/Program Pulse

Input)핀에서 ALE는 외부메모리를 호출하는 동안에 하

위 번지 바이트를 래치하기 위해 사용되며, PROG 는

EPROM일 경우 프로그램을 기록할 때 펄스의 입력으로

사용한다. PSEN(Program Strobe Enable) 핀은 외

부 코드메모리를 읽을 경우 사용하는 신호이며, 각 머신

사이클에서 2번 출력되고 ALE의 하강에서 포트0이 어드

레스 번지로 사용된다. EA/Vpp(External Access

Enable) 핀은 GND에 연결되면 0~FFFh 번지까지 코

드메모리는 내부 ROM을 사용하게 되고 Vcc에 연결되면

코드메모리는 외부 ROM을 사용하게 된다. Vpp 는 8751

일 경우, 프로그램 기록용 전원입력 단자로 12.75V~21V

사이의 전압을 스팩에 맞게 공급해 주어야 한다.

메모리 구성에 대해 알아보자. 메모리는 내부메모리와

외부메모리로 나눌 수 있는데, 8051 코어를 가진 마이컴

의 내부메모리는 레지스터 메모리가 128바이트(8052는

256바이트) SFR이 128바이트, 합해서 256바이트로 구

CPU(Central Processing Unit)는 중앙연산처리장치, 데이터처리, 제어

판단 등을 담당하는 중추 부분을 말한다. CPU와 메모리, I/O, 타이머 등을

하나의 LSI로 집적하여 One-Chip 한 것을 MPU(Micro Processing

Unit)라 하지만 특별히 구분하는 의미가 없다. 최초의 마이크로프로세스는

1971년에 Intel사의 2,250개의 트랜지스터로 구성되어 있고 4개의 LSI

(Large Scale Integration) 칩 세트로 만든 4비트 마이크로컴퓨터시스템

MCS-4이다. One-Chip 마이컴은 한 개의 실리콘 칩에 CPU, 메모리(기

억장치), I/O, 타이머, 변환장치 등을 포함한 마이크로컴퓨터를 지칭하며 근

래에는 간단히 마이컴이라고 한다.

전자상식 : CPU, MPU, One-Chip 마이컴

8비트 마이크로프로세스 8051 코어를 사용한 LSI를 말한다. 8031은 ROM

이 없는 것이며 8051은 4Kbyte ROM이나 EPROM(창이 달린 8751)이

내장된 On-Chip이다. 프로세스 내부를 CHMOS로 반도체를 만들면 '5'

혹은 '3' 앞에 'C'를 붙여 80C51 등으로 불린다. 128×8비트의 내부

RAM이 있으며 32개의 양방향 프로그램 가능한 I/O(Input/Output), 2개

의 16비트 타이머, 우선 순위를 가진 5개의 인터럽트, 1개의 Serial 포트

(완전한 이중 UART), 클록 발진기 내장, 64K 바이트의 외부 Code 어드

레스 공간, 64K 바이트의 외부 Data 어드레스 공간, IDLE와 Power Down

Mode의 특징을 가지고 있다.

전자상식 : 인텔의 8031/8051/8751의 특징

전자 114CM YK CM YK

CM YK CM YK

114

Embedded Systems Special

성되어있다. 8051의 기본 메모리 구성은 아래 그림1의

8051 메모리 맵의 회색부분이 없는 상태, 즉 128 바이트

와 SFR로 되어 있다. 외부메모리는 Code(Program) 와

Data로 나누는데, 어드레스 능력 때문에 최대 각각 64K

로 구성할 수 있다. C 프로그램을 만들고 컴파일하면 Hex

파일로 만들어진 기계어의 놓일 자리가 Code(Program)

메모리 부분이 되고, 마이컴이나 사용자의 연산 명령에 의

해 저장된 데이터는 Data 메모리 부분이 된다. 그래서 개

발자가 Source 프로그램을 컴파일하고 난 후에는 이론적

으로 Code 크기가 64K, 사용한 Data 메모리가 64K 이

상 되지 않게 하고 Target System 에 맞게 Coding을 해

야한다.

내부메모리에서 128바이트는(혼동을 피하기 위해 Reg-

ister Memory 라고 한다) 4개의 범용 레지스터뱅크(0~7,

8~F, A~17, 18~1F)로 이루어지고 20~2F까지는 비

트 어드레스 영역으로 사용할 수 있는 공간, 그리고 30~7F

까지는 스택이나 사용자 공간으로 사용할 수 있게 되어 있

다. 또 128바이트로 되어 있는 SFR(Special Function

Register)은 21개의 레지스트로 구성되어 있는데 C 언

어로 프로그램을 하더라도 자세히 알아두어야 한다.

SFR은 크게 소프트웨어 제어와 연산, I/O를 제어하는

부분의 두 가지로 나눌 수 있는데 우선 P0~P3은 I/O 포

트와 연결되어 있는 레지스터이다. ACC(Accumulator)

는 모든 연산의 중심이 되며 산술, 논리에 이용된다. B는

ACC와 더불어 곱셈에서는 상위 값을 저장하고 나눗셈에

서는 나머지를 저장한다.

PSW(Program Status W ord)에는 프로그램 수행

때에 상태 결과를 나타내는 역할을 하며 CY, AC, F,

RS1, RS2, OV, P 등이 있다.

SP(Stack Point) 는 리셋되었을 때, 초기값은 07h이

며 스택의 최하위 번지를 지정해서 PUSH되면 자동으로

증가하고 POP되면 감소한다. 최대 증가 번지가 내부메모

리를 초가하면 시스템이 정지되므로 넘치지 않도록 주의

해야 한다. DPTR(Data Pointer Register) 은 8비트

의 DPH와 DPL로 구성되어 외부데이터 메모리의 번지

를 지시할 때 사용한다. SBUF는 직렬통신에서 송신, 수

신버퍼로 이용된다. PC(Program Count) 는 프로그램

의 실행 번지를 지시할 때 사용하며, SFR이나 내부 RAM

레지스터 메모리와 독립적으로 움직이는 16비트 레지스

터다. 이 밖에 제어레지스터로 IP, IE, TMOD, TCON,

SCON, PCON 그리고 타이머 레지스터가 있다.

본인이 미처 설명하지 못한 내용은 인텔 웹사이트

(http://www.intel.com/design/product.htm) 의

Microcontrollers/MCS 51 microcontroller family

를 참조하면 된다. 여기에는 마이컴의 본거지답게 여러 종

류의 8051 관련 Data Sheet 가 있으므로 더욱 깊이있는

지식을 얻을 수 있을 것이다.

KEIL 8051 C 컴파일러에서 메모리와 관련되어 사용

하는 명령어 키워드(Keyword)는 code, xdata, pdata,

data, idata, bdata 가 있다. 먼저 외부메모리에 있는

Code 메모리는 사용자에 의해 ‘code’ 키워드를 사용하여

어드레스를 지정하고 Firmware 에 이식 후 기계어를 로

딩하기도 하지만 대부분 컴파일러에게 Code 배치를 알아

서 하도록 위임한다.

Code는 일단 운영(Run)중에는 읽기만 가능하고 쓰기

는 할 수 없다. ‘xdata’, ‘pdata’ 명령어를 사용하는 Data

메모리는 마이컴의 운영중에 발생하는 정보저장 장치로

사용하며 읽고 쓰기가 자유롭다. 내부메모리는 레지스터

메모리의 크기에 따라 사용하는 명령어가 다르다.

8051은 내부레지스터 크기가 128바이트에서는 ‘data’,

256(레지스터 메모리의 128K바이트 어드레스 구성표에

서 회색부분 포함)바이트에서는 ‘idata’, 그리고 16바이

트 영역의 0x20∼0x2F(128K바이트 어드레스 구성도의

00∼7F)까지만 사용할 수 있는 ‘bdata’ 명령어로 나눌

수 있다. bdata 는 뒤에 비트로 조정할 수 있는 키워드가

별도로 있다.

그림 1. 8051 메모리 맵

FFh

7Fh

0

128Byte

128Byte

RegisterMemory

SpecialFunctionRegister

Program(Code)Memory

DataMemory

64K

CODE

64K

XDATA128Byte

SFR

FFFFh FFFFh

내부 Memory 외부 Memory

oh oh

전자 115

115월간 전자기술/ 2000년 7월호

CM YK CM YK

CM YK CM YK

8051 평가 컴파일러를 이용한 타깃보드 설계

3. KEIL 컴파일러 평가버전의 설치

저자가 설명하고자하는 컴파일러는 독일 KEIL사의 컴

파일러이다. 21세기에는 다른 회사에서 더 좋은 Tool이

나올지 모르지만 나와 같은 Firmware 엔지니어에게는

한번 권해 주고 싶은 컴파일러이다. 저자는 KEIL의 한국

특약점(Agent) 한국MDS(02-2645-0386)에서 PK51

V5.5a를 구입했다. 8051 Development Tool 의 컴파일

러는 지원항목에 따라 가격과 종류가 다양하므로 개발자

의 형편에 맞게 구입하면 된다.

KEIL(http://www.keil.com/home.htm) 컴파일러

를 이미 구입한 독자들은 그 성능이나 특성에 대해 잘 알고

있겠지만 본지에서는 접해 보지 않은 Firmware 엔지니

어를 위해 ‘KEIL Evaluation Kit Manual ’의 평가용

프로그램의 설치와 실행에 대해 하드웨어와 함께 설명하

고자 한다. 우선 평가용 버전을 다운로딩(http://www.

8051.co.kr 또는 ftp://8051.co.kr/incoming) 받고 압

축을 푼 다음 설치준비를 하자. 51컴파일러 프로그램을

설치하기 위해서 요구되는 사항으로 OS(Operating

System)는 Win95, Win98, Win2000, Windows NT

Version 4이면 되고 10M의 하드디스크 여유공간과 32M

바이트의 RAM이 있으면 된다. 그러나 공짜 평가 프로그

램이 다 그렇듯이 제약이 있는데, Object Code 를 기준으

로 2K바이트 이하의 제한조건(8051 compiler,

assembler, linker, debugger 해당)이 있고 칩 내부에

ROM이 있는 single-chip(on-chip ROM) 에서는 사

용하지 못한다. 이유는 컴파일러가 ‘LJMP’ 코드를 강제

로 생성하여 0x4000이 처음 시작 번지가 되기 때문이다.

또 floating-point 연산 Library 등을 지원하지 않는다.

그림2는 EK51V50.ZIP의 압축을 푼 다음 SETUP.EXE

를 실행한 뒤의 초기화면이다. 경로는 본인이 다른 것으로

지정하거나 Default 로 한 후 ‘OK’를 하면 그림3처럼 시리

얼 번호를 묻는데, ‘PK51-EVAL’로 그대로 두어야 정상적

으로 설치할 수 있다. 경로에서 주의 할 것은 한글을 사용하

지 않고 영문으로만 작성해야 한다는 것이다. 설치가 완료되

면 4개의 아이콘이 생성된 폴더가 완성된다. 그러면 이제 그

림4의 ‘цVision-51’을 클릭 하여 컴파일러를 실행해 보자.

KEIL 컴파일러는 цVision 통합환경의 Window 에

서 운용되지만 컴파일할 때는 DOS로 갔다가 다시 윈도

우로 되돌아온다. 아마 원래 도스에서 개발 후 KEIL에서

_at_ alien bdata bit code data idata

large pdata sbit sfr sfr16 small _task_

using xdata _priority_ reentrant compact interrupt

그림 3. 개인정보, 시리얼번호 입력

그림 2. 8051 컴파일러 평가판 초기화면

표 1. KEIL 컴파일러의 종류

-

-

-

-

-

A51Assembler

-

-

-

-

지원항목

Kit 이름 CA51Compiler

DK51Developer's

uVision IDE

A51 Macro Assembler

BL51 Code Banking Linker

OH51 Object-HEX Converter

C51 ANSI C Compiler

OC51 Banked Object Converter

dScope Simulator/Debugger

MON51 Target Monitor

RTX51 Tiny Real-time Kernel

PK51

Prof. Developer's

C51에서 미리 등록해 놓고 사용하는 단어로 프로그램을 작성할 때에는 변

수이름이나 루틴이름을 키워드에 있는 단어와 동일하게 사용할 수 없다.

C51은 대문자, 소문자를 구분하는데 키워드는 소문자로 되어있다. 아래에

C51에서 사용하는 키워드의 일부를 나타냈다.

전자상식 : C51 키워드(Keyword)

전자 116CM YK CM YK

CM YK CM YK

116

Embedded Systems Special

버전 업(Version Up) 시켰으리라 생각된다. KEIL 의

8051 컴파일러를 C51이라고 하는데 이후에 8051 C 컴

파일러(Compiler)를 이런 용어로 사용하겠다. C51은

ANSI(American National Standard Institute) 규

격을 표준으로 사용하므로 C 언어를 사용하는 개발자는

ANSI C로 프로그래밍하면 되며, 8051 컴파일과 C 언어

에 관련된 참고서적을 원서로 보고자 하는 독자는 다음의

책들을 참고하기 바란다. ‘The C program Language,

Kernighan , Pr entice-Hall , ISBN 0-13-110370-9’,

‘C and the 8051, Schultz, Prentice-Hall, ISBN

0-13-753815-4’.

우선 초기화면이 실행되면 그 동안 작업한 프로젝트가

없으므로 바탕화면이 텅 비어 있게 된다. 일단 상단의 8가

지(File, Edit, Project, Run, Option, Tool,

Windows, Help) 메뉴가 있는데 윈도우 사용자라면 그

리 어렵지 않은 Pull Down 메뉴이다. C51은 프로그램

을 관리할 때 Project라는 파일로 통괄 처리한다. 본인도

처음에는 상당히 어색했는데 여러 개의 프로그램이나 루

틴을 일괄처리 하는 데는 당연히 사용해야 하며 익숙해지

면 편하다. Project 는 프로그램 환경, 심지어 편집에 관련

된 정보까지도 고스란히 가지고 가기 때문에 사용자는 실

제로 개발하듯이 프로젝트 단위로 C51을 사용하면 된다.

그러나 Project 파일을 새로 만들 때는 Project 환경이

나 Option 메뉴를 수정해 주어야 한다. 아래에 KEIL에

서 제공해 주는 Project 환경을 나타냈는데 하나씩 이해

하면서 따라해 보도록 하자. ‘Source Files’ 항목에는 여

러 종류의 프로그램(어셈블리, 라이브러리, C 등)과 도큐

멘테이션을 이곳에 놓으면 최종적으로 프로젝트가 컴파

일 한 후 연관된 파일과 연결시켜준다. 우선 ‘Project/

Open Project ’를 한 뒤, C51eval/examples/hello/

hello.prj를 열고 소스를 편집화면에 놓기 위해 ‘Open

All’ 하자.

여기서 C 언어를 이용하여 프로그램하는 과정을 처음

접하는 독자를 위해 소스 그림5에 있는 HELLO.C를 잠

시 분석하고 넘어가자.

ABSTRACT.TXT 는 프로그램을 설명한 주석문에 해

당되며 컴파일할 때는 전혀 상관없는 파일이다. 프로젝트

를 이렇게 관리하는 독자라면 오랜 시간이 지나도 본인의

프로그램을 분석하는 데에 그리 많은 시간을 요하지 않을

것이다.

그림 4. 폴더 생성

그림 5. Project Open

/*

Purpose : 평가버전 Test(EA51 V5.0)

Fi Name : HELLO.C

Compiler: KEIL PK51-EV AL(한국MDS:02-2645-0386)

Support : [email protected]

Copyright 1995-1997 KEIL Software, Inc.

*/

전자 117

117월간 전자기술/ 2000년 7월호

CM YK CM YK

CM YK CM YK

8051 평가 컴파일러를 이용한 타깃보드 설계

#pragma DEBUG OBJECTEXTEND CODE // 디버그 정보, 변수 정보를 저장한다.

// 꼭 필요한 것은 아니다.

#include <reg51.h> // Standard 8051의 SFR(Special Function Register)

// 정의 헤드 파일

#include <stdio.h> // I/O함수 선언 헤드파일

#include <intrins.h> // 어셈블리 명령어가 포함되어 있다.

#ifdef RISM // RISM 문자를 전처리기(Pre-Processor)가 받으면 실행

const char data rism_1 [24] _at_ 0x28; // 28번지부터 data 영역으로 배열 24개를 정의

#endif // end ifdef

void main (void)

#ifdef RISM // RISM 단어를 만나면 NOP(No Operation) 를 3번 실행한다.

_nop_ ();

_nop_ ();

_nop_ ();

#endif

/*-------------------------------------------------------------------------------------------------------------

시리얼 통신 초기화 1200 baud at 16MHz

--------------------------------------------------------------------------------------------------------------*/

SCON = 0x50; // SCON: 통신 Mode 1, 8-bit UART, Enable Receive Flag

TMOD |= 0x20; // TMOD: timer 1, 타이머 Mode 2, 8-bit reload

TH1 = 221; // reload value for 1200 baud 16MHz 에서

// TH1=256-(2MOD/(12*32*(16MHz)-1*원하는 통신속도)), MOD는 0 또는 1

TR1 = 1; // Timer 1 R un

TI = 1; // set TI to send first char of UART

while (1) // ()의 내용이 0(Zero)이 아니고 참(1 이상)이므로 무한루프

P1 ^= 0x01; // P1=P1 000 0001, P1.0의 값이 실행될 때마다 0과 1을 반복한다.

printf ("Hello W orld\n"); // 연속해서 "Hello World" 를 직렬통신을 통해 출력한다.

// End while

// 메인 프로그램의 마지막

/*************************************************************************************************************/

프로그램 초반에 ‘#ifdef RISM ’ 라고 정의한 부분은

컴파일러가 컴파일할 때 전처리기에 알려, 그 해당 단어

(여기서는 ‘RISM’)를 만나면 실행하고 아니면 그냥 지나

칠 수 있도록 하기 위해 사용한다. ‘#ifdef’의 마지막은

‘#endif’으로 if 문의 마지막을 알려주기 위해 사용되는데

HELLO.PRJ 에서는 define 에 넘겨줄 명령어가 정의되

어 있지 않다. 그러면 RISM의 단어를 컴파일러에게 알려

주기 위해서는 어떻게 지정해야 할까? 이어지는 그림에는

전자 118CM YK CM YK

CM YK CM YK

118

Embedded Systems Special

option/c51 compiler options/misc/symbols... 항

목에 ‘RISM’을 넣은 상태를 보여준다. 저자는 #ifdef 를

디버그(debug)할 때 주로 사용하는데 Target Board 개

발 중 디버그 할 때만 전처리기에 알려 사용하고, 정상적

으로 개발이 완료되면 항목에서 삭제하여 최종 코드를 생

성하는 데 이용한다.

4. 컴파일러의 사용

KEIL 컴파일러를 설치한 후 프로젝트 파일을 정상적

으로 열고 C 소스를 편집기 바탕화면에서 보았다면 이제

부터는 컴파일하고 프로그램을 실행해 보자. 프로젝트 파

일 HELLO.PRJ 를 불러오면 이미 컴파일 환경에 관련된

정보도 함께 로딩(Loading)되어 있는 상태이므로 그냥

컴파일하면 된다. 컴파일은 ‘project/compile’을 선택하

거나 을 마우스로 클릭 한 후 에러가 없다면, OBJ 파

일이 생성되고 HEX 코드는 다시 OH51.EXE 파일이 호

출되어 만들어 낸다. 링크는 생성된 오브젝트 파일을 가지

고 절대 오브젝트 파일을 만들어 주는데 ‘project/make

: link pr oject’를 실행하거나 툴바의 (Build All) 를

클릭하면 확장자가 없는 OMF51 파일을 프로젝트 이름

으로 만들어 준다. 또 (Update) 기호가 있는데 프로젝

트에 의해 불러온 파일들 중에서 전부 컴파일, 링크하지

않고 소스코드를 고친 것만 컴파일하고 링크해 준다. 긴

소스 프로그램이 여러 가지일 경우에 유용하게 사용할 수

있다. 그러나 제시된 샘플프로그램 HELLO.PRJ 는 컴파

일하고 링크를 해도 HEX 파일은 어디에도 생성되지 않는

다. 그 이유는 ‘Option/make/after compile ’의 마지막

항목 ‘Run OH51 Object Hex Converter ’을 선택하지

않았기 때문이다. 그것을 선택하면 컴파일한 뒤에 에러가

없을 경우에 프로젝트와 동일한 디렉토리에 동일한 이름

으로 HELLO.HEX 가 생성된다.

컴파일을 에러 없이 완료하게 되면 디스코프(dScope)

가 이들 결과를 받아 무엇인가를 빠르게 실행하는데 일단

은 컴파일러에 대해 좀더 알아보고 디스코프로 건너가도

록 하자. KEIL 컴파일러 C51은 메모리의 크기와 운영방

식에 따라 Small, Compact, Large 등 3가지 메모리 모

델(Memory Model) 이 있다. Small 모델은 ‘data’ 키

워드를 이용 8051 내부의 램을 사용하며, Compact 모델

은 ‘pdata’ 키워드를 이용 8051 외부 램의 한 페이지에

R0, R1 레지스터로 어드레싱 한다.

Large 모델은 ‘xdata’ 키워드를 이용하고 Compact

와 비슷하지만 DPTR을 사용하여 모든 변수를 외부 램에

어떤 언어로 된 원시 프로그램으로부터 그와 동등한 일을 하는 다른 언어로

는 생성하는 작업을 통칭한다. Firmware 분야의 컴파일러는 좁은 의미로

는 고급언어로 된 원시 프로그램을 어셈블리 언어나 기계어 등의 저급 언어

로 된 목적 프로그램으로 번역하는 작업을 칭한다. 컴파일은 원시코드를 몇

단계로 통과시켜 C의 원시코드를 기계어 코드로 변환하는데 그 과정을 세부

적으로 보면, 우선 첫 번째 단계에서는 C 프리프로세서(전처리기:Pre-

Processor)가 호출된다. 다음 단계는 C 언어의 문법과 문형을 검사하고 어

셈블리 코드로 변환한다. 마지막으로 시스템에 맞는 이진 기계어 코드로 변

환한다. 이러한 이진 코드를 오브젝트 코드라 하는데 여기까지 오면 링크될

준비를 마친 것이다. 링크 단계의 목적은 프로그램을 실행 형태로 만들어 주

는 것인데 오브젝트 코드와 외부 함수, 라이브러리 루틴을 참조한 후 연결하

여 실행 가능한 코드파일로 만들어 준다.

전자상식 : 컴파일(Compile)

그림 7. HEX 파일을 만들기 위한 선택항목

그림 6. ifdef 설정항목

전자 119

119월간 전자기술/ 2000년 7월호

CM YK CM YK

CM YK CM YK

8051 평가 컴파일러를 이용한 타깃보드 설계

어드레싱 한다.

보통 외부메모리의 크기가 256바이트 이하일 경우는

Compact 모델을 사용하고, 64K바이트 이하일 경우는

Large 모델을 선택하면 된다. 사용자는 메모리 양에 맞게

모델과 메모리 타입(Memory Type) 의 키워드를 선정하

여 프로그램해야 한다. 이어지는 그림은 메모리모델의

Code Size와 RAM 메모리의 크기를 선정하는 항목을 나

타낸다.

여기서 잠깐 메모리 타입에 대해 알아보자. test라는 변

수를 사용해서 설정하는 예를 표의 오른쪽에 나타냈다. 가

장 빠르게 변수에 접근하는(취해오는) 메모리 타입 키워

드는 내부‘data’이다.

다음은 프로그램을 작성하다 보면 심각하게 접하게 되

는 Data의 범위 데이터 타입을 나타낸다.

표2와 3에 정리한 사항은 컴파일러를 구매하면 여러 권

의 매뉴얼 중 ‘C51 Compiler’에 있으므로 외워두거나 적

을 필요는 없다. 자 그럼 디스코프로 넘어 가도록 하자.

HELLO.PRJ를 컴파일러로 실행하면 자동으로 빠르게 무

엇인가 화면이 뒤바뀌게 된다. 개의치 말고 다음 ‘Command’

항목으로 마우스를 이동한 다음, ‘$=main’이라고 타이

핑하고 엔터하면 아래와 같이 ‘Module:HELLO’ 항목

의 HELLO.C 27 번 줄에서 눈에 띄는 색(Pink)으로 화

면에 나타난다.

‘Module/go’ 혹은 ‘Tool box ’의 ‘Run Hello ’ 버튼을

클릭하면 ‘Serial I/O Window ’ 화면에 ‘Hello World ’

가 무한정 보이게 된다. 이유는 while(1) 문에서 무한 루

프로 정의해 놓았기 때문이다.

그림 8. 설정한 메모리 모델(Option/C51 Compiler/Memory)

표 2. KEIL의 메모리 타입

Type

code

data

idata

bdata

xdata

pdata

설 명

프로그램(코드)메모리 최대 64K바이트 사용

직접 내부 데이터메모리에 번지 지정, 128바이트 사용,

변수형 키워드를 사용하지 않으면 기본설정(Default)

간접 내부 데이터메모리 256바이트 사용

비트 지정 내부 데이터메모리 16바이트 사용

외부 데이터메모리 최대 64K바이트 사용

page된 외부 데이터메모리 256바이트 사용

char code test;

char date test;

char test;

char idata test;

char bdata test;

char xdata test;

char pdata test;

표 3. KEIL C51의 데이터 타입

float xdata test;

용 어 비트/바이트 범 위 보 기

bit

sbit

bit test(void); // 함수의 리턴값char bdata d; // bdata 선언sbit d0=d^0;// d 변수 LSBsbit d7=d^7;// d 변수 MSBsbit EA=0xAF; // 비트 선언

1 / - 0 ∼ 1

signed long

signed char 8 / 1 -128 ∼ +127 signed char xdata test;

sfrunsigned char

8 / 1 0 ∼ 255 sfr P0=0x08; // 0x80∼0xFFunsigned char xdata test;

enumsigned intsigned shot

16 / 2 -32,768 ∼ +32,767 signed int code test=-1234;

sfr16unsigned intunsigned shot

0~65,53516 / 2 sfr16 test=0xCC; // 16비트 선언unsigned int xdata d=0xFFFF;

32 / 4-2,147,483,648∼ 2,147,483,647

signed long xdata test;

unsigned long 32 / 4 0∼4,294,967,295 unsigned long xdata test;

float 32 / 4 ±1.175494E-38∼±3.402823E+38

그림 9. 디스코프 실행화면

전자 120CM YK CM YK

CM YK CM YK

120

Embedded Systems Special

Hello 프로그램을 정지하려면 ‘Module/stop’을 선택

하거나 손 모양의 아이콘을 클릭하면 된다. 디스코프는 프

로그램을 만든 다음 소프트웨어에 의해 검증해 볼 수 있는

막강한 기능을 가진 시뮬레이터에 해당하므로 코드를 작

성한 뒤 타깃보드에 이식하기 전에 디스코프를 이용해서

검증해 보는 것이 디버그 시간을 줄일 수 있는 방법이다.

그러면 프로그램을 구분 실행하면서 포트의 변화 값에 대

해 알아보자. 우선 디스코프의 화면이 너무 복잡하므로 간

단하게 한 뒤에 ‘Peripherals/I/O-Ports/Port1 ’ 과

‘Peripherals/Serial ’을 선택 활성화시킨다(그림10참

조). 실수로 디스코프 화면을 빠져나갔다면 KEIL 에디터

화면에서 다시 컴파일하거나 아니면 디스코프(‘Run/

dScope debugger... ’ 또는 를 실행한 후에 ‘File/

Load Object File... ’에서 Hello OMF 파일을 불러오

고 ‘File/Load CPU Driver... ’에서 8051.DLL을 선택

하면 된다. ‘Module’ 화면에 샘플로 작성되어 있는 프로

그램이 올려져 있다면 풀다운 메뉴의 Go(실행), Gotilcurs

(지정한 커서가 있는 곳까지 실행), Stepout(Return 까

지 실행), Stepinto(1 개의 라인씩 또는 1개의 코드 실

행), Stepover( 함수단위로 실행), Stop(정지)을 한두

번 실행해 보자. 윈도우에 익숙한 사용자라면 어떤 일을

하는지 알 수 있다.

스텝(Step) 단위로 실행될 때 레지스터 윈도우와 시리

얼, 그리고 포트 윈도우를 보면, 값이 변하면서 상태를 시

뮬레이션해 주는 것을 볼 수 있다. 마치 MDS(Micro

Processor Development System) 장비가 있는 것 같

은 놀라운 기능을 독자들도 느낄 것이다.

HELLO.C 프로그램에는 특별히 변수를 정의한 것이 없

지만 Watch 기능을 이용해서 변수 값을 확인할 수 있다. 우

선 포트 P1의 값을 보기 위해 ‘Setup/Watchpoints... ’

을 열고 동일 윈도우에서 ‘Show symbols... ’를 클릭하

자. 심벌 윈도우가 열리면 프로그램에서 사용된 모든 변수

(Publics)가 나오고 main에서 사용된 변수(Local)가

나온다. 보고자 하는 변수를 클릭하면 파란색으로 되는데

이때, 변수를 마우스 왼쪽 버튼을 누른채 ‘Watcpoint’ 윈

도우의 작은창 ‘expr’항목으로 옮긴다. 이때 ‘symb’라는

작은 직사각형 표시가 나올 것이다. ‘expr’ 항목에 정상적

으로 옮겨지면 P1의 이름이 나타날 것인데 밑에 있는 버

튼 ‘define watch ’를 누르면 ‘current watch

definitions ’의 큰 윈도우와 ‘watch’ 윈도우에 나타나게

된다. ‘Step’으로 한 줄씩 실행하거나 ‘Step over’를 하

면 여러 개의 활성화된 윈도우에서 변수가 변화하는 것을

볼 수 있을 것이다. 또 디스코프의 일련의 과정을 DOS의

배치파일처럼 정의할 수도 있는데, 다음에 이어지는 그림

처럼 DSCOPE.INI를 미리 작성한 후에 ‘Option/dScope

Debugger... ’에서 등록하면 된다. 즉, KEIL PK51 은 컴

파일을 완료한 후에 디스코프 옵션에 실행파일이 있으면

불러와 환경을 미리 만들어 놓는다. 여기서는 8051.DLL

과 HELLO 파일을 불러오고 ‘Go’ 버튼 ‘Run Hello ’를

만들게 되는 것이다. 이곳에 사용하는 옵션과 명령어도 여

러 가지가 있는데 디스코프 매뉴얼에 나와 있다.

그림 10. Hello 코드를 디스코프로 디버깅 실행

while (1) // ( )의 내용이 0(Zero)이 아니고 참(1 이상)이므로 무한루프

P1 ^= 0×01; // P1=P1⊗000 0001, P1.0의 값이 실행될 때마다 0과 1을 반복한다.

printf ("Hello W orld\n"); // 연속해서 "Hello World" 를 직렬통신을 통해 출력한다.

// End while

그림 11. Option/dScope Debugger

129월간 전자기술/ 2000년 8월호

Embedded Systems Special

8051 평가 컴파일러를 이용한 타깃보드 설계

연재(2)

글/김형태[email protected]

5. 타깃보드 인터페이스

실제로 평가판을 이용해서 C로 프로그램하고 컴파일 한

뒤에 타깃보드에 이식하고 실행해 보자. 백 번 보는 것 보

다 한번 실행 해 보는 것이 지름길이라 생각된다. 그림 1과

같이 KEIL 평가판의 ‘uvsion-51’을 실행시키고 그림 2

와 같이 ‘Project/New Project.../Create New Project’

항목에서 새로운 프로젝트 demo.prj(본인이 임의로 작성

해도 된다)를 만든다.

처음 프로젝트를 작성한다면 그림 3처럼 소스 파일의

이름을 묻는데 소스 프로그램이 있으면 표기하고 아니면

새로이 편집기에 만든 후 ‘Project/Edit Project’에서

수정하면 된다. ‘Source Files’의 윈도 안에는 어셈블리

나 C 소스 상관없이 혼합되어 있어도 되며 ‘Main()’ 이

하나 있는 여러 개의 C언어로 작성된 *.C를 등록해도 된

다. 하지만 코드의 길이가 2Kbyte를 초과하지 않도록 주

의하자. 예를 보인 것은 하나의 C 소스만 등록한 상태를

보였다. 선택한 파일만 열고자 할 경우는 ‘Open’, 여러 개

를 전부 열고자 할 경우는 ‘Open All’ 하면 에디터 창에

프로그램이 열려 편집 가능한 상태가 된다.

몇 가지 더 선택할 항목이 있는데 ‘Options/C51

Compiler.../Memory Model’의 메뉴에서 ‘Code Size

그림1. KEIL Compiler의 실행

그림2. 새로운 프로젝트 생성

그림3. Create New Project 후의 파일선택

130

Embedded Systems Special

: Small/Compact/Large’ 그리고 ‘Memory Model :

Small/Compact/Large’중에서 자신의 타깃보드에 맞

게 선택한다. 후반부에 제시하겠지만 자작할 하드웨어는

밑줄 친 부분을 선택하면 된다. 그리고 ‘/Option/C51

Environment..’에서 Automatically 또는 그림 4와

같이자신의 컴파일러가 있는 경로를 표시한 다음 프로그

램을 만든다(제시한 화면은 정품일 경우 해당 경로임).

‘TMP File Directory’의 경로는 컴파일하고 난 후에

생성되는 파일을 보관하는 곳을 지정하는 것임으로 본인

의 Work 디렉토리가 적당하다. 그리고 설명한 것 이외의

나머지 설정은 매뉴얼을 보고 확인하기 전에는 안전하게

원래 있던 값으로 두고 진행한다.

DEMO.C의 예제 프로그램을 다음과 같이 만들어 보

았다.

업그레이드가 되면 본인의 홈페이지(http://members.

namo.co.kr/~conan98/)에 올릴 계획을 가지고 있다.

그리고 PK51 V5.50a 버전에서는 한글 입력이 지원되지

않는데 메모장에서 한글로 입력 후 복사하여 컴파일러 에

디터에 옮겨오면 된다.

예제 프로그램을 List하면 C 소스로도 상당히 길다. 그

래서 4개의 부분으로 나누어 보았다.

/*

Purpose : Electronic Engineer Magazine Program

Fi Name : List 1 of DEMO.C

Compiler: KEIL C51 5.03 Professional (한국MDS:02-2645-0386)

Author : [email protected]

V1.0 : Chip initial

V2.0 : Temp setting

V3.0 : RTC setting

---------------------------------------------------Copyright(c) by conan All Rights Reserved.

*/

#include <stdio.h> // I/O에 관련된 Prototype 선언

#include <string.h> // String, Buffer 에 관련된 헤드파일(Head File)

#include <intrins.h> // _nop_(); 사용하기위한 함수

#include <std51.h> // SFR Register Include, 저자제작

#include <ctype.h> // function

#include "d:\hardware\work\part\demo.h" // include define, 저자제작

/****************************************/

/* function prototype */

/****************************************/

// Utility

uchar xtoa_h(uchar _byteh); // Hex to ASCII Converter 상위 Nibble

uchar xtoa_l(uchar _bytel); // Hex to ASCII Converter 하위 Nibble

//uchar h2n(uchar hex_num); // Exchange hex to number(a=>10)

그림 4. 저자의 PK51 경로

131월간 전자기술/ 2000년 8월호

8051 평가 컴파일러를 이용한 타깃보드 설계

void putbyte(char c); // 문자(文字) 출력

void putstring(char *str); // Point 문자열 출력

void init_serial(void); // 19200Bps setting

void init_timer0(void); // 타이머0의 초기화

uint Timer0_Check(void); // Read Tick of Timer0 Interrupt

void Timer0_Delay(unsigned int count); // Delay one is 1mS at 11.0592Mhz

void check_chip(void); // LCD, TEMP 센서의 검사

// Communication

void init_qbuffer(void); // q-buffer setup

bit check_pop(void); // check SBUF Point

//LCD

void LCD_goxy(unsigned char x, unsigned char y); // lcd display location

void LCD_string(uchar *s); // string print to LCD

void LCD_clr(void); // clear display DATA=0000 0001

void LCD_CMD_Write(unsigned char pass_value); // instruction Write

void LCD_DAT_Write(unsigned char pass_value); // Data Write

void LCD_putbyte(uchar c);// One Char Write to LCD

unsigned char LCD_DAT_Read(void); // lcd check if apear then = LCD_FLAG

void LCD_init(void);

void LCD_busy(void);// busy check

void delay(unsigned int number);

void LCD_evrytmp(void);// every day display on LCD

void LCD_evrytime(void); // Display Time At LCD

/****************************************/

/* temp Function */

/****************************************/

void tmp_init(void);

uint tmp_protocol(uchar dum, uchar dum2);

/****************************************/

/* RTC Function */

/****************************************/

void rtc_init(void);

void rtc_read(void);

void rtc_write(uchar value); // v=1 date, v=2 time, v=3 all

132

Embedded Systems Special

/****************************************/

/* variables declarations */

/****************************************/

// Struct

typedef struct

uchar year; // 0~99

uchar month; // 0~12

uchar date; // 1~31

uchar days; // 1~7

uchar hour; // 0~23

uchar min; // 0~59

uchar sec; // 0~59

TIME; // Time

table

TIME data timer; // for store now time

struct ring data q; // for Communication q-

buffer

uchar data get_char;

uint tempdata; // for temp

uchar flag; // flag check. look

wpr_type.h

uint tick;

// main() 함수는 있는 List 3에 계속된다.

/

*************************************************************************/

소스 프로그램을 편집기 화면에서 작성하고 ‘Project/

Make: Update Project’ 항목에서 컴파일한 후 Project

를 만든 경로에 프로젝트 이름과 동일하게 기계어 코드 프

로그램 파일을 만들어 준다. 즉 DEMO.HEX 파일이 저

자와 같이 했다면 ‘d:\hardware\work’에 생긴다. 물론

에러가 없어야 정상적으로 생성된다.

또 프로젝트 경로에 DEMO.LST가 생성되는데 C언

어로 작성된 소스 코드에 대한 컴파일 정보가 들어있다.

첨부된 소스파일이 두 개라면 리스트도 두 개가 만들어진

다. 리스트 파일은 소스코드를 어셈블리로 바꾼 파일이나

code, xdata, pdata, idata 등의 사용된 정보를 바이트

단위로 나타내 주며 컴파일 결과에서 발생한 Error,

Warning의 발생과 개수를 보여준다.

개발자에게 유용한 정보를 제공하는 또 다른 파일도 생

성되는데 DEMO.M51이다. M51 파일은 컴파일과 링크

를 행한 뒤의 최종 결과 보고서로써 사용한 컴파일러의 버

전, 옵션선택, 메모리 모델, 참조한 Link 경로, data,

code 메모리의 시작 위치 및 길이 등의 정보를 나타낸다.

컴파일과 링크를 무사히 통과하면 DEMO.C의 최종 목표

인 기계어 코드가 만들어진다. DEMO.HEX 파일을 코

드메모리 영역에 놓거나 ROM(Read Only Memory)

에 이식후(흔히 굽는다고 표현한다) 실행하면 된다.

인텔 HEX File Format은 바이너리 코드를 ROM

Writer등으로 다운로드하기 위해 만들어진 형식으로 데

이터를 바이트 단위로 ASCII 코드로 표현한다. 예를 들어

16진수 ‘09’는 0x30(‘0’), 0x39(‘9’)와 같다.

다음에 제시된 핵사코드는 이해를 돕기 위해 만들어진 샘

플로 실제 분석해보도록 하자.

:09000F00D2A0C2A0B28080F82248

:03000000020003F8

:0C000300787FE4F6D8FD75810702000F3D

:00000001FF

:-> 인텔 Hex Format의 레코드(Record) 시작

09-> Record의 데이터 바이트의 수, 밑줄 부분의 Hex

값을 나타낸다. 어셈블리 소스의 니모닉 코드에 해당한다.

000F-> 데이터 바이트를 저장할 어드레스 위치 000Fh

번지를 나타냄

00-> Record 형식, 01이면 마지막 Record를 나타낸다.

D2∼22 -> 컴파일 후의 Hex Data

48-> 09+00+F0+00+D2+A0+∼+F8+22의 2

의 보수(Sum의 반전+1) 값을 나타낸다.

본 기고에서 저자는 KEIL C 컴파일러 평가버전을 이

용해서 시계와 온도를 LCD에 표시하는 펌웨어를 구현했

는데 독자들의 폭넓은 이해와 기술 적용을 할 수 있도록 하

드웨어와 프로그램을 오가며 주석을 달고자 한다. 우선

U3의 부품 LCD인데 워낙 대중적인 디스플레이여서 대

부분의 전자관련 엔지니어들이 많이 접했으리라 믿고 기

본적인 것만 언급하고 넘어가도록 하겠다.

133월간 전자기술/ 2000년 8월호

8051 평가 컴파일러를 이용한 타깃보드 설계

액정 디스플레이 (LCD:Liquid Crystal Display)

의 원리는 고체와 액체의 중간상태인 액정을 이용하여 전

압이나 열 등의 작용에 의해 다른 분자 배열 상태로 변화되

는데 이를 이용하여 광학적 성질의 변화 즉 시각 변화를 주

게된다. LCD는 가볍고 저 소비전력, 수광형 방식을 지원

해 밝은 장소에서 사용할 수 있는 장점이 있는 반면에 어두

운 곳에서는 표시를 할 수 없고(Back Light를 이용하여

해결) 시각의 위치에 제약을 받으며(12시 방향, 6시 방향

이 있다) 응답시간도 온도에 의존하여 저온 동작(-30∼-

40)이 나쁘다는 단점이 있다. 구현한 회로의 LCD는 현

대전자의 16202로 설명의 내용은 매뉴얼을 참고했다.

U3 LCD를 그림 5에서 보는 것처럼 16번 핀 중에 Vss

(1번핀)는 그라운드, Vdd(2)는 Vcc, 입력되는 전압의

크기로 액정의 Contrast를 조정하는 Vo(3)핀은 가변저

항에 연결했다. Vo 핀은 가변 저항 VR5(10KΩ)와 연결

했는데 온도에 따라 텍스트의 선명도를 변경 할 수 있도록

하기 위해서다.

Vdd-Vss 전압은 5V, Vdd-Vo은 0에서 4.8V

(Normal 경우), 25에서 4.4V, 50에서 4.1V로 조

정하면 LCD가 최적으로 된다고 매뉴얼에 있다. 그리고

소비전류는 상온(25)에서 120이다. 14핀 이외에

Back Light 핀이 추가로 15, 16 두 핀 있는데 15번

(Anode) 핀은 Vcc를, 16번(Cathode) 핀에는 그라운

드를 연결하여 LED로 되어 있는 Back Light가 항상

ON 될 수 있도록 하거나 선택에 의해 조정 할 수 있는

On/Off 스위치를 연결하여 사용하기도 한다.

LCD의 자세한 인터페이스 방법은 본 전자기술 2000

년 3월 호의 「8051 코어를 이용한 Input/Output의 고

찰」을 참고하면 되며 웹사이트 사용이 가능한 독자는 첨단

이나 본인의 홈페이지 「http://www.chomdan.co.kr/,

http://members.namo.co.kr/~conan98/」에서 과월

호를 다운 받아 참고하면 된다. 이어지는 표 1에 LCD의

각 핀에 대한 설명을 정리한다.

LCD는 국산과 외국산 여러 종류가 국내에서 시판되고

있지만 기본적인 동작과 제어명령은 거의 같다. 이유는

LCD 기판 뒷면에 사용한 제어 칩이 HD44780(Hitachi),

HD44100H(Hitachi), M5259(OKI), SED1300F로

제한적이기 때문이다. 또 많이 사용하는 종류로는 1x8(1

줄 8문자), 2x8, 1x16, 2x16, 4x20, 2x40 등이 있다.

한 문자를 나타내는 Dot의 수도 크게 두 가지가 있는데

5x10, 5x7이 있다. 동작에는 표 1의 LCD 핀 설명에도

있듯이 RS(Register Select), R/*W(Read/Write)의

신호를 이용하여 4가 지 경우의 수로 나누게 된다. 제시된

표 2에서 명암을 넣은 부분이다. 즉 명령 레지스터 쓰기

(00), LCD 사용 검사(01) 혹은 데이터 레지스터 쓰기

(10), 읽기(11)로 디코드 된다고 할 수 있다.

LCD를 초기화(Initialization) 하기 위해서는 다음

과 같이 1번부터 10번까지 절차를 제시했는데 설명은 현

대전자의 매뉴얼에 나와 있는 흐름도를 참조했다.

1)LCD 안정화를 위해서 System Power On 뒤에

표 1. LCD 핀 설명(I/O는 LCD를 기준으로 입/출력을 나타낸다)

그림 5. 8051고 LCD의 연결

번호 이 름 I/O 설 명

1 Vss - Ground 또는 Signal Ground.

2 Vdd - +5Vdc Power Supply.

3 Vo I Contrast 전압으로 필요 없을 때는 그라운드에 연결

4 RS I Register Select Signal,

1->LCD RAM으로부터 데이터 쓰기/읽기

0->LCD Control 제어명령과 관련되어 있을 때

5 R/*W I Data Read or Write.

1->Read From the LCD, 0->Write To the LCD,

6 E or CE I Enable Signal, 1->Chip Select 상태, 0->Disable

7~14 Data 핀 I/O DB0∼DB7, Data Bus이며 제어와 명령실행의 데이터로 사용

15 A - Anode, Vcc에 연결 Back Light 전원으로 사용

16 K - Cathode, GND(그라운드)에 연결 Back Light 전원

134

Embedded Systems Special

15 기다리거나 Vdd 전압이 4.5V 될 때까지 대기한

다(하드웨어로 해결했다면 상관없다).

2)Function Set의 DL=1로 8비트, N=1로 2 Line

LCD로 설정한다. 즉 RS=0, RW=0, Data=0x38.

3) 4.1이상 대기한다.

4)또 한번 RS=0, RW=0, Data=0x38.

5)100이상 기다린다.

6)또 한번 RS=0, RW=0, Data=0x38.

7)Function Set의 DL=1, N=1, F=0,

Data=0x38.

8)Display On 설정, Data=0x0C.

9)Display Clear 설정, Data=0x01.

10)Entry Mode 설정, Data=0x06.

여기서 번호 7)번 이하는 LCD가 사용 중인지를 검사

하는 Busy Check를 해야하고 나머지는 하지 않는다. 전

체 프로그램이 나오기 전에 이해하면 좋겠다.

다음은 온도 검출을 도와주는 DALLAS의 DS1620

이다. Data Sheet에서의 이름은 ‘Digital Thermom-

eter and Thermostat’인데 주어진 프로토콜을 시리얼

통신으로 보내고 실려온 온도값을 읽는 방법으로 되어 있

다. LCD에 디스플레이 된다. DS1620의 주요 특징은 온

도 검출 IC이긴 하지만 주변에 다른 검출 소자나 OP

Amp가 필요 없는 8핀 DIP(SOIC Type도 있음) 타입

이다.

온도 측정범위는 -55∼+125 온도계 눈금은 0.5

간격을 가지고 있다. 변환시간은 약 200, 9비트 값을

읽으면 바로 현재의 온도를 알 수 있다. 3단자(CLK, DQ,

/RST) 통신 인터페이스에 의해 데이터를 읽고 설정값을

I/D = 1->AC의 값을 자동 Increment (+1), 0->AC의 값을 자동 Decrement (-1)

S = 1->커서의 위치는 정지하고 디스플레이가 변함, 0->I/D가 어떤 값이든 효과 없다.

D = 1->표시 On, 0->표시 Off(On으로 하면 다시 표시가능)

C = 1->커서 보이게 함, 0->커서 보이지 않음

B = 1->커서에 놓인 문자를 깜박깜박, 0->기능 취소

S/C = 1->표시 전체를 움직임(Scroll), 0->커서 위치를 이동

R/L = 1->Shift to the Right, 0->Shift to the Left

DL = 1->8Bit(DB0∼DB7사용), 0->4Bit(DB4∼DB7사용)

N = 1->표시행 수 2줄 설정, 0->표시행 수 1줄 설정

F = 1->Dot Matrix 5*10, 0->Dot Matrix 5*7(보통사용)

BF = 1->LCD Controller Busy로 사용 불가능, 0->명령(Instruction) 쓰기 가능

DDRAM = Display Data RAM

CGRAM = Character Generator user RAM(문자를 만들어 넣기도 한다)

AC = Address Counter used for both DDRAM and CGRAM Address

X = Don't Care(1 또는 0 상관없다)

명령RS R/*W D7 D6 D5 D4 D3 D2 D1 D0 설 명(실행시간)

Clear Display 0 0 0 0 0 0 0 0 0 1 Clear all display and returns the cursor to the home position(0번지),

D=1이면 커서가 Home으로 간다.

Return Home 0 0 0 0 0 0 0 0 1 X Returns the cursor to the home position. Also returns the display being shifted to the

original position.

DDRAM contents remain unchanged.

Entry Mode Set 0 0 0 0 0 0 0 1 I/D S Set the cursor move direction and specifies or not the shift display.

These operations are performed during data write and read.

Display On/ 0 0 0 0 0 0 1 D C B Sets On/Off of all display (D), Cursor On/Off (C),and blinking of cursor position

character (B)

Cursor or 0 0 0 0 0 1 S/C R/L X X Moves the Cursor and shifts the display without changing DDRAM contents

Function Set (40) 0 0 0 0 1 DL N F X X Sets Interface data length (DL), Number of display lines (N) and character font (F)

Write Data(40) 1 0 Write Data Writes data into DDRAM

Read Data(40) 1 1 Read Data Reads data from DDRAM

Set CGRAM 0 0 0 1 Address CGRAM Sets the CGRAM address. CGRAM Data is sent and received after this Setting.

Set DDRAM 0 0 1 Address DDRAM Sets the DDRAM address. DDRAM Data is sent and received after this Setting.

Read Busy Flag 0 1 BF AC(Address Count) Read Busy Flag(BF) indicating internal operation is Being performed and reads

address counter content

(1.64ms)

(1.64ms)

Off Control(40)

Display Shift(40)

Address(40)

Address(40)

and Address(40)

약 어

표 2. LCD Instruction List

(40)

135월간 전자기술/ 2000년 8월호

8051 평가 컴파일러를 이용한 타깃보드 설계

기록할 수 있다. 표 3은 온도검출 IC DS1620의 핀 설명

이다. 핀 번호 1, 2, 3을 3-Wire Communication Port

라 한다. 스팩에는 IC의 납땜 온도가 260에서 10초라

고 되어 있기 때문에 PCB에 조립 할 때 이상온도가 되지

않도록 주의가 요망된다.

온도검출 IC DS1620은 3개의 선을 이용해서 8051의

I/O 포트(P3_0, P3_1, P3_2)와 통신을 한다. CLK핀으

로 클록을 보내고 /RST 신호로 Active 한 후 DQ를 통해

8비트 Command를 보낸 뒤에 이어지는 데이터를 버퍼

에 넣고 읽으면 그 값이 9비트 온도값이 된다. DS1620에

서는 온도데이터 비트 중에서 LSB가 가장 먼저 출력되며

MSB가 마지막에 출력되고 난 다음 송

신을 종료한다.

온도데이터는 -55∼+125까지

0.5씩 나누어 9비트 데이터 0x0FA

(0 1111 1010)부터 0x192(1 1001

0010)까지 나타낸 것이다. 대표적인 온

도값을 나타내면 다음과 같은데 표 오른

쪽의 Hex 값은 9비트의 온도데이터를

나타내므로 2바이트 ‘unsigned Int’

변수를 사용했다.

DQ핀을 이용해서 온도데이터를 받

기 위해서는 먼저 명령어에 해당하는

프로토콜을 보내주어야 한다. 명령어

는 시리얼 통신으로 정보를 보내고

받는데 온도를 읽는 것은 물론 TH

(High Temperature), TL(Low Temperature), Con-

figuration 비트 값을 쓰고 읽을 수 있으며 온도변환 시작

과 종료를 제어할 수 있다.

CLK핀에 의한 클락 사이클은 온도데이터의 입력에서

는 하강검출(Falling Edge), 온도데이터의 출력에서는

상승검출(Rising Edge)에서 동작하게 되어 있다. /RST

핀이 Low로 되면 통신을 더 이상 할 수 없으며 DQ핀은

High Impedance 상태가 된다.

다음의 표 5는 DS1620 온도검출 IC에서 사용하는 명령

어 프로토콜이다. Hex 값을 시리얼로 보내고 이어지는 데

이터에 의해 레지스터나 변환값을 읽고 쓰기를 할 수 있다.

프로토콜 설정값 0x0C, 0xAC에서 사용한 Configu-

ration Status Register는 8비트로 구성되어 있는 레지

스터로써 8051의 SFR처럼 온도 IC 내부에 들어 있다.

특히 CPU, 1SHOT비트는 EE Memory(표 6의 어두

1 DQ Data I/O 핀, 로직1은 2V이상, 로직0은 0.8V이하, 온도데이터 MSB를 마지막에 보냄.

2 CLK /CONV 신호와 겸용, 클락 입력, 최대 1.75

3 /RST Reset 입력, 1->온도데이터 전송, 0-> 통신 불가능.

4 GND 전원 그라운드

5 TCOM High/Low 설정 복합 트리거(Combination Trigger),

1->현재온도가 설정된 TH값 이상일 경우 발생하여 현재온도가 TL로 될 때까지 유지,

0->현재온도가 설정된 TH값 이하일 경우, 일단 '1'이 된 뒤에는 온도가 TL로 떨어진 이후.

6 TLOW Low 온도 트리거, 1->현재온도가 설정된 TL값 이하.

7 THIGH High 온도 트리거, 1->현재온도가 설정된 TH값 이상.

8 Vdd 5V±0.5 전원공급

핀 기호 기 능 및 스 팩

표 3. DS1620 핀 설명

그림 6. DS1620 인터페이스

9비트 이진 출력 2byte Hex값

125 0 1111 1010 00FA

25 0 0011 0010 0032

0.5 0 0000 0001 0001

0 0 0000 0000 0000

-0.5 1 1111 1111 01FF

-25 1 1100 1110 01CE

-55 1 1001 0010 0192

표4. DS1620 Digital 출력

Hex Command 설 명

AA 온도 읽기 최근 온도변환 결과 요구, DQ핀을 통해 이어지는 9비트 온도 데이터

A1 TH값 읽기 이어지는 9비트 데이터에 읽을 TH 레지스터 요구

A2 TL값 읽기 이어지는 9비트 데이터에 읽을 TL 레지스터 요구

01 TH값 쓰기 이어지는 9비트 데이터에 기록할 TH 레지스터 값

02 TL값 쓰기 이어지는 9비트 데이터에 기록할 TL 레지스터 값

EE Start Convert 온도변환 동작시작, One-Shot 모드에서만 사용, 9비트 데이터 필요 없음

22 Stop Convert 온도변환 동작정지, 9비트 데이터 필요 없음

0C Write Coinfig 이어지는 9비트 데이터에 기록할 8비트 Config 레지스터 값

AC Read Config 이어지는 9비트 데이터에 읽을 8비트 Config 레지스터 요구

표5. DS1620 명령어 Protocol

136

Embedded Systems Special

운 부분)로 되어있어 전원이 없어져도 지워지지 않지만 기

록 횟수는 5만 번으로 한정되어 있다. 상대적으로 THF,

TLF 등은 휘발성 메모리임으로 전원이 없어지면 초기값

0으로 됨으로 주의해야 한다.

온도 검출을 하기 위해서는 DS1620을 선택한 후에(/

RST) 클록으로 동기화 시키고 시리얼 통신으로 프로토콜

이나 데이터를 보내어 액티브 한 후에 리턴 되어 오는 데이

터를 처리하면 된다.

3가지 상태가 적절하게 타이밍과 로직을 맞춰야 설정

값을 기록하거나 IC로부터 온도값을 읽어 올 수 있다. 클

록을 생성, 비트 단위로 데이터를 보낸 것 또한 쉽지 않다

는 것을 디버그(Debug)하다 보면 여러분도 알 수 있을

것이다.

작은 비트 조작을 I/O 포트를 통해 보내고 받아야 하며

아주 작은 시간을 늘리기도 하고 줄이기도 하는 마이크로

의 세계가 그리 좁아 보이지는 않을 것이다. 다음 그림 7

의 타이밍도를 보자. DS1620 읽기/쓰기 타이밍 그림은

왼쪽에서 오른쪽으로 오실로스코프 파형처럼 시간이 흘

러간다. 상단에 있는 읽기 파형을 보면 /RST 신호는

High를 유지하여 DS1620을 선택하고 CLK는 상승 트

리거에 동작함으로 DQ 신호에 올려진 로직 데이터를 읽

기 위해서 CLK 신호 트리거를 Low에서 High로 올려

주면 된다.

DQ의 왼쪽이 프로토콜을 보내고 오른쪽이 데이터를

읽거나 쓰기 할 수 있는 9비트 정보이다. /RST와 CLK는

사실 별로 문제될 것이 없었는데, 프로토콜과 데이터는

LSB가 가장 먼저 나오고 MSB가 마지막을 장식해 타이

밍만 잘 맞추어 주면 되기 때문이다. 읽기/쓰기를 마치면

/RST는 Low로 유지해야 한다.

전자상식 : EPROM,EEPROM

보통 ROM(Read Only Memory)이 한번 쓴 후에는 내용을 지우거나 바꿀

수 없는 반면에 EPROM(Erasable Programmable ROM)은 전기적으로

혹은 자외선으로 지워 다시 사용할 수 있다. 종류로는 메모리 IC에 창문이 달려

있고 강한 자외선으로 지우는 UVEPROM(Ultraviolet Erasable Program-

mable ROM)과 전기적으로 지우는 EEPROM(Electrically Erasable Pro-

grammable ROM=E2ROM)이 있다. 현재는 프로그램에 의해 쓰고 지울 수

있는 플래시 Memory가 인기 있다.D7 D6 D5 D4 D3 D2 D1 D0

DONE THF TLF NVB 1 0 CPU 1SHOT

이 름 설 명

DONE 1-> 온도변환 종료, 0->온도변환 진행

THF Temperate High Flag, 1->설정된 TH 값으로 동작

TLF Temperate Low Flag, 1->설정된 TL 값으로 동작

NVB Non-volatile Memory Bus Flag,EE memory 기록시간이 10

소요됨으로 판단하기 위한 비트,

1->EE메모리 쓰기 진행중, 0->기록하지 않음

CPU CPU 사용 비트, 1->온도값은 3핀 DQ, /RST,CLK를 사용해서

전송, 0->CLK, /RST 사용해서 전송(Standalone 모드)

1SHOT One Shot 모드, 1->프로토콜 명령 Start Convert(0xEE)에 의해

온도 변환됨, 0->온도변환 계속진행

표 6. DS1620의 Read/Write Configuration Status Register

그림 7. DS1620 읽기/쓰기 타이밍

123월간 전자기술/ 2000년 9월호

8051 평가 컴파일러를 이용한타깃보드 설계(마지막회)

아래의 프로그램은 DS1620 읽기/쓰기 타이밍의

‘tmp_protocol(uchar dum, uchar dum2)’함수의 일

부분에 해당하는 프로그램 리스트이다. High와 Low의

글 / 김형태 [email protected]

반복임으로 비트 조작을 잘 생각해야 할 것이다. 전체 프

로그램에서 List의 일부를 복사해서 설명했음으로 주석문

을 보고 수동 통신의 차례를 익히도록 하자.

1)신호 파형 시작 초기화

T_RST=1; // U27의 3번(/RST) 핀에 8051 포트 P3_1을 연결

T_CLK=1; // U27의 2번(CLK) 핀에 CPU 포트 P3_0을 연결

T_DQ=0; // U27의 1번(DQ) 핀에 CPU 포트 P3_2를 연결

dopass=0; // 리턴값 2바이트 초기화, 변수 선언 생략

2)시리얼 통신 프로토콜은 전체 8비트로 구성되어 있음으로 같은 내용을 8번 루틴 돌린다.

for(count=1;count<=8;count++) // Send Protocol 루틴

3)CLK를 Low로 놓는다. 최소 Low 유지시간 tCL은 285이다.

T_CLK=0; // 1 머신사이클 = 1085, 충분하다.

4)LSB부터 Dx를 DQ로 데이터를 보낸다. (DS1620 명령어 Protocol 참조)

// dum은 전달 인수이며 Protocol Data값 1바이트가 들어있다.

if(dum&0x01) _nop_(); T_DQ=1; // Dx=1일 경우만 실행

else _nop_(); T_DQ=0; // Dx=0일 경우만 실행

_nop_(); _nop_(); // 1 비트를 보내고 Delay(=2 Machine Cycle)

5)CLK를 High로 놓는다. 최소 High 유지시간 tCH도 285이다.

T_CLK=1; // 상승 트리거 후 다음정보 준비

dum=_cror_(dum,1); // 오른쪽으로 1비트 회전(Rotate Right), 다음 비트 보낼 준비

// end for

6)2)에서 5)를 8비트 전부 보낼 때까지 되풀이

7)여기서는 온도값을 읽는 모드로 놓고 예를 들어 설명, 온도 읽기 데이터는 0xAA이다.

if(dum==T_TMP) // T_TMP는 헤드파일에서 0xAA로 설정해 놓았다.

dum=0x0; // 전달인수 dum도 0xAA(온도 읽기 프로토콜)가 들어있었다.

8)온도값은 전체 9비트 중에 8비트 먼저 읽기 위해 같은 내용을 8번 루틴 돌린다.

for(count=0; count<=7; count++) // Read 온도 데이터 8비트

124

9)CLK를 Low로 놓는다. 최소 유지시간 tCL은 285이다.

T_CLK=0; // Inverter CLK(L)

_nop_(); // Time Delay

10)LSB부터 Dx를 DQ로 데이터로부터 1비트 읽는다. 온도값은 9비트로 되어 있다.

if(T_DQ) dum|=0x01; // T_DQ=1이면 dum = dum ∪ 0000 0001

else dum&=0xFE; // T_DQ=0이면 dum = dum ∩ 1111 1110

11)CLK를 High로 놓는다. 최소 High 유지시간 tCL은 285이다.

T_CLK=1; // Once More High

dum=_cror_(dum,1); // 오른쪽으로 1비트 회전, 다음 비트 받을 준비

// end for(count~

12)8번∼11번, 8비트 전부 받을 때까지 되풀이

dopass=0x00FF & dum; // 받은 1바이트를 2바이트 변수의 하위에 저장

13)CLK를 Low로 유지

T_CLK=0; // 'T_CLK=~T_CLK'와 같은 의미

_nop_(); _nop_(); _nop_(); _nop_(); // 데이터 안전을 위해 지연

14)최상위 비트 MSB 비트 읽기

if(T_DQ) dopass|=0x0100; // IF문 참이면 OR 0x0101

else dopass&=0x00FF; // IF문 거짓이면 하위 1바이트 이외는 Zero

15)CLK를 High, DQ를 하이 임피던스로 유지

T_CLK=1; // Once More High, 마무리

16)/RST를 Low로 유지하여 마무리한다.

T_RST=0; // /RST 3번 핀 Low

return(dopass); // 읽은 온도 데이터 2바이트 값을 리턴.

// end if((dum~

‘tmp_protocol()’ 함수의 제어 프로그램을 구동한 후 실제로 파형이 정상적으로 만들어졌나를 확인하기 위해

파형을 측정했다. 시간은 왼쪽에서 오른쪽으로 흐르고 Ch1

이 CLK 신호의 클락이며 Ch2가 DQ의 온도 데이터를

나타낸다. 클락의 High를 유지하는 시간 14(14,000)를 파형에 나타내었다.

온도 검출 IC를 현장에서 사용할 때는 적절한 Offset

값으로 조정해 주어야 할 것 같다. 이유는 응답속도가 느

리고 공기중의 온도를 IC가 반영하기 위해서는 회로 주변

도 신경 써야 하기 때문이다.

온도계가 정상 온도인지를 알아보는 방법은 온도 센서

를 방수처리 한 뒤에 얼음과 물을 혼합한 그릇에 넣고 10

분 정도 지난 뒤의 디스플레이 온도가 0가 되면 된다.

이렇게 IC에서 꺼낸 9비트 Hex 온도값은 귀찮으리만큼

잘 생각해야 비트 조작의 미미한 오류가 발생하지 않는다.그림 1. 타이밍 ‘tmp-protocol()’의 함수를 동작시킨 파형

125월간 전자기술/ 2000년 9월호

혹시 저자의 잘못을 지적하고 싶은 독자는 conan98@netsgo.

com로 편지를 보내주길 바란다.

본인이 수긍하면 실험을 거친 후 홈페이지에 올려놓을

생각이다.

/*

Purpose : Electronic Engineer Magazine Program

Fi Name : List 2 of DEMO.C

Compiler: KEIL C51 5.03 Professional(한국MDS:02-2645-0386)

Author : [email protected]

V1.0 : Chip initial

V2.0 : Temp setting

V3.0 : RTC setting

---------------------------------------------------------------------

Copyright(c) by conan All Rights Reserved.

*/

void tmp_init(void)// DS1260 초기화

tempdata=tmp_protocol(T_STCO, NO); // 0A=0000 1010

uint tmp_protocol(uchar dum, uchar dum2)// dum의 값에 의해 읽고/쓰기를 나눈다.

uchar count;

uint dopass;

/* 헤드 파일에는 다음과 같이 정의해 두었다.

// Utility

#define NOP _nop_()

#define NO 0

// for Temperature

#define T_DQ P3_2

#define T_CLK P3_0

#define T_RST P3_1

#define T_TMP 0xAA // 1010 1010

#define T_WTH 0x01 // TH값 쓰기

#define T_WTL 0x02 // TL값 쓰기

#define T_RTH 0xA1 // TH값 읽기

#define T_RTL 0xA2 // TH값 읽기

#define T_STCO 0xEE // 변환시작

#define T_SPCO 0x22 // 변환 끝

#define T_WCO 0x0C // DS1620 레지스터 쓰기

126

#define T_RCO 0xAC // DS1620 레지스터 읽기

#define TMP_OFFSET 0x0003

*/

T_RST=1; // /RST Pin High, P3_1, TxD

T_CLK=1; // Clock High,P3_0, RxD

T_DQ=0; // Init, P3_2, INT0

dopass=0;

for(count=1;count<=8;count++) // send protocol, 8번

T_CLK=0; // Inverter CLK(L)

if(dum&0x01) _nop_(); T_DQ=1;

else _nop_(); T_DQ=0;

_nop_(); _nop_(); // delay

T_CLK=1; // Once More(H), Write Data

dum=_cror_(dum,1); // Rotate Right

// Read Mode

if((dum==T_TMP) | (dum==T_RTL) | (dum==T_RTL)|(dum==T_RCO))//dum의 값으로 결정

dum=0x0;// 초기화

for(count=0;count<=7;count++) // Read data

T_CLK=0; // Inverter CLK(L)

_nop_();

if(T_DQ) dum|=0x01; // T_DQ=1

else dum&=0xFE; // then T_DQ=0

T_CLK=1; // Once More(H), Write Data

dum=_cror_(dum,1);

// end for(count~

dopass=0x00FF & dum;

T_CLK=0; // Inverter CLK(L)

_nop_(); _nop_(); _nop_(); _nop_();

if(T_DQ) dopass|=0x0100;

else dopass&=0x00FF;

T_CLK=1; // Once More(H)

T_RST=0; // /RST Pin Low

return(dopass);

// end if((dum~

// WRITE Mode

if((dum==T_WTH) | (dum==T_WTL) | (dum==T_WCO))//dum의 값으로 결정

127월간 전자기술/ 2000년 9월호

for(count=0;count<=7;count++) // Read data

T_CLK=0; // Inverter CLK(L)

_nop_(); _nop_();_nop_();

if(dum2 & 0x01) T_DQ=1;

else T_DQ=0;

_nop_();_nop_();

T_CLK=1; // Once More(H)

dum2=_cror_(dum2,1);// dum2는 쓰고자 하는 값

// end for(count~

T_RST=0; // /RST Pin Low

return(ON);

// end if((dum~

// alone Mode

if((dum==T_STCO) | (dum==T_SPCO))//dum의 값으로 결정

T_RST=0; // /RST Pin Low

T_CLK=1; // Clock High

return(ON);

// end if((dum~

return(OFF);

/*************************************************************************/

TH, TL값에 의해 출력되는 Thigh, Tlow, Tcom은 히스테

리시스를 이용한 피드백 장치라고 할 수 있다. 에어컨을

예를 든다면 현재온도가 25이고 에어컨을 20에 설정

해 놓은 상태에서 기계가 가동되어 온도가 점점 내려가 20

에 도달하게 된다. 이때 기게는 설정값 이하가 되어 OFF

가 되고 다시 실내온도가 상승하여 미세한 온도변화가 있

을 때마다 ON/OFF를 반복하게된다. 기계는 하루종일

껴졌다 켜졌다 하게 될 것이다. 레지스터에 기록해 놓은

TH 값은 현재 검출된 온도가 TH값 이상일 경우에 Thigh

핀이 High로 되고 TH값 이하로 되면 Low가 된다. Tlow

핀은 현재 온도가 설정해 놓은 TL값 이하로 되면 High가

되고 이상이 되면 Low가 된다. 또 앞에 설명했던 히스테

리시스 곡선의 출력을 가지고 있는Tcom핀은 현재 온도가

TH값으로 올라갈 때는 Low로 출력되다가 TH값에 오면

High로 된다.

그리고 온도가 내려가 TL 값으로 도달하기까지는 High

를 유지하다가 TL값에 이르면 그때서야 Low로 출력된

다. 산을 오리기전과 오른 후가 다르다고 할까? 에어컨과

같은 자동제어 시스템에 많이 사용하는 기법이다.

다음은 8051과 연결되어 있는 메모리 그리고 RTC

(Real Time Clock)이다. KEIL 평가 버전을 사용하여

구성한 Target Board는 전자시계와 xdata 메모리 영역

을 동시에 해결할 수 있는 미국 DALLAS 회사의 DS1283

'Watchdog Timekeeper Chip'을 사용했다. DS1283

은 내부에 WDT(Watchdog Timer)가 들어 있는 IC로

써 두 가지 타입(DIP, SOIC)이 있는데 본 실험용 보드

에서는 구하기 쉬운 28핀 DIP을 사용했다. 그리고 다음

과 같은 특징이 있다.

- 시계기능은 물론 내부적으로 알람(Alarm)기능이 있다.

- 전지의 전압만 계속 공급되면 시계가 계속 돌아가게

설계되어 있다.

- 인터럽트를 프로그램에 의해 조정할 수 있다.

- 전지로 설계가 가능하다.

128

- 2100년까지의 년, 월, 일, 요일, 시, 분,

초, 1/100초가 지원된다.

- 정형파(Square Wave)가 23번핀을 통

해 1024의 주파수로 출력된다.

- 레지스터는 어드레스와 데이터 버스로 나

누어져 있어 프로그램하기가 쉽다.

- 25에서 1개월에 ±2분 정도의 오차를

가진다(클락이 정확할 경우에).

- 내부에 비휘발성(Non-Volatile RAM)

메모리 50(32h)바이트가 있다.

- 28핀 DIP과 28핀 SOIC 두 가지 타입이

있으며 메모리와 외형이 같다.

- 크리스탈(Crystal) 클락은 32.768KHz를 사용한다.

표1은 DS1283의 핀에 대해 설명했는데 신호 이름의

'/' 표시는 부논리를 의미하며 로직 0(Zero)일 때 Ac-

tive 된다.

어드레스에 의해 선택되고 데이터를 주고받는 DS1283

의 레지스터와 관계된 하드웨어 설정은 DEMO.H의 헤

드파일에 정의되어 있다. 다음 표 DS1283 레지스터의 좌

측 '주소' 항목은 회로도를 보면 알겠지만 어드레스 8000h

번지가 메모리 맵 어드레스(Memory Map Address)가

된다. 이어서 IC 내부의 RTC 레지스터의 기능에 대해 알

아보자. DALLAS의 시계와 관련된 Chip은 비슷비슷하

게 구성되어 있다.

RTC 레지스터를 표 2에 있는 주소 순서로 나열하여

설명하면 다음과 같다.

0,1,2,4,6,8,9,A : 시계와 달력(Calendar)을 나타내

며 내부 설정값은 BCD(Binary Coded Decimal) 코

드로 되어 있다.

3,5,7 레지스터 : 알람 설정을 나타낸다. MSB의 비트

7에 있는 'M'은 표3의 설정상태에 따라 다르게 알람 동작

을 한다.

12/24(시간제) : 0->24시간제 선택(십의 자리 필요),

1->12시간제 선택(AM, PM 선택이 추가. 즉 A/P가 0이

면 AM, 1이면 PM)

10,A/P(10단위시간 혹은 AM, PM선택) : 12/24 시

간 선택에 의해 달라진다.

C,D 레지스터 : 0.01초∼99.99초까지 설정이 가능하

고 설정해 놓은 값에서 감소되어 0에 도달하면 Watch-

dog Timer Interrupt Output이 발생한다.

/EOSC(Enable Oscillator) : 0->RTC가 동작한다.

/ESQW(Square Wave Output) : 0->23번핀으로

1024Hz의 정형파를 출력한다. 1->23번핀은 High Im-

주소

0

1

2

3

4

5

6

7

8

9

A

B

C

D

E~3F

Bit7

O

O

M

O

M

O

M

INP

/EOSC

TE

6

12/24

O

O

O

/ESQW

IPSW

5

10Sec

10 Min

10,A/P

O

O

O

IBH LO

4

10,A/P

O

O

O

PU LVL

10 Min Alarm

10 Year

0.1 Sec

10 Sec

0.1 Sec

3

O

O

WAM

2

TDM

1

WAF

Bit0

TDF

0.01 Sec

SEC

Min

Min Alarm

Hour

Hour Alarm

Day

Day Alarm

Date

Month

Year

0.01 Sec

Sec

범위

0~99

0~59

1~12A/P or 0~23

1~7

1~31

1~12

0~99

-

0~99

0~99

설명

1//100초

분 알람

시 알람

요일

요일 알람

날짜

날짜 알람

제어용

WDT

50 Byte 사용자 메모리

표 2. DS1283 레지스터와 메모리

번호 이름 I/O 설명

1

2, 3

4

10~5

11~13

14

15~19

20

21

22

23

24

25

26

27

28

/INTA

X1, X2

NC

A0~A5

DQ0~DQ2

GND

DQ3~DQ7

/CE

/INTP

/OE

SQW

/RCLR

VBAT

/INTB

/WE

VCC

O

I

-

I

I/O

-

I/O

I

O

I

O

I

I

O

I

-

Interrupt Output A(Open Drain)

32.768kHz(CITIZEN Quartz Crystal CFS-206 Cylinder

Type 사용)사용하며 내부에 6pF의 콘덴서 연결되어 있다.

No Connection

어드레스 버스

Data Input/Output

그라운드

Data Input/Output

Chip Enable

Interrupt Output P(Open Drain)

Output Enable

Square Wave Output

RAM Clear, 로직 0이 입력되면 50바이트 RAM만 지워짐, 내부 Pull Up

전지입력

Interrupt Output B(Open Drain), 사용중일 때 소비전류 500

, 사용하지 않을 경우는 Pull Down 저항 연결

Write Enable

4.5V~5.5V 전원 전압

표 1. DS1283핀 설명

주소 3의 ‘M’

1

0

0

0

주소 5의 ‘M’

1

1

0

0

주소 7의 ‘M’

1

1

1

0

설명

Alarm Once per Minute(초 일치할 때)

분 일치할 때 알람

시, 분 일치할 때 알람

시, 분, 초 일치할 때 알람

표 3. M의 값에 따른 알람 설정

129월간 전자기술/ 2000년 9월호

pedance상태로 된다.

TDF(Time of Day Alarm Flag) : 1->알람 발생이

설정되지만 TE=0이면 효과 없다.

WAF(Watchdog Timer Flag) : 1->Watchdog

Timer 동작 설정

TDM(Time of Day Alarm Mask Bit) : 1->Time

of Day Alarm Interrupt Output을 해제, 0->Time

of Day Alarm Interrupt Output을 설정하는데 주소

B의 비트0,4,5,6,7의 값에 의해 결정된다.

WAM(Watchdog Alarm Mask Bit) : 1->Watch-

dog Interrupt Output을 해제한다. 0->Watchdog

Interrupt Output이 설정되는데 주소 B의 비트1,4,5,

6,7의 값에 의해 결정된다.

/INTA, /INTB : 비트4에 의해 결정된다. 1->/INTA

는 Pulse Mode가 된다. 최소 3동안 신호가 유효하다.

IPSW : /INTA, /INTB를 인터럽트 핀으로 사용할

수 있도록 한다. 1->/INTA가 Time of Day Alarm In-

terrupt 핀이 되고 /INTB는 Watchdog Interrupt 핀

이 된다, 0->'1'일 경우와 같은데 /INTA, /INTB핀이 서

로 반대로 된다.

TE(Transfer Enable) : 1->매 1/100초마다 값이 새

로 갱신된다. 0->레지스터 값이 사용자에 의해 바뀌는 것

을 보호한다.

알나간 BCD 코드

--------------------------------------------------

4비트를 이용하여 십진수를 표현한다. 예로 10진수 137

이면 BCD코드로 0001 0011 0111이 된다. 그래서 BCD

코드에서는 16진수에 있는 A, B 등이 있을 수 없고 9가 4

비트로 표현할 수 있는 제일 큰 수가된다. 참고로 10진수

137을 단순히 2진수로 바꾸면 1000 1001(2)이 되어 BCD

에 비해 비트 효율이 좋다.

--------------------------------------------------

'메모리와 RTC 회로도'는 8051의 어드레스(573을 통

과한 신호) 버스 A0∼A5와 DS1283의 A0∼A5(5번∼

10번) 그리고 8051의 A15번핀과 DS1283의 /CE가 서

로 연결되어 있음을 보여주는데 다음과 같은 메모리 맵

(Address Map)을 가진다. 만약 시계의 분을 읽고 싶으

면 RTC_MIN을 프로그램에 써넣고 실행하면 된다(너무

간단한 설명인가?). 이어지는 표는 헤드파일 DEMO.H

에 있는RTC와 관계된 어드레스의 지도(맵)를 나타낸다.

RTC가 선택되기 위해 어드레스 A15가 High가(Not

Gate를 통해 나중에 반전됨) 되어야 한다. 어드레스 A5∼

A0까지 RTC에 연결되어 있음으로 조합에 의해 RTC 메

모리를 선택하게 되어 있다. 다음의 부분 회로도는 RTC

의 메모리(U4)와 ROM(U7)이 8051과 인터페이스 된

상태이다. 타겟보드의 8051은 프로그램 code를 27128

에서 가지고 와서 해석한 뒤에 data 메모리 영역(xdata)

50바이트를 사용하게 되는 것이다. RTC에 연결된 C1의

6의 콘덴서는 연결하지 않아도 되지만 25번핀에 연결하

는 전지는 있어야 전원이 OFF 되어도 현재의 시간을 잃

어버리지 않는다.

다음의 프로그램은 RTC를 설정한 후 루틴에서 불러온

A15

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

A5

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

1

A4

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

1

A3

0

0

0

0

0

0

0

0

1

1

1

1

1

1

1

1

A2

0

0

0

0

1

1

1

1

0

0

0

0

1

1

1

1

A1

0

0

1

1

0

0

1

1

0

0

1

1

0

0

1

1

A0

0

1

0

1

0

1

0

1

0

1

0

1

0

1

0

1

DEMO.H 정의

uchar xdata RTC-SEC1 -at- 0x8000:

uchar xdata RTC-SEC2 -at- 0x8001:

uchar xdata RTC-MIN -at- 0x8002:

uchar xdata RTC-MINALM-at- 0x8003:

uchar xdata RTC-HR -at- 0x8004:

uchar xdata RTC-HRALM -at- 0x8005:

uchar xdata RTC-DAY -at- 0x8006:

uchar xdata RTC-DYALM -at- 0x8007:

uchar xdata RTC-DATE -at- 0x8008:

uchar xdata RTC-MONTH-at- 0x8009:

uchar xdata RTC-YEAR -at- 0x800A:

uchar xdata RTC-CMD -at- 0x800B:

uchar xdata RTC-WDALM1-at- 0x800C:

uchar xdata RTC-WDALM2-at- 0x800D:

uchar xdata RTC-USER1 -at- 0x800E:

...50 바이트를 xdata 영역으로 사용한다...

uchar xdata RTC-USER50-at- 0x800F:

...............

표. 4 DS1283의 어드레스 맵과 xdata 영역

그림 2. 메모리와 RTC 회로도

130

시간 값을 LCD에 프린터 하는 루틴이다. 특히 50마다

Timer 인터럽트가 발생하게 하여 읽어온 시간 값의 월:

일:시:분:초:1/10초를 LCD에 표시하게 했다.

평가 버전은 2K 한도를 가지고 있음으로 코드의 범위를

초과한다. 그래서 RS-232 부분과 Temp 부분으로 나누

어 코드의 길이가 초가 하지 않도록 컴파일 해야한다. LCD

가 없는 독자(만원이하의 고가)는 통신 케이블을 연결 후

PC의 하이퍼터미널을 구동한 다음 Loading 후 실행하는

프로그램을 추가하면 된다. 프로그램에는 주석문을 나름

대로 달았는데 충분하지는 않을 것이다. 특히 do while,

if 문(文)에 대해서는 알라간에서 먼저 알아두고 프로그램

을 독파하길 바란다.

알나간 if, wile, do, for문(文)

if(조건1)루틴1

else루틴2

if:괄호 안에 있는 조건1이 참(Zero가 아니면)이면 루

틴1을 실행하고 조건1이 거짓(Zero)이면 else에 있는 루

틴2를 실행한다. else를 생략하면 조건1이 참일 때 루틴1

을 실행하고 또 루틴2를 실행한다. elseif도 있다.

while(조건2)루틴3

while:조건2가 참이면 루틴3을 실행하고 거짓이면 한

번도 실행하지 않는다.

do루틴4while(조건3);

do:일단은 루틴4를 실행하고 조건3이 참이면 계속 실

행, 거짓이면 do를 빠져 나온다. 적어도 한번은 실행하는

조건문이며 while 괄호 뒤에 세미콜론(';')을 붙인다.

for(식1;조건4;식2)루틴5

for:while 문을 변형한 것으로 셀 수 있는 루틴에 주로

사용한다. 식1은 변수의 초기화에 해당하고 식2는 증감

(+,-)을 나타낸다. 조건4의 값이 참이면 루틴5를 실행하

고 식2를 변경 후 다시 조건4를 검사한다. 조건4가 거짓이

면 루틴5를 실행하지 않고 빠져나간다. 조건4가 초기에 0

(Zero)이면 한번도 실행되지 않는다.

조건식에 들어가는 연산 기호로는 다음과 같은 것이 있다.

연산자의 구분

괄호, 포인터

Type, 증가, 감소, 반전, Not

산술연산자

비트 쉬프트

비교연산자

비트 연산자

논리 연산자

대입연산자

기호

(), [],‘.’

(type), ++, --, ~,!

*, /, %, +, -

<<, >>

<, >=, >, >+, !=, ==

&, ^, :

&&, ::

?:,=, +=, -=, *=, /=, <<=, >>=, &=, %=, =,;=

/*

Purpose : Electronic Engineer Magazine Program

Fi Name : List 3 of DEMO.C

Compiler: KEIL C51 5.03 Professional(한국MDS:02-2645-0386)

Author : [email protected]

V1.0 : Chip initial

V2.0 : Temp setting

V3.0 : RTC setting

---------------------------------------------------------------------

Copyright(c) by conan All Rights Reserved.

*/

/****************************************/

/* main function */

/****************************************/

void main(void)

131월간 전자기술/ 2000년 9월호

uchar pass;// for test

EA=0; // Disable Interrupt

init_timer0();

EA=1;

tmp_init();

check_chip(); // check instrument, temp_init();

rtc_init();

init_qbuffer(); // q-buffer setup

init_serial(); // 19200Bps setting

LCD_init();

LCD_clr(); // clear display DATA=0000 0001

LCD_goxy(1,1); // new 2 line 1 char

LCD_string("Hello Enginner!");

LCD_goxy(1,2); // new 2 line 1 char

LCD_string("Temp & time");

Timer0_Delay(50);// for 500ms

while(2000)

LCD_goxy(1,1); // new 1 line 1 char

LCD_evrytime(); // Display every Time At LCD

LCD_goxy(1,2); // new 2 line 1 char

LCD_evrytmp();// every day display on LCD

LCD_string(" Degree ");

// for RS232 input

if(check_pop() && get_char==0x0D) // CR(Enter) check

putstring("₩nCMD>"); // check q-buffer and run

switch(get_char)

case('h'):case('H'):case('?'):

putstring("Read(1), Time Write(2), Date Write(3), Help(H)₩nCMD>");

132

break;

case('1'):case('!'): // Clock read

putstring("This Date/Time is ");

rtc_read();

putbyte('2');putbyte('0'); //20XX display

putbyte(xtoa_h(timer.year)); putbyte(xtoa_l(timer.year)); putbyte(':');

putbyte(xtoa_h(timer.month));putbyte(xtoa_l(timer.month));putbyte(':');

putbyte(xtoa_h(timer.date)); putbyte(xtoa_l(timer.date)); putstring(" ");

putbyte(xtoa_h(timer.hour)); putbyte(xtoa_l(timer.hour)); putbyte(':');

putbyte(xtoa_h(timer.min)); putbyte(xtoa_l(timer.min)); putbyte(':');

putbyte(xtoa_h(timer.sec)); putbyte(xtoa_l(timer.sec));

putstring("₩nCMD>");

break;

case('3')://case('#'): // RTC date write

putstring("Write Date 'yy:mm:dd' of RTC ₩nCMD>");

rtc_read();

putstring("EX)");

putbyte(xtoa_h(timer.year));putbyte(xtoa_l(timer.year)); putbyte(':');

putbyte(xtoa_h(timer.month));putbyte(xtoa_l(timer.month));putbyte(':');

putbyte(xtoa_h(timer.date));putbyte(xtoa_l(timer.date)); putstring(" ");

get_char=NULL;

pass=1;//

while(1)

if(check_pop()) // check q-buffer and run

if(get_char==':') pass++;putbyte(get_char);

if(get_char>='0' && get_char<='9')

putbyte(get_char); // input char Print

switch(pass++)

case(1):

timer.year=0x0;

timer.year=get_char-'0'; // '0'=0x30

timer.year=(timer.year<<4) & 0xf0;break;

case(2):timer.year=timer.year|(get_char-'0');break;

case(4):

timer.month=0x0;

timer.month=get_char-'0';

timer.month=(timer.month<<4) & 0xf0;break;

case(5):timer.month=timer.month|(get_char-'0');break;

case(7):

133월간 전자기술/ 2000년 9월호

timer.date=0x0;

timer.date=get_char-'0';

timer.date=(timer.date<<4)&0xf0;break;

case(8):

timer.date|=(get_char-'0');break;

default:break;

// end switch(pass++)

// end if(get_char>='0' && get_char<='9')

if((get_char==0x0D) && (pass>=9)) // Return Check

if((timer.year<=0x99)&&((timer.month&0x1F)<=0x12)&&((timer.date&0x3F)<=0x31))

putstring("₩nCMD>Now Data write!");

rtc_write(1); // v=1 date, v=2 time, v=3 all

rtc_read();

putstring("₩nCMD>New Date is ");

putbyte(xtoa_h(timer.year)); putbyte(xtoa_l(timer.year)); putbyte(':');

putbyte(xtoa_h(timer.month)); putbyte(xtoa_l(timer.month)); putbyte(':');

putbyte(xtoa_h(timer.date)); putbyte(xtoa_l(timer.date));

get_char=NULL;

break; // end while

// if(timer.month<=0x12) && (timer.date<=0x31)

else

putstring("₩nCMD>ERROR! Can't write Date");

// pass=1; // initial pass value

get_char=NULL;

pass=1; // initial pass value

break; // end while

// end else

// end if(get_char==0x0D && pass==9)

if(get_char>=0x3B) // for test ASCII Code is ';'

// CR check

get_char=NULL;

break;

// if check_pop()

// end do while(1)

putstring("₩nCMD>");

break;// end case('3')

case('2')://case('@'): // RTC time

134

putstring("Write time 'hh:mm:ss' of RTC ₩nCMD>");

putstring("EX)");

rtc_read();

putbyte(xtoa_h(timer.hour));putbyte(xtoa_l(timer.hour));putbyte(':');

putbyte(xtoa_h(timer.min));putbyte(xtoa_l(timer.min));putbyte(':');

putbyte(xtoa_h(timer.sec));putbyte(xtoa_l(timer.sec));putstring(" ");

pass=1;

get_char=NULL;

while(2)

if(check_pop()) // check input

if(get_char==':') pass++;putbyte(get_char);

if(get_char>='0' && get_char<='9')

putbyte(get_char);

switch(pass++)

case(1):

timer.hour=0x0;

timer.hour=get_char-'0';

timer.hour=(timer.hour<<4)&0xf0;break;

case(2):timer.hour|=(get_char-'0');break;

case(4):

timer.min=0x0;

timer.min=get_char-'0';

timer.min=(timer.min<<4)&0xf0;break;

case(5):timer.min|=(get_char-'0');break;

case(7):

timer.sec=0x0;

timer.sec=get_char-'0';

timer.sec=(timer.sec<<4)&0xf0;break;

case(8): timer.sec|=(get_char-'0');break;

default: break;

// end switch(pass++)

// end if(0~9)

if((get_char==0x0D) && (pass==9))

// ener check

if((timer.hour<=0x23)&&((timer.min&0x1F)<=0x59)&&((timer.sec&0x3F)<=0x99))

putstring("₩nCMD>Now write!");

rtc_write(2); // v=1 date, v=2 time, v=3 all

rtc_read();

putstring("₩nCMD>New time is ");

135월간 전자기술/ 2000년 9월호

putbyte(xtoa_h(timer.hour)); putbyte(xtoa_l(timer.hour));

putbyte(':');

putbyte(xtoa_h(timer.min)); putbyte(xtoa_l(timer.min));

putbyte(':');

putbyte(xtoa_h(timer.sec)); putbyte(xtoa_l(timer.sec));

get_char=NULL;

break; // out of while()

// end if(timer.hour, timer.min, timer.sec, timer.year Check)

putstring("\nCMD>ERROR! Can't write Time");

pass=1; // initial pass value

get_char=NULL;

break;

// end if(get_char==0x0D && pass==9)

if(get_char>=0x3B)// || get_char==0x0D) // ';' Check

get_char=NULL;

break;

// end if check_pop()

// end do while(2)

putstring("₩nCMD>");

break;// end case('2')

default: break;

// end switch(get_char)

get_char=NULL;

// if you went other program put hear!

// end while(2000)

// end main

/*************************************************************************/

철심을 자화할 경우 자계의 세기를 증가할 때 생성된 자속의 밀도 곡선과 반대로 감소할

때 생성된 자속의 밀도 곡선이 일치하지 않고 다른 경로를 통하기 때문에 고리모양의 곡

선이 된다. 이 고리모양을 히스테리시스 루프라고 하는데 기계공학에서 사용하는 용어

이지만 이런 종류의 현상을 지칭하기도 한다.

전자상식 : 히스테리시스(Hyetereeie)