(128c\272\273\271\256.hwp)

Similar documents
ISP and CodeVisionAVR C Compiler.hwp

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202831C1D6C2F72C2032C1D6C2F729>

정보보안 개론과 실습:네트워크

Microsoft PowerPoint - avr_lecture1.ppt

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202834C1D6C2F7207E2038C1D6C2F729>

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A634C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

인터럽트 (Interrupt) 범용입출력포트에서입출력의내용을처리하기위해매번입출력을요구하는플래그를검사하는일 (Pollong) 에대하여마이크로컨트롤러에게는상당한시간을소비하게만든다. 인터럽트란 CPU가현재처리하고있는일보다급하게처리해야할사건이발생했을때, 현재수행중인일을중단하고

Microsoft PowerPoint - 제3장 GPIO 입출력 제어 (HBE-MCU-Multi AVR)

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A638C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

AVR ATmega128 소개 마이크로컨트롤러 AVR ATmega128 저자 : 이상설 소속 : 원광대학교전기 정보통신공학부

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074>

슬라이드 1

OCW_C언어 기초

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202834C1D6C2F7207E2038C1D6C2F729>

AVR Atmega128

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202831C1D6C2F72C2032C1D6C2F729>

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

Microsoft Word - PLC제어응용-2차시.doc

2. AVR(ATmega162)의 구조

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

[ 마이크로프로세서 1] 1 주차 1 차시. 마이크로프로세서개요 1 주차 1 차시마이크로프로세서개요 학습목표 1. 마이크로프로세서 (Microprocessor) 를설명할수있다. 2. 마이크로컨트롤러를성능에따라분류할수있다. 학습내용 1 : 마이크로프로세서 (Micropr

AVR ATmega128 소개 AVR ATmega128 IT Eng 학습목표 ü 다양한 AVR 패밀리와소자특징을알아보고, 제어환경에따라 AVR 소자를선택하여개발할수있는융통성을이해할수있다. ü ATmega128 내부구조에서메모리공간, I/O 공간의프로그램과데이터를처리하기

Microsoft Word - AVRISP mkII 장비 운용.doc

Microsoft Word - MAI-ISP-STK500_매뉴얼_Ver25.docx

JMOD : ATmega128 기본모듈 사용자설명서 제이씨넷

Microsoft PowerPoint - 제5장 인터럽트 (HBE-MCU-Multi AVR).ppt [호환 모드]

Microsoft PowerPoint - chap06-2pointer.ppt

[ 마이크로프로세서 1] 1 주차 2 차시. 마이크로프로세서와마이크로컨트롤러발달과정 1 주차 2 차시마이크로프로세서와마이크로컨트롤러발달과정 학습목표 1. 마이크로프로세서발달과정과종류를설명할수있다. 2. 인텔 8051 계열과아트멜 (Atmel) 의특성을설명할수있다. 학습

[8051] 강의자료.PDF

CHAPTER 2 마이크로컨트롤러구조이해하기 가. ATmega128 기능 나. CRX10 구조

SAT8-10.hwp

슬라이드 1

Microsoft PowerPoint - chap01-C언어개요.pptx

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A636C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

<4D F736F F F696E74202D203137C0E55FBFACBDC0B9AEC1A6BCD6B7E7BCC72E707074>

ATmega128

슬라이드 1

<4D F736F F F696E74202D2037C0E55FC0CEC5CDB7B4C6AEC0C720B5BFC0DB2E707074>

(1) 주소지정방식 Address Mode 메모리접근 분기주소 명령어 직접번지 Reg. 지정 Reg. 간접 Base Index 간접 Immediate 상대번지 절대번지 Long 주소 Reg. 간접 Byte Access Bit Access 내부 Data M

Microsoft Word - EastSocket매뉴얼_ _.doc

마이크로프로세서 개요

Microsoft Word - Ahram_ISP_V15_Manual_V20.doc

À̵¿·Îº¿ÀÇ ÀÎÅͳݱâ¹Ý ¿ø°ÝÁ¦¾î½Ã ½Ã°£Áö¿¬¿¡_.hwp

HBE-MCU-Multi 로배우는 마이크로컨트롤러 (AVR 편 ) 마이크로컨트롤러기능 제 6 장타이머와카운터

Microsoft Word - PEB08_USER_GUIDE.doc

Microsoft Word - logic2005.doc

<BDC7C7E83520BFB9BAF1BAB8B0EDBCAD2E687770>

Microsoft PowerPoint - chap03-변수와데이터형.pptx

ADP-2480

PowerPoint 프레젠테이션

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

Microsoft Word - codevision사용법_pdf버전.docx

슬라이드 1

Microsoft PowerPoint - chap04-연산자.pptx

목차 1. ATMega128의외부메모리인터페이스 2. TEXT LCD 3. TEXT LCD에글자쓰기 4. SRAM 5. 외부메모리인터페이스에 SRAM붙이기

Microsoft PowerPoint - Chapter 8_USART Serial Communication

Microsoft PowerPoint - 3ÀÏ°_º¯¼ö¿Í »ó¼ö.ppt

2. GCC Assembler와 AVR Assembler의차이 A. GCC Assembler 를사용하는경우 i. Assembly Language Program은.S Extension 을갖는다. ii. C Language Program은.c Extension 을갖는다.

<4A4B49542D D312DBBE7BFEBC0DABCB3B8EDBCAD2E646F63>

온라인 IT 교육최강 ( 강의정보처리필기강사조대호 차시명 [CA-06 강 ] 프로세서와명령어차시 6 차시 학습내용 프로세서와명령어 학습목표 컴퓨터의구조와프로세서에대해이해할수있다 컴퓨터의명령어에대해이해할수있다 학습내용 1. 컴퓨터의구성 - 1

Chapter. 14 DAC 를이용한 LED 밝기제어 HBE-MCU-Multi AVR Jaeheung, Lee

2주차: 입출력 제어 복습

Microsoft PowerPoint - C프로그래밍-chap03.ppt [호환 모드]

Microsoft PowerPoint - ch07 - 포인터 pm0415

BY-FDP-4-70.hwp

API 매뉴얼

iii. Design Tab 을 Click 하여 WindowBuilder 가자동으로생성한 GUI 프로그래밍환경을확인한다.

<4D F736F F F696E74202D C61645FB3EDB8AEC7D5BCBA20B9D720C5F8BBE7BFEBB9FD2E BC8A3C8AF20B8F0B5E55D>

Microsoft PowerPoint - hy2-12.pptx

untitled

Section 03 인터럽트활성화와인터럽트서비스루틴연결 34/82 장치에대한인터럽트설정과활성화 내부장치에대한특수레지스터존재 장치의특성을반영한동작설정용또는상태관찰용비트로구성 인터럽트사건의발생패턴을설정해야함 인터럽트활성화비트를 1 로셋하여, 인터럽트발생을허락» 전제, 전역

Microsoft Word - Armjtag_문서1.doc

Microsoft PowerPoint - es-arduino-lecture-03

PowerPoint 프레젠테이션

사용자매뉴얼

Microsoft PowerPoint - hy2-12.pptx

Chapter ...

Microsoft Word - FunctionCall

<BFACBDC0B9AEC1A6C7AEC0CC5F F E687770>

프로그램카운터 (Program Counter) 명령레지스터 (Instruction Register) 누산기 (AC: Accumulator) 상태레지스터 (Status Register) PSWR(Program Status Word Register) 메모리주소레지스터 (M

Microsoft PowerPoint - 부호기와 복호기.PPT

정보보안 개론과 실습:네트워크

UART.h #ifndef _UART_H_ #define _UART_H_ #define DIR_TXD #define DIR_RXD sbi(portd,4) cbi(portd,4) #define CPU_CLOCK_HZ UL UART PORT1 void UAR

슬라이드 1

<4D F736F F F696E74202D20332EB5F0C1F6C5D0C8B8B7CEBFCD20B1B8C7F62E >

Chapter. 1 마이크로컨트롤러개요 Jaeheung, Lee

금오공대 컴퓨터공학전공 강의자료

Microsoft PowerPoint - M07_RTL.ppt [호환 모드]

학습목차 r 개념으로살펴보는 CPU 속의제어장치 r 마이크로연산 r 제어장치의동작 r 마이크로프로그램을이용한제어 컴퓨터구조 제어장치

Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3

2 PX-8000과 RM-8000/LM-8000등의 관련 제품은 시스템의 간편한 설치와 쉬운 운영에 대한 고급 기술을 제공합니다. 또한 뛰어난 확장성으로 사용자가 요구하는 시스템을 손쉽게 구현할 수 있습니다. 메인컨트롤러인 PX-8000의 BGM입력소스를 8개의 로컬지

PowerPoint 프레젠테이션

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

학습목표 2/33 마이크로프로세서와마이크로컨트롤러의차이를알수있다. 마이크로프로세서에서프로그램이수행되기위한명령어형식과명령어실행절차를알수있다. 프로그램을수행하려면어떤종류의명령어가필요한지알수있다. 현대컴퓨터의기본모델인저장형프로그램컴퓨터의한계점과그한계를완화하려는방법을알수있다.

Microsoft PowerPoint - 30.ppt [호환 모드]

Microsoft Word - 1. ARM Assembly 실습_xp2.doc

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

Microsoft PowerPoint - e pptx

PowerPoint 프레젠테이션

슬라이드 제목 없음

Transcription:

마이콤기초와응용강의노트 (ATmega128 시스템 ) 최한호 서울시중구필동 3가 26번지동국대학교전기공학과 TEL: 2260-3777, FAX:2275-6013 e-mail : hhchoi@dongguk.edu, WWW: //home.dongguk.edu/user/hhchoi * 하늘아래새로운것이있을까? 학문은모방을통해발전하고정보공유를통해세상에대한이해는빨라지 고지식의지평선은넓어진다고생각합니다. 이자료는출처를밝히지않고자유로이사용하셔도됩니다. 많 이사용하셔야제가쓰레기를만들어낸것이아니라는위안을받을수있으니까요.

제목차례 1. AVR 개요 1 1.1. AVR 의일반적특징 1 1.2. AVR 의종류 1 1.3. ATmega128 의특징 3 1.4. 외형과핀기능 4 1.5. ATmega128 의메모리 7 1.5.1. 프로그램메모리 7 1.5.2. 데이터메모리 : 범용레지스터 8 1.5.2.1. X,Y,Z 레지스터 8 1.5.3. 데이터메모리 : I/O 레지스터 8 1.5.3.1. 상태레지스터(SREG) 9 1.5.3.2. 스택포인터(SP) 10 1.5.3.3. RAMPZ(RAM Page Z select) 레지스터 10 1.5.4. 데이터메모리 : 확장 I/O 레지스터 10 1.5.5. 데이터메모리 : 내부 SRAM 10 1.5.6. 데이터메모리 : EEPROM 11 1.5.6.1. EEAR 레지스터 12 1.5.6.2. EEDR 레지스터 12 1.5.6.3. EECR 레지스터 12 1.5.6.4. EEPROM 쓰기과정 12 1.5.6.5. EEPROM 읽기과정 12 1.5.7. 외부데이터메모리 13 1.5.7.1. 외부메모리인터페이스 13 1.5.7.2. MCUCR 레지스터 14 1.5.7.3. XMCRA 레지스터 14 1.5.7.4. XMCRB 레지스터 14 1.5.8. 메모리 lock 비트 15 1.5.9. 퓨즈비트 16 1.5.9.1. Extended Fuse Byte 16 1.5.9.2. Fuse High Byte 16 1.5.9.3. Fuse Low Byte 16 1.6. 시스템클록과슬립모드 17 1.6.1. 클록분배 17 1.6.2. 클록발생과선택 17 1.6.2.1. 내부 RC( 디폴트클록) 발진기 17 1.6.2.2. 외부 RC 발진기 18 1.6.2.3. 외부수정발진기 19 1.6.2.4. 저주파수정발진기 19 1.6.2.5. 외부클록 20 1.6.2.6. XDIV 레지스터를이용한클럭주파수조정 20 1.6.3. 슬립모드 20 1.6.3.1. MCUCR 레지스터를이용한모드설정 21 - i -

1.6.3.2. 아이들모드 21 1.6.3.3. ADC noise reduction 모드 21 1.6.3.4. Power-down 모드 21 1.6.3.5. Power-save 모드 21 1.6.3.6. Standby 모드 21 1.6.3.7. Extended Standby 모드 21 1.6.3.8. 슬립모드의동작요약 22 1.7. Reset 과워치독타이머 22 1.7.1. 리셋 22 1.7.1.1. 파워온리셋(POR) 23 1.7.1.2. 외부리셋 23 1.7.1.3. Brown-out 리셋 24 1.7.1.4. 워치독리셋 24 1.7.1.5. MCUCSR 레지스터 25 1.7.2. 워치독타이머 25 1.7.2.1. 워치독타이머의구성 25 1.7.2.2. WDTCR 레지스터 25 1.7.2.3. 워치독의설정 26 2. ATmega128 시스템개발기초 27 2.1. 명령어분류와주소지정방식 27 2.2. 명령어요약 28 2.2.1. 어셈블리어의일반형태 30 2.2.2. 지시어( 의사명령) 30 2.2.3. 숫자, 문자, 연산자 32 2.2.4. 함수 32 2.3. AVR Studio4 33 2.3.1. 새프로젝트등록과실행파일만들기 33 2.3.2. 디버깅과시뮬레이션 37 2.4. AVR의 ISP 40 2.4.1. 마이컴시스템개발방법 40 2.4.1.1. ICE(In Cricuit Emulator) 를이용하는법 40 2.4.1.2. ROM Emulator 를이용하는법 40 2.4.1.3. ROM Writer 를이용하는법 41 2.4.1.4. 외부 RAM 을이용하는법 41 2.4.1.5. ISP 를이용하는법 41 2.4.2. AVR ISP 용다운로더 42 2.4.2.1. AVR Studio와 ATAVRISP 42 2.4.2.2. Atmel AVR ISP 프로그래머 42 2.4.2.3. PonyProg2000 42 2.4.2.4. Codevisin AVR 43 2.5. Codevision AVR C 컴파일러 43 2.5.1. 새프로젝트등록하기와옵션설정하기 43 2.5.2. 새소스파일만들기 46 2.5.3. 프로젝트에소스파일등록하고실행파일만들기 47 2.5.4. 디버깅 51 - ii -

2.5.5. 플래쉬롬 ISP 프로그래밍하기 54 2.5.6. EEPROM ISP 프로그래밍하기 56 2.6. C 프로그래밍에서유의할점 56 2.6.1. C 프로그램의구성요소 56 2.6.2. C 프로그램의일반적형식 56 2.6.2.1. 전처리 57 2.6.2.2. 선언문 57 2.6.2.3. 주석 57 2.6.2.4. 함수와 main 함수부분 57 2.6.3. 기본데이터형 57 2.6.3.1. 문자형 58 2.6.3.2. 정수형 58 2.6.3.3. 실수형 58 2.6.3.4. 변수나상수이름짓는법 58 2.6.3.5. 상수정의 59 2.6.3.6. 변수선언과초기화 59 2.6.4. 확장데이터형 59 2.6.4.1. bit 데이터형 59 2.6.4.2. eeprom 데이터형 59 2.6.4.3. flash 데이터형 59 2.6.4.4. sfrb, sfrw 데이터형 59 2.6.5. 연산자 59 2.6.5.1. 조건연산자 59 2.6.5.2. 데이터형변환연산자 59 2.6.5.3. 콤마연산자 60 2.6.5.4. 산술연산자 60 2.6.5.5. 논리와비교연산자 60 2.6.5.6. 비트연산자 60 2.6.5.7. 대입연산자 61 2.6.6. 제어문 61 2.6.6.1. if 문 61 2.6.6.2. switch-case 문 61 2.6.6.3. for 문 62 2.6.6.4. while 문 62 2.6.6.5. do-while 문 62 2.6.6.6. break 문 62 2.6.6.7. continue 문 62 2.6.6.8. goto 문 62 2.6.7. 함수와변수 62 2.6.7.1. 프로토타입선언 62 2.6.7.2. 일반함수의정의 62 2.6.7.3. 라이브러리함수 63 2.6.7.4. 인터럽트함수의정의 63 2.6.7.5. 변수 63 2.6.7.6. 어셈블리어와결합 64 - iii -

2.6.8. 포인터와배열 64 2.6.8.1. 배열선언방법 64 2.6.8.2. 배열초기화 64 2.6.8.3. 포인터선언방법 65 2.6.8.4. 포인터초기화및참조방법 65 2.6.8.5. 포인터의연산 65 2.6.8.6. 함수포인터 65 2.6.8.7. 배열과포인터의차이점 66 2.6.9. typedef, structure, union, enum 66 2.6.9.1. typedef 를사용한새로운데이터형정의법 66 2.6.9.2. 구조체의개념과필요성 66 2.6.9.3. 구조체선언법과초기화 66 2.6.9.4. 구조체사용법 67 2.6.9.5. 공용체(union) 67 2.6.9.6. 열거형상수 67 3. 기본프로그래밍과입출력실험 68 3.1. 기본프로그래밍연습 68 3.1.1. 실험1 : 내부램에데이터쓰기1 68 3.1.2. 실험2 : 내부램에데이터쓰기2 68 3.1.3. 실험3 : EEPROM 에데이터쓰기와읽기 68 3.1.4. 실험4 : 롬데이터읽기 69 3.1.5. 실험5 : 롬데이터검색1 70 3.1.6. 실험6 : 롬데이터검색2 70 3.1.7. 실험7 : 8비트 2진수의 BCD 변환 70 3.1.8. 실험8 : 16비트 2진수의 BCD 변환 71 3.1.9. 실험9 : 아스키문자의 16 진수변환 72 3.1.10. 실험10 : 숫자의아스키코드변환 72 3.1.11. 실험11 : 지연루틴 73 3.2. I/O Port 74 3.2.1. 관련레지스터 74 3.2.1.1. DDRx 레지스터 74 3.2.1.2. PORTx 레지스터 74 3.2.1.3. PINx 레지스터 74 3.2.1.4. SFIOR 레지스터 74 3.2.2. 구조및동작 74 3.3. 단순출력연습 75 3.3.1. 실험12 : LED 점멸1 75 3.3.2. 실험13 : LED 점멸2 77 3.3.3. 실험14 : LED 점멸3 77 3.3.4. 실험15 : LED 점멸4 78 3.4. 단순입출력연습 78 3.4.1. 실험16 : 키누름수세기 78 3.4.2. 실험17 : 파일럿램프1 80 3.4.3. 실험18 : 파일럿램프2 80 3.4.4. 실험19 : 입출력함수구현 81 - iv -

3.4.5. 실험20 : 입력값에따른 LED 점멸속도조절 81 4. 인터럽트와타이머실험 82 4.1. 외부인터럽트실험 82 4.1.1. 인터럽트의개념과종류 82 4.1.2. ATmega128 의인터럽트처리과정 82 4.1.3. 인터럽트처리시간 82 4.1.4. 인터럽트제어 83 4.1.4.1. 벡터배치 83 4.1.4.2. MCUCR 레지스터 83 4.1.4.3. 허용과우선순위 83 4.1.4.4. 외부인터럽트트리거 83 4.1.4.5. EICRA 레지스터 85 4.1.4.6. EICRB 레지스터 85 4.1.4.7. EIMSK 레지스터 85 4.1.4.8. EIFR 레지스터 85 4.1.5. 실험21 : LED 점멸1 85 4.1.6. 실험22 : LED 점멸2 86 4.1.7. 실험23 : 카운터 87 4.2. 타이머실험 88 4.2.1. 타이머카운터0, 2 88 4.2.1.1. 구성 89 4.2.1.2. TCCRn 레지스터 89 4.2.1.3. TIMSK 레지스터 90 4.2.1.4. TIFR 레지스터 90 4.2.1.5. ASSR 레지스터 90 4.2.1.6. SFIOR 레지스터 91 4.2.1.7. 타이머0,2 의일반모드 91 4.2.1.8. 타이머0,2의 CTC 모드 91 4.2.1.9. 타이머 0, 2의고속 PWM 모드 92 4.2.1.10. 타이머 0, 2의 Phase Correct PWM 모드 93 4.2.2. 타이머카운터1, 3 93 4.2.2.1. 구성 94 4.2.2.2. TCCRxA 레지스터 95 4.2.2.3. TCCRxB 레지스터 95 4.2.2.4. TCCRxC 레지스터 96 4.2.2.5. TIMSK 레지스터 96 4.2.2.6. ETIMSK 레지스터 96 4.2.2.7. TIFR 레지스터 97 4.2.2.8. ETIFR 레지스터 97 4.2.2.9. 타이머1, 3 의일반모드 97 4.2.2.10. 타이머1, 3의 CTC 모드 98 4.2.2.11. 타이머 1, 3의고속 PWM 모드 98 4.2.2.12. 타이머 1, 3의 Phase Correct PWM 모드 98 4.2.2.13. 타이머 1, 3의 Phase and Frequency Correct PWM 모드 99 4.2.2.14. 출력비교변조 99 - v -

4.2.3. 실험24 : 타이머를이용한 LED 점멸1 100 4.2.4. 실험25 : 타이머를이용한 LED 점멸2 100 4.2.5. 실험26 : 타이머를이용한 LED 점멸3 101 4.2.6. 실험27 : 타이머를이용한 LED 점멸4 102 4.2.7. 실험28 : 타이머를이용한 LED 점멸5 102 4.2.8. 실험29 : 워치독타이머 103 4.2.9. 실험30 : 타이머를이용한카운터 104 4.2.10. 실험31 : 펄스폭측정 104 4.3. 인터럽트와타이머복합실험 105 4.3.1. 실험32 : LED 점멸속도조절 105 4.3.2. 실험33 : 스톱워치 105 4.3.3. 실험34 : PWM 신호발생1 106 4.3.4. 실험35 : PWM 신호발생2 107 5. 응용실험 109 5.1. FND(Flexible Numeric Display) 109 5.1.1. FND 의개요 109 5.1.2. 실험36 : 디코더없는 FND 구동 109 5.1.3. 실험37 : 디코더를사용한 FND 구동 110 5.1.4. 실험38 : FND 동적구동 110 5.1.5. 실험39 : 시계 111 5.1.6. 실험40 : 스톱워치 112 5.1.7. 실험41 : 시간조정이가능한시계 113 5.2. 키보드스캐닝 115 5.2.1. 실험42 : 단순키보드스캔 115 5.2.2. 실험43 : 키매트릭스스캔 116 5.3. 음향발생 117 5.3.1. 음향발생개요 117 5.3.2. 실험44 : 사이렌소리내기 118 5.3.3. 실험45 : 전화벨소리내기 119 5.3.4. 실험46 : 동요재생하기 120 5.3.5. 실험47 : 전자오르간 121 5.4. 16x2 문자 LCD 122 5.4.1. 16x2 문자 LCD 모듈개요 122 5.4.2. LCD 제어기의내부구성 123 5.4.3. 명령어 123 5.4.4. 초기화방법(4 비트인터페이스경우) 124 5.4.5. 실험48 : LCD 초기화 124 5.4.6. 실험49 : 점멸하며문자표시하기 127 5.4.7. 실험50 : 사용자폰트이용하기 127 5.4.8. 실험51 : 시간조정이가능한시계 128 5.5. 모터제어 129 5.5.1. 스텝모터개요 129 5.5.1.1. 특징 129 5.5.1.2. 종류 130 5.5.1.3. 특성과사양 130 - vi -

5.5.1.4. 4 상스텝모터의결선확인법 130 5.5.2. 4 상스텝모터의구동원리 131 5.5.2.1. 1 상여자방법 131 5.5.2.2. 2 상여자방법 131 5.5.2.3. 1-2 상여자방법 131 5.5.3. 스텝모터의위치제어법 132 5.5.4. 스텝모터의속도제어법 132 5.5.5. 스텝모터의가감속제어시펄스레이트결정법 133 5.5.6. 모터구동용 H 브리지회로 133 5.5.7. 모터구동용 IC L298 의개요 134 5.5.8. 실험52 : 스텝모터정속제어 135 5.5.9. 실험53 : 스텝모터속도제어 136 5.5.10. 실험54 : 스텝모터가감속제어 137 5.5.11. 직류모터개요 137 5.5.11.1. 특징 137 5.5.11.2. 직류모터구동원리 138 5.5.11.3. 직류모터구조 138 5.5.12. 실험55 : 직류모터속도제어1 138 5.5.13. 실험56 : 직류모터속도제어2 139 5.6. D/A 변환 140 5.6.1. D/A 변환기의종류 140 5.6.2. DAC 0800 소개 141 5.6.3. 실험57 : 톱니파발생 141 5.6.4. 실험58 : 사인파발생 141 5.7. A/D 변환 142 5.7.1. A/D 변환과정 142 5.7.2. A/D 변환기의종류 143 5.7.3. ATmega128의 ADC 143 5.7.3.1. 특징 143 5.7.3.2. ADCH, ADCL 레지스터 144 5.7.3.3. ADMUX 레지스터 144 5.7.3.4. ADCSRA 레지스터 144 5.7.3.5. 동작 144 5.7.3.6. 잡음제거방법 145 5.7.4. 실험59 : 조도변화측정 146 5.8. 아날로그비교기 147 5.8.1. 구성 147 5.8.2. 제어 148 5.8.2.1. ACSR 레지스터 148 5.8.2.2. SFIOR 레지스터 148 5.8.3. 실험60 : 아날로그비교기실험 149 5.9. 직렬통신 150 5.9.1. SPI 포트제어 150 5.9.1.1. SPI 의동작 150 5.9.1.2. SPCR 레지스터 151 - vii -

5.9.1.3. SPSR 레지스터 151 5.9.2. USART 포트제어 152 5.9.2.1. 데이터프레임포맷 152 5.9.2.2. UDRn 레지스터 152 5.9.2.3. UCSRnA 레지스터 152 5.9.2.4. UCSRnB 레지스터 153 5.9.2.5. UCSRnC 레지스터 153 5.9.2.6. UBRRnH, UBRRnL 레지스터 154 5.9.3. RS232C 개요 154 5.9.4. 실험61 : PC와통신1 155 5.9.5. 실험62 : PC와통신2 156 5.9.6. 실험63 : PC와통신3 156 5.9.7. 실험64 : PC와통신4 157 5.9.8. 실험65 : PC와통신5 157 6. 참고문헌 161 7. 색인 162 - viii -

표차례 표 표 표 표 표 표 표 표 표 1. AVR 의종류와사양 2 2. 포트B 의다른기능설명 5 3. 포트D 의다른기능설명 6 4. 포트E 의다른기능설명 6 5. 포트F 의다른기능설명 6 6. 포트G 의다른기능설명 7 7. 어셈블리명령에쓰인약자의의미 28 8. 기본데이터형 58 9. 산술연산자 60 표 10. 논리, 비교연산자 60 표 표 11. 비트연산자 60 12. 대입연산자 61 표 13. 음계에따른 tone_data 값 118 표 14. 박자에따른지속시간값 118 표 15. 일때 k 에따른속도 133 - ix -

그림차례 그림 그림 그림 그림 그림 1. ATmega128 의블록선도( 출처:ATMEL) 4 2. ATmega128 의핀배치( 출처:ATMEL) 5 3. ATmega128 의메모리맵( 출처: ATMEL) 7 4. 범용레지스터( 출처:ATMEL) 8 5. XYZ 레지스터( 출처:ATMEL) 8 그림 6. ATmega128의 I/O 레지스터( 출처:ATMEL) 9 그림 7. ATmega128의확장 I/O 레지스터( 출처:ATMEL) 11 그림 그림 그림 8. 외부램의연결( 출처:ATMEL) 13 9. SRL2-SRL0 를이용한메모리분할( 출처:ATMEL) 14 10. Lock bit 의구성( 출처:ATMEL) 15 그림 11. Lock bit 설정에따른기능 ( 출처:ATMEL) 15 그림 그림 12. 부트사이즈의선택( 출처:ATMEL) 16 13. ATmega128 의클록분배( 출처:ATMEL) 17 그림 14. 외부 RC 발진기의연결( 출처:ATMEL 사) 18 그림 15. 외부 RC 발진기동작모드 ( 출처:ATMEL) 18 그림 16. 외부 RC 발진기의기동시간선택( 출처:ATMEL) 18 그림 17. 외부수정발진기의연결( 출처:ATMEL) 19 그림 18. 외부수정발진기동작모드 ( 출처:ATMEL) 19 그림 그림 그림 그림 그림 그림 그림 그림 그림 그림 그림 그림 그림 19. 수정발진기의기동시간선택( 출처:ATMEL) 19 20. 저주파수정발진기의기동시간선택( 출처:ATMEL) 20 21. 슬립모드의설정( 출처:ATMEL) 20 22. 슬립모드의동작요약( 출처:ATMEL) 21 23. 리셋관련내부회로블록선도( 출처:ATMEL) 22 24. 리셋관련변수( 출처:ATMEL) 23 25. 파워온리셋동작타이밍도( 출처:ATMEL) 23 26. 외부리셋동작타이밍도( 출처:ATMEL) 24 27. 저전압검출리셋동작타이밍도( 출처:ATMEL) 24 28. 워치독리셋동작타이밍도( 출처:ATMEL) 24 29. 워치독타이머의구성( 출처:ATMEL) 25 30. 워치독타이머프리스케일러의설정( 출처:ATMEL) 26 31. 워치독타이머의설정( 출처:ATMEL) 26 그림 32. 분기명령모음 ( 출처:ATMEL) 28 그림 33. MCU 제어명령모음 ( 출처:ATMEL) 28 그림 그림 34. 데이터명령모음( 출처:ATMEL) 29 35. 산술과논리연산명령모음( 출처:ATMEL) 29 그림 36. 비트조작명령모음 ( 출처:ATMEL) 30 그림 그림 그림 그림 그림 그림 37. AVR Studio 의초기화면 33 38. New Project 의실행 34 39. 프로젝트의설정 34 40. 디버그플랫폼과디바이스의설정 35 41. 프로젝트등록의최종결과로생긴에디터창 35 42. Build 실행 36 - x -

그림 그림 그림 그림 43. 성공적으로실행파일이만들어진결과 36 44. 에러가있을때결과 37 45. [Debug->Start Debugging] 메뉴 37 46. Debug 세션의시작 38 그림 47. 디버그세션에서메인메뉴 [View->Register] 의실행 38 그림 48. 디버그세션에서메인메뉴 [View->Memory] 의실행 39 그림 49. 디버그세션에서메인메뉴 [View->Watch] 의실행 39 그림 50. [Debug] 메뉴의하위메뉴들 40 그림 51. Atmel AVR ISP, PonyProg2000, CodevisonAVR용의 ISP 인터페이스회로 42 그림 그림 그림 그림 그림 그림 그림 그림 그림 그림 그림 52. CodevisionAVR Compiler 의초기화면 43 53. [File->New] 메뉴의실행과새로운프로젝트생성 44 54. CodeWizardAVR 사용여부를설정하기위한창 44 55. CodevisionAVR 에서새로운프로젝트이름의설정 45 56. CodevisionAVR 에서프로젝트옵션설정하기 45 57. [File->New] 메뉴의실행과새로운파일생성 46 58. CodevisionAVR 에서새로운파일의작성 46 59. [File->Save As] 메뉴를통한파일저장 47 60. [Project->Configure] 메뉴의실행 47 61. Add 메뉴를통한소스파일등록 48 62. Add 메뉴를통한소스파일등록결과 48 그림 63. CodeVisionAVR의 Make 실행 49 그림 64. CodevisionAVR에서 Make 의성공적인결과 49 그림 65. CodevisionAVR에서파일에에러가있을때 Make 결과 50 그림 그림 그림 그림 그림 그림 66. CodeVisionAVR 를이용한문법에러의수정 50 67. Debugger 의선택 51 68. [Tools->Debugger] 메뉴 51 69. AVR Studio4 의프로젝트선택창 52 70. cof 파일의선택대화창 52 71. 디버깅을위한프로젝트생성 53 그림 72. CodeVisionAVR에서 AVR Studio4 를이용한디버깅화면 53 그림 그림 73. AVR Chip 프로그래머설정화면 54 74. CodeVisionAVR 의칩프로그래머대화창 54 그림 75. 다운로드할 rom이나 hex 혹은 bin 파일의선택 55 그림 그림 그림 그림 그림 그림 그림 그림 그림 그림 76. 플래시롬을지우는과정을보여주는창 55 77. 프로그램의다운로드과정을보여주는창 56 78. I/O 포트의기본구조( 출처:ATMEL) 75 79. 기본입출력실험을위한회로도 76 80. 단순키보드스캔을위한회로도 79 81. 딥스위치를이용한간단한입력회로 80 82. 인터럽트벡터의배치( 출처:ATMEL) 83 83. ATmega128 의인터럽트발생원과벡터값( 출처:ATMEL) 84 84. 간단한채터링방지키입력회로 86 85. 타이머0 의블록선도( 출처:ATMEL) 88 그림 86. 타이머0,2의 CTC 모드동작( 출처:ATMEL) 92 그림 87. 타이머의고속 PWM 모드동작( 출처:ATMEL) 92 - xi -

그림 88. 타이머0, 2의위상교정 PWM 모드동작 ( 출처:ATMEL) 93 그림 89. 타이머1,3 의불록선도( 출처:ATMEL) 94 그림 90. 타이머1,3 의동작모드설정( 출처:ATMEL) 96 그림 91. 타이머1,2 를이용한출력비교변조의예 99 그림 그림 92. LED 배열회로. 107 93. FND 의내부구성과핀배치 109 그림 94. FND 기초실험도( 왼쪽: 디코더비사용, 오른쪽: 디코더사용) 110 그림 그림 그림 그림 95. FND 의동적구동을위한회로도 111 96. 키보드스캔을위한순서도 115 97. 5X5 키매트릭스 117 98. 음향발생을위한회로도 119 그림 99. 16x2 문자 LCD 실험회로도 125 그림 그림 그림 100. LCD 에문자등록을위해패턴값구하는예 128 101. 스텝모터의토크속도특성 130 102. 4 상스텝모터의결선도 131 그림 103. 1 상여자방법( 왼쪽: sw1 만닫힌경우, 오른쪽: sw2 만닫힌경우) 131 그림 104. 2 상여자방법( 왼쪽: sw1, sw2 만닫힌경우, 오른쪽: sw2, sw3 만닫힌경우) 132 그림 105. 스텝모터의가속패턴 133 그림 106. 다목적 H 브리지회로의예 134 그림 그림 107. 모터실험회로도 135 108. 직류모터의구동원리 138 그림 109. D/A 변환기의종류. 가산형( 왼쪽) 과사다리형( 오른쪽) 141 그림 그림 110. D/A 변환실험회로도 142 111. ADCH, ADCL 레지스터( 출처:ATMEL) 144 그림 112. ADC 채널과 Gain 의설정( 출처:ATMEL) 145 그림 그림 그림 그림 그림 그림 113. 아날로그전원단자의처리( 출처:ATMEL) 146 114. 조도측정회로 147 115. 아날로그비교기의블록선도( 출처:ATMEL) 148 116. SPI 포트의블록선도( 출처:ATMEL) 150 117. SPI 의동작( 출처:ATMEL) 151 118. USART 통신의데이터프레임( 출처:ATMEL) 152 그림 119. 보레이트와 UBRR 의관계( 출처:ATMEL) 154 그림 그림 120. RS232C 통신을위한인터페이스 155 121. 직렬통신에의한문자열수신순서도 158 - xii -

머리말 마이컴이란프로그램메모리, 데이터메모리, 입출력포트등으로구성된작은규모의컴퓨터인마이크로컴퓨터 의기능을단일칩에집적해구현한단일칩마이크로컴퓨터를지칭하는말로마이크로콘트롤러라고도불리운다. 마 이컴은아래와같은특성을갖기때문에모든산업전반에걸쳐다양하게응용되고있다. 소형화와경량화 : 다양한기능을 VLSI 기술에의해단일칩에집적해구현했기때문에제품제작시소형화와 경량화를실현할수있다. 쉽고편리한개발 할수있다. 저가격 융통성 : 입출력, 인터럽트처리, 비트조작명령어가많아프로그램작성이수월하여개발을빨리 : 개발비, 부품비와제작비를감소시켜제품의가격을저렴하게할수있다. : 프로그램변경만으로기능을변경하거나확장시키는것을짧은시간내에수월하게할수있다. 신뢰성 : 마이크로컴퓨터의기능이 VLSI 기술에의해단일칩에집적되어있기때문에제품의부품수를줄일 수있어제품의구성을간단하게하고고장률을줄일수있으며고장시유지보수가쉽다. 마이컴의시초는인텔사가 1971년 2300 여개의트랜지스터를집적하여, 46 개의명령어, 12 개의주소선, 16개의 내부 4비트범용레지스터를사양으로 108kHz의발진주파수에서동작하도록만든 4비트마이컴 4004 이다. 그후 인텔은 1972년에는 4004를개선한 8008 8 비트마이크로프로세서를, 1973년에는 8008을개선한 8080 8비트 프로세서를발표하였다. 1975년에는 TI 에서중앙처리장치와, 메모리, 입출력장치를단일칩에내장한 TMS1000 시리즈를출시하여마이컴시대를열었고이후마이크로프로세서의개발은연산용프로세서와제어용마이컴으로 분화되었다. 1976년에는 8비트마이컴 8048, 8748, 8035가포함된 MCS48시리즈를인텔사에서출시하고그상 위버전인 MCS51 시리즈의 8051을 1981년에출시한이후여러회사에서계속적으로향상된기능의마이컴을출 시하고있다. 인텔의 80960, 모토로라의 68332, ST마이크로의 ST40이나 STR7, 삼성전자의 KS32 등 32비트의고성능마 이컴도있지만아직 8 비트마이컴이가전제품 (TV/VCR, CD, 카메라, 리모콘, 전자레인지, 공기청정기등), 사무 기기( 모니터, 마우스, 키보드, 스캐너, 프린터, 복사기, 팩스, PC LAN 시스템, 바코드리더, 탁상계산기, 하드디스크 등), 통신기기 ( 전화기, 자동응답기, 모뎀, 발신자확인기등), 자동차 (ABS, 속도측정기, Power seat, 운항제어, 자 동경보기, 온도제어, 연료제어, Air bag 센서, Sun roof 제어등), 계측기, CCTV, 자동차주행시험장의점수계 산장치, PLC, 신용카드리더, 공정제어등산업전반에걸쳐다양하게응용되고있는형편이다. 그리고인텔의 8051, 모토로라의 68HC11, ST마이크로의 ST7 시리즈, Microchip 의 PIC 시리즈, Zilog의 Z88C00, Atmel 의 AVR 등의 8비트마이컴에서 Atmel의 AVR 은교육로봇 (robotkim.com), US Technology(www.us-technology.co.kr), 로보블록 (roboblock.co.kr), 마이컴월드 (www.micomworld.co.kr) 등국내여러회사에서값싼키트를공급하고 있으며 AVR이플래쉬롬을내장하여값싸고쉽게프로그래밍이가능한이점을갖고있어초보자들이쉽게구현해 볼수있으므로여기에서는 AVR 그가운데 ATmega128 시스템개발의기초와응용을다룬다. 1장에서는 ATmega128 의구조와기능에대하여설명하고 2장에서는 AVR 시스템개발을위한환경을꾸미는 방법과어셈블리어와 C 언어에대한설명을한다. 3장에서는기초적인프로그램과단순입출력을위한프로그램 작성과실습을다루고 4 장에서는타이머와인터럽트를사용한프로그램작성과실습을다룬다. 5장에서는응용실 험으로마이컴시스템의고기능화를위해사용되는 FND, 키보드, D/A와 A/D 변환, 모터, 스피커, LCD 등다양한 주변장치에대한설명과이들을이용한응용시스템을위한프로그램작성과실습을다룬다. 아무쪼록본책이독자들의마이컴시스템개발능력을향상시키는데일조하길바랍니다. 2007 년여름최한호 - xiii -

1. AVR 개요 1.1. AVR 의일반적특징 AVR은 Atmel 사의마이컴들로저가의고기능마이컴으로다음과같은특성을갖고있다. 유사 RISC (Reduced Instruction Set Code) 구조 : 명령어가많고복잡하며주소지정방식도다양한 CISC (Complex Instruction Set Code) 방식이사용된 8051에비해명령어와주소지정방식이작지않지만유사 RISC 구조로연산및전송이레지스터간에직접이루어지고명령어의길이가 16비트 1워드로고정적이어디코딩이쉬 운특징을갖고있으며발진주파수를분주해서내부클록으로사용하는 8051과달리발진주파수와같은내부클 록을사용하며대부분 1기계사이클에명령어가실행되어보통 1MHz 당 1MIPS 의처리속도를보인다. 결국통상 적인 RISC처럼명령어와주소지정방식이작지않아어셈블리어프로그램작성에서불리하지도않으면서도통상 적인 RISC처럼속도가매우빠른유사 RISC 의특성을갖고있다. 하바드구조의메모리구성 아니고 : Z80처럼프로그램메모리와데이터메모리가구분되지않은폰노이만방식이 TMS320 과같이프로그램메모리와데이터메모리가분리되어있는하바드구조를채택하였다. 저전력소모 : CMOS 기술을채택하고있어소비전력이매우적고동작전압이 1.8-5.5V 로큰장점이있다. 다양한동작모드를제공해저전력동작을지원한다. 큰잡음여유와입력임피던스 : CMOS 정전기및과전압에의한파손위험이큰단점도있다. 기술을채택하고있어잡음여유와입력임피던스가큰장점이있으나 고집적 : CMOS 기술에의해 1K-256Kbyte 플래시롬메모리와변수저장을위한 EEPROM 및 SRAM 이작은 칩하나에내장되어있다. 고속 : 유사 RISC 구조와 32개의레지스터사용과고집적으로대부분 1기계사이클에명령어가실행되어보통 1MHz 당 1MIPS 의처리속도를보인다. 효율적인프로그래밍 : C언어를고려하여설계하였으며 32개의레지스터와 C와유사한주소지정방식를사용 하고있으며 16비트와 32 비트의산술연산을지원하여효율적으로최적의프로그램을가능하게한다. 다양하고값싼개발도구 : 공짜의개발도구인 AVR Studio 와값싼평가보드나 Starter 키트가이용가능하다. 다양한사양지원 : 8핀에서 100핀의외형과이에상응하는메모리와기능을갖는다양한시리즈의제품이존 재하여적절한응용에대응하여제어기를개발할수있다. ISP (In System Program) 지원 : 내부에롬라이터와같은기능을하는부분이내장되어있어내부플래시롬 을롬라이터없이읽고쓰기가가능하여따로값비싼롬라이터를이용하지않고도 장하고전원과클럭이공급되는상태에서프로그래밍이가능한 1.2. AVR 의종류 ISP 기능이제공된다. PCB 기판상에마이컴을실 Atmel 사의 8비트마이컴 AVR은크게 Tiny, AT90, Mega 시리즈로나뉠수있다. 표 1은 AVR의사양을보여 준다. Tiny 시리즈 : 핀수가 8-24핀정도의작은외형으로대부분외부시스템버스가없고내부에 1K-2K byte 정 도의플래시메모리를가지고있어용량도작은편이다. UART 를지원하지않고 RTC 타이머가없으며 16비트 타이머가없고 8비트타이머만 1-2개있는등기능이나성능이비교적낮지만가격이저렴하여소형제어기에 적당하다. Mega 시리즈 : 28-100 핀정도의외형을갖고내부에 8K-256Kbyte 정도의플래시메모리와 256-4K byte 정도의 EEPROM 과 512-4K byte의 SRAM 을내장하고있다. 20MHz 의클럭에서 20MIPS 의속도를갖는등성 능과기능이높으나가격도높다. - 1 -

AT90 시리즈 : 중간정도사양을가진시리즈로 AT90S 의경우에는사양화되었다. Device Flash (K) EEPROM (K) SRAM (byte) 표 1. AVR의종류와사양 M a x I/O F.max (MHz) Vcc (V) 16-bit Timers AT90PWM1 8 0.5 512 19 16 2.7-5.5 1 1 7 No -- 11 26 AT90PWM2 8 0.5 512 19 16 2.7-5.5 1 1 7 Yes -- 11 29 AT90PWM216 16 0.5 1024 19 16 2.7-5.5 1 1 10 Yes -- 11 29 AT90PWM3 8 0.5 512 27 16 2.7-5.5 1 1 10 Yes -- 11 29 AT90PWM316 16 0.5 1024 27 16 2.7-5.5 1 1 10 Yes -- 11 29 ATmega128 128 4 4096 53 16 2.7-5.5 2 2 8 2 Yes 8 34 ATmega1280 128 4 8192 86 16 1.8-5.5 4 2 16 4 Yes -- 57 ATmega1281 128 4 8192 54 16 1.8-5.5 4 2 9 2 Yes -- 48 ATmega128RZAV 128 4 8192 54 16 1.8-5.5 4 2 9 2 Yes -- 48 ATmega128RZBV 128 4 8192 86 16 1.8-5.5 4 2 16 4 Yes -- 57 ATmega16 16 0.5 1024 32 16 2.7-5.5 1 2 4 1 Yes -- 20 ATmega162 16 0.5 1024 35 16 1.8-5.5 2 2 6 2 -- -- 28 ATmega164P 16 0.5 1024 32 20 1.8-5.5 1 2 6 2 Yes 8 31 ATmega165 16 0.5 1024 54 16 1.8-5.5 1 2 4 1 USI -- 23 ATmega165P 16 0.5 1024 54 16 1.8-5.5 1 2 4 1 USI -- 23 ATmega168 16 0.5 1024 23 20 1.8-5.5 1 2 6 1 Yes 6/8 26 ATmega168P 16 0.5 1024 23 20 1.8-5.5 1 2 6 1 Yes 8 26 ATmega169 16 0.5 1024 54 16 1.8-5.5 1 2 4 1 USI -- 23 ATmega169P 16 0.5 1024 54 16 1.8-5.5 1 2 4 1 USI -- 23 ATmega2560 256 4 8192 86 16 1.8-5.5 4 2 16 4 Yes -- 57 ATmega2561 256 4 8192 54 16 1.8-5.5 4 2 9 2 Yes -- 48 ATmega256RZAV 256 4 8192 54 16 1.8-5.5 4 2 9 2 Yes -- 48 ATmega256RZBV 256 4 8192 86 16 1.8-5.5 4 2 16 4 Yes -- 57 ATmega32 32 1 2048 32 16 2.7-5.5 1 2 4 1 Yes -- 19 ATmega324P 32 1 2048 32 20 1.8-5.5 1 2 6 2 Yes -- 31 ATmega325 32 1 2048 54 16 1.8-5.5 1 2 4 1 USI -- 23 ATmega3250 32 1 2048 69 16 1.8-5.5 1 2 4 1 USI -- 32 ATmega3250P 32 1 2048 69 20 1.8-5.5 1 2 4 1 USI -- 32 ATmega325P 32 1 2048 54 20 1.8-5.5 1 2 4 1 USI -- 23 ATmega328P 32 1 2048 23 20 1.8-5.5 1 2 6 1 Yes 8 26 ATmega329 32 1 2048 54 16 1.8-5.5 1 2 4 1 USI -- 25 ATmega3290 32 1 2048 69 16 1.8-5.5 1 2 4 1 USI -- 25 ATmega3290P 32 1 2048 69 20 1.8-5.5 1 2 4 1 USI -- 25 ATmega329P 32 1 2048 54 20 1.8-5.5 1 2 4 1 USI -- 25 ATmega406 40 0.5 2048 18 1 4.0-25 1 1 1 -- Yes -- 23 ATmega48 4 0.25 512 23 20 1.8-5.5 1 2 6 1 Yes 6/8 26 ATmega48P 4 0.25 512 23 20 1.8-5.5 1 2 6 1 Yes 6/8 26 ATmega64 64 2 4096 54 16 2.7-5.5 2 2 8 2 Yes -- 34 ATmega640 64 4 8192 86 16 1.8-5.5 4 2 16 4 Yes -- 57 ATmega644 64 2 4096 32 20 1.8-5.5 1 2 6 1 Yes -- 31 ATmega644P 64 2 4096 32 20 1.8-5.5 1 2 6 2 Yes -- 31 ATmega645 64 2 4096 54 16 1.8-5.5 1 2 4 1 USI -- 23 ATmega6450 64 2 4096 69 16 1.8-5.5 1 2 4 1 USI -- 32 ATmega649 64 2 4096 54 16 1.8-5.5 1 2 4 1 USI -- 25 ATmega6490 64 2 4096 69 16 1.8-5.5 1 2 4 1 USI -- 25 ATmega64RZAPV 64 2 4096 32 20 1.8-5.5 1 2 6 2 Yes -- 31 ATmega64RZAV 64 2 4096 32 20 1.8-5.5 1 2 6 1 Yes -- 31 ATmega8 8 0.5 1024 23 16 2.7-5.5 1 2 3 1 Yes 6/8 18 ATmega8515 8 0.5 512 35 16 2.7-5.5 1 1 3 1 -- -- 16 ATmega8535 8 0.5 512 32 16 2.7-5.5 1 2 4 1 Yes -- 20 ATmega88 8 0.5 1024 23 20 1.8-5.5 1 2 6 1 Yes 6/8 26 ATmega88P 8 0.5 1024 23 20 1.8-5.5 1 2 6 1 Yes 8 26 ATtiny11 1 -- -- 6 6 2.7-5.5 -- 1 -- -- -- -- 4 ATtiny12 1 0.0625 -- 6 8 1.8-5.5 -- 1 -- -- -- -- 5 ATtiny15L 1 0.0625 -- 6 1.6 2.7-5.5 -- 2 1 -- -- 4 8 ATtiny2313 2 0.125 128 18 20 1.8-5.5 1 1 4 1 USI -- 8 ATtiny24 2 0.125 128 12 20 1.8-5.5 1 1 4 -- USI 8 17 ATtiny25 2 0.125 128 6 20 1.8-5.5 -- 2 4 -- USI 4 15 ATtiny26 2 0.125 128 16 16 2.7-5.5 -- 2 2 -- USI 11 11 ATtiny261 2 0.125 128 16 20 1.8-5.5 1 2 2 -- USI 11 19 ATtiny28L 2 -- 32 11 4 1.8-5.5 -- 1 -- -- -- -- 5 ATtiny44 4 0.25 256 12 20 1.8-5.5 1 1 4 -- USI 8 17 ATtiny45 4 0.25 256 6 20 1.8-5.5 -- 2 4 -- USI 4 15 ATtiny461 4 0.25 256 16 20 1.8-5.5 1 2 2 -- USI 11 19 ATtiny84 8 0.5 512 12 20 1.8-5.5 1 1 4 -- USI 8 17 ATtiny85 8 0.5 512 6 20 1.8-5.5 -- 2 4 -- USI 4 15 ATtiny861 8 0.5 512 16 20 1.8-5.5 1 2 2 -- USI 11 19 8-bit Timer PWM ( 채널 ) UART TWI A/D ( 채널 ) 인터럽트 - 2 -

1.3. ATmega128 의특징 그림 1은 ATmega128 의블록선도로다음과같은특징을갖는다. 유사 RISC 구조 : 대부분한클럭에동작하는 133 개의명령어, 32개의 8 비트범용레지스터, 16MHz 에서 16MIPS 의성능, 2사이클에서실행되는내장곱셈장치 6개의 Sleep 모드 : idle, ADC noise reduction, power save, power down, standb, extended standby 모 드지원 메모리 : 128K byte의 10000 번까지 ISP를이용해쓰고지우기가능한플래시롬내장하고있으며부트코드 영역으로사용가능, 십만번까지쓰고지우기가능한 4K바이트의 EEPROM 내장, 4K바이트의 SRAM 을내장, 최 대 64K 바이트의외부데이터메모리추가가능, 소프트웨어의보안을위한프로그램잠금기능제공 ALU : 32 개의범용레지스터와직접연결되어수학연산, 논리연산, 비트연산을보통한개의시스템클럭안에 서수행한다. Watchdog Timer : 프로세서가안정적으로동작하는지감시하는기능을수행한다. 프로세서에이상이생겨일 정시간마다 Watchdog Timer 가리셋되지않게되는경우시스템에인터럽트를발생시켜프로세서를초기화시 키는동작이이루어지게하여안정적인동작을보장할수있다. 입출력 I/O : 6개의 8비트병렬 I/O포트와 1개의 5비트병렬 I/O포트로총 53개의프로그램가능한입출력선 을갖고있다. 타이머 / 카운터 : 2개의 8 비트타이머 ( 타이머 0와 2) 와 2개의 16 비트타이머( 타이머 1와 2) 를가지고있다. 이들 은 2개의 8비트 PWM 출력, 2-16비트 PWM 출력, 출력비교단자등과관련되어동작한다. AD 변환기 : 8채널의 10비트 AD 변환기를제공한다. 이들은 8개의단일입력혹은 7개의차동입력채널로사 용가능하며, 8 개중프로그램이가능한입력게인(1x, 10x, 200x) 을갖는 2 개의채널이존재한다. 비교기 : 아날로그비교기를 1 개내장하고있다. 발진기 : RC 발진기를내장하고있으며외부에서크리스탈을접속해정확한클럭소스를사용할수도있다. 직렬통신포트 (Serial Port) : 동시양방향전송이가능한범용동기/ 비동기직렬통신(USART) 기능을제공하 는직렬통신포트를 2개존재하여쉽게 RS232C 통신을구현할수있다. 인터럽트 : 리셋과 8개의외부인터럽트를포함하여총 35 개의인터럽트벡터를가지고있다. JTAG 인터페이스 : JTAG 인터페이스로플래시, EEPROM, 퓨즈, Lock 비트를프로그램이가능하며, 내장된 상태에서디버그를가능하게한다. SPI (Serial Peripheral Interface) 인터페이스 : SPI는오직 3라인을이용한통신방법으로 MOSI (Master Out Slave In), MISO (Master In Slave Out), SCK (Serial ClocK) 신호를이용한다. Motolora 에서개발되었으 며 Master 와 Slave 가 SCK에동기하여데이터를교환하는방식으로마이컴의 RST( 리셋) 핀을 0으로한상태에 서앞의세시그널을이용하여메모리의데이터를읽고쓰기가가능하다. 즉내부에롬라이터와같은기능을하 는부분이내장되어있어내부플래시롬을롬라이터없이읽고쓰기가가능하므로 를이용하지않고도 PCB ISP(In System Programming) 기능이제공된다. SPI가지원되면따로롬라이터 기판상에마이컴을실장하고전원과클럭이공급되는상태에서프로그래밍이가능한 동작범위 : 정상적인동작의경우 5.5mA, idle모드의경우 1.6mA, 파워다운모드의경우 1마이크로 A이하를 소비한다. -40도부터 85도사이에서동작가능하고 ATmega128L 의경우 2.7-5.5V에서최대 8MHz에서동작가 능하고, ATmega128 의경우 4.5-5.5V 에서최대 12MHz 에서동작가능하다. - 3 -

그림 1. ATmega128 의블록선도 ( 출처:ATMEL) 1.4. 외형과핀기능 ATmega128 은그림 2와같이 64핀을갖는 TQFP(Thin Quad Flat Pack) 형또는 MLF(Micro Lead Frame) 형 이있다. RESET ( 핀20) : 입력단자로 1레벨이입력되면리셋되어 PC(Program Counter) 는일반적으로 0번지를가르키 고 0 번지부터프로그램이시작됨(1.5.9 절참조). 리셋시대부분의레지스터는 0 으로된다. XTAL1, XTAL2( 핀24,23) : 발진용증폭기입력및출력단자. Vcc( 핀21,51) : 전원입력단자. GND ( 핀22,53,63) : 그라운드입력단자. AVCC( 핀64) : AD변환기및포트 F에대한공급전압 - 4 -

AREF( 핀62) : ADC 참조전압 그림 2. ATmega128 의핀배치 ( 출처:ATMEL) PEN( 핀1) : SPI를활성화시키는단자로일반적인동작모드에서는사용하지않고파워온리셋시 0상태로유 지해 SPI를허용하게한다 포트A (PA7~PA0: 핀44-51) : 내부풀업저항이있는 8 비트양방향입출력단자. 외부메모리를둘경우에는 주소버스 (A7-A0) 와데이터버스 (D7-D0) 로사용. 포트B (PB7~PB0: 핀10-17) : 내부풀업저항이있는 8 비트양방향입출력단자. SPI용단자혹은 PWM 단자 로도사용된다 ( 표2 참조). 포트핀 표 2. 포트B 의다른기능설명 다른특수기능 PB7( 핀17) OC2,OC1C : 타이머 2용의비교신호출력혹은타이머 1용의비교신호C 출력 PB6( 핀16) OC1B : 타이머 1용의비교신호B 출력 PB5( 핀15) OC1A : 타이머 1용의비교신호A 출력 PB4( 핀14) OC0 : 타이머 0 용의비교신호출력 PB3( 핀13) MISO : SPI 채널의마스터데이터입력혹은슬레이브데이터출력신호단자 PB2( 핀12) MOSI : SPI 채널의마스터데이터출력혹은슬레이브데이터입력신호단자 PB1( 핀11) SCK : SPI 채널의마스터클럭출력혹은슬레이브클럭입력신호단자 PB0( 핀10) SS : SPI 태널의슬레이브선택입력신호단자 포트C (PC7~PC0: 핀35-42) : 내부풀업저항이있는 8 비트양방향입출력단자. 외부메모리를둘경우에는 주소버스 (A15-A8) 로사용된다. - 5 -

포트D (PD7~PD0: 핀25-32) : 내부풀업저항이있는 8 비트양방향입출력단자. 타이머용단자혹은외부인 터럽트용단자로도사용된다 ( 표3 참조). 포트핀 PD7( 핀25) T2 : 타이머2 클럭입력 PD6( 핀26) T1 : 타이머1 클럭입력 PD5( 핀27) XCK : USART1 외부클럭입출력 PD4( 핀28) ICP1 : 타이머 1 입력캡춰 표 3. 포트D 의다른기능설명 다른특수기능 PD3( 핀29) INT3/TXD1 : 외부인터럽트 3 혹은 USART1 송신 PD2( 핀30) INT2/RXD1 : 외부인터럽트 2 혹은 USART1 수신 PD1( 핀31) INT1/SDA : 외부인터럽트 1 혹은 2선방식의직렬인터페이스용데이터단자 PD0( 핀32) INT0/SCL : 외부인터럽트 0 혹은 2선방식의직렬인터페이스용클록단자 포트E (PE7~PE0: 핀2-9) : 내부풀업저항이있는 8 비트양방향입출력단자. 타이머용단자, 외부인터럽트, 아날로그비교기, USART 용단자로도사용된다 ( 표4 참조). 포트핀 표 4. 포트E 의다른기능설명 다른특수기능 PE7( 핀2) INT7/ICP3 : 외부인터럽트 7 혹은타이머3 입력캡춰 PE6( 핀3) INT6/T3 : 외부인터럽트 6 혹은타이머3 클럭입력 PE5( 핀4) INT5/OC3C : 외부인터럽트 5 혹은타이머 3용의비교신호C 출력 PE4( 핀5) INT4/OC3B : 외부인터럽트 4 혹은타이머 3용의비교신호B 출력 PE3( 핀6) AIN1/OC3A : 비교기 -입력혹은타이머 3용의비교신호A 출력 PE2( 핀7) AIN0/XCK0 : 비교기 + 입력혹은 USART0 외부클럭입출력 PE1( 핀8) PDO/TXD0 : 프로그램데이터출력(ISP 케이블의 MISO 와연결) 혹은 USART0 송신 PE0( 핀9) PDI/RXD0 : 프로그램데이터입력(ISP 케이블의 MOSI 와연결) 혹은 USART0 수신 포트F (PF7~PF0: 핀54-61) : 내부풀업저항이있는 5 비트양방향입출력단자. AD변환기혹은 JTAG 인터 페이스용단자로도사용된다 ( 표5 참조). 포트핀 다른특수기능 PE7( 핀54) ADC7/TDI : ADC 입력채널 7 혹은 JTAG 테스트용데이터입력단자 PE6( 핀54) ADC6/TDO : ADC 입력채널 6 혹은 JTAG 테스트용데이터출력단자 PE5( 핀54) ADC5/TMS : ADC 입력채널 5 혹은 JTAG 테스트용모드선택단자 PE4( 핀54) ADC4/TCK : ADC 입력채널 4 혹은 JTAG 테스트용클럭단자 PE3( 핀54) ADC3 : ADC 입력채널 3 PE2( 핀54) ADC2 : ADC 입력채널 2 PE1( 핀54) ADC1 : ADC 입력채널 1 PE0( 핀54) ADC0 : ADC 입력채널 0 표 5. 포트F의다른기능설명 포트G (PG4~PE0: 핀19, 18, 43, 34, 33) : 내부풀업저항이있는 8 비트양방향입출력단자. 외부메모리 접속을위한스트로브신호용, RTC(Real Time Counter) 타이머용발진기단자로도사용된다 ( 표5 참조). - 6 -

포트핀 표 6. 포트G의다른기능설명 다른특수기능 PG4( 핀19) TOSC1 : 타이머 0의 RTC 기능사용시클럭발생을위한수정발진자접속단자 PG3( 핀18) TOSC2 : 타이머 0의 RTC 기능사용시클럭발생을위한수정발진자접속단자 PG2( 핀43) ALE : 외부메모리에접근할때하위주소값을래치하도록신호를출력 PG1( 핀34) RD : 외부테이터메모리를읽을때사용되는스트로브신호출력단자로사용 PG0( 핀33) WR : 외부데이터메모리에쓸때사용되는스트로브신호출력단자로사용 1.5. ATmega128 의메모리 ATmega128 의메모리는프로그램메모리와데이터메모리가분리된하바드구조로프로그램메모리는 128K바 이트의크기로 ISP 가가능한플래쉬롬이내장되어있다( 메모리맵은그림 3 의좌측참조). 데이터메모리는램과 EEPROM 으로나뉠수있는데그림3 의우측은데이터메모리의램의 2 가지가능한메모리맵구조를보여준다. 그림 3. ATmega128 의메모리맵( 출처: ATMEL) 플래시프로그램메모리 : 그림3 의좌측에보여진것처럼 16비트단위로접근가능한 64K바이트의주소공간 (0000 번지에서 FFFF 번지) 을갖는플래시롬이프로그램메모리로내장되어있다. 데이터메모리 : 데이터메모리는크게램과롬으로나뉠수있고램은그림3 의우측에보여진것처럼 32바 이트의범용레지스터 (0000번지에서 001F 번지), 64바이트의 I/O 레지스터, 그리고 4K의 SRAM이내장되어있고 롬은 EEPROM 으로 10만번쓰기가가능한 4K 바이트가내장되어있다. 그림3의우측에보여진것처럼이전의구 형 ATmega103 모델과의호환성을유지하기위하여 (4K - 100) 바이트의맵을사용하는 configuration B와내 장된 4K 바이트전부를사용하는 configuration A 모드( 노말모드) 를지원한다. 그림3의우측에보여진것처럼 60K 바이트까지외부램의연결이가능하다. 1.5.1. 프로그램메모리 구성 : 128K바이트의 10000 번까지쓰기가가능한플래시롬으로그림3의좌측에보여진것처럼 16비트단위 로접근가능한 64K 바이트의주소공간 (0000 번지에서 FFFF 번지) 을갖는다. 부트로더섹션과응용프로그램섹션 으로나뉠수있다. 역할 : 16비트또는 32비트구조로되어있는각명령어가프로그램메모리에 1~2개의번지를차지하며저장 - 7 -

된다. 프로그래밍 : SPI 통신방식을이용한 ISP 에의하여프로그램을쓰거나, JTAG 에뮬레이터를사용하거나병렬 프로그래밍모드를이용하여프로그램을쓸수있다. 1.5.2. 데이터메모리 : 범용레지스터 구성 : 그림 3과 4와같이 32바이트로내부메모리의 00번지에서 1F 번지를차지한다. 역할 : 8051의 A레지스터와같은 ALU가따로있지않고 32개가모두 ALU역할을하여기본적인사칙연산을 수행하고일부의상수데이터를사용하는연산명령은 R16-R31 에서수행한다. 1.5.2.1. X,Y,Z 레지스터 그림 4. 범용레지스터 ( 출처:ATMEL) 그림 4,5와같이 R26-R31 은각각 2개씩합쳐져서 3개의 16비트레지스터인 X,Y,Z 레지스터로사용될수있 다. 이들은데이터메모리의 16비트주소를간접지정하는포인터로사용되며 Z 레지스터 (R30, R31 의쌍) 는 LPM, ELPM, SPM 명령에서메모리값에접근할때사용한다. 그림 5. XYZ 레지스터 ( 출처:ATMEL) 1.5.3. 데이터메모리 : I/O 레지스터 그림 3과 6에서처럼 64바이트로구성되며내장된각종 I/O 장치를제어하기위한레지스터로 IN, OUT 명령을 사용하여입출력장치에접근한다. 이들은그림 6의괄호에표시한것처럼 0x20번지에서 0x5F번지까지존재하지 만 IN, OUT 명령을사용할때는그림 6에표시한것처럼 0x00에서 0x3F 로지칭해야한다. 0x00(0x20) 번지에서 0x1F(0x3F) 번지에위치하는 32개의레지스터는 CBI, SBI, SBIC, SBIS 명령을사용하여비트어드레싱이가능하 다. - 8 -

1.5.3.1. 상태레지스터 (SREG) 그림 6. ATmega128 의 I/O 레지스터 ( 출처:ATMEL) 상태레지스터 (SREG:Status REGister) 는 ALU의연산후상태와결과를표시하는레지스터로 8051의 PSW에 해당한다. - 9 -

비트7(I : Global Interrupt Enable) : 전체인터럽트를허용하도록설정하는비트로 SEI 및 CLI 명령으로이 비트를제어할수있다. 인터럽트처리가시작되면자동적으로클리어되고 RETI 명령을만나면원래상태로복구 된다. 개별인터럽트의허용은인터럽트마스크레지스터로설정한다. 비트6(T : Bit Copy Storage) : BLD, BST 명령을사용하여어느레지스터의한비트값의복사가가능하다. 비트5(H : Half Carry Flag) : 산술연산의가감산에서비트3에서올림수가발생하면 1 로세트. BCD 연산에 사용하며 8051 PSW레지스터의 AC 에해당한다. 비트4(S : Sign Bit) : 플랙 N과 V의 XOR(eXclusive OR) 값으로정수들의크기를판단할때사용한다. 비트3(V : 2's Complement Overflow Flag) : 2 의보수연산에서오버플로를표시한다. 비트2(N : Negative Flag) : 연산결과값의최상위비트가 1로되어 2의보수표현을사용하는경우연산결과 가음수임을표시한다. 비트1(Z : Zero Flag) : 연산결과값이 0 이되었음을표시한다. 비트0(C : Carry Flag) : 연산으로자리올림이나자리내림이발생하면 1 로세트된다. 8051 PSW레지스터의 CY 에해당한다. 1.5.3.2. 스택포인터 (SP) 서브루틴이나인터럽트호출시이들을처리하고다시본래위치로되돌아오기위한복귀주소인프로그램카운 터(PC) 값의 SRAM 내의스택위치, push 또는 pop할 SRAM 내의스택위치를표시한다. C프로그램에서지역변수 를저장하거나어셈블리프로그램에서임시데이터를저장하는용도로도사용한다. 초기값은 0x0000인데사용자프로그램에서 SP의초기값은적어도 0x0100 번지이상의값으로설정한다. PC값이저장될때는 SP값이 1만큼증가하고증가된 SP 값이가리키는내부램에하위바이트 (PCL) 가먼저저장 되고다시 SP값이 1만큼증가하고증가된 SP 값이가리키는내부램에상위바이트 (PCH) 가저장된다. push와 pop은 1바이트데이터만이대상이되는데 push 명령이내려지면 1바이트데이터를저장하기전에먼 저 SP값이 1만큼증가하여증가된 SP값이가리키는 SRAM내에데이터가저장되고 pop 명령이내려지면현재 SP값이가리키는내부램에서 1바이트데이터를꺼낸후에 SP값이 1 만큼감소한다. 1.5.3.3. RAMPZ(RAM Page Z select) 레지스터 Z 레지스터 (R30, R31 의쌍) 로 LPM, ELPM, SPM 명령을사용해메모리값에접근할때 RAMPZ0=1 로하면 0x8000 에서 0xffff 에접근하고 RAMPZ0=0 로하면 0x0000 에서 0x7fff 에접근할수있다. 1.5.4. 데이터메모리 : 확장 I/O 레지스터 ATmega128 에추가된각종 I/O를제어하기위한레지스터로 160 바이트 (0x60에서 0xff 번지) 로 I/O레지스터처 럼 IN, OUT 명령을사용할수없고 LD, LDS, LDD, ST, STS, STD 명령어로접근해야한다( 그림7 참조). 1.5.5. 데이터메모리 : 내부 SRAM 구성 : ATmega128 은 4K의 SRAM 이내장되어있다. 그림3 의우측에보여진것처럼이전의구형 ATmega103 모델과의호환성을유지하기위하여 (4K - 100) 바이트의맵을사용하는 configuration B와내장 된 4K 바이트전부를사용하는 configuration A 모드( 노말모드 ) 를지원한다. 노말모드의경우 0x0100 에서 0x10ff 번지를점유한다. 접근법 : LS, LDS, LDD 또는 ST, STS, STD의명령을사용하여 16비트직접데이터에의한번지값을지정 하여접근하거나 역할 X,Y,Z 레지스터를사용하여간접지정으로접근한다. : 프로그램에서사용되는사용자변수의저장영역이나스택영역으로사용된다. - 10 -

1.5.6. 데이터메모리 : EEPROM 그림 7. ATmega128 의확장 I/O 레지스터 ( 출처:ATMEL) ATmega128 은 EEPROM 으로 10만번쓰기가가능한 4K 바이트가내장되어있는데내부램, I/O, 확장 I/O 레 지스터와는별개의주소가할당되어있어 EEPROM 용주소레지스터 (EEARH, EEARL), 데이터레지스터 (EEDR), - 11 -

제어레지스터 (EECR) 를이용해접근한다. 1.5.6.1. EEAR 레지스터 EEAR 의비트12 에서비트 15 : 항상 0 으로읽히며향후버젼을위해유보되어있는비트들이다. EEAR 의비트11(EEAR11) 에서비트0(EEAR0) : 읽고쓸 EEPROM 의 4K 바이트의주소지정에사용된다. 초기 값은부여되지않고임의의값이될수있다. 항상 EEPROM 에접근하기전에주소값을지정하도록한다. 1.5.6.2. EEDR 레지스터 쓰기의경우에는 초기값은 0x00 이다. 1.5.6.3. EECR 레지스터 비트7-비트 4 : 유보된비트들이다. EEAR 의주소에쓰여질값을임시로저장하거나읽기의경우에는읽힌값을저장한다. 비트3(EERIE : EEPROM Ready Interrupt Enable) : 1로설정되면 EEWE 비트가 0이될때 EEPROM Ready 인터럽트를발생하는기능을가진다. 비트2(EEMWE : EEPROM Master Write Enable) : EEWE를 1로설정할때 EEPROM에쓰기가가능하도록 허용할지여부를결정한다. 비트1(EEWE : EEPROM Write Enable) : EEMWE 가 1로설정되면 EEWE 가 1로되고나서 4클록사이클이 내에 EEDR의데이터를 EEAR이가리키는 EEPROM 의주소에쓴다. 쓰기가완료되면 EEMWE는자동적으로 0 이된다. 비트0(EERE : EEPROM Read Enable) : EEPROM의읽기스트로브로서 EEAR 레지스터에적절한주소값이 부여된경우 EERE를 1로해야 EEPROM 읽기가시작될수있다. 1.5.6.4. EEPROM 쓰기과정 다음의과정을거쳐쓰기가이루어지는데쓰기가수행되고나면 CPU는다음명령을실행하기전에 2클럭동 안멈추고 EEPROM 쓰기는 CPU 가플래시메모리에쓰기를할때는불가능하다. 1EEWE 가 0 일될때까지기다린다. 2SPMCSR 레지스터의 SPMEN비트가 0 이될때까지기다린다. 3쓰기할 EEPROM 주소를 EEAR 레지스터에저장한다. 4쓰기할 EEPROM 데이터를 EEDR 레지스터에저장한다. 5EECR레지스터의 EEMWE는 1로 EEWE는 0 으로설정한다. 64클럭사이클이내에 EEWE 를 1 로설정한다. 그리고쓰기가수행된다. 위의쓰기과정에서 3, 4는순서가바뀌어도상관없다. 5, 6 과정중에인터럽트가발생되면 EEMWE 의동작 제한시간이초과되어쓰기동작이실패하게되므로이를방지하기위해 의 I비트를 0 으로설정하여인터럽트발생을금지시켜야한다. 3-6 과정동안에는상태레지스터 SREG EEPROM 쓰기과정중에파워다운슬립모드에진입하면파원다운슬립모드에제대로진입하지못하게되므 로파워다운모드에진입하려면 EEPROM 쓰기가완료되었는지를확인해야한다. 전원전압이낮은동안에는 EEPROM 데이터가손상될수있다. 이를방지하기위해내부 Brown-out 감지기 를작동하게하고전원전압이낮아지면리셋되도록하드웨어를구성하는것도괜찮다. 1.5.6.5. EEPROM 읽기과정 1EEWE 가 0 일될때까지기다린다. - 12 -

2읽기할 EEPROM 주소를 EEAR 레지스터에저장한다. 3EECR레지스터의 EERE를 1 로설정한다. 4EEPROM 데이터를 EEDR 레지스터로부터읽는다. 1.5.7. 외부데이터메모리 ATmega128 은노말모드에서 0x1100-0xffff 번지에외부데이터메모리로사용가능하며이들은외부램, 외부 플래쉬롬또는 LCD나 AD 변환기와같은주변장치의인터페이스용으로사용할수있다. 이를위해다음과같은 기능이제공된다. 1 주변장치와적절한인터페이스를위한 0-3 의대기사이클을지정할수있다. 2 2 개의섹터로외부데이터메모리를분할하고이들에독립적인대기사이클을지정할수있다. 3 16 비트주소의상위바이트에중필요한갯수의비트만을주소버스로동작하게할수있다. 4 데이터버스의신호들이동작할때전류소비량이감소되도록 1.5.7.1. 외부메모리인터페이스 외부램연결을위한핀 : MCUSR 레지스터를이용해서설정한다. 1 PA7~PA0( 핀44~ 핀51) : 8051의포트0 처럼하위주소와데이터버스로사용된다. 2 PC7~PC0( 핀35~ 핀42) : 8051의포트2 처럼상위주소버스로사용된다. Bus-keeper 기능을설정할수있다. 3 ALE(Address Latch Enable, PG2, 핀43) : 외부메모리에접근할때 PA에서출력되는하위주소값을래치할 수있도록 CPU에서 1 레벨값을출력해준다. 4 RD( PG1, 핀34) : 외부테이터메모리를읽을때사용되는스트로브신호출력단자로사용 5 WR (PG0, 핀33) : 외부데이터메모리에쓸때사용되는스트로브신호출력단자로사용 외부램연결블록선도 : 그림 8 은외부램과의연결을보여준다. 외부램읽기( 쓰기) 과정 : 그림 8. 외부램의연결( 출처:ATMEL) 1외부램읽기명령이내려지면 ALE신호가 1레벨이되고 Port A(AD7:0) 는하위주소버스로하위주소값을 내보내고 Port C(A15:8( 는상위주소버스로페이지값을출력시킨다. 2ALE 가 1레벨인동안하위주소값은래치되어 ALE가 0 레벨이된후에도래치에값이보존된다. 3읽기신호 RD ( 쓰기신호 WR) 가 0레벨로변하여활성상태로되면 4외부램의 Output Enable( 혹은 Write Enable) 이활성화되고외부램의데이터값이 Port A를통해 CPU로 읽혀지도록 ( 램에쓰여지도록 ) 한다. ( 외부램과의인터페이스는기본적으로 3클럭사이클에수행되나소프트웨어적 으로 1-3 개의여분의대기사이클을줄수도있다.) - 13 -

1.5.7.2. MCUCR 레지스터 MCUCR(MCU Control Register) 레지스터는 CPU의전체적인기능을설정하는데비트7과 6을사용해서외부 데이터메모리영역을설정할수있다. 비트7(SRE:external SRAM/XMEM Enable) : 1로세트하면 PA7-PA0( 핀44- 핀51), PC7-PC0( 핀35- 핀42), ALE(PG2, 핀43), RD( PG1, 핀34), WR(PG0, 핀33) 핀들을외부메모리와인터페이스를위한핀들로설정하게 되고 0 으로하면병렬포트로동작하도록한다. 비트6(SRW10:Wait-state Select Bit for Upper Sector) : 외부메모리와인터페이스할때외부데이터의 Upper 섹터에부여하는여분의대기사이클의수를 XMCRA 레지스터의 SRW11 비트와조합되어설정한다. [SRW11:SRW10]=00 일때대기사이클은 0 개, 01일때 1 개, 10일때 2 개, 11일때 3 개를준다. 1.5.7.3. XMCRA 레지스터 XMCRA(eXternal Memory Control Register A) 레지스터는외부데이터메모리영역을분할하거나대기사이 클의수를설정할수있다. 비트6(SRL2)~ 비트4(SRL0) : 외부데이터메모리영역을 Lower 와 Upper 2개의섹터로분할하여각섹터에 별도로대기사이클의수를설정할수있도록한다. 그림 9. SRL2-SRL0 를이용한메모리분할( 출처:ATMEL) 비트3~ 비트2(SRW01~SRW00:Wait-state Select Bit for Lower Sector) : 외부메모리와인터페이스할때 외부데이터의 Lower 섹터에부여하는여분의대기사이클의수를설정한다. [SRW01:SRW00]=00 일때대기 사이클은 0 개, 01일때 1 개, 10일때 2 개, 11일때 3 개를준다. 비트1(SRW11:Wait-state Select Bit for Upper Sector) : 외부메모리와인터페이스할때외부데이터의 Upper 섹터에부여하는여분의대기사이클의수를 XMCRA 레지스터의 SRW11 비트와조합되어설정한다. [SRW11:SRW10]=00 일때대기사이클은 0 개, 01일때 1 개, 10일때 2 개, 11일때 3 개를준다. 1.5.7.4. XMCRB 레지스터 XMCRB(External Memory Control Register B) 레지스터는버스키퍼기능을설정하고외부메모리주소의상 위바이트에서어느부분까지가주소지정에사용되는지를설정한다. 비트7(XMBK:eXternal Memory Bus-Keeper enable) : 1로세팅되면 PA7-PA0( 핀44-핀 51) 의값들이보존 되는버스키퍼기능을활성화시킨다. 비트6~ 비트4 : 유보된비트들이다. 비트2~ 비트0(XMM2~0 : external Memory high Mask) : 60K이하의외부메모리를사용하는경우상위주소 버스로사용되는 port C의일부분만이주소버스로사용되도록하고나머지는입출력포트로설정하는데사용된 - 14 -

다. 만약 [XMM2:XMM1:XMM0]=111 로하면포트 C 모두를입출력포트로설정하고, 110이면 PC0와 PC1만을 주소버스로설정하고, 101이면 PC0~PC2, 100이면 PC0~PC3, 011이면 PC0~PC4, 010이면 PC0~PC5, 001이 면 PC0~PC6 을주소버스로설정하고, 000이면포트 C 모두를주소버스로설정한다. 1.5.8. 메모리 lock 비트 메모리의보호를위해설정하는데사용하는 1바이트구조의비트로디폴트로비트값이 1로되어있고프로그램 하면 0으로설정되고 chip erase명령에의해 1 로환원된다. 그림 10은 lock 비트의구성을보여준다. 그리고그림 11은 lock 비트값에따른모드설정값과각모드에따른메모리보호기능을보여준다. 그림 10. Lock bit 의구성( 출처:ATMEL) 그림 11. Lock bit 설정에따른기능 ( 출처:ATMEL) - 15 -

1.5.9. 퓨즈비트 ATmega128 의기본적인설정용으로사용되며 Extended Fuse, Fuse High, Fuse Low바이트로모두 3개의 바이트로구성되어있다. 디폴트로비트값이 1로되어있고프로그램하면 0으로설정되고 chip erase 명령에의해 영향을받지않으므로메모리 Lock비트의 LB1을 0 으로하여퓨즈비트를변경할수없도록할수있다. 퓨즈비 트를먼저설정하고메모리 Lock 비트를설정해야한다. 1.5.9.1. Extended Fuse Byte 비트1~0 만사용하여 ATnega103 과호환모드의설정, Watchdog 타이머동작의설정에사용한다. 비트1(M103C) : 디폴트상태로는 0으로설정되어 ATmega13 과호환모드로되어있다. 1로프로그램하면노 말모드로 ATmega128 의고유기능을전부활용할수있다. 비트0(WDTON: WatchDog Timer ON) : 디폴트상태로는 1로설정되어워치독타이머기능이동작하도록 한다. 1.5.9.2. Fuse High Byte 비트7(OCDEN:On Chip Debug enable) : 디폴트상태로는 1로설정되어 On chip debug 를허용한다. 비트6(JTAGEN : JTAG ENable) : 디폴트상태로는 1로설정되어 JTAG 를허용한다. 비트5(SPIEN : SPI Enable) : 디폴트상태로는 1로설정되어 SPI 를통한직렬프로그래밍을허용한다. 비트4(CKOPT) : 클럭옵션을설정한다 (1.6 절참조). 비트3(EESAVE) : 디폴트상태로는 1로설정되어 Chip Erase 할때 EEPROM 의내용을보호한다. 비트2~1(BOOTSZ1~0) : 부트사이즈를선택하는데사용한다 ( 그림12 참조). 비트0(BOOTRST) : Reset vector 의선택에사용한다. 디폴트상태로는 1로설정되어 0x0000 번지를리셋주 소로하고 0이면그림 12 에주어진값을리셋주소로사용한다. 1.5.9.3. Fuse Low Byte 그림 12. 부트사이즈의선택( 출처:ATMEL) 비트7(BODLEVEL) : 디폴트상태로는 1로설정되어 Brown Out Detector 의기능을레벨값에따라트리거되 도록설정한다. 비트6(BODEN: Brown Out Detector ENable) : 디폴트상태로는 1로설정되어 Brown Out Detector 의기능 을허용한다. 비트5~4(SUT1~0) : Start up 시간을설정한다 (1.6~7 절참조). 디폴트상태로는 10 의값을갖는다. 비트3~0(CKSEL3~0) : 클럭소스를설정한다 (1.6 절참조). 디폴트상태로는 0001의값을갖고있어디폴트 상태로는 1MHz 의내부 RC 발진기를통한클록을사용하도록설정되어있다. - 16 -

1.6. 시스템클록과슬립모드 1.6.1. 클록분배 그림13 에보여진것처럼 ATmega128 은다양한소스에의해클록을발생시키고분배가가능하다. 또한내부의 각부분은모두동시에클록이필요치않아소비전력을절약시키기위해개별적으로공급을차단할수도있다. CPU 클록( ) : 범용레지스터, 상태레지스터, 데이터메모리와같은 AVR 핵심적인동작과관련된클록으 로공급을차단하면이들의동작을멈추게한다. I/O 클록( ) : 타이머, SPI, USART 등 I/O 모듈대부분에서사용되는클록이다. 외부인터럽트모듈에서도 사용되나일부외부인터럽트는 I/O 클록의공급이차단되어도인터럽트처리가된다. 플래쉬클록 ( ) : 플래쉬롬과의인터페이스를제어하며보통 CPU 클록과동시에사용된다. 비동기타이머클록 ( ) : 외부 32kHz 수정발진기를소스로하는비동기타이머용클록이다. AD 변환기클록( ) : AD변환기용의클록으로 CPU와 I/O클록을정지시키고 AD변환을이루어지도록하 여노이즈를줄일수있도록한다. 1.6.2. 클록발생과선택 그림 13. ATmega128 의클록분배( 출처:ATMEL) 5가지의클록발생원이존재하며 CKSEL3~0 와 SUT1~0, XDIV레지스터를이용하여클록발생원과주파수를설 정한다. 1.6.2.1. 내부 RC( 디폴트클록 ) 발진기 XTAL1, XTAL2 단자의연결 : 내부발진기를사용하므로 XTAL1, XTAL2 에는아무것도연결하지않는다. CKOPT 의설정 : 퓨즈하이바이트의비트4 CKOPT 를 1 로설정해야한다. - 17 -

CKSEL3~0 의설정 : 퓨즈로우바이트의비트3~0(CKSEL3~0) 의값들을 0001로하면 1MHz, 0010으로하 면 2MHz, 0011로하면 4MHz, 0100으로하면 8MHz 의클록을사용한다. 디폴트상태로는 0001의값을갖고 있어디폴트상태로는 1MHz 의내부 RC 발진기를통한클록을사용하도록설정되어있다. SUT1~0 의설정 : 퓨즈로우바이트의비트5~4(SUT1~0) 의값들을 11로설정하는것은유보되어있고나머 지값들(00,01,10) 으로하면기동시간이 6 클럭으로설정된다. 또한 00로의설정은 BOD(Brown Out Detector) 사용에권장되고, 01로하면리셋의경우추가적으로 4.1 ms의지연이발생하고 Fast rising power 사용에권 장되고, 10로하면리셋의경우추가적으로 65ms 의지연이발생하고 slowly rising power 사용에권장된다. 내부발진기를통해발생되는클럭은주파수가부정확하므로확장된 I/O레지스터인 OSCCAL(OSCillator CALibration) 레지스터를조정해서사용한다. OSCCAL 의값이 0x00이면 CKSEL3~0 으로설정한값의 50%~100% 의주파수값이클록으로사용되며, 0x7F이면 75%~150%, 0xFF이면 100%~200% 의주파수값이클 록으로사용된다. 1.6.2.2. 외부 RC 발진기 XTAL1, XTAL2 단자의연결 : 그림 14와같이연결하고커패시터의값은적어도 22pF 이상으로한다. 발진주파수 그림 14. 외부 RC 발진기의연결( 출처:ATMEL 사) : 클럭의주파수값은 로결정된다. CKOPT 의설정 : 0으로설정하면내부의 36pF 커패시터가사용되므로그림 18의커패시터 C를연결하면안 된다. CKSEL3~0 의설정 : 그림 15참조 SUT1~0 의설정 : 그림 16 참조. 그림 15. 외부 RC 발진기동작모드 ( 출처:ATMEL) 그림 16. 외부 RC 발진기의기동시간선택( 출처:ATMEL) - 18 -

1.6.2.3. 외부수정발진기 XTAL1, XTAL2 에수정이나세라믹 resonator 를연결하여사용하는경우이다. XTAL1, XTAL2 단자의연결 : 그림 17과같이연결하고커패시터의값은그림 18 을참조한다. CKOPT 의설정 : 그림 18 참조. 그림 17. 외부수정발진기의연결( 출처:ATMEL) CKSEL3~0 의설정 : 그림 18과 19 참조 그림 18. 외부수정발진기동작모드 ( 출처:ATMEL) SUT1~0 의설정 : 그림 19 참조. 1.6.2.4. 저주파수정발진기 그림 19. 수정발진기의기동시간선택( 출처:ATMEL) XTAL1, XTAL2 에저주파수수정을연결하여사용하는경우이다. XTAL1, XTAL2 단자의연결 : 그림 17과같이연결하고수정은 32.768kHz 를사용한다. CKOPT 의설정 : 0으로설정하면내부의 36pF 커패시터가사용되므로그림 14의커패시터들을연결하면안 - 19 -

된다. CKSEL3~0 의설정 : 1001 로설정한다. SUT1~0 의설정 : 그림 20 참조. 1.6.2.5. 외부클록 그림 20. 저주파수정발진기의기동시간선택( 출처:ATMEL) XTAL1, XTAL2 단자의연결 : 외부의클럭신호를 XTAL1 단자에연결하고 XTAL2 단자는비워둔다. CKOPT 의설정 : 0으로설정하면내부의 36pF 커패시터가사용된다. CKSEL3~0 의설정 : 0000 으로설정한다. SUT1~0 의설정 : 퓨즈로우바이트의비트5~4(SUT1~0) 의값들을 11로설정하는것은유보되어있고나머 지값들(00,01,10) 으로하면기동시간이 6 클럭으로설정된다. 또한 00로의설정은 BOD(Brown Out Detector) 사용에권장되고, 01로하면리셋의경우추가적으로 4.1 ms의지연이발생하고 Fast rising power 사용에권 장되고, 10로하면리셋의경우추가적으로 65ms 의지연이발생하고 slowly rising power 사용에권장된다. 유의점 : 클럭주파수가 2% 이상변동하면시스템의동작이불안정해지므로변동이없도록해야한다. 1.6.2.6. XDIV 레지스터를이용한클럭주파수조정 XDIV(Xtal DIVide) 레지스터를이용하여클럭발생원을 2~129 로분주한주파수값을시스템클럭으로사용할 수있도록설정할수있다. 비트7(XDIVEN:Xtal DIVide ENable) : 1 로설정되면클럭발생원의주파수값(clk) 을 XDIV6~0 의값으로설정 한 d 값을이용하여다음의공식에따라모든클럭의주파수값 (f) 으로설정한다. 비트6~0(XDIV6~0) : 클럭주파수의분주비를설정한다. 1.6.3. Sleep 모드 전원을절약할수있는 그림 21. 슬립모드의설정( 출처:ATMEL) 6 가지의다양한슬립모드가제공된다. MCUCR 레지스터를설정하여모드를선택하고 SLEEP 명령을실행하여슬립모드에돌입하도록한다. - 20 -

1.6.3.1. MCUCR 레지스터를이용한모드설정 MCUCR(MCU Control Register) 의비트5(SE), 비트4,3,2(SM1,SM0,SM2) 를이용해모드를설정한다. 비트5(SE:Sleep Enable) : 디폴트는 0으로 1로세트되면 SLEEP 명령시슬립모드의돌입이허용한다. 비트4,3,2(SM1,SM0,SM2) : 그림 21 과같은형태로값을조절하여모드를설정할수있다. 1.6.3.2. Idle 모드 CPU의동작은멈추지만 SPI, USART, 아날로그비교기, ADC, TWI, 타이머, 워치독, 인터럽트의동작은유지 된다. 클럭은차단되지만나머지클럭은공급된다. 1.6.3.3. ADC noise reduction 모드 CPU의동작은멈추지만 ADC, TWI, 타이머 0, 워치독, 인터럽트의동작은유지된다. 클럭은차단되지만나머지클럭은공급된다. ADC가잡음에영향을덜받아서정밀하게동작할수있도록하는모 드로 ADC의동작이활성화된경우 ADC noise reduction 모드로의돌입은 ADC 변환이자동으로시작된다. 1.6.3.4. Power-down 모드 외부수정발진기또는세라믹 resonator 의동작이정지되며 TWI, 워치독, 인터럽트의동작은유지된다. 모든 클럭이차단되어비동기모듈의동작만이가능하다. 이모드가해제될때는클럭이안정적으로되기위해충분한 여유기동시간이필요한데이를사용자가지정할수있다. 1.6.3.5. Power-save 모드 Power-down 모드와유사하나 ASSR 레지스터의 AS0비트를 1로설정하여타이머0을 TOSC1, TOSC2 단자로 입력되는외부클럭에의하여비동기로동작시킬때사용하는것이다른점이다. 클럭을제외한모든클 럭이차단된다. 1.6.3.6. Standby 모드 외부수정발진기또는세라믹 resonator 을클럭발생원으로한경우에만가능한슬립모드로 Power-down 모드 와유사하나발진기가동작하는것이다르다. 해제되어정상동작이개시되는데 6 개의클럭사이클만이소요된다. 1.6.3.7. Extended Standby 모드 외부수정발진기또는세라믹 resonator 을클럭발생원으로한경우에만가능한슬립모드로 Power-save 모드 와유사하나발진기가동작하는것이다르다. 해제되어정상동작이개시되는데 6 개의클럭사이클만이소요된다. 그림 22. 슬립모드의동작요약( 출처:ATMEL) - 21 -

1.6.3.8. 슬립모드의동작요약 동작 : MCUCR 의 SE를 1로세트하고 SM2~0 을그림 21에따라모드를설정하고 SLEEP 명령어를실행시킨 다. 6개의동작모드 Idle, ADC noise reduction, Power-down, Power-save, Standby, Extended Standby 동 작요약은그림 22 에주어졌다. 인터럽트에의한해제 : 슬립모드안에서인터럽트를만나면 MCU가동작을시작하고슬립모드가해제되는데 기동시간이외에 4사이클이더경과한후에동작이개시되고인터럽트서비스를다실행하고슬립모드에돌입하 도록한이전의 SLEEP 명령의바로뒤에이어지는명령으로복귀된다. 해제된모든레지스터와메모리에있는 내용은슬립모드이전의값이보존된다. 리셋에의한해제 : 슬립모드에서리셋이발생하면슬립모드가해제되고리셋동작이수행된다. 1.7. Reset 과 Watchdog 타이머 1.7.1. 리셋 정상적으로동작하고있는마이컴이리셋되면모든 셋벡터에서시작된다. 리셋은 5 가지의발생원이존재한다. I/O레지스터값이디폴트값으로초기화되고프로그램은리 그림 23. 리셋관련내부회로블록선도 ( 출처:ATMEL) - 22 -

1 파워온리셋 : 공급전원이그림 24에정의된 이하일때리셋되는것. 2 외부리셋 : RESET핀에 50ns 이상동안그림 24에정의된 이하의신호가입력되면리셋되는것 3 Brown-out 리셋 : 공급전원이 2마이크로초이상동안그림 24에정의된 이하로떨어져 Brown-out 감 지기가작동해리셋되는것. 4 워치독리셋 : 워치독타이머가지정한주기이상이경과되어워치독기능이동작할때리셋되는것 5 JTAG AVR 리셋 : JTAG 이연결되어있고 JTAG 명령 AVR_RESET 명령에따라선택된 JTAG 리셋레지스 터에논리 1이저장되어있는경우리셋되는것 1.7.1.1. 파워온리셋 (POR) 전원투입후제대로리셋이되지않으면 그림 24. 리셋관련변수( 출처:ATMEL) PC와레지스터들이제대로초기화되지못하여마이컴은임의의위 치에서명령을시작하게되는데이를막기위해전원투입후자동으로리셋이되도록하는것을파워온리셋이 라한다. POR회로는 벨로올라가지못하고그림 보다공급전원이작으면동작이시작되는데공급전원이투입되고나서곧바로정상적인레 25처럼 보다작으므로 POR회로가작동되어파워온리셋동작이시작되고공 급전원이 에도달하면시간지연카운터를동작시켜일정한시간 동안리셋을유지시킨다. 1.7.1.2. 외부리셋 그림 25. 파워온리셋동작타이밍도 ( 출처:ATMEL) RESET핀에 50ns 이상동안그림 24에정의된 이하의신호가입력되면리셋이시작되는데그림 26에 서처럼리셋신호가저전압을유지하다가 이상으로올라가면시간지연카운터를동작시켜일정한시간 - 23 -

이부가적으로경과될때까지리셋을유지시킨다. 1.7.1.3. Brown-out 리셋 그림 26. 외부리셋동작타이밍도 ( 출처:ATMEL) 마이컴내부에있는저전압검출회로 (BOD:Brown-Out Detector) 가공급전원이 2마이크로초이상동안그림 24에정의된 이하로떨어지면발생된다. 그림 27의동작타이밍도처럼발생하는데전압스파이크에의한오동작을줄이기위해히스테리시스특성을 갖도록하여전압이감소하여 이하로될때리셋동작이시작되고전압이증가하여 이상으로된후시간지연카운터를동작시켜일정한시간 이부가적으로경과될 때까지리셋을유지시킨다. 그림 27. 저전압검출리셋동작타이밍도 ( 출처:ATMEL) BOD 기능은 1.5.9절에설명된 Fuse Low byte의 BODEN 비트를 1로하여활성화시킬수있고 BODKEVEL 비트에따라그림 1.7.1.4. 워치독리셋 24 처럼설정할수있다. 워치독타이머가지정한주기이상이경과되면그림 28처럼 1클럭사이클의리셋펄스가발생하여리셋동작이 시작되고리셋펄스가끝나면시간지연카운터를동작시켜일정한시간 이부가적으로경과될때까지리셋을 유지시킨다. 그림 28. 워치독리셋동작타이밍도 ( 출처:ATMEL) - 24 -

1.7.1.5. MCUCSR 레지스터 MCUCSR(MCU Control and Status Register) 레지스터는마이컴의리셋발생원에대한정보를제공한다. 비트4(JTRF:JTAG Reset Flag) : JTAG 리셋이발생한경우 1 로세트된다. 파워온리셋이나 0을써넣음으로 써클리어된다. 비트3(WDRF:Watch Reset Flag) : 워치독리셋이발생한경우 1 로세트된다. 파워온리셋이나 0을써넣음으 로써클리어된다. 비트2(BORF:Brown-Out Reset Flag) : Brown-out 리셋이발생한경우 1 로세트된다. 파워온리셋이나 0을 써넣음으로써클리어된다. 비트1(EXTRF:EXTernal Reset Flag) : 외부리셋이발생한경우 1 로세트된다. 파워온리셋이나 0을써넣음 으로써클리어된다. 비트0(PORF:Power-On Reset Flag) : 파워온리셋이발생한경우 1 로세트된다. 파워온리셋이나 0을써넣 음으로써클리어된다. 1.7.2. 워치독타이머 1.7.2.1. 워치독타이머의구성 역할 : 프로세서가안정적으로동작하는지감시하는기능을수행한다. 프로세서에이상이생겨일정시간마다 워치독타이머가리셋되지않게되는경우시스템을리셋시켜마이컴의안정적인동작을보장하도록한다. 워치 독타이머의리셋은 WDR 명령을실행하거나워치독의동작을금지시키거나마이컴이리셋된는경우리셋된다. 구성 : 그림 29처럼구성되어마이컴내부의 RC발진기와는별개로내장되어있는워치독발진기와그곳에서 만들어지는 1MHz 클럭을받아이를 8 가지로분주하는워치독프리스케일러, WDTCR레지스터의설정값에따 라마이컴리셋을발생시키는논리회로로구성된다. 1.7.2.2. WDTCR 레지스터 그림 29. 워치독타이머의구성( 출처:ATMEL) 비트4(WDTOE:WatchDog Turn-Off Enable) : 디폴트값은 0 이다. WDE비트가 0일때 1 로세트되어야한다. 그렇지않으면워치독은비활성화된다. 1로세트되면 4 클록이지난후에하드웨어적으로클리어된다. 안전레벨 1과 2에서프리스케일러비트를바꾸는경우 1 로세트되어야한다. 비트3(WDE:WatchDog Enable) : 디폴트값은 0 이다. 1로세트되면워치독타이머가활성화되고 0으로클리 어되면비활성화된다. WDE는 WDCE 비트가 1 로세트된경우에만클리어될수있다. - 25 -

비트2~0(WDP2~0: Watch-Dog timer Prescaler2~0) : 디폴트값은 0 이다. 워치독타이머가활성화된경우 프리스케일러를그림 30 처럼설정한다. 1.7.2.3. 워치독의설정 그림 30. 워치독타이머프리스케일러의설정( 출처:ATMEL) 워치독타이머의안전레벨설정 : 1.5.9.1 절에소개된 Etended Fuse Byte의비트들값으로안전레벨0, 1, 2 로그림 31 에보여진것처럼설정할수있다( 퓨즈의비트값들은프로그램되면 0이되고프로그램되지않으면 1). 그림 31. 워치독타이머의설정( 출처:ATMEL) 안전레벨0 : ATmega103 과호환모드로그림 31 에보여진것처럼초기에는워치독이금지되어있다. WDE를 1 로세트하면워치독이허용된다. WDP2~0를바꿔즉프리스케일러의값을바꿔타임아웃주기를변경시키는 것에는제한이없으나워치독타이머를비활성화시키려면다음의과정을거쳐야한다. 1WDTCR 레지스터에동시에 WDCE=1, WDE=1 로세트시킨다. 2 4클록사이클이내에 WDE=0 으로클리어시킨다. 안전레벨 1 : 디폴트상태이다. 그림 31 에보여진것처럼초기에는워치독이금지되어있다. WDE를 1로세트 하면워치독이허용된다. WDP2~0 를바꿔즉프리스케일러의값을바꿔타임아웃주기를변경시키거나워치독 타이머를비활성화시키려면다음의과정을거쳐야한다. 1WDTCR 레지스터에동시에 WDCE=1, WDE=1 로세트시킨다. 2 4클록사이클이내에 WDE비트와 WDP2~0 비트에원하는값을쓴다. 안전레벨 2 : 그림 31에보여진것처럼초기에워치독이허용되어있고 WDE가 1로세트되어있고워치독을 비활성화시킬수없다. WDP2~0 를바꿔즉프리스케일러의값을바꿔타임아웃주기를변경시키려면다음의과 정을거쳐야한다. 1WDTCR 레지스터에동시에 WDCE=1, WDE=1 로세트시킨다. 2 4클록사이클이내에 WDCE=0 으로클리어시키고 WDP2~0 비트에원하는값을쓴다. - 26 -

2.1. 명령어분류와주소지정방식 명령어기본형식 2. ATmega128 시스템개발기초 : 명령어는명령코드 (OP 코드:OPeration code) 와오퍼랜드 (operand) 로구성되는데명령코 드는명령그자체이고오퍼랜드는명령의대상으로레지스터, 메모리, 상수값이사용될수있으며명령에따라 오퍼랜드없이명령코드에포함되는경우가있다. 명령코드는대부분 16비트의길이이지만 LDS, STS, JMP, CALL 4개의명령어는 32 비트이다. 실행시간에따른분류 : 실행하는데 1~4 기계사이클를요구하여 1 1 기계사이클명령어( 예: ADD Rd, Rr) 와 2 2 기계사이클명령어( 예:ADIW Rdl, K) 33 기계사이클명령어 ( 예:ELPM 혹은 LPM) 44기계사이클명령어 ( 예:RETI 혹은 RET) 로나뉠수있다. 기능에따른분류 : 데이터전송, 산술과논리연산, 분기, 비트조작, MCU 제어명령으로나눌수있다. 1 데이터전송명령 : 내부램이나외부램의데이터전송을위한명령으로 MOV, MOVW, LDI, LD, LDD, LDS, ST, STD, STS, LPM, ELPM, SPM, IN, OUT, PUSH, POP 등 16 가지가관계된다. 2 산술과논리연산명령 : 가감산, 증감, 곱하기등산술연산과논리연산명령어로 ADD, ADC, ADIW, SUB, SUBI, SBC, SBCI, SBIW, AND, ANDI, OR, ORI, EOR, COM, NEG, SBR, CBR, INC, DEC, TST, CLR, SER, MUL, MULS, MULSU, FMUL, FMULS, FMULSU 등 28 가지가관계된다. 3 분기명령 : 조건을따져분기하거나프로그램의실행순서를바꾸는명령으로 RJMP, IJMP, JMP, RCALL, ICALL, CALL, RET, RETI, CPSE, CP, CPC, CPI, SBRC, SBRS, SBIC, SBIS, BRBS, BRBC, BREQ, BRNE, BRCS, BRCC, BRSH, BRLO, BRMI, BRPL, BRGE, BRLT, BRHS, BRHC, BRTS, BRTC, BRVS, BRVC, BRIE, BRID 등이관계된다. 4 비트조작명령 : 1비트값에대한비트조작불리안연산명령으로 SBI, CBI, LSL, LSR, ROL, ROR, ASR, SWAP, BSET, BCLR, BST, BLD, SEC, CLC, SEN, CLN, SEZ, CLZ, SEI, CLI, SES, CLS, SEV, CLV, SET, CLT, SEH, CLH 등이관계된다. 5 MCU 제어명령 : NOP, SLEEP, WDR, BREAK 등 4개의 MCU 제어관련명령 오퍼랜드의주소지정방식 1 직접상수지정방식 : 오퍼랜드로서상수값을사용하는방식이다. 2 I/O 직접주소지정방식 : 오퍼랜드로서 64개의 I/O 레지스터의주소값을직접지정한다. 3 레지스터직접주소지정방식 : R0~R31 이오퍼랜드로서지정된다. 4 데이터직접주소지정방식 : 오퍼랜드로서데이터메모리영역의 16 비트주소값을직접지정한다. 5 데이터간접지정방식 : 오퍼랜드의주소를저장하고있는 X,Y,Z 레지스터를이용하여간접적으로지정한다. 6 선증가데이터간접지정방식 : 데이터간접지정방식과비슷하나 X,Y,Z레지스터값을먼저 1 만큼감소시킨다. 7 증가시킨다. 후증가데이터간접지정방식 : 데이터간접지정방식과비슷하나 X,Y,Z 레지스터값을명령실행후에 1만큼 8 9 변위데이터간접지정방식 : 데이터간접지정과비슷하나 Y,Z 레지스터값에변위값을합하여사용한다. 프로그램메모리상수지정방식 : Z 레지스터를사용하여프로그램메모리영역의상수값을지정한다. 10 실행후에 후증가프로그램메모리상수지정방식 : 프로그램메모리상수지정방식과비슷하나 Z레지스터값을명령 1 만큼증가시킨다. - 27 -

2.2. 명령어요약 다음은 ATmega128 의명령을요약한것으로항목에서 #clocks 은수행에걸리는기계사이클, Flags 은명령수 행으로영향을받는 CSEG 의비트를의미한다. 그리고다음의정의들이사용된다. 표 7. 어셈블리명령에쓰인약자의의미 Rd Destination register R0~R31 Rr Source register R0~R31 b, s 바이트데이터의비트번호값 0~7 P I/O 레지스터주소값 (0-31/63) K 8비트상수값 k,q 상수 Rdl R24, R26, R28, R30. X Indirect address register R27:R26 Y Indirect address register R29:R28 Z Indirect address register R31:R30 분기명령 MCU 제어명령 그림 32. 분기명령모음 ( 출처:ATMEL) 그림 33. MCU 제어명령모음 ( 출처:ATMEL) - 28 -

데이터전송명령 그림 34. 데이터명령모음( 출처:ATMEL) 산술과논리연산명령 그림 35. 산술과논리연산명령모음( 출처:ATMEL) - 29 -

비트조작명령 2.2.1. 어셈블리어의일반형태 어셈블리어의일반형태는아래와같다. 그림 36. 비트조작명령모음 ( 출처:ATMEL) [ 라벨 + : + 1 개이상의공백 ] + 명령어( 혹은지시어) + [1 개이상의공백 + ; + 주석] ( 예: START: LDI AL, 0b10000000 ;AL에이진수 10000000 값을넣어라. ) 라벨 (Label) 은기호주소로분기명령이나참조에사용되는심볼(Symbol) 로 1 심볼과바로뒤에공백없이 : ( 콜론) 을두고콜론과명령어는 1 개이상의공백을두어야한다. 2 어셈블러 ( 어셈블리어를기계어로바꾸어주는 프로그램 ) 에따라다르지만길이는보통 1에서수십개까지의기호가허용되고 AVR Studio4 에서심볼은영문자 와숫자와특수문자 (_) 의조합을사용하고처음은반드시숫자가아닌기호( 영문자나 _) 로시작해야한다. 3 R0-R31 과같은어셈블러특수심볼그리고명령어와지시어등예약어는심볼로사용될수없고 4 심볼은보 통명령어, 지시어와함께대문자와소문자의구분이없다(AVR Studio4 에서구분을하게옵션설정가능). 주석은반드시앞에 ;( 세미콜론 ) 을붙여야하는데어셈블러는세미콜론과같은줄에존재하며세미콜론뒤쪽에 존재하는글은주석으로여기고모두무시한다. 2.2.2. 지시어 ( 의사명령 ) 지시어란기계어로번역되지않고어셈블러에게어떤정보만을제공하는것으로의사명령이라고불린다. CSEG DSEG : 프로그램메모리에해당하는코드세그먼트의시작을정의한다. 파라메터를갖고있지않다. : SRAM 데이터메모리세그먼트의시작을정의한다. 파라메터를갖고있지않다. ESEG : EEPROM 데이터메모리세그먼트의시작을정의한다. 파라메터를갖고있지않다. EQU :.EQU +1 개이상의공백 + 심볼 +1 개이상의공백 + 상수값의형태로어떤심볼의값을정의하는데 사용된다. EQU 를사용하면숫자로된값대신에기억하기쉬운심볼을사용하여프로그램을쉽게할수있다. 어셈블러에서는기계어로번역할때라벨을상수값으로대체하여해석하게된다. 한번할당된값은수정되거나 다시정의될수없다. 예 :.EQU BUF= 0x20 ; 기계어로번역시 BUF는 0x20 으로대체된다. - 30 -

SET : EQU 와유사하나나중에다시정의되어수정가능하다. DEF :.DEF +1 개이상의공백 + 심볼 +1 개이상의공백 + 레지스터이름의형태로기억하기쉬운심볼에 레지스터를할당하여프로그램을쉽게할수있다. 나중에다시정의되어수정가능하고같은레지스터에여러 가지심볼을할당할수있다. 예 :.DEF BUF= R0 ; BUF 는 R0 UNDEF :.UNDEF +1 개이상의공백 + 심볼의형태로심볼에레지스터를할당한것을해제한다. 예 :.UNDEF BUF ; BUF 를해제 ORG :.ORG +1 개이상의공백 + 주소의형태로바로뒤에오는프로그램명령어의시작번지나데이터의시 작번지지정에사용된다. 주소로는숫자뿐만아니라라벨도사용될수있다. 다음과같은프로그램의경우명령 어 LDI AL, 0b10000000 와그이후의명령은프로그램메모리의 20 번지를시작으로차례로저장된다. 예 :.CSEG.ORG 0x0020 START: LDI AL, 0b10000000 ;AL에이진수 10000000 값을넣어라.... BYTE : 심볼 +: +1 개이상의공백 +.BYTE +1 개이상의공백 + 숫자의형태로 SRAM 데이터세그먼트에 숫자만큼의메모리를바이트단위로예약해둔다. 예 : CNT:.BYTE 1 ;CNT 을위해 1 바이트를유보해두라. DB (Define Byte) : 라벨 +: + 1 개이상의공백 +.DB +1 개이상의공백 + 데이터의형태로 1 바이트(8 비트) 단위로숫자나문자데이터들을프로그램메모리나 EEPROM 세그먼트에저장할때사용한다. 예 :.ESEG DATA: DB 1, 2, 'S' ; 라벨 DATA 번지에 1을 DATA+1 에 2를 DATA+2 에 S' 를저장. DW (Define Word) : 라벨 +: + 1 개이상의공백 +.DW +1 개이상의공백 + 데이터의형태로 1 워드(2바이 트,16 비트) 단위로숫자나문자데이터들을프로그램메모리나 EEPROM 세그먼트에저장할때사용한다. DD (Define Doubleword) : 라벨 +: + 1 개이상의공백 +.DD +1 개이상의공백 + 데이터의형태로 2워드 (4 바이트, 32 비트) 단위로숫자나문자데이터들을프로그램메모리나 EEPROM 세그먼트에저장할때사용한다. DQ (Define Quadword) : 라벨 +: + 1 개이상의공백 +.DQ +1 개이상의공백 + 데이터의형태로 4 워드(8 바이트, 64 비트) 단위로숫자나문자데이터들을프로그램메모리나 EEPROM 세그먼트에저장할때사용한다. INCLUDE :.INCLUDE + 1 개이상의공백 +"+ 파일이름 + 의형태로외부의파일을 include하여어셈블할 때사용한다. IF :.IF + 1 개이상의공백 + 조건식의형태로조건식을만족하면아래부분를어셈블한다. ELIF :.ELIF + 1 개이상의공백 + 조건식의형태로앞선 IF의조건을만족시키지않는다른조건을판단할 때사용하며주어진조건식을만족하면아래부분를어셈블한다. IFDEF :.IFDEF + 1 개이상의공백 + 심볼의형태로심볼이정의되어있으면아래부분을어셈블한다. IFNDEF :.IFNDEF + 1 개이상의공백 + 심볼의형태로심볼이정의되지않았으면아래부분을어셈블한다. ELSE ENDIF : IF, IFDEF, IFNDEF 와같은조건문에서이전조건이만족되지않으면아래부분을어셈블한다. :.ENDEF 의형태로조건블록의마지막을표시한다. ENDM 혹은 ENDMACRO :.ENDM 혹은.ENDMACRO 의형태로마크로를정의를종료할때사용한다. MACRO :.MACRO + 1 개이상의공백 + 마크로이름의형태로마크로를정의할때사용한다. 마크로는 @0~@9 로지정된 10개까지의파라메터가사용될수있고마크로를호출할때는아래의예에서처럼마크로이 름다음에공백을두고해당파라메터를차례로, 를사용해나열하면된다. 예 :.MACRO SUBL16 ; Start macro definition - 31 -

ERROR :.WARNING + 1 개이상의공백 +" 주의문장 의형태로어셈블시주의문장을출력하고어셈블을중지한다. 예 :.IFDEF EXPTEST WARNING :.WARNING + 1 개이상의공백 +" 주의문장 의형태로어셈블시주의문장을출력하나 ERROR 처럼어셈블을중지하지는않는다. 예 :.IFDEF EXPTEST 2.2.3. 숫자, 문자, 연산자 오퍼랜드로상수값을사용할때는반드시진법표현을명확히해야한다. 2진수의경우에는 0b를앞에붙여주 고( 예: 0b00000000), 16진수의경우에는 0x 혹은 $ 를붙여주고, 8진수의경우 O 를붙여주고, 10진수의경우에 는아무런표시도하지않는다. 문자상수값은반드시앞뒤에반드시따옴표 ( ) 를붙여준다. 문자열의경우에는큰따옴표를사용한다. 오퍼랜드에사용되는수식의연산자에는산술연산자, 논리연산자, 비교연산자, 조건연산자가있다. 산술연산자로 +( 더하기 ), -( 빼기), /( 나누기 ), *( 곱하기), %( 나머지가정수가되도록나눈나누기연산의나머지 값을결과로내놓는 mode 연산), <<( 오른쪽으로이동), >>( 왼쪽으로이동) 이있다. 논리연산자로!(NOT), &&( 논리곱 ), ( 논리합 ), ~( 비트단위 NOT), &( 비트단위 AND), ( 비트단위 OR), ^( 비 트단위 exclusive OR) 이쓰인다. 비교연산자로 == ( 동치),!= (Not Equal), < (Less Than), <= (Less than or Equal to), > (Greater Than), >= (Greater than or Equal to) 가있다. 조건연산자로아래와같은형식으로사용하며삼항연산자로보통불린다. 조건식이참이거나 0이아니면식 1을처리하고거짓이거나 0이면식2 를처리하라는의미이다. 변수 = ( 조건)? 식1 : 식2; 2.2.4. 함수 LOW(x) : x 의하위바이트값을돌려준다. HIGH(x) : x의 2 번째바이트값을돌려준다. BYTE2(x) : x의 2 번째바이트값을돌려준다. BYTE3(x) : x의 3 번째바이트값을돌려준다. BYTE4(x) : x의 4 번째바이트값을돌려준다. LWRD(x) : x의비트 15~0 값을돌려준다. HWRD(x) : x의 4 번째바이트값을돌려준다. PAGE(x) : x의비트 16~21 값을돌려준다. EXP2(x) : 값을돌려준다. - 32 -

LOG2(x) : 값의정수부를돌려준다. INT(x) : x 의정수부분을돌려준다. FRAC(x) : x 의소수부분을돌려준다. Q7(x) : x를 FMUL/FMULS.FMULSU 명령에적절한형태의부호있는 1 바이트수로변환한다. Q15(x) : x를 FMUL/FMULS.FMULSU 명령에적절한형태의부호있는 1 바이트수로변환한다. ABS(x) : x 의절대값을돌려준다. DEFINED(x) : x라는심볼이정의된경우 1 을돌려준다. 2.3. AVR Studio4 AVR Studio 는 ATMEL 사(http://www.atmel.com) 에서개발한 AVR용의소프트웨어개발툴로현재 Ver 4.13.528 이나와있어윈도우즈에기반한통합개발환경을제공한다. 에뮬레이터와시뮬레이터를동시에사용할 수있고어셈블러를제공한다. 만약에 AVRISP, JTAG ICE, STK500, ICE40, ICE50 등의에뮬레이터가 PC의직 렬포트에접속되어있으면에뮬레이터로동작하고그렇지않으면시뮬레이터로동작한다. 2.3.1. 새프로젝트등록과실행파일만들기 1 초기화면 : AVR Studio Ver 4.13.528 을 http://www.atmel.com 에서내려받아설치하고실행하면그림 37 과같은초기화면이뜬다. 상단에 [File], [Project], [Build], [View], [Tools], [Debug], [Help] 메뉴가있고 [New Project], [Open] 등의메뉴를갖는 Welcome to AVR Studio 4라는이름의작은창이있고그이외에 I/O View, Message 라는이름의작은창이있다. 그림 37. AVR Studio 의초기화면 - 33 -

2 New Project 실행 : Welcome to AVR Studio 4 라는이름의작은창의메뉴 [New Projct] 를클릭하면 그림 38 과같은창이뜨게된다. 이창에서프로젝트형태( 어떤어셈블러를사용할것인가를결정), 프로젝트이 름, 어셈블리어파일이름, 파일들이위치할디렉토리를결정할수있다. 그림 38. New Project 의실행 3 프로젝트의설정 : 그림 39와같이메뉴에서 Project type로 Atmel AVR Assember 을선택하고 Project name 와 Initial File, Location 은적절한값으로설정한다 ( 여기에서는각각 hhchoi, hhchoi, C:\Documents and Settings\GX620\My Documents\avr\at128 로설정했다 ). 그러면그림 39 처럼 [Next] 메뉴가활성화된다. 그림 39. 프로젝트의설정 - 34 -

4 Debug 플랫폼과디바이스설정 : Project name 와 Initial File, Location 은적절한값으로설정하고 [Next] 메뉴를누르면그림 40 과같이디버그플랫폼과디바이스를설정하는창이뜬다. Debug platform 은 AVR Simulator 를선택하고 Device는 ATmega128 을선택하고마지막으로 [Finish] 메뉴를누른다. 그림 40. 디버그플랫폼과디바이스의설정 5 에디터창생성 : 디버그플랫폼과디바이스를설정하고 [Finish] 메뉴를누르면그림41 과같이프로젝트설 정단계에서지정한어셈블리파일의코드를작성할수있는파일이름을갖는에디터창과 그만창이뜬다. Project 라는이름의조 그림 41. 프로젝트등록의최종결과로생긴에디터창 - 35 -

6 Build 실행 : 어셈블리파일의코드를작성한이후에메인창의 [Build] 메뉴를그림 42처럼선택하여실행시킨다. 그림 42. Build 실행 7 에러없이종료된결과 : 그림 43 은에러없이실행파일이만들어진경우를보여준다. Build 라는이름의창에실행파일을생성한결과가보여진다. 그림 43. 성공적으로실행파일이만들어진결과 - 36 -

8 에러가있을때결과 : 그림 44 는실행파일을만드는과정에서문법적인에러가발생한경우를보여준다. Build 창에에러가발생한행번호와에러메시지가나타나있음을알수있다. 에러메시지부분을더블클릭하면에 러가발생한위치로커서가자동적으로이동하여손쉽게에러를수정할수있게한다. 2.3.2. 디버깅과시뮬레이션 그림 44. 에러가있을때결과 1 Debug 선택 : 문법적인에러가없어실행파일이만들어진경우그림 45 과같이 [Debug->Start Debugging] 메뉴를선택하면디버깅과간단한시뮬레이션을할수있다. 그림 45. [Debug->Start Debugging] 메뉴 - 37 -

2 Debug 시작 : 디버그세션을시작하면 46과같이 I/O View창이 I/O레지스터의값들을비트별로그래픽하게확인할수있도록변하고에디터창에노란화살표가나타난다. 그림 46. Debug 세션의시작 3 View->Register 실행 : 디버그세션에서메인메뉴의 [View->Register] 를실행하면그림 47처럼 Register 라는이름의창이뜬다. 디버깅하며값이바뀌는 R0~R31 레지스터의값이 Register 창에나타난다. 그림 47. 디버그세션에서메인메뉴 [View->Register] 의실행 - 38 -

4 View-> Memory 실행 : 디버그세션에서메인메뉴의 [View->Memory] 를실행하면그림 48처럼 Memory 라는이름의창이뜬다. 그창에는그림 48 에보여진것처럼 [Data], [EEPROM], [Extended I/O], [I/O], [Program], [Register] 의서브메뉴가있는데이를이용하여 SRAM 데이터메모리, EEPROM, I/O레지스 터, 프로그램메모리, R0~R31 레지스터의값중특정한어느하나를선택하여변화를모니터할수있다. [View->Memory] 와같은역할을하는 [View->Memory2], [View->Memory3] 메뉴가더존재한다. 그림 48. 디버그세션에서메인메뉴 [View->Memory] 의실행 5 View-> Watch 실행 : 디버그세션에서메인메뉴의 [View->Watch] 를선택하면 Watch라는자그만창이 뜨는데그림 49처럼 Name 에레지스터나심볼값을입력하고이들값의변화를모니터할수있다. 그림 49. 디버그세션에서메인메뉴 [View->Watch] 의실행 - 39 -

6 디버그세션에서여러가지메뉴 : 디버그세션에서메인메뉴 [Debug] 의하위메뉴에는그림 50처럼여러 가지가있는데이중 [Run to Cursor] 메뉴는브레이크포인트또는커서가놓인곳까지실행하도록한다. [Step Into] 는한명령씩실행하도록하며 [Step Over] 는서브루틴콜도한명령수행처럼수행하도록하고 [Auto Step] 는 Studio4 에서알아서적당한지점까지실행한다. 디버그세션에서메인메뉴의 [Goggle Breakpoint] 를선 택하면커서가놓인곳을브레이크포인트로설정하거나해제한다. 그이외에다양한메뉴를활용해손쉽게디버깅 할수있다. 그림 50. [Debug] 메뉴의하위메뉴들 2.4. AVR 의 ISP 2.4.1. 마이컴시스템개발방법 2.4.1.1. ICE (In Cricuit Emulator) 를이용하는법 ICE 의역할 : 개발중인 Target System 의마이컴역할을임시적으로대신해주도록타겟시스템과동일한마 이컴을내장한시스템 연결 : 타겟시스템의마이컴을빼고그자리에 ICE의출력핀을꼽고한편 ICE는호스트컴퓨터와도연결된 다. 동작 : 소스코드프로그램을호스트컴퓨터에서 PK51 과같은소프트웨어개발툴을사용해서디버깅하고실행 파일을만들어 ICE에다운로드시키면 ICE는자신의램에저장하고그프로그램을자신의마이컴으로실행시키 는데그핀들이출력핀으로타겟시스템마이컴핀자리에대신들어가있어결국타겟시스템의마이컴역할을 수행한다. 특징 : ICE 는싱글스텝동작, 역어셈블링, 브레이크기능등고기능으로시스템개발용에가장편리한장비이 나고가로교육용에는부적합하다. 2.4.1.2. ROM Emulator 를이용하는법 롬에뮬레이터의역할 : 개발중인타겟시스템의프로그램메모리역할을임시적으로대신해주는마이컴시스 - 40 -

템 연결 : 타겟시스템의프로그램메모리를빼고그자리에롬에뮬레이터출력핀을꼽고한편호스트컴퓨터와 도연결된다. 동작 : 소스코드프로그램을호스트컴퓨터에서 PK51 과같은소프트웨어개발툴을사용해서디버깅하고실행 파일을만들어롬에뮬레이터에다운로드시키면롬에뮬레이터는자신의램에저장하고롬에뮬레이터출력핀들이 타겟시스템프로그램메모리핀자리에대신들어가있으므로결국타겟시스템의롬역할을수행한다. 특징 : Z80, 8031과같이프로그램메모리가외장형인경우에는적절한개발방법이될수있으나롬이내장된 8051 과같은형태는일부러롬을장착해야하므로하드웨어적으로복잡해지는단점이있다. 롬에뮬레이터는롬을 대신하는것이라 ICE 에비해저가의시스템이다. 2.4.1.3. ROM Writer 를이용하는법 롬라이터의역할 : 실행파일를 PROM 에기록해주는마이컴시스템 연결 : 타겟시스템의롬을빼서( 롬내장형마이컴의경우에는마이컴을뺀다) 퓨터와연결한다. 롬라이터에장착하고호스트컴 동작 : 소스코드를호스트컴퓨터에서 PK51 과같은소프트웨어개발툴을사용해서디버깅하고실행파일을만 들어롬라이터에다운로드시키면롬라이터는장착된롬에프로그램을기록하고기록이다끝나면롬을빼서타 겟시스템에장착하고프로그램을실행한다. 특징 : 프로그램을교체할때마다타겟시스템의롬을빼어, 롬소거, 롬기록, 다시롬의장착과실행을되풀 이해야하므로엄청난시간과노력이소모되며실행하며타겟시스템에서의상황을모니터하기어려워디버깅도 힘이드나 ICE 나롬에뮬레이터에비해롬라이터는저가이다. 2.4.1.4. 외부 RAM 을이용하는법 외부램의역할 : 타겟시스템에여분의외부램을장착하고이를개발할프로그램을위한메모리로사용 연결 : 롬에호스트컴퓨터와통신을위한모니터프로그램이기록된타겟시스템과호스트컴퓨터를연결한다. 호스트컴퓨터에서타겟시스템과통신을위한터미널프로그램으로는윈도우기본프로그램중하나인하이퍼터미 널이널리이용된다. 동작 : 소스코드를호스트컴퓨터에서 터미널과같은터미널프로그램을사용하여 템은이를외부램에저장하고이를실행한다. 소프트웨어개발툴을사용해서디버깅하고실행파일을만들어하이퍼 모니터프로그램이기록된타겟시스템에다운로드시키면타겟시스 특징 : 호스트컴퓨터인 PC 의통신용소프트웨어 ( 예: 하이퍼터미널 ) 를통해타겟시스템과통신할수있고실 행상황을모니터할수있어값싸고실용적인방법이나일부러램을장착하고미리모니터프로그램을기록해야 하는등이불편하다. 교육용으로많이사용된다. 2.4.1.5. ISP 를이용하는법 ISP 의역할 : AVR은내장플래시롬의 SPI (Serial Peripheral Interface) 인터페이스를제공한다. SPI는오직 3라인을이용한통신방법으로 MOSI(Master Out Slave In), MISO(Master In Slave Out), SCLK(Serial CLocK) 신호를이용한다. Motolora 에서개발되었으며 Master와 Slave가 SCLK에동기하여데이터를교환하는 방식으로마이컴의 RST( 리셋) 핀을 0으로한상태에서앞의세시그널을이용하여플레시롬의데이터를읽고 쓰기가가능하다. 즉내부에롬라이터와같은기능을하는부분이내장되어있어내부플래시롬을롬라이터없이 읽고쓰기가가능하므로 SPI가지원되면따로롬라이터를이용하지않고도 PCB 기판상에마이컴을실장하고 전원과클럭이공급되는상태에서프로그래밍이가능한 연결 : 타겟시스템과호스트컴퓨터를값싼 동작 : 소스코드를호스트컴퓨터에서 ISP (In System Programming) 기능이제공된다. ISP 용인터페이스를사용하여연결한다. PK51 과같은소프트웨어개발툴을사용해서디버깅하고실행파일을만 - 41 -

들어호스트컴퓨터에설치한 ISP용소프트웨어를통해 PCB 기판상에마이컴을실장하고전원과클럭이공급 되는상태에서프로그래밍한다. 특징 : 약간의회로추가로시스템의디버깅이용이하고업그레이드가쉬운시스템을만들수있다는장점이 있다. AT89S8252, AT89Sxx 나 AVR처럼내부에플래시롬이내장되어있고 SPI를지원하는마이컴을사용해야 하며부피가커지고제품단가가올라간다는단점이있다. 2.4.2. AVR ISP 용다운로더 2.4.2.1. AVR Studio 와 ATAVRISP Atmel 사의 AVR Studio4 는 AVR 마이컴의프로그램을개발하고디버깅할수있는윈도우기반의소프트웨어개 발툴로통합개발환경을제공하는데 AVR뿐만아니라 AT89S51 과 AT89S52 의플래시롬을프로그래밍하는 ISP기 능도지원한다. AVR Studio 를이용한 ISP를위해서는 Atmel 사의 ATAVRISP 라는직렬통신케이블을사용해야 하는데 ATAVRISP 는호스트컴퓨터인 PC의시리얼포트와실장된마이컴의 SPI신호핀간의 RS-232직렬인터페이스 를제공한다. AVR Studio 는 Atmel 사의홈페이지인 http://www.atmel.com 에서공짜로다운로드받을수있는반 면에 ATAVRISP 는구입해야한다. 2.4.2.2. Atmel AVR ISP 프로그래머 Atmel사의 AVR ISP 프로그래머는 AVR 마이컴의내장플래시롬을 ISP하기위한윈도우즈기반의소프트웨어로 MCS-51 호환기종인 AT89S8252 와 AT89S53 의 ISP 도가능하다. AVR ISP 프로그래머를이용한 ISP는호스트컴 퓨터인 PC의프린터포트와타겟시스템마이컴의 SPI신호핀간인터페이스회로가필요한데그림 51과같이 74HC244 가들어가있어신호를제어하는매우간단한회로면충분하다. 여기에서 ISP CON은 PCB 기판상에 실장되어전원과클럭이공급되는상태에서 AVR 과연결한다. AVR의 ISP를할때는딥스위치를 on으로하여 VCC에서공급되는전원을 74HC244 에넣어작동시키고 ISP를다끝낸경우에는딥스위츠를 off로하여 74HC244 를꺼버려 PC 와마이컴의연결을차단한다. 그림에서 LED는 ISP가진행중일때불이들어와알리는기 능을하는것으로프린터포트 8 번핀(D6), 74HC244 의 4번과 16 번핀, LED 와저항은굳이연결안해도된다. AVR ISP는 Atmel 사의홈페이지인 http://www.atmel.com 에서공짜로다운로드받을수있다. 그림 51. Atmel AVR ISP, PonyProg2000, CodevisonAVR 용의 ISP 인터페이스회로 2.4.2.3. PonyProg2000 PonyProg2000 은윈도우즈기반의직렬통신을통한여러다양한마이컴과 PROM 을읽고쓰기위한공짜소프트 웨어로 http://www.lancos.com 에서무료로다운로드가능하다. PonyProg2000 는원래직렬통신을위한것이지 만그림 51에주어진 Atmel AVR ISP용인터페이스회로를사용해서 PC의프린터포트와타겟시스템마이컴의 SPI신호핀간에연결해도되고 http://www.lancos.com 에주어진직렬포트용인터페이스회로를사용해도된다. - 42 -

2.4.2.4. Codevisin AVR 비교적저렴한수십만원대의컴파일러로 2K바이트까지용량제한이있는평가판을인터넷에서자유롭게다운로 드받아서사용가능한 Codevision AVR C 컴파일러와그림 51의 ISP용인터페이스회로를사용해서 ISP가가능 하다. 연결할때 ISP CON의 VCC는 AVR의 VCC 와, ISP CON의 SCK는 AVR 마이컴의 SCK PB1(SCK, 핀11), ISP CON의 MOSI 는 AVR의 PE0(PDI/RXD0, 핀9), ISP CON의 MISO는 PE1(PDO/TXD0, 핀8), ISP CON의 RST는 AVR의 RESET ( 핀20) 과연결한다. 프로그램다운로드하는과정은다음절에서설명할것이다. 2.5. Codevision AVR C 컴파일러 AVR용 C 컴파일러들 : 다음과같은 3 가지정도가많이사용된다. 1 IAR사의 EWAVR C 컴파일러 : 수백만원대의고가의컴파일러이지만상대적으로뛰어난압축률과안정된 기능을내장하고있어산업현장에서많이사용되고있다. 2K바이트까지용량제한이있는평가판을인터넷에서 자유롭게다운로드받아서사용가능하다. 2 AVRGCC 컴파일러 : 기본적으로 text환경에서동작하도록만들어진꽁짜의컴파일러이나 ANSI C언어와다 른점이많은편이라 ANSI C 언어에익숙한사람은불편함을느낄수있다. 3 HPinfotech 사의 Codevision AVR C 컴파일러 : 비교적저렴한수십만원대의컴파일러로 ANSI C언어의모 든구성요소와거의가깝게구현되어있다. 2K바이트까지용량제한이있는평가판을 HPinfotech 사의홈페이지 http://www.hpinfotech.ro 에서자유롭게다운로드받아서사용가능하다. Codevision AVR C 컴파일러의특징은다음과같다. 1 AVR Studio4 와연계하여디버깅이가능하다. 2 ISP 다운로더프로그램을내장하였다. 3 프로그램을자동으로생성할수있는 CodeWizardAVR 를내장하였다. ANSI C언어의표준라이브러리이외에캐릭터 LCD, 필립스 I2C 버스, RTC DS1302, EEPROM DS2430, SPI 용, 지연함수등을위한 AVR 에특화된다양한라이브러리를제공한다. 2.5.1. 새프로젝트등록하기와옵션설정하기 1 초기화면 : 평가판을 http://www.hpinfotech.ro 에서내려받은후실행파일 4 setup_eval.exe 을실행하면그 림 52 와같이 [File], [Edit], [View], [Project], [Tools], [Settings], [Windows], [Help] 의메뉴를갖고 CodeVisonAVR 이라는이름을가진초기화면이나타난다. 그림 52. CodevisionAVR Compiler 의초기화면 - 43 -

2 New Project 실행 : [File->New] 메뉴를선택하면 Create New File 이라는작은창이생성된다. 그때그 림 53과같이 project를선택하고 OK 버튼을클릭한다. 그림 53. [File->New] 메뉴의실행과새로운프로젝트생성 3 CodeWizardAVR 사용여부의설정 : Create New File창에서 project를선택하고 OK버튼을클릭하면그림 54와같이 CodeWizardAVR 의사용여부를묻는 Confirm 창이생성되는데 No 를선택한다. CodeWizardAVR 은입 출력포트의방향, AVR 칩의종류와주파수, 외부인터럽트, 타이머, AD 변환기, 동기및비동기통신, LCD 등을 대화창을통해쉽게설정할수있는위저드기능을제공하여쉽게프로그램을할수있도록하는데스스로공부 하면쉽게알수있으므로여기에서는설명을따로하지않고일단 여설명한다. CodeWizardAVR 를사용하지않는것으로하 그림 54. CodeWizardAVR 사용여부를설정하기위한창 - 44 -

4 프로젝트이름설정 : CodeWizardAVR 의사용여부를묻는 Confirm 창이생성되어 No를선택하면그림 55 처럼 Create New Project 라는이름의대화상자가생성되는데대화상자내의 [ 저장위치 (I)] 메뉴에서적당한위치를 선택하고자신이원하는프로젝트이름( 예:test) 을 [ 파일이름 (N)] 메뉴의입력창에기입한후에 [ 저장(S)] 버튼을 클릭한다. 그림 55. CodevisionAVR 에서새로운프로젝트이름의설정 5 프로젝트옵션설정하기 : 프로젝트이름을설정( 예:test) 하고나면 [Files], [C Complier], [Before Make], [After Make] 메뉴를갖고있는 Configure Project test.prj 라는이름의대화창이생성된다. 16MHz 의주파수를 사용하는 ATmega128 을대상으로하는경우그림56 처럼설정하면된다. 그림 56. CodevisionAVR 에서프로젝트옵션설정하기 - 45 -

2.5.2. 새소스파일만들기 1 New Project 실행 : 메인창의 [File->New] 메뉴를선택하면 Create New File 이라는작은창이생성된다. 그때그림 57과같이 source 를선택하고 OK 버튼을클릭한다. 그림 57. [File->New] 메뉴의실행과새로운파일생성 2 에디터창생성 : Create New File에서 source 를선택하고 OK버튼을클릭하면그림 58처럼특정디렉토 리명\untitled,c 라는이름을갖는 C 코드를작성할수있는에디터창이뜬다. 그창에파일을작성한다. 작성시 [Navigator], [Code Templates], [Clipboard] 메뉴를활용하면작성을쉽게할수있다. 자세한사항은 [Help] 메 뉴를통해얻을수있다. 그림 58. CodevisionAVR 에서새로운파일의작성 - 46 -

3 Save As 실행 : 소스코드의작성을완료하고메인창의 [File->Save as...] 메뉴를선택하면특정디렉토리 명\untitled,c As 라는이름의대화상자가생성되는데대화상자내의 [ 저장위치 (I)] 메뉴에서적당한위치를선택하 고자신이원하는파일이름( 예: fnd) 을 [ 파일이름 (N)] 메뉴의입력창에기입한후에 [ 저장(S)] 버튼을클릭한다. 그러면본예에서는 at128 에 fnd.c 가저장된다. 그림 59. [File->Save As] 메뉴를통한파일저장 2.5.3. 프로젝트에소스파일등록하고실행파일만들기 1 Configure 실행 : 소스파일은프로젝트에등록이되어야컴파일하고디버깅이가능하다. 그림처럼 CodevisionAVR 을실행해새프로젝트를생성하거나기존의프로젝트를열어놓은상황에서메인창의 [Project->Configure] 를실행하면그림60 과같은 Configure Project 대화창이새롭게생성된다. 그림 60. [Project->Configure] 메뉴의실행 - 47 -

2 Add 실행 : 그림60과같은 Configure Project 대화창에서 [Add] 메뉴를선택하면그림 61과같은 Add File To Project 라는이름의대화창이생성되는데대화상자내의 [ 찾는위치(I)] 메뉴에서적당한위치( 예:at128) 를선 택하고파일이름( 예: fnd) 을 [ 파일이름 (N)] 메뉴의입력창에기입한후에 [ 열기(O)] 버튼을클릭한다. 그림 61. Add메뉴를통한소스파일등록 3 Add 실행결과 : Add File To Project 라는이름의대화창에서파일을등록하면그림 62와같이프로젝트에 등록된결과를 Configure Project 대화창을통해확인할수있다. 다른파일을더등록하려면마찬가지과정을통 해실행한다. 특정파일을프로젝트에서제거하려면 Configure Project 대화창에서파일을선택하고 [Remove] 메 뉴를통해제거하면된다. 본예에서는 at128 디렉토리의 fnd,c 가 test.prj 프로젝트에등록된것을그림 62에서확 인할수있다. 등록을다했으면대화창에서 [OK] 메뉴를누르고나간다. 그림 62. Add메뉴를통한소스파일등록결과 - 48 -

4 Make 실행 : 소스파일을프로젝트에등록을완료한후에그림 63 처럼메인창의 [Project->Make] 메뉴를통해실행파일을생성한다. 그림 63. CodeVisionAVR의 Make 실행 5 에러없이종료된결과 : 그림 64 는에러없이실행파일이만들어진경우를보여준다. Information 이라는이름 의창이생겨 Make 결과를설명한다. 그림 64. CodevisionAVR 에서 Make 의성공적인결과 - 49 -

6 에러가있을때결과 : 그림 65 는실행파일을만드는과정에서문법적인에러가발생한경우를보여준다. Information 창에결과가나타나있고 messages 창에에러가발생한행번호와에러메시지가나타나있음을알수 있다. Information 창의 [OK] 메뉴를클릭하면창이없어지고그림 66 과같이된다. 에러메시지부분을더블클릭 하면에러가발생한위치로커서가자동적으로이동하여손쉽게에러를수정할수있게한다. 그림 65. CodevisionAVR 에서파일에에러가있을때 Make 결과 7 에러수정 : 그림 65에서 Information 창의 [OK] 메뉴를클릭하면창이없어지고그림 66 과같이된다. 에러 메시지부분을더블클릭하면에러가발생한위치로커서가자동적으로이동하여손쉽게에러를수정할수있게 한다. 그림 66. CodeVisionAVR 를이용한문법에러의수정 - 50 -

2.5.4. 디버깅 1 Debugger 설정 : 문법적인에러가없이성공적으로 Make 가되어실행파일이만들어진경우 AVR Studio4 가설치되어있으면이를이용해디버깅과간단한시뮬레이션을할수있다. 그림 68과같이 CodeVisionAVR 메 인메뉴 [Settings->Debuger] 를선택하면 Debugger Settings 라는이름의대화창이생성되는데 AVR Studio4 가 설치된디렉토리와디버거의이름을입력하고 [OK] 메뉴를클릭한다. 그림 67. Debugger 의선택 2 Debug 선택 : 문법적인에러가없어실행파일이만들어진경우 AVR Studio4 가설치되어있으면그림 67과 같이 [Tools->Debugger] 메뉴를선택하면디버깅과간단한시뮬레이션을할수있다. 그림 68. [Tools->Debugger] 메뉴 - 51 -

2 프로젝트선택 : [Tools->Debugger] 메뉴를선택하면그림 69처럼 AVR Studio4가실행되며프로젝트를 선택하기위한 Welcome to AVR Studio4 라는이름의대화창이생성된다. 그림 69. AVR Studio4 의프로젝트선택창 3 cof 파일선택 : Welcome to AVR Studio4 라는이름의창의메뉴 [Open] 을클릭하면그림 70과같은 Open Project File or Object File 이라는이름의대화창이생성된다. [ 파일이름(N)] 메뉴에디버깅하려하는파일 을 Make 하여생성된파일들중에서 extension 이 cof 로끝나는파일을선택한다. 본예에서는 fnd.c 를 make 하였 으므로 fnd.cof 를선택한다. 그리고 [ 열기(O)] 메뉴를더블클릭한다. 그림 70. cof파일의선택대화창 - 52 -

4 프로젝트생성 : cof 파일을선택하면그림 71과같은 Save AVR Studio Project File이라는이름의대화 창이생성된다. 적당한이름을 [ 파일이름 (N)] 메뉴의입력창에쓰고 [ 저장(S)] 메뉴를클릭한다. 그림 71. 디버깅을위한프로젝트생성 5 Debug 플랫폼과디바이스설정과디버깅하기 : 적절한프로젝트이름을설정하고나면그림 40과같이디 버그플랫폼과디바이스를설정하는창이뜬다. Debug platform 은 AVR Simulator 를선택하고 Device 는 ATmega128 을선택하고마지막으로 [Finish] 메뉴를누른다. 그러면그림72 처럼디버그세션이시작되고 /O View창이 I/O레지스터의값들을비트별로그래픽하게확인할수있도록변하고에디터창에노란화살표가나타 난다. 이이후의과정은 2.3.2 절을참조하면된다. 그림 72. CodeVisionAVR 에서 AVR Studio4 를이용한디버깅화면 - 53 -

2.5.5. 플래쉬롬 ISP 프로그래밍하기 1 Programmer 설정 : 프록그램의시뮬레이션까지끝내어완벽해진경우 ATmega128 의프로그램메모리에 ISP 를통해프로그램을다운로드해야한다. CodeVisonAVR 의메인메뉴 [Settings->Programmer] 를선택하면그 림 73 과같은대화창이생성된다. 그림 51의병렬 ISP 인터페이스회로를사용하는경우 [AVR Chip Programmer Type] 는그림 73처럼 STK200+/300 으로선택하고 [Print Port] 는 ATmega128 과연결된병렬포 트를선택한다. 그림 73. AVR Chip 프로그래머설정화면 2 Programmer 실행 : 프로그래머의설정이이루어졌으면 CodeVisonAVR 의메인메뉴 [Tools-> Chip Programmer] 를선택한다. 그러면그림 74와같은 CodeVisionAVR Chip Programmer 이라는이름을갖는대화 창이생성된다. 그림 74. CodeVisionAVR 의칩프로그래머대화창 - 54 -

3 rom 파일선택 : CodeVisionAVR Chip Programmer 이라는이름을갖는대화창이생성된다. 대화창의메 뉴 [File->Load FLASH] 를선택하면그림 75와같은 Load File to FLASH Buffer 이라는이름의대화창이생성 된다. [ 찾는위치(I)] 메뉴에서파일이존재하는위치( 예:at128) 를선택하고 make 를통해만들어진 rom이나 hex, bin 파일이름( 예: fnd.rom) 을 [ 파일이름 (N)] 메뉴의입력창에기입하거나선택한후에 [ 열기(O)] 버튼을클릭한다. 그림 75. 다운로드할 rom이나 hex 혹은 bin 파일의선택 4 erase chip 실행 : 그림 51의병렬 ISP 인터페이스회로와 ATmega128 시스템이연결되어있고전원이들 어간상태에서다운로드할 hex파일을선택한다음 CodeVisionAVR Chip Programmer 대화창의메뉴 [Program->Erase Chip] 를선택하면그림 76과같은 FLASH Erasure checking 창이생성되고새로써넣기전 에 Flash 롬의내용을지운다. 그림 76. 플래시롬을지우는과정을보여주는창 - 55 -

5 프로그램다운로드 : 위의과정을거친다음 CodeVisionAVR Chip Programmer 대화창의메뉴 [Program->Frash] 를선택하면그림 77과같은 Verifying the FLASH programming 창이생성되고플래쉬롬에 프로그램이다운로드된다. 2.5.6. EEPROM ISP 프로그래밍하기 그림 77. 프로그램의다운로드과정을보여주는창 1 Programmer 실행 : CodeVisonAVR 의메인메뉴 [Tools-> Chip Programmer] 를선택한다. 그러면그림 74와같은 CodeVisionAVR Chip Programmer 이라는이름을갖는대화창이생성된다. 2 EEPROM 파일로드 : CodeVisionAVR Chip Programmer 대화창의메뉴 [File->Load EEPROM] 으로화 일을선택해서로드하거나 [Edit->EEPROM] 을선택해 Edit EEPROM Buffer 이라는이름을갖는대화창을생성 시키고직접편집을한다. 3 다운로드 : 위의과정을거친다음 Chip Programmer 대화창의메뉴 [Program->EEPROM] 를선택하면 그림 76, 77과비슷한 EEPROM programming 창과 Verifying the EEPROM programming 창이차례대로생성되 고 EEPROM 이프로그램된다. 2.6. C 프로그래밍에서유의할점 2.6.1. C 프로그램의구성요소 C 프로그램은지시어, 심볼, 문장, 블록의 4 가지구성요소가있다. 지시어또는키워드 : C 프로그램명령어들과같이 C 컴파일러가특별한의미로인식하는예약된문자들 심볼 : 지시어와달리사용자가특별히의미를부여한문자이다. 알파벳대문자와소문자과숫자와 _ 가가능하 며첫문자는반드시숫자가아니어야하며대소문자가구별된다. 문장 : 프로그램실행단위로반드시 ;( 세미콜론 ) 으로끝낸다. 블록 : { 로시작해 로끝맺으며여러개의문장을묶은것이다. 2.6.2. C 프로그램의일반적형식 C는매우자유로운형식의언어인데 C 프로그램파일은소스파일과헤더파일로구분된다. - 56 -

헤더파일 : 여러소스파일에공통으로들어가는함수의프로토타입의선언문, 새로운데이터형의정의또는 다른헤더파일을 include 시킨다. 전역(global) 변수의선언문이나함수의정의는헤더파일에두지않는것이좋 다. 소스파일 : 일반적으로전처리문, 선언문, 주석, main 함수및사용자정의함수등으로구성된다. 2.6.2.1. 전처리 # 문자로시작하며다음과같은지시어들이존재한다. #include : 외부파일로부터소스를읽어들인다. include 디렉토리에존재하는외부파일은 < > 로묶어주어 include 시키고현재의디렉토리에존재하는외부파일은 로묶어준다. #define : 매크로나상수를정의한다. 매크로의정의가길어한줄에쓰지못할때는 \ 를사용해줄바꾼다. #undef : 매크로나상수정의를취소한다. #ifdef : 매크로나상수가정의되어있다면해당부분만컴파일한다. #ifndef : 매크로나상수가정의되어있지않다면해당부분만컴파일한다. #if : 어떤조건을만족하면해당부분만컴파일한다. #elif : ifdef, ifndef, if와같은조건문에서또다른조건에의한분기조건을정의하여그조건이만족하면해 당부분만컴파일한다. #else : ifdef, ifndef, if 와같은조건문에서이전조건이만족되지않으면해당부분만컴파일한다. #endif : ifdef, ifndef, if, elif, else 조건블록의마지막을표시한다. 2.6.2.2. 선언문 함수와변수등심볼을선언하는부분이다. 변수는문자형인지, 정수형인지, 실수형인지데이터형을선언하고함 수의경우에는함수의이름, 함수를처리하고난후리턴할데이터형, 전달받을인수의데이터형등함수의프로 토타입을선언한다. 결과를리턴하지않는경우 void 를쓴다. 2.6.2.3. 주석 /* 와 */ : /* 로시작해서 */ 로끝맺으면그사이의글자는컴파일러가무시한다. /* 과 */ 사이에줄을바꿔도 그사이의글자는주석으로간주된다. // : // 를사용하면같은줄에서 // 뒤의글자는컴파일러가무시한다. 2.6.2.4. 함수와 main 함수부분 반드시하나의블럭으로되어있어어떤내용을처리하고그결과를리턴하는등실제적인프로그램을기술하 는부분이다. 다음의형태를띤다. 리턴데이터형함수명 ([ 데이터형인수1, 데이터형인수2,...]) { 프로그램내용 리턴데이터형은내용을처리하고난후리턴할결과데이터형태가정수형인지, 문자형인지, 실수형인지등무 엇인지를기술하는부분이다. 결과를리턴하지않는경우 void 를쓴다. 함수명은함수의이름을나타내는심볼이 며프로그램을처리할때전달받을값은인수들을통해하는데함수를정의할때인수들의데이터형과함께 ( ) 안에써넣는다. 전달받을값이없으면인수를안쓰거나 void 라고쓴다. main 함수는함수명이 main으로반드시 C 프로그램에서만들어야하는함수이다. 2.6.3. 기본데이터형 C 언어에서데이터는문자와숫자로분류할수있고또한상수와변수로구분할수있다. 변수는사용범위에따 라광역( 또는전역, global) 과지역(local) 변수가있다. 그리고이들데이터는기본적으로문자형, 정수형, 실수형 - 57 -

으로구분할수있다. 표5 에기본데이터형지시어의설명이주어졌다. 문자 : 알파벳과특수기호들로컴퓨터에표현하려면특정코드를사용해야하는데 C언어에서는아스키코드를 사용한다. 문자한개를표현할때는 'a', 'b', '@' 식으로 ' ' 기호를사용하고 2 개이상의문자열의경우에는 기 호를사용한다. 숫자 : 정수와소수로나뉠수있다. 정수는 10 진수, 16 진수, 8진수등을사용하는데 16진수를가장많이쓰 며 16진수는숫자앞에 0x를붙여주고 8진수는 0만붙여주고 10진수는 0이나 0x 를붙이지않고표기한다. 소 수의경우에는 0.0123 과같은식으로소수를쓰는방법과 1.23E-2 식으로지수를사용하는방법이있다. 음수 의경우에는 상수 -를숫자앞에붙이고양수의경우 + 를생략해도된다. : 프로그램내에서값의변화가없는데이터를지칭한다. 변수 : 값의변화가있는데이터를지칭하며값을마음대로바꿀수있는기억장소를의미한다. 변수는전역 (global), 지역(local), 정적(static), 외부(extern) 변수, 레지스터 (register) 로나뉠수있다( 함수부분설명참조). 데이터형지시어크기범위 문자형 정수형 실수형 2.6.3.1. 문자형 문자형데이터는 데지시어로부호가없는형태에 char unsigned char int unsigned int long unsigned long float double 표 8. 기본데이터형 1 바이트 -128 ~ 127 1 바이트 0 ~ 255 2 바이트 -32768 ~ 32767 2 바이트 0 ~ 65535 4 바이트 -2147483648 ~ 214783647 4 바이트 0 ~ 42967295 8 바이트 ± 1.2E-38 ~ ± 3.4E38 8 바이트 ± 1.2E-38 ~ ± 3.4E38 1바이트크기로하나의문자를의미하며작은숫자나아스키문자를표현하기위해사용되는 char와부호가있는형태에 unsigned char 를사용한다. char형은 -128 ~127 사이의값을갖고 unsigned char형은 0 ~ 255 사이의값을갖는다. 2.6.3.2. 정수형 정수를표현하기위해사용되는지시어로 int, unsigned int, long, unsigned long 가있다. int는 2바이트크기 로 -32768 ~ 32767 사이의값을갖고 unsigned int는 2바이트크기로 0 ~ 65535 사이의값을갖는다. long은 바이트크기로 -2147483648 ~ 214783647 사이의값을갖고 unsigned long는 4바이트크기로 0 ~ 4294967295 사이의값을갖는다. 2.6.3.3. 실수형 실수를표현하기위해사용되는지시어로 float, double 이있는데, float 는 8 바이트크기로 ± 1.2E-38 ~ ± 3.4E38 사이의값을갖고, double 은 8 바이트크기로 ± 1.2E-38 ~ ± 3.4E38 사이의값을갖는다. 2.6.3.4. 변수나상수이름짓는법 알파벳대문자와소문자과숫자와 변수이름의첫글자는숫자가아니어야한다. _ 가아닌특수문자는사용이안된다. 지시어는사용할수없다. _ 가가능하며대소문자가구별된다. 되도록이면헝가리언표기법에따라특별한접두어를사용해서변수이름을짓는다. 포인터를정의할때는접 두어 p, 문자열은 str, 플래그를정의할때는 f, 카운터나 int형을정의할때는접두어 c, long형은 l, unsigned - 58 -

int형은 u 를접두어로사용하면알아보기쉽다. 2.6.3.5. 상수정의 #define 을사용하여다음과같은식으로정의한다. 여기에서문자의끝에 ; 가들어가지않음에유의해야한다. #define 상수이름상수값 const 지시어를사용하여다음과같은식으로정의한다. const 데이터형상수이름 = 상수값 ; 2.6.3.6. 변수선언과초기화 변수는함수내의첫부분에서선언하거나함수밖에서프로그램첫부분에서선언할수있다. 함수내의첫부분에 서선언하면지역변수가되어함수내에서만사용할수있으며함수밖에서선언하면전역변수가되어정의된소 스프로그램내의모든함수에서사용가능하다. 다음과같은식으로선언하고초기화한다. 변수명 1만선언하는 경우에는 [ ] 안에주어진값과 [ ] 기호는생략가능하다. 데이터형변수명 1[= 초기값 1, 변수명 2= 초기값 2,... ]; 2.6.4. 확장데이터형 CodeVisionAVR 컴파일러는 2.6.3절에주어진 ANSI C의데이터형에더해 bit, eeprom, flash, sfrb, sfrw등 의데이터형을지원해주어 2.6.4.1. bit 데이터형 AVR 하드웨어특성을활용할수있도록하였다. 범용 I/O레지스터와 R2~R14 레지스터에 1 비트단위의데이터를위치시킨다. bit 데이터형은일반적으로광역 변수로선언된다. R15레지스터에 1비트단위의데이터를위치시키는지역변수의선언도 8 개까지허용된다. 2.6.4.2. eeprom 데이터형 EEPROM 메모리에위치한상수데이터를접근하는데사용한다. 2.6.4.3. flash 데이터형 플래쉬메모리에위치한상수데이터를접근하는데사용한다. 2.6.4.4. sfrb, sfrw 데이터형 I/O 레지스터를바이트혹은워드단위로접근하는데사용한다. Keil C컴파일러의 sfr 데이터형과유사하다. 신 텍스는다음과같다. sfrb 심볼1 = IO 레지스터주소값 ; sfrw 심볼2 = IO 레지스터주소값 ; I/O 레지스터들은 \INC 디렉토리밑에디바이스명칭.h( 예:mega128.h) 의형태로헤더파일에정의되어있으므로 사용자는별도로선언할필요없이헤더파일을프로그램선두에 include 시켜서사용하면된다. 즉예로 ATmega128 용으로프로그램을작성하는경우 #include <mega128.h> 를프로그램선두에놓으면 DDRA, PORTA, TCNT1, ICR1 등그림7과 8에주어진 I/O레지스터의이름을사용해서아래의예처럼값을직접할당할 수있다. 예 : DDRA=0xff; PORTA = 0x01 // PORT A를출력으로설정하고 0x01 값을출력하라. 2.6.5. 연산자 2.6.5.1. 조건연산자 아래와같은형식으로사용하며삼항연산자로보통불린다. 조건식이참이거나 0이아니면식1을처리하고거 짓이거나 0이면식2 를처리하라는의미이다. 변수 = ( 조건)? 식1 : 식2; 2.6.5.2. 데이터형변환연산자 - 59 -

변수가선언될때설정한데이터형과다른데이터형을사용할때사용하는연산자로다음과같이 ( 와 ) 사이에 형변환하려는데이터형의이름을넣어주면변수1 은데이터형으로형이변환되어변수2 에대입된다. 변수2 = ( 데이터형 ) 변수1; 2.6.5.3. 콤마연산자 두개이상의여러행에걸쳐사용하는문장을하나의행에서실행할때사용한다. 두개이상의문장을, 를사 용하여구분하여나열하면왼쪽부터차례대로실행된다. 아래의형태는문장1 을실행하고문장2를실행하고문장 n 을실행한다. 문장1, 문장2, 문장n; 2.6.5.4. 산술연산자 2.6.5.5. 논리와비교연산자 표 9. 산술연산자 연산자 사용예 설명 + a+b a와 b를더하라 - a-b a에서 b를빼라 - -a a의부호를반대로바꿔라 * a*b a와 b를곱하라 / a/b a를 b로나누어라 % a%b a/b의나머지를구하라 ++ c++ c를포함한연산을수행하고 c= c+1 ++c c=c+1 을하고 c를포함하여연산하라 -- c-- c를포함한연산을수행하고 c= c-1 --c c=c-1 을하고 c를포함하여연산하라 조건문에사용되는연산자들로비교연산자는크기를비교할때사용되고논리연산자는둘이상의비교연산 자를묶을때사용한다. 2.6.5.6. 비트연산자 표 10. 논리, 비교연산자 연산자 사용예 설명 < a<b a가 b보다작다 > a>b a가 b보다크다 <= a<=b a가 b 보다작거나같다. >= a>=b a가 b 보다크거나같다. == a==b a와 b 는동치이다.!= a!=b a와 b 는동치가아니다.!!(a<b) (a<b) 의논리부정 && a>b && b>c a>b 와 b>c의논리곱 a>b b>c a>b 와 b>c의논리합 비트를조작하는데사용하는연산자로데이터를비트별로처리한다. 표 11. 비트연산자 연산자 사용예 설명 << a<<2 a값을우측으로 2비트이동 >> a>>2 a값을좌측으로 2비트이동 ~ ~a a의비트반전값 & a&b a와 b의대응비트별로계산한논리곱 a b a와 b의대응비트별로계산한논리합 ^ a^b a와 b의대응비트별로계산한 XOR - 60 -

2.6.5.7. 대입연산자 표 12. 대입연산자 연산자 사용예 설명 = c = a+b a+b의결과를 c에대입하라 += c += 2 c = c+2와등가 -= c -= 3 c = c -3과등가 *= c *= 3 c = c*3 과등가 /= c /= 2 c = b/2와등가 %= c %= 3 c = c % 3과등가 <<= c <<= 3 c = c << 3 과등가 >>= c >>= 2 c = c >> 2와등가 &= c &= b c = c & b과등가 ^= c ^= b c = c^b 과등가 = c = b c = c b 와등가 2.6.6. 제어문 2.6.6.1. if 문 if 문 : 아래와같은형식으로괄호안의조건식이충족되거나 0 이아니면그뒤의문장이나블록을수행한다. if ( 조건 ) 문장 ; if ~ else 문 : 아래와같은형식으로괄호안의조건이충족되거나 0이아니면문장1을수행하고괄호안의조 건이충족되지않으면문장2 를수행한다. 문장1 이나문장2 는블록이될수있다. if ( 조건 ) 문장1; else 문장2; if ~ else if ~ else 문 : 아래와같은형식으로여러가지의조건식으로제어가능하다. 우선 if 문의조건1 이 충족되는지점검하고충족되거나 0이아니면문장1을수행하고 if 문의조건1이성립하지않으면 else if 문의 조건2 를점검하고충족되거나 0이아니면문장2 를수행하고 else if 문의조건2가성립하지않고그다음에 else if문이존재하면앞서의과정을반복하고 else문이나오면 else문뒤의문장n 을수행한다. 문장1이나문장2, 문장 n 은블록이될수있다. if ( 조건1 ) 문장1; else if ( 조건2 ) 문장2; else 문장n; 2.6.6.2. switch-case 문 if문과함께 switch-case 문은조건문으로 if문에서는조건이비교연산자의형태가되어변수값이어떤범위에 존재하는지여부를점검하지만 비교해일치하면 switch-case 문에서는 switch 문의변수값이 case문의값과정확히일치하는지를 case 문의뒤에오는문장을실행한다. 아래의예에서는변수값을상수1 과비교해서같으면문장 1을실행하고 break 에따라 switch-case 문의블록을빠져나온다 ( 만약 break 가없으면블록을빠져나오지않고 그다음 case 문을점검한다 ). 변수값이상수1과다르면다음 case문으로가서상수2와변수를비교해서같으면 문장2를실행하고 break 에따라 switchc-case 문의블록을빠져나온다. 그다음에 case문이존재하면앞서의과 정을반복하고 default 문이나오면 default 문뒤의문장n 을수행하고 break 에따라 switch-case 문의블록을빠져 나온다. 문장1이나문장2, 문장 n 은블록이될수있다. switch ( 변수 ) { case 상수1 : 문장1; break; case 상수2 : 문장2; break; default : 문장n; break; - 61 -

2.6.6.3. for 문 반복문의하나로제어할변수의초기화, 조건, 연산이하나의문장으로해결할수있다. 아래와같은형태로초 기화식, 제어조건식, 연산식은 ; 를써서분리되어있고초기화식과연산식은콤마(,) 를사용하여여러개의수식이 사용가능하고또한생략도가능하다. 제어조건식은반드시하나만설정하거나생략가능하다. 처음에는초기화식 에따라제어변수를초기화하고, 제어조건식을점검하고, 제어조건식이성립하면문장을실행하고, 제어변수를 연산식에따라연산하고, 제어조건식을다시점검하고, 제어조건식이성립하면문장을실행하고, 제어변수를연 산식에따라연산한다. 이러한과정을제어조건식이충족되는동안반복적으로수행한다. 문장이제어변수연산 식에포함된형태인경우문장은생략가능하다. 문장은블록이될수있다. for( 제어변수초기화식 ; 제어변수제어조건식 ; 제어변수연산식 ) 문장 ; 2.6.6.4. while 문 반복문의하나로초기화식과연산식이생략된 조건식의결과가 while( 조건 ) 문장 ; 2.6.6.5. do-while 문 for 문이라생각하면된다. 아래와같은형태로조건이충족되거나 0 이아닌동안반복적으로문장을수행한다. 문장은블록이될수있다. 아래와같은형태로 while 문과비슷하나 while 문이반복문을수행하기전에조건을점검하나 do-while 문은반 복문을실행한다음에조건을점검한다. 즉 do-while 문은적어도한번은반복문이수행이되나 while 문은한번 도수행되지않을수있다. 문장은블록이될수있다. do { 문장 ; while( 조건 ) ; 2.6.6.6. break 문 반복문이나조건문등제어문의실행에서현재의실행을중지하고제어문을빠져나가게한다. 2.6.6.7. continue 문 반복문이나조건문등제어문의실행에서제어문을완전히빠져나가지말고현재차례의실행만을중지하고다 음횟수의반복을진행하게한다. 2.6.6.8. goto 문 어셈블리어의 JMP명령과유사하게미리정해져있는 label 의위치로점프하게한다. 아래의예와같은경우 goto문을만나면문장2 는실행이되지않고 goto문이가리키는 label1 으로점프하여문장1 이수행된다. label 이름 뒤에는어셈블리어프로그래밍에서처럼 goto label1; 문장 2; label1: 문장 1; 2.6.7. 함수와변수 2.6.7.1. 프로토타입선언 프로토타입 :( 콜론) 을붙인다. : 프로그램에서사용할함수이름과리턴값, 인수( 파라미터 ) 의데이터형을 main() 함수위에서미리 정의하는것을프로토타입선언이라한다. 다음의형태로프로토타입을정의한다. 함수의내용을 main() 함수 위에서정의한경우는불필요하다. 리턴데이터형 함수명 ([ 인수1 의데이터형, 인수2 의데이터형,...]); 다음의형태로인수들을명기해도된다. 리턴데이터형 함수명 ([ 데이터형인수1, 데이터형인수2,...]); 2.6.7.2. 일반함수의정의 함수는반드시하나의블럭으로되어있어어떤내용을처리하고그결과를리턴하는등실제적인프로그램을 기술하는부분이다. 다음의형태를띤다. - 62 -

리턴데이터형함수명 ([ 데이터형인수1, 데이터형인수2,...]) { 프로그램내용 리턴데이터형 : 함수는내용을수행하고리턴데이터가있는경우와없는경우가있는데함수를 call한쪽으로 결과를돌려보내는경우프로그램내용끝에다음과같은명령을표시한다. return 리턴데이터 ; 경우 리턴데이터형이정수형인지, 문자형인지, 실수형인지등무엇인지를기술하는부분이다. 결과를리턴하지않는 void 를쓴다. 함수명 : 함수의이름을나타내는심볼로알파벳대문자와소문자과숫자와 _ 가가능하며대소문자가구별된 다. 2.4.3.4 절의변수나상수이름짓는법에따라이름을만들면된다. main 함수는함수명이 main으로반드시 C 프로그램에서만들어야하는함수이다. 인수 : 프로그램을처리할때전달받을값은인수들을통해하는데함수를정의할때인수들의데이터형과 함께 ( ) 안에써넣는다. 전달받을값이없으면인수를안쓰거나 void 라고쓴다. 프로그램내용 2.6.7.3. 라이브러리함수 : { 안에정의하여블록을이루며실제함수의실행코드가위치한다. CodeVisionAVR 은 ANSI C 언어의표준라이브러리의함수들을제공해준다. 자세한것은 CodeVisionAVR manual(http://www.hpinfotech.ro) 를참조하거나 CodeVisoinAVR C컴파일러의 help 를참조하길바랍니다. stdio.h : 이헤더파일을 include 시키면 UART 에서사용할수있는 getchar(), putchar(), puts(), putsf(), printf(), vprintf(), psprintf(), scanf() 등의기본입출력함수를사용할수있다. stdlib.h : 이헤더파일을 include시키면 atoi(), itoa(), ftoa(), atof(), rand(), *malloc(), free() 등의기본라이 브러리함수를사용할수있다. math.h : 이헤더파일을 include 시키면 abs(), max(), fmax(), min(), fmin(), sign(), sqrt(), ceil(), floor(), fmod(), exp(), log(), log10(), pow(), sin(), cos(), tan(), sinh(), cosh(), tanh(), asin(), acos(), atan(), atan2() 등의수학함수를사용할수있다. string.h : 이헤더파일을 include 시키면 *strcat(), *strcatf(), strcmp(), *strcpy(), strnlen() 등의문자열조 작용함수를사용할수있다. 2.6.7.4. 인터럽트함수의정의 AVR 은다수의인터럽트소스를가지며이를위한특별한정의가요구된다. 다음의형태를띤다. interrupt [ 인터럽트벡터번호 ] void 인터럽트함수명 ( void ) { 인터럽트서비스프로그램내용 인터럽트함수명 : 인터럽트함수의이름을나타내는심볼로알파벳대문자와소문자과숫자와 _ 가가능하며 대소문자가구별된다. 앞서설명된변수나상수이름짓는법에따라이름을만들면된다. 인터럽트벡터번호 : 각 AVR 디바이스가제공할수있는인터럽트소스가운데선언할인터럽트를지정하는 번호로다른일반함수와구별하기위해반드시써줘야한다. 헤더파일에인터럽트소스명이정의되어있다. ATmega128 의경우 mega128.h 에리셋인터럽트를제외한 34개의인터럽트소스명이정의되어있는데외부인 터럽트 0~7( 인터럽트번호 2~9) 은 EXT_INT0~EXT_INT7 로정의되어있다. 2.6.7.5. 변수 변수는값의변화가있는데이터를지칭하며값을마음대로바꿀수있는기억장소를의미한다. (global), 지역(local), 정적(static), 외부(extern) 변수, 레지스터로나뉠수있다. 변수는전역 전역변수 : 소스파일내부에있는모든함수나프로그램블록에서사용할수있다. 소스파일전체에서서로 공유하는데이터가있는경우에사용하면좋다. 지역변수 : 하나의프로그램블록안에서선언되고사용되는변수로선언된블록밖에서는변수로서의기능을 - 63 -

상실한다. 프로그램블록이실행되는순간에지역변수를위한기억장소가확보되고실행이종료되면자동적으로 해제되어다른프로그램블록이실행되는동안에는메모리에전혀영향을주지않는다. 레지스터변수 : CPU 의레지스터를사용하여변수를저장한다. 그러므로연산속도가향상될수있다. 일반적으 로지역변수에만지정할수있고레지스터의갯수가한정이되어있으므로일정한도가넘어서면나머지들은레 지스터변수로선언되었어도무시당하고지역변수에할당된다. 정적변수 : 아래와같이자료형앞에 static이라는지시어를데이터형앞에써정의하며정적변수가선언된 함수가종료되더라도그값을계속유지하며프로그램이종료될때까지유효한변수이다. static 데이터형변수명 1[= 초기값, 변수명 2= 초기값 2,... ]; 외부변수 : 다른소스파일에정의된변수를지칭한다. 프로그램선두에아래와같이 extern 이라는지시어를 데이터형앞에써정의하여사용하며프로그램이종료될때까지유효하다. 여러사람이공동으로하나의프로그 램을개발할때다른사람이만든변수를쉽게사용할수있도록해준다. 함수의경우도마찬가지로프로그램선 두에프로토타입선언문앞에 그램이종료될때까지유효하다. extern extern 데이터형변수명 1[= 초기값, 변수명 2= 초기값 2,... ]; 2.6.7.6. 어셈블리어와결합 함수내의 C 내려면지시어 2.6.8. 포인터와배열 지시어를붙여서선언하여다른소스파일에정의된함수를사용하며프로 소스중간에어셈블리어를사용하기시작하려면지시어 #endasm 을사용한다. #asm(" 어셈블리어명령어 ") 도가능하다. 2.6.8.1. 배열선언방법 #asm을사용하고어셈블리어의사용을끝 배열의선언은아래와같이데이터형, 배열명을써주고배열차원수를 [ ] 기호로묶어주면된다. 데이터형배열명 [ 배열항목수 1][ 배열항목수 2]... [ 배열항목수 n]; 데이터형 : 앞에나온데이터형을사용한다. 배열명 : 배열의이름을나타내는심볼로알파벳대문자와소문자과숫자와 _ 가가능하며대소문자가구별된 다. 2.4.3.4 절의변수나상수이름짓는법에따라이름을만들면된다 배열항목수 : 배열의크기를설정한다. 주의할점은배열의마지막인덱스는 ( 배열차원수 -1) 이고첫인덱스는 0 임에유의해야한다. 예로 char buf[3]; 와같이선언된배열 buf의첫번째항목은 buf[1] 이아니라 buf[0] 이 며두번째항목은 buf[2] 가아니라 buf[1] 이고세번째항목이자마지막항목은 buf[3] 이아니라 buf[2] 이다. 2.6.8.2. 배열초기화 1 차원배열의초기화 : 배열은선언과동시에값을초기화할수있는데 { 기호를사용하여한다. 1차원배 열의경우아래와같이차례대로값을나열하고,( 콤마) 로구분하고 { 기호로묶어주면된다. 인덱스 0에서부터 차례대로 n-1 까지순서대로주어진항목값에따라초기화된다. 배열항목수는 n보다작거나같을수있는데작 은경우초기화되지않은항목의값은자동적으로 0 으로초기화된다. 데이터형배열명 [ 배열항목수 ] = { 1 번째항목값,..., n 번째항목값 ; 1 차원배열의선언과초기화를동시에하는경우아래와같이배열항목수를빼고해도된다. 그러나이경우 선언된배열명의항목수는 n 으로됨에유의해야한다. 그리고 2 차원이상의경우에는허용되지않는다. 데이터형배열명 [] = { 1 번째항목값,..., n 번째항목값 ; 문자형배열의초기화 : 문자열의경우에는초기화할때 { 기호를사용하지않고큰따옴표를써서해도된 다. 그래서아래의두선언문은같다. 정수형이나다른데이터형의경우에는허용되지않는다. char char buf[11] = "I am HHCHOI"; buf[[11] = {'I', ' ', 'a', 'm', ' ', 'H', 'H', 'C', 'H', 'O', 'I'; 다차원배열의초기화 : 1차원배열의초기화와비슷하며다만 2 중으로 { 기호를사용한다. 1번째값 1이배열 - 64 -

의배열명 [0][0]... [0] 의항목값으로초기화되고차례대로 m번째항목값 1 이배열명 [0][0]... [m-1] 의항목값 으로초기화된다. 1번째값 2 은배열명 [1][0]... [0] 의항목값으로초기화되고차례대로 p번째항목값 2이배열명 [1][0]... [p-1] 의항목값으로초기화된다. 마찬가지의과정을거쳐차례대로초기화되며초기화되지않은항목 의값은자동적으로 0 으로초기화된다. 여기에서 1 차원배열과달리항목수는반드시기입해야한다. 데이터형배열명 [ 항목수 1]... [ 항목수 n] = { {1번째값 1,..., m번째항목값 1, {1번째값 2,..., p번째항목값 2... ; 2.6.8.3. 포인터선언방법 아래와같이일반변수와같은형식으로선언하되변수의이름앞에 *( 애스터리스크 ) 기호를붙인다. * 는포인 터변수의내용을의미하는연산자이다. 데이터형 * 포인터이름 ; 2.6.8.4. 포인터초기화및참조방법 일반변수주소를포인터변수에대입하는방법 이터를할당하고초기화할수있다. 데이터형 일반변수이름 = 초기값 ; 데이터형 * 포인터이름 ; 포인터이름 = & 일반변수이름 ; 위의형태는아래와같은형태로대체될수있다. 데이터형 일반변수이름 = 초기값 ; 데이터형 * 포인터이름 = & 일반변수이름 ; 문자열을포인터로선언하는법 큰따옴표를사용하면된다. char * 포인터이름 = 문자열 ; : : 아래와같은형태로주소연산자 & 를사용하여포인터에데 포인터를선언하면서동시에문자열데이터로초기화할때는아래와같이 포인터로배열을가리키게하기위해배열이름을포인터변수에대입하는방법 : 미리선언된배열을미리선 언된포인터변수로가리키게하기위해다음과같이배열이름을포인터이름에대입할수있다. 데이터형배열명 [ 배열항목수 ] = { 1 번째항목값,..., n 번째항목값, * 포인터이름 ; 포인터이름 = 배열이름 ; 위의형태는아래와같은형태로대체될수있다. 데이터형 배열명 [ 배열항목수 ] = { 1 번째항목값,..., n 번째항목값 ; 데이터형 * 포인터이름 = 배열이름 ; 포인터로배열을가리키게하기위해배열의첫번째항목의주소를포인터변수에대입하는방법 : 미리선언 된 1차원배열을미리선언된포인터변수로가리키게하기위해다음과같이주소연산자 & 를사용하여배열의 첫번째항목의주소를사용할수있다. 데이터형배열명 [ 배열항목수 ] = { 1 번째항목값,..., n 번째항목값, * 포인터이름 ; 포인터이름 = & 배열이름 [0]; 포인터변수에서값읽기방법 : 미리선언되고사용중인포인터변수의내용을그내용과같은자료형의일반 변수에값을써넣을때는연산자 일반변수이름 = * 포인터이름 ; 포인터변수에값쓰기방법 포인터변수에값을써넣을때도연산자 * 포인터이름 = 일반변수이름 ; 2.6.8.5. 포인터의연산 포인터변수는 ++, --, +, : * 를사용해아래와같이한다. 미리선언되고사용중인포인터변수의내용과같은자료형의일반변수값을 * 를사용해아래와같이한다. -, +=, -= 등의연산자를사용하여연산이가능하다. 만약다음과같이포인터와배 열이선언된경우 *ptr++ 가가리키는값은 buf[1] 즉 b 와같다. 여기에서 ++ 나 -- 가 * 연산자보다우선하기때 문에 *ptr++ 와 *(ptr++) 는동일하고, *ptr-- 과 *(ptr--) 은동일함에유의해야한다. char buf[6] = "abcdef"; char *ptr = buf; 2.6.8.6. 함수포인터 - 65 -

함수포인터의선언 : 함수프로토타입선언과같이아래처럼하면함수포인터를선언할수있다. 함수프로토타 입선언에서처럼인수들은생략하고인수들의데이터형만 사용한다. 리턴데이터형 (* 함수명 ) ([ 데이터형인수1, 데이터형인수2,...]); ( ) 안에나열해도된다. 인수가없는경우에는 void를 함수포인터의무조건점프명령에의활용 : 아래와같이 function_ptr 이라는함수포인터가선언된경우 void (* function_ptr) (void); function_ptr 에다음과같은식으로절대번지값 ( 예: 0x4000) 을대입을하고콜을하면프로그램카운터 (PC) 값은 절대번지값 0x4000으로바뀌어 0x4000 번지부터명령을수행하게된다. function_ptr = (void *) 0x4000; 2.6.8.7. 배열과포인터의차이점 선언 초기화 데이터접근 function_ptr(); : 배열은선언시차원을미리지정해줘야하나포인터는그럴필요없다. : 배열은초기화가쉬우나포인터는미리메모리를항당받고해야한다. : 배열은 [ ] 기호사이에넣어진값즉인덱스를사용하여바로필요한위치의데이터에접근할 수있으나포인터는포인터변수의연산을통해데이터를읽고써야한다. 메모리의사용 는그렇지않다. : 배열이선언될때필요한메모리가할당되어중간에메모리크기를변경할수없으나포인터 2.6.9. typedef, structure, union, enum 2.6.9.1. typedef 를사용한새로운데이터형정의법 typedef 는자주사용하는데이터형을기억하기쉽거나편리한이름을갖는새로운데이터형을정의하여쓸수 있도록한다. 사용형식은아래와같다. typedef 기존데이터형새데이터형 ; 일반적으로다음과같은데이터형의변경이많이쓰인다. typedef unsigned char byte; typedef unsigned int word; 2.6.9.2. 구조체의개념과필요성 서로다른유형의변수들을새로운하나의데이터형으로묶어서정의한것으로구조체 (structure) 는다양한유 형의변수를구성원으로갖는변수의묶음이다. 인사기록카드를만드는경우사원의이름, 사번, 주민번호, 나이, 최종학력등이 필요한데이러한것은사원별로나누어지는데이터이므로각사원에대하여하나로묶어처리하 면취급, 프로그램개발과이해가매우쉽겠다. 2.6.9.3. 구조체선언법과초기화 방법1 : 우선아래와같은형태로구조체항목들을나열하여 { 로묶어구조체이름으로새로운데이터형을정 의한다. struct 구조체이름 { 데이터형구조체항목 1; 데이터형구조체항목 2; 데이터형구조체항목 n; ; 이렇게만든구조체로지시어 struct 구조체이름변수이름 ; 선언과동시에초기화할경우에는아래와같이한다. struct 와구조체이름을사용하여변수를아래와같이선언한다. struct 구조체이름변수이름 = { 구조체항목 1 의초기값, 구조체항목 2 의초기값, 구조체항목 n 의초기값 ; 방법2 : 아래와같은형태로구조체항목들을나열하여 { 로묶어구조체이름으로새로운데이터형을정의하 며동시에정의된구조체형태의변수를선언하고초기화할수있다. - 66 -

struct 구조체이름 { 데이터형구조체항목 1; 데이터형구조체항목 2; 데이터형구조체항목 n; 변수이름 = { 구조체항목 1 의초기값, 구조체항목 2 의초기값, 구조체항목 n 의초기값 ; 방법3 : typedef 를사용하여우선아래와같은형태로구조체항목들을나열하여 { 로묶어구조체이름으로 새로운데이터형을정의한다. typedef struct _ 구조체이름 { 데이터형구조체항목이름 1; 데이터형구조체항목이름 2; 데이터형구조체항목이름 n; 구조체이름 ; 이렇게만든경우지시어 구조체이름변수이름 ; struct 를쓸필요없이구조체이름만사용하여변수를아래와같이선언한다. 구조체변수선언과동시에초기화할경우에는아래와같이한다. 구조체이름변수이름 = { 구조체항목이름 1 의초기값, 구조체항목이름 2 의초기값, 구조체항목이름 n 의초기값 ; 방법4 : typedef 를사용하여아래와같은형태로구조체를정의하고변수의선언과초기화는방법3 과똑같이 할수도있다. typedef struct { 데이터형구조체항목이름 1; 데이터형구조체항목이름 2; 데이터형구조체항목이름 n; 구조체이름 ; 구조체포인터변수나배열선언 : 앞서의방법1~4 가운데하나를사용해서구조체이름을선언하고변수를 포인터나배열로선언할수있다. 2.4.9 절에주어진일반데이터형의포인터나배열선언방법과동일하다. 예로 구조체이름을방법3이나 4 를이용하여선언한경우포인터나배열변수는아래와같이하면된다. 구조체이름 * 구조체포인터변수이름, 구조체배열이름 [ 배열항목수 ]; 2.6.9.4. 구조체사용법. 연산자를통한항목접근 : 구조체변수의항목은아래와같이.( 도트) 연산자를통해접근한다. 구조체변수이름. 구조체항목이름 -> 연산자를통한항목접근 : 구조체포인터변수의항목은아래와같이 -> 연산자를통해접근한다. 구조체보인터변수이름 -> 구조체항목이름 2.6.9.5. 공용체 (union) 개념 : 항목들이같은메모리공간을점유하는것을제외하고구조체와동일하다. 하나의 union 변수가점유하 는메모리의크고변수의항목에서가장큰것과동일하다. AVR에서는 SRAM 에저장된다. 아래의예를보면 쉽게필요성과사용법을이해할수있을것이다. 같은값의다른표현에활용할수있다. union tag_length { unsigned int all; unsigned char byte[2]; data; data.all = 0x1230; //data 공용체에 16진수 0x1234 할당 low = data.byte[0] ; // low에 data 의하위바이트를할당즉 low=0x30 와동치 high = data.byte[1] ; // hig에 data 의상위바이트를할당즉 high=0x12 와동치 선언법과초기화 사용법 : 구조체와같다. 2.6.9.6. 열거형상수 개념 : 구조체와같다. : 정수형상수의일종으로상수값에일종의별명을부여하여열거해둔것이다. 선언법과초기화 : 선언법과초기화는구조체와비슷한데각항목에할당되는값은만약 n-1번째항목의값이 정수 N-1이라면 n번째항목값은 N 이다. 초기화는첫번째항목값만정의해주면된다. 첫번째항목을정의하지 않으면첫번째항목에 0 이할당된다. 아래의예는상수 d_of_weeks 의 sunday 항목은 1 에, monday 는 2 에,... saturday 에는 7 을할당하는것이다. enum days {sunday=1, monday, tuesday, wednesday, thursday, friday, saturday d_of_week; - 67 -

3.1. 기본프로그래밍연습 3.1.1. 실험 1 : 내부램에데이터쓰기 1 3. 기본프로그래밍과입출력실험 예제 : 내부램에데이터를쓰는다양한방법을익힌다. 내부램 0x130-0x136 번지에차례대로숫자 1, 2, 0xff 와문자 'A', 'a', 'F', 'f' 를써넣어라. 즉다음을하라. (0x130) <-1, (0x131) <-2, (0x132) <-0xff, (0x133) <-'A', (0x132) <-'a', (0x135) <-'F', (0x136) <-'f' 프로그램예 : #include <mega128.h> #define DBYTE ((unsigned char volatile *) 0) #define Im136 *((unsigned char *) 0x0136) /* define 에는 ; 로종결하지않음에주의 */ unsigned char *pim130 = 0x0130; void main(void){ *pim130++ = 1; /* (0x130) <- 1, pim130h = pim130 + 1 */ *(pim130++) = 2; /* *pim130++ = *(pim130++) */ *pim130 = 0xff ; /* (0x132) <- 0xff */ *++pim130 = 'A' ; /* pim130 = pim130 +1, *pim130 <- 'A' */ *(++pim130) = 'a'; /* *(++pim130) = *++pim130 */ DBYTE[0x0135] = 'F'; /* (0x135) <- 'F' */ Im136 = 'f'; /* (0x136) <- 'f' */ 실험방법 : 1CodeVisionAVR 의에디터를통해실행파일을만든후 AVR Studion4 디버그세션에들어간후메 인메뉴의 [View->Memory] 를실행하여 Memory 라는이름의창을생성하고창에서 [Data] 을선택한다. 또한 [View->Register] 를실행하여 Register 라는이름의창을생성한다. 2디버그세션에서메인메뉴 [Debug] 의하 위메뉴인 [Step Into], [Auto Step], [Run to Cusor] 등을적절히활용하면서 Memory, Register, I/O View 창을통해내부램과레지스터의값의변화를확인하라. 성공적으로수행된경우내부램 0x130-0x136 에는차례 대로 1,2, 0xff, 0x41, 0x61, 0x46, 0x66 값이저장된다. 과제 : 내부램 0x140-0x147 번지에차례대로문자 A', 'b', 'C', 'D', 'E', 'F', 'G', 'h' 를다양한방식으로써 넣어라. 3.1.2. 실험 2 : 내부램에데이터쓰기 2 예제 : 내부램 0x130-0x17F 번지에차례대로 0xff 을써넣어라. 프로그램예 : #include <mega128.h> unsigned char *pim130 = 0x0130; void main(void){ for(;pim130<=0x17f;){ *pim130++ = 0xff; /* 포인터 pim130 가가리키는곳에 ff를쓰고다음위치를가르키도록 1 증가시킨다. */ 실험방법 : 실험1 과같은방식으로수행하라. 성공적으로수행된경우내부램 0x130H-0x17F 번지에차례대 로 과제 0xff 값이저장된다. : #define DBYTE ((unsigned char volatile *) 0) 를활용하여같은역할을하도록하라. 3.1.3. 실험 3 : EEPROM 에데이터쓰기와읽기 - 68 -

예제 : EEPROM 의일정영역에데이터를저장시켜놓고읽는방법을익힌다. EEPROM 에 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x67 등 10개의데이터를쓰고저장된값을읽어들여 SRAM 0x130 번지를시작으로하여차례대로저장한다. 프로그램작성시유의점 : 1.5.6.4절과 1.5.6.5 절을참조하여작성한다. 프로그램예 : #include <mega128.h> #include <mem.h> // void pokeb(unsigned int addr, unsigned char data) 명령어를사용해 SRAM 에쓸수있다. #include <delay.h> unsigned char read_eeprom(unsigned int addr) { // EEPROM 읽기 while((eecr & 0x02) == 0x02); // EEWE = 0 인가를확인한다. EEAR = addr; EECR = 0x01; // EERE =1 return EEDR; void write_eeprom(unsigned int addr,unsigned char data) { // EEPROM 에쓰기 while((eecr & 0x02) == 0x02); // EEWE = 0 인가를확인한다. EEAR = addr; EEDR = data; EECR = 0x04; // EEMWE = 1 EECR = 0x02; // EEWE = 1 void main(void){ unsigned char arr[ ]={0x3f, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x67 ; int i, j; j = 0x00; while(arr[j]!= 0) write_eeprom(j,arr[j++]); delay_ms(100); for(i=0x0130, j=0;i<=0x013a; i++, j++) { pokeb(i, read_eeprom(j)); delay_ms(10); // 읽은데이터를램에쓴다. 실험방법 : 실험1 과비슷한방식으로수행하라. EEPROM 창을띠우고이를통해성공적으로써졌는지확인하 라. 성공적으로수행된경우내부램 0x130-0x13a 에는차례대로 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x67 값이저장된다. 과제 : 플래쉬롬에 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x67 등 10개의데이터를 저장해두고저장된값을읽어들여실험1 을참조하여다른방식으로 EEPROM 에 0x00번지를시작으로하여차 례대로저장하는프로그램을작성하라. 3.1.4. 실험 4 : 롬데이터읽기 예제 : 플래쉬롬의일정영역에데이터를저장시켜놓고읽는방법을익힌다. 롬에 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x67 등 10개의데이터를저장해두고저장된값을읽어들여 SRAM 0x130 번지를시작으로하여차례대로저장한다. 프로그램예 : #include <mega128.h> #include <mem.h> // void pokeb(unsigned int addr, unsigned char data) 명령어를사용해 SRAM 에쓸수있다. flash unsigned char arr[ ]={0x3f, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x67 ; void main(void){ int i, j; for(i=0x0130, j=0;i<=0x013a; i++, j++) pokeb(i, arr[j]); - 69 -

실험방법 : 실험1 과같은방식으로수행하라. 성공적으로수행된경우내부램 0x130-0x13a 에는차례대로 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x67 값이저장된다. 과제 : 플래쉬롬에 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x67 등 10개의데이터를 저장해두고저장된값을읽어들여실험1을참조하여다른방식으로 SRAM 에 0x130 번지를시작으로하여차례 대로저장하는프로그램을작성하라. 3.1.5. 실험 5 : 롬데이터검색 1 예제 : 플래쉬롬의일정영역에저장된 16개의데이터에서 5의배수를뽑아 SRAM 0x131부터저장하고 5의 배수의개수를 프로그램예 : 0x130 에저장한다. #include <mega128.h> #define DBYTE ((unsigned char volatile *) 0) flash unsigned char arr[ ]={12, 5, 2, 25, 3, 9, 15, 19, 25, 99, 45, 56, 77, 99, 34, 26 ; void main(void){ int i = 0x0131, j = 0, k =0 ; for(;j<=15; j++) if ( arr[j]%5 == 0 ) { DBYTE[i++] = arr[j]; k++ ; DBYTE[0x0130] = k; /* j=0 으로초기화하는것은선언문에서했으므로생략 */ 실험방법 : 실험1 과같은방식으로수행하라. Eeprom 창과 Data, IO view 창을띠우고변화하는모양을성공 적으로수행된경우내부램 0x130H~0x135H 에차례로 0x05, 0x05, 0x19, 0x0F, 0x19, 0x2D 가저장된다. 과제 : 프로그램메모리일정영역에저장된 16개의데이터에서 5의배수가아닌것을뽑아 SRAM 0x131 부터 저장하고그개수를 3.1.6. 실험 6 : 롬데이터검색 2 0x130 에저장하는프로그램을작성하라. 예제 : 롬의일정영역에저장된 16개의데이터에서가장작은수를뽑아 SRAM 0x130 번지에저장한다. 프로그램예 : #include <mega128.h> #define DBYTE ((unsigned char volatile *) 0) flash unsigned char arr[ ]={12, 5, 2, 25, 3, 9, 15, 19, 25, 99, 45, 56, 77, 99, 34, 26 ; void main(void){ unsigned char j = 0; DBYTE[0x00130] = arr[0]; /* 가장작은수가될후보로 arr[0] 로 */ for(j=1;j<=15; j++) if ( DBYTE[0x0130] > arr[j] ) DBYTE[0x0130] = arr[j]; 실험방법 : 실험1 과같은방식으로수행하라. 성공적으로수행된경우내부램 0x0130 에 2 가저장된다. 과제 : 프로그램메모리일정영역에저장된 16개의데이터에서가장큰값을찾아 SRAM 0x130 에저장하라. 3.1.7. 실험 7 : 8 비트 2 진수의 BCD 변환 예제 : 8비트 2진수를 3자리수 BCD 값으로변환하는프로그램을작성한다. 주어진 2 진수헥사값 ( 예: 0xFF) 을 BCD로변환하여 100의자리수는 SRAM 0x0130번지에 10의자리수는 0x0131번지의상위 4비트에 1의자리 수는 0x0131 번지의하위4 비트에저장하는프로그램을작성하라. 프로그램작성시유의점 : bcd.h 를 include 시켜서 bin2bcd() 를사용해서해도되나이경우 0~99까지의값만 사용할수있다. 8비트의 2진수는 0~255 의값을갖는다. 그러므로결과값의저장은 2바이트를요구하고 100의 - 70 -

자리수가저장되는 0x0130 는 0~2의값을갖고 0x0131 에는 00~99 의값을갖는다. 프로그램예 : #include <mega128.h> #define DBYTE ((unsigned char volatile *) 0) void h2bcd(unsigned char bin){ unsigned char tmp; DBYTE[0x0130] = bin/100; /* 100의자리수는 0x130 번지에저장 */ DBYTE[0x0131] = ( bin % 100 ) / 10; /* 10의자리수가 0x131 번지의하위 4 비트에저장 */ tmp = ( bin % 100 ) % 10 ; /* 1의자리수를 tmp 에임시저장 */ DBYTE[0x0131] <<=4 ; /* 10의자리수를 0x131 번지의상위 4비트로저장하기위해 4 번쉬프트 */ DBYTE[0x0131] = tmp ; /* 1의자리수를 0x131 번지의하위 4 비트로저장 */ void main(void){ unsigned char bin = 0xff; /* 주어진 2진수를 0xff 로초기화 */ h2bcd(bin); 실험방법 : 실험1 과같은방식으로수행하라. 성공적으로수행된경우내부램 0x130, 0x131 에는차례대로 0x02, 0x55 값이저장된다. 과제 : 주어진 2진수 0xE0를 BCD로변환하여 100의자리수는램 0x1000번지에 10의자리수는 0x1001번 지의상위 4비트에 1의자리수는 0x1001 번지의하위4 비트에저장하는프로그램을실험1을참조하여다른방식 으로작성하라. 3.1.8. 실험 8 : 16 비트 2 진수의 BCD 변환 예제 : 16비트 2진수를 5자리수 BCD 값으로변환하는프로그램을작성한다. 주어진 2바이트 2진수의헥사값 ( 예: 0xF0FF) 를 BCD로변환하여 10000의자리수는 0x130번지에 1000의자리수는 0x131번지의상위 4비트 에 100의자리수는 0x131번지의하위4비트에 10의자리수는 0x132번지의상위 4비트에 1의자리수는 0x132 번지의하위4 비트에저장하는프로그램을작성하라. 프로그램작성시유의점 : 16비트의 2진수는 0~65535 의값을갖는다. 그러므로결과값의저장은 5바이트를 요구하고 10000 의자리수가저장되는 0x130 는 0~6의값을갖고 0x131~0x132 에는 00~99 의값을갖는다. 프로그램예 : #include <mega128.h> #define DBYTE ((unsigned char volatile *) 0) void h2bcd2(unsigned int bin){ unsigned char tmp; DBYTE[0x0130] = (char)(bin/10000); /* 10000 의자리수저장 */ DBYTE[0x0131] = (char) (( bin % 10000 ) / 1000) ; /* 1000 의자리수가 0x131 번지의하위 4 비트에저장 */ tmp = (char) ((( bin % 10000 ) % 1000) / 100) ; /* 100 의자리수를 tmp 에임시저장 */ DBYTE[0x0131] <<=4 ; /* 1000의자리수를 0x131 번지의상위 4비트로저장하기위해 4 번쉬프트 */ DBYTE[0x0131] = tmp ; /* 100의자리수를 0x131 번지의하위 4 비트로저장 */ DBYTE[0x0132] = (char)((( (bin % 10000) % 1000) %100)/10); /* 10의자리수가 132번지의하위 4 비트에저장 */ tmp = (char)((( ( bin % 10000 ) % 1000) % 100) % 10); /* 1의자리수를 tmp 에임시저장 */ DBYTE[0x0132] <<=4 ; /* 10의자리수를 0x132 번지의상위 4비트로저장하기위해 4 번쉬프트 */ DBYTE[0x0132] = tmp ; /* 1의자리수를 0x132 번지의하위 4 비트로저장 */ void main(void){ unsigned int bin = 0xf0ff; /* 주어진 2진수를 0xff 로초기화 */ h2bcd2(bin); 실험방법 : 실험1 과같은방식으로수행하라. 성공적으로수행된경우내부램 0x130~132 에는차례대로 0x06, 0x16, 0x95 값이저장된다. - 71 -

과제 : 주어진 2진수 0xffe0 를 BCD로변환하여 10000 의자리수는램 0x1000 번지에 1000의자리수는 0x1001번지의상위 4비트에 100의자리수는 0x1001번지의하위4비트에 10의자리수는 0x1002번지의상위 4 비트에 1의자리수는 0x1002 번지의하위4 비트에저장하는프로그램을실험1 을참조하여다른방식으로작성하 라. 3.1.9. 실험 9 : 아스키문자의 16 진수변환 예제 : 아스키코드로주어진숫자배열 { 0, 1,..., 9, 'A', 'B',..., 'F', 'a',..., 'f' 을 16진수헥사코드로 변환하여내부램 0x130 를시작번지로차례대로저장한다. 프로그램작성시유의점 : 숫자 0~9의값은 stdlib.h 를 include 시켜 itoa() 함수를사용해서할수도있다. 숫자 0~9의값은아스키코드는 0x30~0x39 이고, A~F의값은 0x41~46, a~f의값은 0x61~66 이라는점을염두에 두어야한다. 프로그램예 : #include <mega128.h> #define DBYTE ((unsigned char volatile *) 0) flash unsigned char arr[ ]= "0123456789ABCDEFabcdef"; unsigned char asc2hex(unsigned char asc){ if ((asc >= '0') && (asc <='9')) return (asc - '0'); else if ((asc >= 'A') && (asc <='F')) return ((asc - 'A')+10); else if ((asc >= 'a') && (asc <='f')) return ((asc - 'a')+10); else return(0xff); void main(void){ int j = 0, i=0x0130; for(;j<=21; j++) DBYTE[i++] = asc2hex(arr[j]); 실험방법 : 실험1 과같은방식으로수행하라. 성공적으로수행된경우내부램 0x130~13f 에는차례대로 0x00~0x0F 값이 0x140~145 에는 0x0A~0x0F 값이저장된다. 3.1.10. 실험 10 : 숫자의아스키코드변환 예제 : 한자리를갖는 16 진숫자배열 {0,1,2,3,4,5,6,7,8,9, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f 를아스키 코드로변환하여내부램 0x130 를시작번지로차례대로저장한다. 프로그램작성시유의점 : 숫자 0~9의값은 stdlib.h 를 include 시켜 itoa() 함수를사용해서할수도있다. 숫자 0~9의값은아스키코드는 0x30~0x39 이고, A~F의값은 0x41~46, a~f의값은 0x61~66 이라는점을염두에 두어야한다. 프로그램예 : #include <mega128.h> #define DBYTE ((unsigned char volatile *) 0) flash unsigned char arr[ ]= {0,1,2,3,4,5,6,7,8,9, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f; unsigned char hex2asc(unsigned char num){ if(num>=10) return(num+'a'-10); else return(num+'0'); void main(void){ int j = 0, i=0x0130; for(;j<=15; j++) DBYTE[i++] = hex2asc(arr[j]); 실험방법 : 실험1 과같은방식으로수행하라. 성공적으로수행된경우내부램 0x130~139 에는차례대로 0x30~0x39 값이 0x13a~13f 에는 0x41~0x46 값이저장된다. - 72 -

3.1.11. 실험 11 : 지연루틴 예제 : 타이머를쓰지않고소프트웨어에의해적절한시간지연을얻는방법을익힌다. 100usec 시간의지연을 주면서내부램 (0x130) 에저장된값을증가시키는프로그램을작성한다.( 발진주파수는 16MHz 라고가정한다 ). 프로그램작성시유의점 : 다음과같이 while 문을반복적으로사용하여시간지연을얻는프로그램을작성할 수있겠다. void delay(unsigned char i){ while(i--); void main(void){ delay(0x0100); 위의프로그램을컴파일하고 AVR Studio 4 를통해디버그세션에들어가메인메뉴의 [View->Disassembler] 를 클릭하여 Disassembler 창을띠우면 while(i--) 문에해당하는부분에서다음과비슷하게어셈블리어로번역되어 나타난모습을확인할수있다. LDD R30,Y+0 ; Load indirect with displacement, 2 기계사이클소요 ( 반복) SUBI R30,0x01 ; Subtract immediate, 1 기계사이클소요 ( 반복) STD Y+0,R30 ; Store indirect with displacement, 2 기계사이클소요 ( 반복) SUBI R30,0xFF ; Subtract immediate, 1 기계사이클소요 ( 반복) BRNE PC-0x04 ; Branch if not equal, 1/2 기계사이클소요( 반복할때 1 벗어날때 2) ADIW R28,0x01 ; Add immediate to word, 2기계사이클소요 RET ; Subroutine return, 4기계사이클소요 위의루틴에서 i 값에대하여반복수행하는데걸리는시간을계산해 (i+1)*(2+1+2+1+1)+7 기계사이클과같 다. i값은 0~255 를갖게되니최소지연값은 14 기계사이클 ( 발진주파수 16MHz 일때 14/16=0.875usec) 최대지연값 은 1799 기계사이클 ( 발진주파수 16MHz 일때 1799/16=112.4375usec) 가된다. 결국원하는 delaytime_us 마이크 로초에대한 i 값은 (i+1)*(2+1+2+1+1)+7=16*delaytime_us 에의하여다음처럼주어진다. i = delaytime_us*16/7-2 위식에따라 100usec 를얻으려면 i=226 으로하면될것이다. 만약 112usec 보다긴시간의지연을얻으려면 delay() 를여러분호출하면될것이다. 위의루틴으로정확한시간지연을얻기에는 i값이원하는지연시간에대하 여정수로딱떨어지지도않아오차가생기며마이컴의발진주파수에도좌우되는등상황에따라시간지연값이 들쭉날쭉해적절하지않을수도있다. CodeVisionAVR 에는이를위해함수가준비되어있다. delay.h 헤더파일 을 include 시켜 delay_ms(unsigned int i), delay_us(unsigned int i) 를사용하여밀리초나마이크로초단위로비 교적정확하게시간지연을얻을수있다. 그러나인터럽트등에의해지연이발생할수있어아주정확한것은 아니다. 아주정확한시간지연은타이머를사용하거나 DS1302 와같은 RTC IC 를사용한다. 프로그램예 1 : #include <mega128.h> #include <delay.h> #define DBYTE ((unsigned char volatile *) 0) void main(void){ for(;;){ DBYTE[0x0130] += 1; delay_us(100); 프로그램예 2 : #include <mega128.h> #define DBYTE ((unsigned char volatile *) 0) void delay(unsigned char i){ while(i--); void main(void){ for(;;){ DBYTE[0x0130] += 1; delay(226); - 73 -

실험방법 : 실험1 과같은방식으로수행하라. 시뮬레이션에서시간지연은호스트 PC 의성능에좌우된다. 시 뮬레이션에서의지연시간이실제하드웨어를구현했을때의시간지연과는다르다는것을명심해야한다. 실제하 드웨어에구현하였을때는프로그램예2의 delay() 에의한시간지연은마이컴의발진주파수에좌우된다. 3.2. I/O Port 8051은 CPU와외부장치를연결해주기위해양방향성을갖는 6 개(PORTA~PORTF) 의 8 비트입출력 (I/O) 포트 와 1 개(PORTG) 의 5 비트입출력포트를갖고있다. 8051과달리 LED 1개정도는구동하기에충분한전류 40mA를최대구동전류로출력하므로 LED 를포트에연결할때전류흡입형으로구현할필요는없다. 3.2.1. 관련레지스터 3.2.1.1. DDRx 레지스터 입출력의방향설정을하여 DDRA~DDRG 레지스터에입출력포트에대응하는해당비트에 1을쓰면출력으로 0 을쓰면입력으로설정된다. 초기값은 0 으로설정되어있다. 비트별로만약포트 A의비트3를출력으로설정하 려면 DDRA.3 = 1로하면되포트 A를전부출력으로설정하려면 DDRA = 0xff 로하면된다. 3.2.1.2. PORTx 레지스터 DDRx 의값을조절하여출력으로설정된경우 PORTx 레지스터에해당하는값을쓰면된다. 비트별로설정하 려면 PORTx.n = 1 의형태로하면된다(x 는 A~G, n은 0~7). 만약포트 B의비트3에 1을출력하려면 PORTB.3 = 1 로하면된다. 3.2.1.3. PINx 레지스터 입력으로설정된경우 PINx 레지스터에해당하는값을읽으면된다. 해당핀의값을읽어들인다. 쓰기가금지 되어있다. 비트별로읽어들이려면 PINx.n 를사용하면된다비트별로만약포트 C의비트3 값을읽어들여 led3라는비트값에할당하려면 led3 = PINC.3 로하면된다. 3.2.1.4. SFIOR 레지스터 SFIOR(Special Function IO Register) 의비트2(PUD: Pull-Up Disable) 를 1로세트하면풀업저항을비활성화 시킨다. 3.2.2. 구조및동작 기본구조 : 그림 78에보여진것과같이양방향성으로 20K~100K 옴의내부풀업을갖는구조를갖고있다. 내부풀업저항의설정 : SFIOR 의비트 2 를이용하여모든입출력핀의풀업저항을비활성화할수있다. DDRx.n 의값을조절하여입력으로설정된경우에는해당하는 PORTx.n 에 1을쓰면내부풀업저항을사용할 수있다. 내부풀업저항을사용하지않기위해서는 PORTx.n 에 0 을쓰거나해당핀을출력으로설정하면된다. 읽어들이는동작 : PINx.n 레지스터비트를읽을때안정을위하여최대 1.5클럭에서 0.5클럭의지연이존재 하므로이를감안해서읽어야한다. 결국 PORTx.n 비트에출력한값을다시읽어들일때는 NOP(1 클럭이소요 됨) 와같은명령을삽입하는것이좋다. 슬립모드시핀의동작 : 슬립모드가동작하면포트의핀입력은접지로클램프되어동작이멈춘다. 이때사용 하지않는핀은외부에서풀업또는풀다운으로확실한논리상태를입력하는것이전력소비를감소시킨다. 손쉬 운방법으로내부의풀업을이용하는것이다. 포트A (PA7~PA0: 핀44-51) : 내부풀업저항이있는 8 비트양방향입출력단자. 외부메모리를둘경우에는 주소버스 (A7-A0) 와데이터버스 (D7-D0) 로사용. 포트B (PB7~PB0: 핀10-17) : 내부풀업저항이있는 8 비트양방향입출력단자. SPI용단자혹은 PWM 단자 - 74 -

로도사용된다 ( 표2 참조). 포트C (PC7~PC0: 핀35-42) : 내부풀업저항이있는 8 비트양방향입출력단자. 외부메모리를둘경우에는 주소버스 (A15-A8) 로사용된다. 포트D (PD7~PD0: 핀25-32) : 내부풀업저항이있는 8 비트양방향입출력단자. 타이머용단자혹은외부인 터럽트용단자로도사용된다 ( 표3 참조). 포트E (PE7~PE0: 핀2-9) : 내부풀업저항이있는 8 비트양방향입출력단자. 타이머용단자, 외부인터럽트, 아날로그비교기, USART 용단자로도사용된다 ( 표4 참조). 포트F (PF7~PF0: 핀54-61) : 내부풀업저항이있는 5 비트양방향입출력단자. AD변환기혹은 JTAG 인터 페이스용단자로도사용된다 ( 표5 참조). 포트G (PG4~PE0: 핀19, 18, 43, 34, 33) : 내부풀업저항이있는 8 비트양방향입출력단자. 외부메모리 접속을위한스트로브신호용, RTC(Real Time Counter) 타이머용발진기단자로도사용된다 ( 표5 참조). 3.3. 단순출력연습 3.3.1. 실험 12 : LED 점멸 1 그림 78. I/O 포트의기본구조( 출처:ATMEL) - 75 -

예제 : 포트C 에연결된 8개의 LED를 0.4 초간격으로좌로이동하며한개씩켠다. 즉처음 PORTC.0 에연결 된 LED만켜고 0.4초후에 PORTC.1 에연결된 LED만켜고이런식으로반복적으로 8개의 LED를순차적으로 켠다. 프로그램작성시유의점 : 0.4초의시간지연은실험10의 delay 루틴을사용한다. 그림 79의회로에서 0을출력 해야 LED가켜지고 1 을출력하면꺼진다. mega128.h 를 include시켜야 PORTC.n 을사용할수있다. delay_ms() 를사용하려면 delay.h를 include 시켜야한다. 회로도 : 그림 79 의시스템을구성한다. LED는화합물반도체의 PN접합에빛이투과하도록 P형층을매우얇 게만든소자로 P 형( 애노드 : 양극) 에 (+) 전위 N 형( 캐소드 : 음극) 에 (-) 전위를가하면즉순방향을가하면전류가 흐르면서전계발광현상에의해발광한다. 대략 2 V와 20 ma 정도의직류전압전류에서동작한다. 기본적으로 전압구동소자가아니라전류구동소자이며발광하는광의세기는전류에비례하며각종표시장치에응용되는소 자이다. LED 의단자중긴것이애노드( 양극) 이다. 실험할때는 LEDSW 를닫고한다. 프로그램예 : 그림 79. 기본입출력실험을위한회로도 #include <mega128.h> void delay(unsigned char i){ // 시간지연루틴약 0.875~112usec 시간지연얻을수있다 while(i--); // delay(226) 은대략 0.1msec 의시간지연을얻을수있다. void delayms(unsigned int i){ // i msec 시간지연을얻을수있다. unsigned int j,k; for(j=0;j<i;j++) for(k=0;k<10;k++) delay(226); void main(void){ unsigned char led=0xfe; DDRC = 0xff; for(;;){ if (led!= 0x7f) led = (led << 1 ) 0x01; /* 비트7 를켜지않았으면 1비트씩좌로시프트하고빈자리에 1 을 */ else led = 0xfe; /* 비트7 을켰으면다시처음으로와서비트0 를켠다. */ - 76 -

delayms(400); /* 0.4 초시간지연, 시뮬레이션할때는제거하고해도됨*/ PORTC = led; 실험방법 : 1CodeVisionAVR 의에디터를통해실행파일을만든후 AVR Studion4 디버그세션에들어간후메 인메뉴의 [View->Memory] 를실행하여 Memory 라는이름의창을생성하고창에서 [Data] 을선택한다. 메인메 뉴의 [View->Memory1] 를실행하여 Memory1 라는이름의창을생성하고창에서 [Program] 을선택한다. 또한 [View->Register] 를실행하여 Register 라는이름의창을생성한다. 2디버그세션에서메인메뉴 [Debug] 의하 위메뉴인 [Step Into], [Auto Step], [Run to Cusor] 등을적절히활용하면서 Memory, Register, I/O View 창을통해내부램과레지스터의값의변화를확인하라. 시뮬레이션할때 delay(), delayms() 는시간을많이걸리 게하므로제거하고해도된다. 3시뮬레이션이성공적이었으면실행파일을만들고그림 51의인터페이스회로와 그림 79의 ISP CON을연결하고 79의전원을넣은상태에서 2.5.5 절에나온방법을참조하여다운로드하라. 4 시스템이성공적으로동작하는지확인하라. 과제 : 1 0.3 초마다우로이동하며점멸동작하도록해보라. 2 LED가 2진가산형태로 0.4초마다점멸동작하 도록해보라. 3.3.2. 실험 13 : LED 점멸 2 예제 : 포트C 에연결된 8개의 LED를 0.04초간격으로좌로이동하며한개씩켜고 PORTC.7 해당하는 LED 까지켰으면우로이동하며한개씩켠다. 이것을반복적으로수행하여점멸이좌우로흔들리도록한다. 프로그램작성시유의점 : 그림 79의회로에서 0을출력해야 LED가켜지고 1 을출력하면꺼진다. 회로도 : 그림 79 의시스템을사용한다. 실험할때는 LEDSW 를닫고한다. 프로그램예 : #include <mega128.h> #include <delay.h> // delay_ms(), delay_us() 를이용할것이다. void main(void){ unsigned char led=0xfe, i; DDRC = 0xff; for(;;){ for(i=0;i<=6;i++) { led = (led << 1 ) 0x01; /* 비트7 를켜지않았으면 1비트씩좌로시프트하고빈자리에 1 을 */ delay_ms(40); // 시뮬레이션할때는제거하고해도됨 PORTC = led; for(i=0;i<=6;i++) { led = (led >> 1 ) 0x80; /* 비트7 을켰으면 1비트씩우로시프트하고빈자리에 1 을 */ delay_ms(40); // 시뮬레이션할때는제거하고해도됨 PORTC = led; 실험방법 : 실험11 을참조해서하라. 시뮬레이션할때 delay_ms() 는시간을많이걸리게하므로제거하고해 도된다. 과제 : 0.04초간격이외의 0.01초나 0.1 초등다양한시간간격으로똑같은동작을구현해보라. 3.3.3. 실험 14 : LED 점멸 3 예제 : PORTC 포트에연결된 8개의 LED 를롬데이터에따라점등패턴과지속시간을결정하여점등한다. 롬 데이터를끝까지다읽어점등했으면다시처음의데이터에따라점등한다. 이를무한히반복한다. 프로그램작성시유의점 : 지속시간은롬데이터에주어진값에 100을곱한값으로하며롬데이터의끝까지 수행한경우다시처음의데이터를읽어반복수행한다. 회로도 : 그림 79 의시스템을사용한다. 실험할때는 LEDSW 를닫고한다. 프로그램예 : - 77 -

#include <mega128.h> void delay(unsigned char i){ // 시간지연루틴약 0.875~112usec 시간지연얻을수있다 while(i--); // delay(226) 은 0.1msec 의시간지연을얻을수있다. void delayms(unsigned int i){ // i msec 시간지연을얻을수있다. unsigned int j,k; for(j=0;j<i;j++) for(k=0;k<10;k++) delay(226); flash unsigned char ledp[ ] = { 0xfe, 0xef, 0x44, 0x11, 0x23, 0x34, 0x35, 0x67; flash unsigned char ledt[ ] = { 0x22, 0x33, 0x44, 0x45, 0x56, 0x66, 0x78, 0x66; void main(void){ unsigned char i; DDRC = 0xff; for(;;){ for(i=0;i<=8;i++){ PORTC = ledp[i]; delayms((unsigned int)(ledt[i]*100)); 과제 : 다양한시간간격과패턴으로점멸하는동작을구현해보라. 3.3.4. 실험 15 : LED 점멸 4 예제 : C포트에연결된 8개의 LED를 stdlib.h 에있는 rand() 함수를이용하여패턴과지속시간을결정하여점 등한다. 프로그램작성시유의점 : rand() 를사용하여려면 #include <stdlib.h> 를프로그램에포함시켜야한다. 그리고 rand() 는 0~32767 까지의숫자를만들어낸다. 회로도 : 그림 79 의시스템을사용한다. 실험할때는 LEDSW 를닫고한다. 프로그램예 : #include <mega128.h> #include <stdlib.h> // rand() 를이용할것이다. void delay(unsigned char i){ // 시간지연루틴약 0.875~112usec 시간지연얻을수있다 while(i--); // delay(226) 은 0.1msec 의시간지연을얻을수있다. void delayms(unsigned int i){ // i msec 시간지연을얻을수있다. unsigned int j,k; for(j=0;j<i;j++) for(k=0;k<10;k++) delay(226); void main(void){ DDRC = 0xff; for(;;){ PORTC = (char)(rand() % 0x80); delayms((unsigned int)(2*rand())); 과제 : delay.h를 include 하여 delay_ms(), delay_us() 로시간지연하는프로그램으로수정해보라. 3.4. 단순입출력연습 3.4.1. 실험 16 : 키누름수세기 예제 : PD0에연결된누름키가눌린수를세어 C포트에연결된 8개의 LED 로표시한다. 회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 또한그림 80의 SW1 을누르면서실험한다. 프로그램작성시유의점 : 기계식키를누르면탄성에의해( 키를누르면 0이고안누른상태를 1이라가정했 을때 ) 0상태에안정적으로도달하기전에 0과1 을여러번반복하는바운스 (Bounce) 또는채터링 (Chattering) 이 - 78 -

일어난다. 바운스현상은수십 msec 동안일어나사람은단지 1번누른것처럼느끼지만마이컴은여러번눌린 것처럼오인하게된다. 키를눌렀다뗄때도마찬가지로바운스현상이일어난다. 키에 2개의 NAND 게이트를사 용하여하드웨어적으로바운스현상을줄일수도있지만소프트웨어에의해할수있다. 여러가지소프트웨어에 의한바운스처리법이있지만본실험에서는키가눌리지않은상태(1 레벨) 에서시작하여키가눌려짐 (0 레벨) 을 검출하고적절한시간지연후에( 보통 20-50 msec) 또다시눌려짐 (0 레벨) 을검출하는즉두번확인하는방식 을택한다. 그림 80의회로에서풀업저항 10K옴대신무한대의저항즉풀업저항 10K옴을없애고개방하여 입력장치로사용해도된다. 이것은 I/O 포트들이입력으로사용될때내부풀업저항을사용할수있기때문이다. 이런경우해당포트핀을입력으로설정하기위해 DDRx.n=0 명령에부가적으로 PORTx.n=1 명령으로해당포 트핀에 1 을써넣어야내부풀업저항을사용할수있다. 프로그램예 : 그림 80. 단순키보드스캔을위한회로도 #include <mega128.h> #include <delay.h> // delay_ms(), delay_us() 를이용할것이다. void main(void){ unsigned char key_num = 0; DDRC = 0xff; // 포트C 를출력으로 DDRD = 0x00; // 포트D 를입력으로디폴트입력으로설정되어있으므로필요하지는않음 for(;;) { while( PIND.0 == 1 ); /* 눌릴때(PIND.0 ==0) 까지대기눌리면아래로 */ delay_ms(40); /* 약 40msec 시간지연하고다시읽기*/ if( PIND.0 == 0){ /* 40msec 후에도눌려있으면유효한키입력이므로아래로 */ key_num += 1; PORTC = ~key_num; /* 1일때꺼지고 0 일때켜지므로반전시켜출력시킨다. */ while(pind.0 == 0); /* 키눌림이해제될때까지대기 */ 실험방법 : 1CodeVisionAVR 의에디터를통해실행파일을만든후 AVR Studion4 디버그세션에들어간후메 인메뉴의 [View->Memory] 를실행하여 Memory 라는이름의창을생성하고창에서 [Data] 을선택한다. 메인메 뉴의 [View->Memory1] 를실행하여 Memory1 라는이름의창을생성하고창에서 [Program] 을선택한다. 또한 [View->Register] 를실행하여 Register 라는이름의창을생성한다. 2디버그세션에서메인메뉴 [Debug] 의하 위메뉴인 [Step Into], [Auto Step], [Run to Cusor] 등을적절히활용하면서 Memory, Register, I/O View 창을통해내부램과레지스터의값의변화를확인하라. 시뮬레이션할때 delay_ms() 는시간을많이걸리게하므 로제거하고해도된다. [Auto Step] 를누르고 IO View창의 PIND레지스터비트0의값을변화시켜가며 PORTC 의변화를관찰하라. PIND.0 을변화시킬때마다 PORTC 의값이증가해야한다. 3시뮬레이션이성공적이었으면 실행파일을 ISP소프트웨어와인터페이스회로를사용하여그림 79 의시스템에다운로드하라. 4시스템이성공적 으로동작하는지확인하라. - 79 -

과제 : 시간지연을다르게하여수행해보라 ( 수 msec 단위로작게수백 msec 단위로크게). 3.4.2. 실험 17 : 파일럿램프 1 예제 : 딥스위치가연결된 PORTD.0~3 로부터입력을받아그에대응하는 PORTD.4~7 에연결된 LED 를켠다. 프로그램작성시유의점 : LED가켜지는것이 0상태이고꺼지는것이 1 상태이다. 그러므로그림 81의회로에 서딥스위치를조작했을때그에연결된 LED가켜졌다면입력으로 0 상태가들어간것이다. 회로도 : 그림 81에주어진회로의 L1을그림 79의 D_CON 을연결하고, 그림 81의딥스위치의 5~8번을개 방한상태로한다. 그러면 PORTD.0~3 을통해 LED 를점멸할수있는상태가된다. 그림 81의딥스위치의 1~4 번을열고닫아실험하면된다. 프로그램예 : #include <mega128.h> void main(void){ unsigned char ledp; DDRD = 0xf0; for(;;) { ledp = PIND; // PORTD.4~7 을출력으로나머지를입력으로설정 ledp = (ledp << 4) & 0xf0 ; // 비트4~7 에연결된 LED 에출력하기위해 4 번시프트한다. PORTD = ~ledp; // 반전시켜출력하라. 실험방법 : 실험 16 을참조해서수행하라. 3.4.3. 실험 18 : 파일럿램프 2 그림 81. 딥스위치를이용한간단한입력회로 예제 : 딥스위치가연결된포트D 로부터입력을받아그에대응하는포트A 에연결된 LED 를켠다. 회로도 : 그림 81에주어진회로의 L1을그림 79의 D_CON 을연결한다. 그림 79의 LEDSW 를닫는다. 그림 81의딥스위치의 1~8 번을열고닫아실험하면된다. 프로그램예 : #include <mega128.h> void main(void){ DDRD = 0x00; // PORTD 를 입력으로설정 DDRA = 0xff; // 포트A 를출력으로설정 for(;;) { PORTA = ~PIND; // 반전시켜출력하라. - 80 -

3.4.4. 실험 19 : 입출력함수구현 예제 : 딥스위치가연결된포트D 비트0~2 로부터입력을받아미리롬에기록된데이타값에따라포트D 3~7 에연결된 LED 를켜고끈다. 본실험에서구현된입출력관계는다음과같다. 입출력관계 : 000->01101, 001->10010, 010->00010, 011->10001, 100->11100, 101->10101, 110->00100, 111->10100 회로도 : 그림 81에주어진회로의 L1을그림 79의 D_CON 을연결하고, 그림 81의딥스위치의 4~8번을개 방한상태로한다. 그러면 PORTD.3~7 를통해 LED 를점멸할수있는상태가된다. 그림 81의딥스위치의 1~3 번을열고닫아실험하면된다. 프로그램작성시유의점 : LED가켜지는것이 0상태이고꺼지는것이 1 상태이다. 입력이 000일때 01101을 출력하는것으로했는데롬에이패턴을기록해둘때는 01101xxx( 여기에서 x는 0 또는 1) 이되어야한다. 본 실험에서는 x=0 으로하였다. 즉 01101의패턴은 0x68로기록되고 10010의패턴은 0x90 식으로한다. 프로그램예 : #include <mega128.h> unsigned char arr[ ]={ 0x68, 0x90, 0x10, 0x88, 0xE0, 0xA8, 0x20, 0xA0; void main( void ) { unsigned char ledp; DDRD = 0b11111000; // 비트0~2 는입력, 나머지는출력 for(;;) { ledp = PIND & 0b00000111 ; /* 하위 3 비트만마스킹 */ PORTD = arr[ledp] ; // 반전시켜출력한다. 예제 : 다른형태의입출력함수를구현해보아라. 3.4.5. 실험 20 : 입력값에따른 LED 점멸속도조절 예제 : 딥스위치가연결된포트D 로부터입력을받아포트C 에연결된 LED 의점멸속도를조절한다. 회로도 : 그림 81에주어진회로의 L1에그림79 의 D_CON 을연결한다. 그림 81의딥스위치를열고닫아그 값을입력으로삼아실험하면된다. 실험할때는그림79 의 LEDSW 를닫고한다. 프로그램예 : #include <mega128.h> #include <delay.h> void main(void){ unsigned char led=0xfe; unsigned int dt; DDRC = 0xff; //Port C 를출력으로설정. DDRD = 0x00; // 포트 D를입력으로설정 for(;;){ for(dt=0; dt < (int) 256*PIND ;dt++) delay_ms(1); // 시간지연값을입력받아시간지연한다. if (led!= 0x7f) led = (led << 1 ) 0x01; // 비트7 를켜지않았으면 1비트씩좌로시프트하고빈자리에 1을 else led = 0xfe; /* 비트7 을켰으면다시처음으로와서비트0 를켠다. */ PORTC = led; - 81 -

4.1. 외부인터럽트실험 4. 인터럽트와타이머실험 4.1.1. 인터럽트의개념과종류 인터럽트는어떤조건이나사건의발생으로정상적인프로그램을일시적으로중지시키고보다시급한작업을 먼저수행하고다시원래로복귀하여실행순서를변경하도록만드는것을말한다. 인터럽트요청에따라수행하 는프로그램을인터럽트서비스루틴또는인터럽트핸들러라한다. 인터럽트는마이컴시스템을구현하는데커다 란역할을차지하며발생시기를예측하기힘든사건에마이컴이가장빠르게대응할수있는방법이며비교적 저속으로동작하는주변장치의요청에고속으로동작하는마이컴사이에효율적으로일을수행하는중요한수단 이된다. 인터럽트의 3 요소 : 1 발생원 : 누가요청했는가? 2 우선순위 : 2 개이상의요청시누구를먼저서비스할까? 3 인터럽트벡터 인터럽트의종류 : 서비스루틴의시작번지는어디인가? : 발생원인이존재하는곳에따라내부와외부로나뉘고, 차단가능성에따라차단가능인터럽 트와차단불가능인터럽트로나뉘고, 인터럽트발생원인을확인하는방법에따라조사형과벡터형으로나뉜다. 내부인터럽트는영으로나누는등금지된연산이나금지된메모리로의접근시도등에따라마이컴내부에서 발생하는인터럽트며외부인터럽트는입출력장치의작업종료, 타이머의오버플로, 외부장치의통신요청등외부 장치에의해발생되는인터럽트로일반적으로인터럽트하면외부인터럽트를지칭한다. ATmega128 은 8051처 럼내부인터럽트에해당하는것이없다. 프로그램에의해인터럽트서비스요청을차단하지못하는것을차단불가능인터럽트라하며전원이상등의매 우중요한돌발사태에대비하기위해대부분의마이크로프로세서에서사용되지만 ATmega128 는 8051처럼차 단불가능인터럽트를사용하지않는다. 차단가능한인터럽트를차단하는방법은특정레지스터값의설정에따라 한다. 인터럽트를요청한장치가특정한상태비트를세트해표시해놓으면이를마이컴이소프트웨어적으로조사하 고찾는순서에따라우선순위가정해지는방식을조사형인터럽트라하고인터럽트발생원인에따라미리지정 된서비스루틴의시작번지 ( 인터럽트벡터) 에서처리하는방식을벡터형이라하는데벡터형이인터럽트발생원인 을찾고서비스루틴을처리하는시간이빠른장점이있다. ATmega128 은벡터형을사용한다. ATmega128 의인터럽트는차단가능한외부인터럽트에해당하며리셋을포함하여총 35개의인터럽트벡터를 가지고있다. 리셋을제외한 34개의인터럽트는외부핀을통하여요청되는외부인터럽트 8 개, 타이머 0 관련 2 개, 타이머1 관련 5 개, 타이머2 관련 2 개, 타이머3 관련 5 개, USART0 관련 3 개, USART1 관련 3 개, 기타 6개 로분류될수있다. 4.1.2. ATmega128 의인터럽트처리과정 1 단계 : 매사이클의인터럽트요청이있는지확인하고해당인터럽트플랙에기록한다. 2 단계 : 어느인터럽트요청이있는지인터럽트플랙을조사하고우선순위와허용여부를결정한다. 3 단계 : 인터럽트벡터주소를찾아가기위한 CALL 명령이수행되며다른인터럽트발생을방지하기위해 SREG의 I 비트를클리어시키고복귀주소 (PC) 값을스택에저장한다. 4 단계 : 인터럽트벡터에따라인터럽트서비스루틴으로점프하여실행한다. 5 단계 : RETI 를만나면스택에저장된 PC 를복구하여원래프로그램으로복귀한다. 4.1.3. 인터럽트처리시간 - 82 -

응답시간 : 인터럽트를허용하는 SEI 명령이실행되었더라도최소한그다음에있는 1개의명령이실행되고 인터럽트가수행된다. 인터럽트서비스를끝내고원래의프로그램으로복귀한경우에도이미대기상태에있던 다른인터럽트를수행하기전에최소한 1 개의명령이실행된다. 또한인터럽트벡터는 3클럭이요구되는 JMP 명령으로이루어져있어 1개의명령이최소 1클럭이므로인터럽트요청후서비스시작하기까지최소 4클럭이걸 린다. 이동안에다른인터럽트발생을방지하기위해 SREG의 I비트를클리어시키고 PC를스택에저장하고인 터럽트벡터주소를찾아가서거기에있는값에따라인터럽트서비스루틴으로점프한다. 만약 2클럭이상의명 령을수행하고있었으면응답시간은증가한다. 슬립모드에있었을때는기동시간이포함되어응답시간이증가된 다. 복귀시간 : RETI는 4 클럭이소요된다. 즉인터럽트서비스를마치고원래프로그램으로복귀하는데에는 4클 럭이소요된다. 이시간동안 PC의값이스택에서꺼내지고스택포인터가 2만큼증가되며 SREG의 I비트가 1로 세트된다. 4.1.4. 인터럽트제어 4.1.4.1. 벡터배치 Fuse High Byte의 BOOTRST 비트값과 MCUCR 레지스터의 IVSEL 비트값으로벡터의배치를그림 82처럼 바꿀수있다. 그림 82에서 Boot Reset Address 는그림 12 에주어졌다. 그림 82. 인터럽트벡터의배치( 출처:ATMEL) 그림 83은 Fuse High Byte의 BOOTRST 비트값이 1로 MCUCR 레지스터의 IVSEL은 0으로즉디폴트로설정 된경우의인터럽트벡터를보여준다. 4.1.4.2. MCUCR 레지스터 비트1(IVSEL:Interrupt Vector SELect) : 그림 82 처럼인터럽트벡터의배치를변경할수있다. IVSEL 이변 경되인터럽트벡터의예기치않게이동되는것을방지하기위해 IVSEL 의변경은다음의절차에따른다. 1 IVCE비트에 1 을쓴다. 2 4사이클이내에 IVCE =0 으로설정하고 IVSEL 에원하는비트값으로설정한다. 비트0(IVCE:Interrupt Vector Change Enable) : 1로세트하면 IVSEL 을변경할수있다. IVCE비트는 IVSEL 비트를변경하고난이후에 4클럭이지나면하드웨어의의해서 0 으로자동적으로클리어된다. 4.1.4.3. 허용과우선순위 전체적인허용은상태레지스터 (SREG) 의비트7(I) 를 1 로하여설정한다. 개별적인허용은여러가지인터럽트마스크레지스터를통하여개별적으로허용여부를제어한다. ATmega128 은 8051 처럼인터럽트의우선순위를줄수없고먼저들어온것을먼저처리한다. 동시에들어오 는경우에는하드웨어에의해순위가정해져있는데그림 4.1.4.4. 외부인터럽트트리거 83 에벡터표순서대로순위가고정되어있다. 입력 : 외부인터럽트핀 INT0~3( 핀25~28, PD0~3), INT4~7( 핀6~9, PE4~7) 을통해입력되는신호로발생 하며입출력포트핀이출력으로설정되더라도발생시킬수있다. 소프트웨어적으로해당핀에값을출력시켜인 - 83 -

터럽트를발생시킬수있다. 그림 83. ATmega128 의인터럽트발생원과벡터값 ( 출처:ATMEL) 트리거링 : 논리 0 의레벨, 하강에지, 상승에지값을해당핀에주어인터럽트를발생시킬수있다. 이들은 EICRA(INT0~3 용), EICRB(INT4~7 용) 으로설정한다. 에지트리거는 50ns 이상의펄스폭을가져야한다. 레벨 - 84 -

트리거인터럽트신호는워치독오실레이터에의해 2 번샘플링되며이기간이상의펄스폭을주어야한다. 허용제어 : SREG의 I비트를사용하여전체적인허용을제어하고 EICRA, EICRB 를이용하여트리거링을설 정하고 EIMSK 를이용하여개별적으로허용하여발생을제어한다. 개별적으로허용되어있더라도 SREG의 I비트 가 0 으로되어있으면인터럽트는발생되지않는다. 개별적인허용과전체적인허용이있고해당핀에적절한신 호가들어와야인터럽트는발생될수있다. 슬립모드의해제 : 레벨트리거로설정한경우의 INT0~7 과하강또는상승에지트리거방식으로설정된 INT0~3 은인터럽트가클럭에관계없이비동기로검출되어슬립모드를해제하는데사용할수있다. 하강또는 상승에지트리거방식으로설정된 INT4~7 의경우는 I/O 클럭을필요로하여이클럭이차단되는슬립모드들 ( 아 이들모드를제외한모든슬립모드 ) 에서는슬립모드를해제하는데사용할수없다. 4.1.4.5. EICRA 레지스터 EICRA(External Interrupt Control Register A) 레지스터는초기값은 00으로외부인터럽트 0~3의트리거설 정에사용된다. 비트7~0(ISCn1, ISCn0) : 여기에서 n은 3~0 의값을갖는다. 값이 ISCn1:ISCn0 = 11일때 INTn을상승에지 에서, 10 일때는하강에지에서, 00일때는 0 레벨에서트리거되도록설정한다. 01 은보류되어있다. 4.1.4.6. EICRB 레지스터 비트7~0(ISCn1, ISCn0) : 여기에서 n은 7~4 의값을갖는다. 값이 ISCn1:ISCn0 = 11일때 INTn을상승에지 에서, 10 일때는하강에지에서, 01 일때는상승에지또는하강에지에서, 00일때는 0 레벨에서트리거되도록설정 한다. 4.1.4.7. EIMSK 레지스터 EIMSK(External Interrupt MaSK register) 레지스터는 INT7~0 의개별적인허용제어에사용된다. 비트7~0(INT7~0) : 초기값은 00으로 1 로설정되어있으면해당인터럽트가허용된다. 4.1.4.8. EIFR 레지스터 EIFR(External Interrupt Frag Register) 레지스터는외부인터럽트가에지트리거에의해요청된경우허용여 부에상관없이 1 로세트된다. 만약인터럽트가허용된경우인터럽트서비스와함께자동적으로 0으로클리어된 다. 플랙에 1 을써넣음으로클리어시킬수있다(0 을써넣는것이아님에주의하라 ). 레벨트리거로설정한경 우에는항상 0 으로클리어된다. 4.1.5. 실험 21 : LED 점멸 1 예제 : INT0(PORTD.0) 에연결된스위치를누르면상승에지트리거에의한인터럽트가발생하여 PORTC 에 연결된 LED가 1 칸옮겨가면서켜진다. 회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 또한그림 80의 SW1 을누르면서실험한다. 프로그램작성시유의점 : 디버깅시 [Auto Step] 를누르고 IO View창의 PIND레지스터비트0의값을변화시 켜가며 PORTC 의변화를관찰하라. PIND.0 을변화시킬때마다 PORTC 의값이변화해야한다. CodeVisoinAVR 에서인터럽트번호에따른이름을예로 INT0~7 은 EXT_INT0~EXT_INT7 로 ATmega128 의경우에는 mega128.h 에정의해놓았다. 이를이용해서프로그램을짜도된다. 그림 80의회로에서풀업저항 10K옴대 신무한대의저항즉풀업저항 10K 옴을없애고개방하여입력장치로사용해도된다. 이것은 I/O포트들이입력 으로사용될때내부풀업저항을사용할수있기때문이다. 이런경우해당포트핀을입력으로설정하기위해 DDRx.n=0 명령에부가적으로 PORTx.n=1 명령으로해당포트핀에 1을써넣어야내부풀업저항을사용할 수있다. - 85 -

프로그램예 : #include <mega128.h> #include <delay.h> // delay_ms(), delay_us() 를이용할것이다. void main(void){ unsigned char led = 0xfe; interrupt [2] void exint0(void){ // interrupt [EXT_INT0] void exint0(void) 처럼 mega128.h 에저장된정의를사용해도됨 if(led!=0x7f) led = (led << 1) 0x01; // 비트7 을켜지않았으면 1비트씩좌로시프트하고빈자리에는 1 을채운다. else led = 0xfe; // 비트7 을켰으면다시처음으로와서비트 0 을켠다. PORTC = led; delay_ms(5); // 5msec delay void main(void){ DDRC = 0xff; // 포트C 를출력으로 PORTC = led; DDRD = 0x00; // 포트D 를입력으로디폴트입력으로설정되어있으므로필요하지는않음 SREG.7 = 1; // 인터럽트전체허용 EIMSK = 0x01; // INT0 개별허용 EICRA = 3; // 상승에지트리거 while(1); 과제 : 1 실제구현했을때한번누를때마다하나씩이동하지않고여러개가이동하는현상이발생할것 이다. 이는실험 16 에서도이야기한채터링에의한현상이다. delay_ms(5) 의값을변화시켜가면서실험해보고 적정한시간지연을찾아보아라. 2 그림 80의회로대신그림84 의회로를이용하되시간지연을작게해서실 험해보고비교해보라. 3외부인터럽트 1~3 으로같은역할을하는프로그램을구현해보라. 4.1.6. 실험 22 : LED 점멸 2 그림 84. 간단한채터링방지키입력회로 예제 : INT0(PORTD.0) 에연결된스위치를누르면상승에지트리거에의한인터럽트가발생하여 PORTC 에 연결된 LED가 1 칸좌로옮겨가면서켜진다. INT1(PORTD.1) 에연결된스위치를누르면레벨트리거에의한인 터럽트가발생하여 PORTC 에연결된 LED가 1 칸우로옮겨가면서켜진다. - 86 -

회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 또한그림 80의 SW1과 SW2 를누르면서실험한다. 프로그램예 : #include <mega128.h> #include <delay.h> // delay_ms(), delay_us() 를이용할것이다. unsigned char led = 0xfe; interrupt [2] void exint0(void){ // interrupt [EXT_INT0] void exint0(void) 처럼 mega128.h 에저장된정의를사용해도됨 if(led!=0x7f) led = (led << 1) 0x01; // 비트7 을켜지않았으면 1비트씩좌로시프트하고빈자리에는 1 을채운다. else led = 0xfe; // 비트7 을켰으면다시처음으로와서비트 0 을켠다. PORTC = led; delay_ms(40); interrupt [3] void exint1(void){ // interrupt [EXT_INT1] void exint1(void) 처럼 mega128.h 에저장된정의를사용해도됨 if (led!= 0xfe) led = (led >> 1 ) 0x80; /* 비트0 를켜지않았으면 1비트씩우로시프트하고빈자리에 1 을 */ else led = 0x7f; /* 비트0 을켰으면다시처음으로와서비트7 를켠다. */ PORTC = led; delay_ms(40); void main(void){ DDRC = 0xff; // 포트C 를출력으로 PORTC = led; DDRD = 0x00; // 포트D 를입력으로디폴트입력으로설정되어있으므로필요하지는않음 SREG.7 = 1; // 인터럽트전체허용 EIMSK = 0b00000011; // INT0, 1 개별허용 EICRA = 3; // INT0 상승에지트리거, INT1 레벨트리거 while(1); 과제 : 1 INT0(PORTD.0) 와 INT1(PORTD.1) 의역할을바꾼프로그램을구현해보라. 2 INT2(PORTD.2) 와 INT3(PORTD.3) 을이용하여같은역할을하는것을구현해보라. 4.1.7. 실험 23 : 카운터 예제 : 에지트리거되는외부인터럽트를이용하여카운트하는프로그램으로 INT0(PORTD.0) 에연결된 SW1 를누르면상승에지트리거에의한인터럽트가발생하여눌린수를세어 PORTC 에연결된 LED 에표시한다. 회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 또한그림 80의 SW1 을누르면서실험한다. 프로그램예 : #include <mega128.h> #include <delay.h> // delay_ms(), delay_us() 를이용할것이다. unsigned char led; interrupt [2] void exint0(void){ // interrupt [EXT_INT0] void exint0(void) 처럼 mega128.h 에저장된정의를사용해도됨 PORTC = ~(++led); /* led를 1 증가시키고반전한것을출력시킨다 */ delay_ms(5); void main(void){ DDRC = 0xff; // 포트C 를출력으로 DDRD = 0x00; // 포트D 를입력으로디폴트입력으로설정되어있으므로필요하지는않음 SREG.7 = 1; // 인터럽트전체허용 EIMSK = 0b00000001; // INT0 개별허용 EICRA = 3; // INT0 상승에지트리거 PORTC = ~led; /* 0일때 LED 가켜지고 1 일때꺼지므로반전시켜서출력 */ for(;;); /* 인터럽트발생할때까지대기 */ - 87 -

과제 : 1 실제구현했을때한번누를때마다하나씩이동하지않고여러개가이동하는현상이발생할것 이다. 이는실험 16 에서도이야기한채터링에의한현상이다. delay_ms(5) 의값을변화시켜가면서실험해보고 적정한시간지연을찾아보아라. 2 그림 80의회로대신그림84 의회로를이용하되시간지연을작게해서실 험해보고비교해보라. 3외부인터럽트 1~3 으로같은역할을하는프로그램을구현해보라. 4 INT0(PORTD.0) 에 연결된 SW1를누르면증가하고 INT1(PORTD.1) 에연결된 SW2 를누르면감소하는프로그램을구현해보라. 4.2. 타이머실험 ATmega128 에는타이머 0~3 모두 4 개의타이머 / 카운터가존재한다. 이들은인터럽트와 PWM 출력기능을갖 고있다. 그중에서타이머0, 2는 8비트로서로기능이유사하고타이머 1, 3는 16 비트로서로기능이유사하다. 다만타이머0은다른타이머와달리 32.768KHz 의수정진동자에접속하는 TOSC1,2 단자를가지고있어서 Real Time Clock 의기능을갖고있다. 인터럽트는오버플로에의해발생하는오버플로인터럽트, 카운터값이출력비교레지스터의값과같게되는 경우발생하는출력비교인터럽트, 입력캡쳐인터럽트가있다. PWM 기능은출력비교기능을이용하여출력비교신호에주기와 duty ratio를가변할수있는출력신호를생 성하여 OC0, OC2, OC1A~C, OC3A~C 단자로출력하는것이다. 타이머 1, 3 은외부트리거신호에의해현재의카운터값을캡쳐할수있는기능을갖고있다. 4.2.1. 타이머카운터 0, 2 그림 85. 타이머 0 의블록선도 ( 출처:ATMEL) PWM 및비동기동작모드를갖는 8 비트업/ 다운카운터로 10비트의프리스케일러를갖고있어이를통하여 - 88 -

내부클럭을소스로받아타이머나카운터로동작한다. 오버플로와출력비교에의한인터럽트기능을갖고있으며 주파수를발생할수있는기능을갖고있고출력비교와재장전기능을갖고있다. 타이머0의경우부가적으로 32.768KHz 의수정진동자를 TOSC1,2 단자에연결해 Real Time Clock 으로사용할수있는기능이있다. 4.2.1.1. 구성 그림 85는 8 비트타이머의블록선도를보여준다. 프리스케일러 (prescaler) : 타이머 0의경우에는 TOSC1 에입력된시스템클럭주파수의 1/4 미만의외부클럭, TOSC1 과 TOSC2 단자에연결된수정진동자에의해발생되는클럭이나내부클럭 을클럭소스로사용하 여 1, 8, 32, 64, 128, 256, 1024의분주비로프리스케일러에서나누어 클럭을생성한다. 타이머0 의클럭 소스는 ASSR 레지스터로선택한다. 타이머 2의경우에는 TOSCT1,2 핀에해당하는것이없고대신 T2핀으로입 력되는외부클럭을프리스케일러를거치지않고 클럭을생성하거나내부클럭 하여 을클럭소스로사용 1, 8, 64, 256, 1024의분주비로프리스케일러에서나누어 클럭을생성한다. 분주비의선택은 TCCRn 레지스터로설정한다. TCCRn : 타이머n 의동작모드를설정하는레지스터 (n은 0 또는 2) TCNTn (Timer/CouNTer n) 레지스터 : 프리스케일러에서생성된 클럭을제어로직에따라업/ 다운카운 팅을수행하거나리셋되는타이머 n의 8 비트카운터값을저장하는레지스터. TOVn : TCNTn 가카운팅에의해 0xFF에서 0x00로오버플로우가일어나면 TOVn플랙이세트되고오버플로 인터럽트를발생시킬수있게된다. OCRn(Output Compare Resister n) 레지스터 : TCNTn 의값과출력비교되기위한 8비트데이터값을저 장하고있는레지스터로 TCNTn 의값과같으면 OCFn플랙을세트시키고출력비교인터럽트를요청하고출력핀 OCn 단자로적절한데이터가출력되도록한다. 제어로직 (Control Logic) : 와 TCNTn 가제로가되었을때발생하는 BOTTOM 신호, TCNTn 카운터값 이 0xFF에도달하거나 OCRn 레지스터에설정된값에도달할때발생하는 TOP신호를입력으로받아들여 TCNTn 카운터를업/ 다운카운팅을수행하게하거나리셋시킨다. 4.2.1.2. TCCRn 레지스터 TCCRn(Timer/Counter Control Register n) 는타이머 n의동작모드를설정하고프리스케일러의분주비를설정 한다. 비트7(FOCn:Force Output Compare n) : PWM 모드가아닌경우에만유효하며 1로설정하면강제로 OC0(PB4, 핀14) 단자( 타이머2 의경우 OC2(PB7, 핀17) 에출력비교가일치할때출력하게되는값과동일한출 력을내보낸다. 이경우인터럽트가발생하지도않고 CTC모드에서 TCNTn 를클리어시키지도않으므로보통 0 으로설정한다. 비트6, 3(WGMn0, n1: Waveform Generation Mode n0, n1) : 타이머n 는 4가지의동작모드를갖는데각각 Normal( 일반), CTC, PC(Phase Correct) PWM, 고속 PWM 이다. WGMn1:n0 을 00 으로하면일반모드, 01로하 면 PC PWM, 10으로하면 CTC, 11로하면고속 PWM 모드로설정한다. 비트5,4(COMn1, n0 : Compare Match output mode n1, n0) : OCn 핀의동작을다음처럼조절한다. 1 00 : 정상적인범용입출력포트로동작(OCn 출력을차단) 2 01 : PWM모드가아닌경우출력비교에의해 OCn 출력을토글시키며, PWM 모드에서는보류되어있다. 3 10 : PWM모드가아닌경우출력비교에의해 OCn 출력을클리어, FAST PWM 모드의경우 OCn를클리어 하고 TOP신호를받아 OCn를 1 로세트, Phase Correct PWM 모드상향카운팅의경우 OCn를클리어하고 PWM 모드하향카운팅의경우 OCn를 1 로세트시킨다. - 89 -

4 11 : PWM모드가아닌경우출력비교에의해 OCn 출력을세트, FAST PWM 모드의경우 OCn를세트하고 TOP신호를받아 OCn 를클리어, Phase Correct PWM 모드상향카운팅의경우 OCn를세트하고 PWM 모드하 향카운팅의경우 OCn 를클리어시킨다. 비트2~0(CSn2~n0: Clock Selectn2~n0) : n=0 즉타이머0 일때클럭의분주비를선택하여 000일때클럭 입력을차단하고, 001일때 1 분주, 010일때 8 분주, 011일때 32 분주, 100일때 64 분주, 101일때 128 분주, 110일 때 256 분주, 111일때 1024 분주비가되도록한다. n=2 즉타이머 2의경우에는분주비와클럭소스를선택하여 000 일때클럭입력을차단하고, 001일때 1 분주, 010일때 8 분주, 011일때 64 분주, 100일때 256 분주, 101일때 1024분주비가되도록하고 110일때 T2(PD7, 핀32) 핀에서입력되는외부클럭의하강에지에서카운터 2가동작 하고, 111일때는 T2(PD7, 핀32) 핀에서입력되는외부클럭의상승에지에서카운터2 가동작하도록한다. 4.2.1.3. TIMSK 레지스터 TIMSK(Timer Interrupt MaSK) 레지스터는타이머0,1,2 가발생하는인터럽트를개별적으로허용제어하는레 지스터이다. 비트7(OCIE2:Output Compare match Interrupt Enable for timer2) : 1로설정되면타이머2 의출력비교인 터럽트를개별적으로허용한다. 비트6(TOIE2:Timer Overflow Interrupt Enable for timer2) : 1로설정되면타이머2의오버플로인터럽트를 개별적으로허용한다. 비트1(OCIE0:Output Compare match Interrupt Enable for timer0) : 1로설정되면타이머0 의출력비교인 터럽트를개별적으로허용한다. 비트0(TOIE0:Timer Overflow Interrupt Enable for timer0) : 1로설정되면타이머0의오버플로인터럽트를 개별적으로허용한다. 4.2.1.4. TIFR 레지스터 TIFR(Timer Interrupt Frag Register) 레지스터는타이머0~2 가발생하는인터럽트플랙을저장한다. 소프트웨 어적으로강제로클리어하려면 1 을기록해야한다. 비트7(OCF2 : Output Compare match Flag 2) : 타이머2의 TCNT2레지스터와출력비교레지스터 OCR2의 값을비교하여같으면 OCF2 는 1 로세트되고출력비교인터럽트가요청된다. 인터럽트가서비스되기시작하면 자동적으로클리어된다. 비트6(TOV2 : Timer Overflow Flag 2) : 타이머2 에서오버플로가발생하면 (0xFF 까지세고 0x00으로넘어 가게되면) 이 TOV2는 1 로세트되면서오버플로인터럽트가요청된다. 인터럽트가서비스되기시작하면자동적 으로클리어된다. Phase correct PWM 모드에서는타이머2이 0x00에서계수방향을바꿀때 TOV2 가세트된다. 비트1(OCF0 : Output Compare match Flag 0) : 타이머0의 TCNT0레지스터와출력비교레지스터 OCR0의 값을비교하여같으면 OCF0 는 1 로세트되고출력비교인터럽트가요청된다. 인터럽트가서비스되기시작하면 자동적으로클리어된다. 비트0(TOV0 : Timer Overflow Flag 0) : 타이머0 에서오버플로가발생하면 (0xFF 까지세고 0x00으로넘어 가게되면) 이 TOV0는 1 로세트되면서오버플로인터럽트가요청된다. 인터럽트가서비스되기시작하면자동적 으로클리어된다. Phase correct PWM 모드에서는타이머0이 0x00에서계수방향을바꿀때 TOV0 가세트된다. 4.2.1.5. ASSR 레지스터 ASSR(ASynchronous Status Register) 레지스터는타이머 0이클럭소스를선택하거나외부클럭에의해비동기 모드로동작하는경우제어를위한레지스터이다. 비트3(AS0 : ASynchronous timer 0) : 0이면내부클럭 를클럭소스로설정하여동기모드로타이머 0 가동작하게하고 1이면 TOSC1 을통해들어오는외부클럭을소스로설정하여비동기모드로동작하게한다. - 90 -

AS0의수정은 로주의해야한다. TCNT0, OCR0, TCCR0 의내용의변동을초래하고예상하지못한인터럽트가발생할수있으므 비트2(TCN0UB : Timer/CouNter0 Uptate Busy) : 타이머0이외부에서 TOSC1 단자로입력되는클럭을소 스로하여비동기모드로동작하고있을때 TCNT0 레지스터에새로운값을기록하면 1 로세트된다. 기록이완료 되면 0으로자동적으로클리어되어 TCNT0 에새로운값을기록할수있음을표시한다. 비트1(OCR0UB : Output Compare Register 0 Update Busy) : 타이머0이외부에서 TOSC1 단자로입력되 는클럭을소스로하여비동기모드로동작하고있을때 OCR0레지스터에새로운값을기록하면 1 로세트된다. 기록이완료되면 0으로자동적으로클리어되어 OCR0 에새로운값을기록할수있음을표시한다. 비트0(TCR0UB : Timer Conter Register 0 Update Busy) : 타이머 0이외부에서 TOSC1 단자로입력되는 클럭을소스로하여비동기모드로동작하고있을때 TCCR0 레지스터에새로운값을기록하면 1 로세트된다. 기 록이완료되면 0으로자동적으로클리어되어 TCCR0 에새로운값을기록할수있음을표시한다. 4.2.1.6. SFIOR 레지스터 SFIOR(Special Function I/O Register) 는타이머들을동기화시키는데사용되는레지스터이다. 비트7(TSM : Timer Synchronization Mode) : 0으로클리어하면 PSR0, PSR321비트가하드웨어적으로클리 어되며타이머들이동시에카운팅동작을시작한다. 1로하면 PSR0, PSR321 비트에기록한값을유지하여대응 하는프리스케일러리셋신호를발생하고해당타이머의동작을정지시켜같은값으로설정할수있도록한다. 비트1(PSR0 : Prescaler Reset Timer 0) : 1로하면타이머0 의프리스케일러를리셋시키며완료후에자동적 으로클리어된다. TSM = 1 이면자동적으로클리어되지않는다. 비트0(PSR123 : Prescaler Reset Timer 123) : 1로하면타이머 0의프리스케일러를리셋시키며완료후에자 동적으로클리어된다. TSM = 1 이면자동적으로클리어되지않는다. 4.2.1.7. 타이머 0,2 의일반모드 설정 : TCCRn레지스터의 WGMn1:n0 = 00 으로설정한다. 동작 : 타이머 n 는항상상향카운터로만동작한다. TCNTn 의값이 255에서 0으로바뀌는순간 TIFR레지스 터의 도있으나 TOVn 비트가세트되며오버플로인터럽트발생이요청된다. 출력비교인터럽트를일반모드에서사용할수 FAST PWM 모드를사용하는것이좋다. 시간간격설정 : 오버플로인터럽트가요청될때마다인터럽트를발생시켜 TCNTn 의초기값 을적당하게 설정하면원하는시간간격을얻을수있다. TCCRn 의비트2~0(CSn2~0) 값에따라 1, 8, 32, 64, 128, 256, 1024 분주가되므로 ( 타이머 2의경우 1,8, 64, 256, 1024) 클럭을 MHz로사용하는경우분주비를 이라하면 다음에의해시간간격 가결정된다. 즉오버플로인터럽트가요청되는시간간격은 이다. 4.2.1.8. 타이머 0,2 의 CTC 모드 설정 : TCCRn레지스터의 WGMn1:n0 = 10 으로설정한다. 동작 : CTC(Clear Timer on Compare match) 모드에서는 TCNTn의값이 OCRn레지스터에설정한값과일치 되면그다음클럭사이클에서 TCNTn의값이 0 으로클리어된다. 이때 TIFR레지스터의 OCFn비트가세트되며 출력비교인터럽트발생이요청된다. 이때인터럽트를발생시켜 OCRn 의값을바꾸면주기를원하는대로변경 할수있다. OCn단자로하여금출력파형을발생하도록할수있는데 TCCRn 의 COMn1~n0 을 01로설정하고 OCRn 레지스터값을바꿔가면서출력비교에의해 OCn의신호를토글하는경우를그림 86 이보여준다. 주기설정 : TCCRn 의 COMn1~n0 을 01로설정하고 OCRn 레지스터값을어떤일정한값 OCR0 로놓고출력 비교에의해 OCn의신호를토글하는경우 TCCRn 의비트2~1(CSn2~n0) 값에따라 1, 8, 32, 64, 128, 256, 1024 분주가되므로 ( 타이머 2의경우 1,8, 64, 256, 1024) 클럭을 MHz로사용하고분주비를 이라하면다음 - 91 -

에의해주기 가결정된다. 출력비교인터럽트가요청되는시간간격은 이다. 4.2.1.9. 타이머 0, 2 의고속 PWM 모드 그림 86. 타이머 0,2의 CTC 모드동작( 출처:ATMEL) 설정 : TCCRn레지스터의 WGMn1:n0 = 11 으로설정한다. 동작 : TCNTn 는반복적으로업카운팅하며항상 0x00~0xFF 의값을갖는다. TCNTn 의값이 OCRn 레지스터 에설정한값과일치되면 TIFR레지스터의 OCFn 비트가세트되며출력비교인터럽트가요청되며 OCn의값은 0 으로클리어된다. 그리고 TCNTn 는업카운팅을계속하여 TCNTn 는 255까지증가했다가 0으로바뀌는순간 TIFR레지스터의 TOVn 비트가세트되어오버플로인터럽트가요청되며 OCn는 1 로세트된다. ( 그림 87 참조). TOVn 비트가세트되어오버플로인터럽트가요청될때인터럽트를발생시켜 OCRn 의값을바꾸어듀티비를제 어할수있다. OCRn 레지스터값과듀티비가비례함을그림 88 에서알수있다. OCRn = 0x00일때듀티비는 1/256 이며 OCRn=0xFF 일때 100% 가됨을알수있다. 레귤레이터, 정류및 DA 변환에적합하다. 특히고주파 를사용하기때문에코일, 콘덴서등외부소자가필요없어비용을절감시킬수있다. 그림 87. 타이머의고속 PWM 모드동작( 출처:ATMEL) 주기설정 : TCCRn의 COMn1~n0 을 10 혹은 11로설정하고 OCRn레지스터값을변화시켜가며출력비교에 의해 OCn의신호를 PWM하는경우 TCCRn 의비트2~1(CSn2~n0) 값에따라 1, 8, 32, 64, 128, 256, 1024 분 - 92 -

주가되므로 ( 타이머 2의경우 1,8, 64, 256, 1024) 클럭을 MHz로사용하고분주비를 주기 가결정된다. 즉오버플로인터럽트가요청되는시간간격은 이다. 이라하면다음에의해 4.2.1.10. 타이머 0, 2 의 Phase Correct PWM 모드 설정 : TCCRn레지스터의 WGMn1:n0 = 01 으로설정한다. 동작 : TCNTn는업카운팅하여 0xFF으로증가하다가다운카운팅으로 0x00 으로감소를반복한다. TCCRn의 COMn1~n0 을 10 혹은 11로설정하고 OCRn레지스터값을변화시켜가며출력비교에의해 OCn의신호를 PWM 하는경우TCNTn 의값이 OCRn 레지스터에설정한값과일치되면 TIFR레지스터의 OCFn 비트가세트되며출력 비교인터럽트발생이요청되며 OCn의값은상향카운팅의경우에는 0으로하향의경우에는 1 로세트된다. 그 리고 TCNTn 는업카운팅을계속하여 TCNTn 는 255에도달하면 OCR2 의값이경신되고하향카운팅이시작된 다. 하향카운팅을하다가 0에도달하면 TIFR레지스터의 TOVn비트가세트되며오버플로인터럽트가요청된다 ( 그림 88 참조). PC PWM모드에서는 OCRn 레지스터에이중버퍼링기능이있어 PWM 주기를변경하기위해 OCRn 레지스터에새로운값을기록하더라도즉기변경되지않고 TCNTn 이 255 에도달하면갱신된다 ( 그림 88 참조). OCRn 레지스터값과듀티비가비례함을그림 88 에서알수있다. OCRn = 0x00일때듀티비는 0이며 OCRn=0xFF 일때 100% 가됨을알수있다. 그림 88. 타이머0, 2의위상교정 PWM 모드동작 ( 출처:ATMEL) 주기설정 : TCCRn의 COMn1~n0 을 10 혹은 11로설정하고 OCRn레지스터값을변화시켜가며출력비교에 의해 OCn의신호를 PWM하는경우 TCCRn 의비트2~1(CSn2~n0) 값에따라 1, 8, 32, 64, 128, 256, 1024 분 주가되므로 ( 타이머 2의경우 1,8, 64, 256, 1024) 클럭을 MHz로사용하고분주비를 이라하면다음에의해 주기 가결정된다. 즉오버플로인터럽트가요청되는시간간격은 이다. 4.2.2. 타이머카운터 1, 3 3개의 PWM 출력및캡춰기능을갖는 16 비트업/ 다운카운터로 10비트의프리스케일러를갖고있어이를통 하여내부클럭을소스로받아타이머나카운터로동작한다. 오버플로와출력비교에의한인터럽트이외에입력 - 93 -

캡춰인터럽트기능을갖고있고주파수를발생할수있는기능과출력비교와재장전기능을갖고있다. 4.2.2.1. 구성 그림 89는타이머 1과 3 의블록선도를보여준다. 그림 89. 타이머 1,3 의불록선도 ( 출처:ATMEL) 프리스케일러 (prescaler) : 내부클럭 을클럭소스로사용하여 1, 8, 64, 256, 1024의분주비로나누어 TCLK 에사용될클럭을생성한다. 분주비의선택은 TCCRxB 레지스터로설정한다 (x는 1 또는 3). TCLK : Tx핀으로입력되는외부클럭을프리스케일러를거치지않고 TCLK 클럭이생성되거나내부클럭 을프리스케일러에서나누어 TCLK 클럭이생성된다. TCCRxA~C : 타이머 x 의설정을위한레지스터. TCNTx (Timer/CouNTer x) 레지스터 : TCLK 클럭을제어로직에따라업/ 다운카운팅을수행하거나리셋되 는타이머 x의 16 비트카운터값을저장하는레지스터. TOVx : TCNTx 가카운팅에의해 0xFFFF 에서 0x0000 로오버플로우가일어나면 TOVx 플랙이세트되고오 버플로인터럽트를발생시킬수있게된다. OCRxA~C(Output Compare Resister x A~C) 레지스터 : TCNTx 의값과출력비교되기위한 16비트데이 - 94 -

터값을저장하고있는레지스터로 TCNTx 의값과같으면 OCFxA~C 플랙이세트되고출력비교인터럽트를요 청하여출력핀 OCxA~C 단자로적절한데이터가출력되도록한다. ICRx(Input Capture Register x) : 입력캡쳐핀 ICx( 타이머1 의경우에는아날로그비교기의출력신호도가능) 으로들어오는신호변화를검출하여일어나는입력캡쳐시 TCNTx의카운터값을저장하는 16비트레지스터로 이때 ICFx 플랙이세트되고입력캡쳐인터럽트가요청된다. 어떤신호의주기측정에응용될수있다. 제어로직 (Control Logic) : TCNTx 가제로가되었을때발생하는 BOTTOM 신호, TCNTx 카운터값이 0xFFFF 에도달하거나카운터가실제로도달할수있는최대값혹은 OCRxA~C, ICRx에설정된값에도달하면 발생하는 TOP신호를입력으로받아들여 TCNTx 카운터를업/ 다운카운팅을수행하게하거나리셋시킨다. 4.2.2.2. TCCRxA 레지스터 TCCRxA(Timer/Counter Control Register x A) 는타이머 x의동작모드와출력비교단자의파형발생법등을 설정한다. 비트7~6(COMxA1~0:Compare match Output Mode for channel A) : OCxA 핀의동작을아래처럼설정. 비트5~4(COMxB1~0:Compare match Output Mode for channel B) : OCxB 핀의동작을아래처럼설정. 비트3~2(COMxC1~0:Compare match Output Mode for channel C) : OCxC 핀의동작을아래처럼설정. 1 00 : 정상적인범용입출력포트로동작(OCxn 출력을차단, n=a,b,c) 2 01 : PWM모드가아닌경우출력비교에의해 OCxn 출력을토글시키며, FAST PWM 모드에서는모드 15의 경우출력비교에의해 OCxA 출력을토글하고 OCxB, OCxC는출력을차단하고기타의모드에서 OCxn 출력을 차단하며, Phase Correct PWM 모드에서모드9,11 의경우출력비교에의해 OCxA 출력을토글하고 OCxB, OCxC 는출력을차단하고기타의모드에서 OCxn 출력을차단한다. 3 10 : PWM모드가아닌경우출력비교에의해 OCxn 출력을클리어, FAST PWM 모드에서출력비교에의 해 OCxn출력을클리어하고 TOP신호를받아 OCxn를 1 로세트, Phase Correct PWM 모드상향카운팅의경우 OCxn 를클리어하고 PWM 모드하향카운팅의경우 OCxn 를 1 로세트시킨다. 4 11 : PWM모드가아닌경우출력비교에의해 OCxn 출력을세트, FAST PWM 모드의경우 OCxn 를세트하 고 TOP신호를받아 OCxn 를클리어, Phase Correct PWM 모드상향카운팅의경우 OCxn를세트하고 PWM 모 드하향카운팅의경우 OCxn 를클리어시킨다. 비트1~0(WGMx0~1: Waveform Generation Mode x 1~0) : 타이머x 는 16가지의동작모드를갖는데 TCCRxB 의비트4~3(WGMx3~2) 와결합하여동작모드를설정한다. 그림 90 은모드의번호, WGMx4~0 비트값, 모드의동작, TOP 값, OCRx 레지스터의업데이트시점, TOVx 플랙의세트시점을보여준다. 4.2.2.3. TCCRxB 레지스터 TCCRxB(Timer/Counter Control Register x B) 는타이머 x 의동작모드와분주비등을설정한다. 비트7(ICNCx:Input Capture Noise Canceler x) : 1로세트하면입력캡쳐단자 ICx로입력되는캡쳐신호를위 한노이즈회로를작동시켜필터링을한다. 필터링에의해캡쳐신호가 4 클럭지연된다. 비트6(ICESx:Input Capture Edge Selectr x) : 1로세트하면 ICx로입력되는캡쳐신호가상승에지일때 0이 면하강에지일때캡쳐가수행된다. 비트5 : 보류된비트 비트3~2(WGMx3~2: Waveform Generation Mode x 3~2) : 타이머x 는 16가지의동작모드를갖는데 TCCRxA 의비트1~0(WGMx1~0) 와결합하여동작모드를설정한다. 그림 90 은모드의번호, WGMx4~0 비트값, 모드의동작, TOP 값, OCRx 레지스터의업데이트시점, TOVx 플랙의세트시점을보여준다. 비트2~0(CSx2~0: Clock Select x2~x0) : 분주비와클럭소스를선택하여 000 일때클럭입력을차단하고, - 95 -

001일때 1 분주, 010일때 8 분주, 011일때 64 분주, 100일때 256 분주, 101일때 1024분주비가되도록하고 110 일때 Tx핀에서입력되는외부클럭의하강에지에서카운터x 가동작하고, 111일때는 Tx핀에서입력되는외부 클럭의상승에지에서카운터x 가동작하도록한다. 4.2.2.4. TCCRxC 레지스터 그림 90. 타이머 1,3 의동작모드설정( 출처:ATMEL) 비트7~5(FOCxA~C:Force Output Compare x A~C) : PWM 모드가아닌경우에만유효하며 1로설정하면 강제로 OCxA~C 에출력비교가일치할때출력하게되는값과동일한출력을내보낸다. 이경우인터럽트가발 생하지도않고 CTC모드에서 TCNTx를클리어시키지도않으므로보통 0 으로설정한다. 4.2.2.5. TIMSK 레지스터 TIMSK(Timer Interrupt MaSK) 레지스터는타이머0,1,2 가발생하는인터럽트를개별적으로허용제어하는레 지스터이다. 비트5(TICIE1:Timer Input Capture Interrupt Enable 1) : 1로설정되면타이머1 의입력캡쳐인터럽트를개 별적으로허용한다. 비트4~3(OCIE1A~B: Output Compare match Interrupt Enable timer 1 A~B) : 1로설정되면타이머 1의 출력비교인터럽트 A, B 를개별적으로허용한다. 비트2(TOIE1:Timer Overflow Interrupt Enable for timer 1) : 1로설정되면타이머1 의오버플로인터럽트 를개별적으로허용한다. 4.2.2.6. ETIMSK 레지스터 ETIMSK(Extended Timer Interrupt MaSK) 레지스터는타이머1, 3이발생하는인터럽트를개별적으로허용 제어하는레지스터이다. 비트5(TICIE3:Timer Input Capture Interrupt Enable 3) : 1로설정되면타이머3 의입력캡쳐인터럽트를개 별적으로허용한다. 비트4~3(OCIE3A~B: Output Compare match Interrupt Enable timer 3 A~B) : 1로설정되면타이머 3의 - 96 -

출력비교인터럽트 A, B 를개별적으로허용한다. 비트2(TOIE3:Timer Overflow Interrupt Enable for timer 1) : 1로설정되면타이머3 의오버플로인터럽트 를개별적으로허용한다. 비트1~0(OCIExC: Output Compare match Interrupt Enable timer x C) : 1로설정되면타이머x 의출력비 교인터럽트 C 를개별적으로허용한다. 4.2.2.7. TIFR 레지스터 TIFR(Timer Interrupt Frag Register) 레지스터는타이머0~2 가발생하는인터럽트플랙을저장한다. 소프트웨 어적으로강제로클리어하려면 1 을기록해야한다. 비트5(ICF1 : Input Capture Flag 1) : 타이머1 의입력캡쳐신호또는아날로그비교기로부터의신호에의해 캡쳐동작이수행될때 1 로세트되고입력캡쳐인터럽트가요청된다. ICR1 레지스터가 TOP 값으로사용되는동 작모드에서 TCNT1 의값이 TOP과같아질때 1 로세트되고인터럽트가요청된다. 인터럽트가서비스되기시작 하면자동적으로클리어된다. 비트4~3(OCF1A~B : Output Compare match Flag 1 A~B) : 타이머1의 TCNT1레지스터와출력비교레지 스터 OCR1A~B 의값을비교하여같으면 OCF1A~B 는 1 로세트되고출력비교인터럽트가요청된다. 인터럽트가 서비스되기시작하면자동적으로클리어된다. 비트2(TOV1 : Timer Overflow Flag 1) : 타이머 1 에서오버플로가발생하면 (0xFFFF까지세고 0x0000으로 넘어가게되면) 이 TOV1는 1 로세트되면서오버플로인터럽트가요청된다. 인터럽트가서비스되기시작하면자 동적으로클리어된다. Phase correct PWM 모드에서는타이머1이 0x00에서계수방향을바꿀때 TOV1가세트 된다. 4.2.2.8. ETIFR 레지스터 ETIFR(Extenede Timer Interrupt Frag Register) 레지스터는타이머 1,3가발생하는인터럽트플랙을저장한 다. 소프트웨어적으로강제로클리어하려면 1 을기록해야한다. 비트5(ICF3 : Input Capture Flag 3) : 타이머3 의입력캡쳐신호또는아날로그비교기로부터의신호에의해 캡쳐동작이수행될때 1 로세트되고입력캡쳐인터럽트가요청된다. ICR3 레지스터가 TOP 값으로사용되는동 작모드에서 TCNT3 의값이 TOP과같아질때 1 로세트되고인터럽트가요청된다. 인터럽트가서비스되기시작 하면자동적으로클리어된다. 비트4,3,1(OCF3A,B,C: Output Compare match Flag 3 A,B,C) : 타이머 3의 TCNT3레지스터와출력비교레 지스터 OCR3A~C 의값을비교하여같으면 OCF3A~C 는 1 로세트되고출력비교인터럽트가요청된다. 인터럽트 가서비스되기시작하면자동적으로클리어된다. 비트2(TOV3 : Timer Overflow Flag 3) : 타이머 3 에서오버플로가발생하면 (0xFFFF까지세고 0x0000으로 넘어가게되면) 이 TOV3는 1 로세트되면서오버플로인터럽트가요청된다. 인터럽트가서비스되기시작하면자 동적으로클리어된다. Phase correct PWM 모드에서는타이머1이 0x00에서계수방향을바꿀때 TOV3가세트 된다. 비트0(OCF1C: Output Compare match Flag 1 C) : 타이머 1의 TCNT1 레지스터와출력비교레지스터 OCR1C 의값을비교하여같으면 OCF1C 는 1 로세트되고출력비교인터럽트가요청된다. 인터럽트가서비스되기 시작하면자동적으로클리어된다. 4.2.2.9. 타이머 1, 3 의일반모드 설정 : TCCRxA~B 의 WGMx3~0 = 00 으로설정한다. 동작 : 타이머x 는항상상향카운터로만동작한다. TCNTx 의값이 0xFFFF 에서 0으로바뀌는순간 TOVx 비 트가세트되며오버플로인터럽트가발생이요청된다. 출력비교인터럽트를일반모드에서사용할수도있으나 - 97 -

FAST PWM 모드를사용하는것이좋다. 시간간격설정 : 오버플로인터럽트가요청될때마다인터럽트를발생시켜 TCNTx 의초기값 을적당하게 설정하면원하는시간간격을얻을수있다. TCCRxB 의비트2~0(CSx2~0) 값에따라 1,8, 64, 256, 1024가될 수있으므로클럭을 MHz로사용하는경우분주비를 로인터럽트가요청되는시간간격은 이다. 4.2.2.10. 타이머 1, 3 의 CTC 모드 이라하면다음에의해주기 가결정된다. 즉오버플 설정 : TCCRxB 레지스터의 WGMx3~0 을 4 또는 12 로설정한다. 동작 : CTC(Clear Timer on Compare match) 모드의 4번모드에서는 TCNTx의값이 OCRxA레지스터에설 정한값과일치되면그다음클럭사이클에서 TCNTx 의값이 0 으로클리어된다. 이때 OCFxA 비트가세트되며 출력비교인터럽트발생이요청된다. 이때인터럽트를발생시켜 OCRxA 의값을바꾸면주기를원하는대로변경 할수있다. OCx단자로하여금출력파형을발생하도록할수있는데 COMxn1~0 을 01로설정하고 OCRxA 레 지스터값을바꿔가면서출력비교에의해 OCxn 의신호를토글하는경우는그림 86 과비슷하다 ( 여기에서 x=1,3, n=a,b,c). 12번모드에서는 TCNTx 의값이입력캡춰레지스터 ICRx에설정한값과일치되면그다음클럭사 이클에서 TCNTx의값이 0 으로클리어된다. 이때 ICFx 비트가세트되며입력캡춰인터럽트발생이요청된다. 이 때인터럽트를발생시켜 ICRx 의값을바꾸면주기를원하는대로변경할수있다. OCxn 단자로하여금출력파 형을발생하도록할수있는데 COMxn1~0 을 01로설정하고 OCRxn 레지스터값을바꿔가면서출력비교에의해 OCxn 의신호를토글하는경우는그림 86 과비슷하다. 주기설정 : COMxn1~0 을 01로설정하고 OCRxA 나 ICRx레지스터값을어떤일정한값 CR0로놓고출력비 교에의해 OCxn 의신호를토글하는경우 TCCRxB 의비트2~0(CSx2~0) 값에따라 1,8, 64, 256, 1024의분주 비로분주되므로클럭을 MHz로사용하고분주비를 인터럽트가요청되는시간간격은 이다. 4.2.2.11. 타이머 1, 3 의고속 PWM 모드 이라하면다음에의해주기 가결정된다. 즉오버플로 설정 : TCCRxB 레지스터의 WGMx3~0 을 5,6,7,14,15 로설정한다. 동작 : TCNTx 는반복적으로업카운팅하며항상 0x0000~TOP 의값을갖는다. TOP의값은모드번호에따 라 0x00FF, 0x1FF, 0x03FF, ICRx, OCRxA 을갖는다 ( 그림 90 참조). TCNTx 의값이 TOP 값과일치되면그다 음사이클에서 0으로클리어되며 OCFxA비트가세트되어출력비교인터럽트가요청되거나 ICFx비트가세트되어 입력캡춰인터럽트가요청되거나 TOVx 비트가세트되어오버플로인터럽트가요청될수있으며 OCRxA 와 TOP 값을업데이트할수있다. COMxn1~0 을 10으로세팅한경우 TCNTx 의값은 ICRx나 OCRxn 값과같아지면 OCxn 의값은 0 으로클리어된다. 그리고 TCNTx 는업카운팅을계속하여 TOP까지증가했다가 0으로바뀌는순 간 OCxn 는 1 로세트된다. 인터럽트가요청될때인터럽트를발생시켜 TOP 값이나 OCRxn 의값을바꾸어듀 티비를제어할수있다. 레귤레이터, 정류및 DA 변환에적합하다. 특히고주파를사용하기때문에코일, 콘덴서 등외부소자가필요없어비용을절감시킬수있다. 주기설정 : 0~TOP값을업카운팅하므로 TCCRxB의비트2~0(CSx2~x0) 값에따라 1,8, 64, 256, 1024의분 주비로분주되므로클럭을 MHz로사용하고분주비를 오버플로인터럽트가요청되는시간간격은 이다. 이라하면다음에의해파형의주기 가결정된다. 즉 4.2.2.12. 타이머 1, 3 의 Phase Correct PWM 모드 설정 : TCCRxB 레지스터의 WGMx3~0 을 1, 2, 3, 10, 11 로설정한다. 동작 : TCNTx 는업카운팅하여 TOP으로증가하다가다운카운팅으로 0x0000 으로감소를반복한다. TOP의 - 98 -

값은모드번호에따라 0x00FF, 0x1FF, 0x03FF, ICRx, OCRxA 을갖는다 ( 그림 90 참조). TCNTx 가 TOP값에 도달하면 OCRxn, TOP의값이경신되고 OCFxA비트가세트되어출력비교인터럽트가요청되거나 ICFx비트가 세트되어입력캡춰인터럽트가요청될수있다. TCNTx 가 0x0000 에도달하면 TOVx 비트가세트되어오버플로 인터럽트가요청될수있다. COMxn1~0 을10으로세팅한경우 TCNTx 의값이 OCRxn 레지스터에설정한값과 일치되면 OCxn 의값은상향카운팅의경우에는 0으로하향의경우에는 1 로세트된다. 그리고 TCNTx 는업카운 팅을계속하여 TOP 에도달하면하향카운팅이시작된다 ( 그림 88 참조). PC PWM모드에서는 OCRxn 레지스터에 이중버퍼링기능이있어 PWM 주기를변경하기위해 OCRxn 레지스터에새로운값을기록하더라도즉시변경 되지않고 TCNTxn 이 TOP 에도달하면갱신된다 ( 그림 88 참조). OCRxn 레지스터값과듀티비가비례함을그림 88 에서알수있다. 주기설정 : 0~TOP 값을업/ 다운카운팅하므로 TCCRxB 의비트2~0(CSx2~x0) 값에따라 1,8, 64, 256, 1024의분주비로분주되므로클럭을 MHz로사용하고분주비를 이라하면다음에의해주기 가결정된다. 즉오버플로인터럽트가요청되는시간간격은 이다. 4.2.2.13. 타이머 1, 3 의 Phase and Frequency Correct PWM 모드 설정 : TCCRxB 레지스터의 WGMx3~0 을 8,9 로설정한다. 동작 : PC PWM모드와거의똑같고다른점은 TOP의값이모드번호에따라 ICRx, OCRxA 만을갖는다는 것이고새로운값으로의경신이 TCNTx 가 0 일때이루어진다는것이다( 그림 90 참조).TCNTx 는업카운팅하여 TOP으로증가하다가다운카운팅으로 0x0000 으로감소를반복한다. TCNTx가 TOP값에도달하면 OCFxA비트 가세트되어출력비교인터럽트가요청되거나 ICFx 비트가세트되어입력캡춰인터럽트가요청될수있다. TCNTx 가 0x0000 에도달하면 OCRxn, TOP의값이경신되고 TOVx 비트가세트되어오버플로인터럽트가요청 될수있다. COMxn1~0 을10으로세팅한경우 TCNTx 의값이 OCRxn 레지스터에설정한값과일치되면 OCxn 의값은상향카운팅의경우에는 0으로하향의경우에는 1 로세트된다. 그리고 TCNTx 는업카운팅을계속하여 TOP 에도달하면하향카운팅이시작된다 ( 그림 88 참조). 주기설정 : Phase Correct PWM 과동일. 4.2.2.14. 출력비교변조 그림 91. 타이머 1,2를이용한출력비교변조의예 설정 : 타이머 1용출력비교설정을위한 TCCR1A 레지스터의비트 3~2(COM1C1~0) 를 10 이나 11로설정하 여출력비교가이루어지도록하는동시에타이머 2용출력비교설정을위한 TCCR2 레지스터의비트 5~4(COM21~0) 를 01~11로설정하여출력비교가이루어지도록하고 DDRB.7=1 로한다. - 99 -

동작 : PORTB.7 의값을 1로세트시키면 OC1C와 OC2의신호를 OR시킨것이 17 번핀(PB7, OC1C, OC2) 에 서출력되고 0으로하면 0C1C와 OC2를 AND 시킨신호가 17 번핀에서출력된다. 4.2.3. 실험 24 : 타이머를이용한 LED 점멸 1 예제 : 타이머 0의일반모드를이용하여 10밀리초간격으로오버플로인터럽트를발생시켜 PORTC에연결된 LED가 1 칸씩왼쪽으로회전시키며점멸시킨다. 회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 프로그램작성시유의점 : 디버깅시 [Auto Step] 를누르고 IO View창의 TCNT0와 PORTC의변화를관찰하 라. 그림 83과같이타이머 0~3의오버플로인터럽트는 17, 15, 11, 30 번이다. CodeVisoinAVR 에서인터럽트 번호에따른이름을 TIM0_OVF~TIM3_OVF 로 mega128.h 에정의해놓았다. 이를이용해도된다. 시뮬레이션에 서는 10 밀리초의간격으로회전시키면시간이너무많이걸리므로줄여서구현하라. 프로그램예 : #include <mega128.h> unsigned char led = 0xfe; unsigned int cnt; interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 if(cnt++ >= 9999){ // 10000*1 = 10000 usec cnt = 0; if(led!=0x7f) led = (led << 1) 0x01; // 비트7 을안켰으면 1비트씩좌로시프트하고빈자리에는 1 을채운다. else led = 0xfe; // 비트7 을켰으면다시처음으로와서비트 0 을켠다. TCNT0 = 240; // 재정의 1usec = 1*(256-240)/16 16MHz 와분주비 1사용시 PORTC = led; void main(void){ DDRC = 0xff; // 포트C 를출력으로 PORTC = led; SREG = 0x80; // 인터럽트전체허용 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 TCCR0 = 1; // 분주비를 1로설정 TCNT0 = 240; while(1); 과제 : 1동일한일을타이머 1~3 을이용하여수행하라. 2 1초간격으로 LED가증가하는형태로켜지도록프 로그램하라. 4.2.4. 실험 25 : 타이머를이용한 LED 점멸 2 예제 : 타이머 1의일반모드를이용하여오버플로인터럽트를발생시키지말고 100밀리초간격으로 PORTC에 연결된 LED가 1 칸씩왼쪽으로회전시키며점멸시킨다. 회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 프로그램작성시유의점 : 타이머 1는초기값에서시작하여 0xFFFF 까지다세면( 오버플로가발생하면 ) TOV1 가 1 로세트된다. while 문을이용하여 TOV1 가세트되는것을감시하여인터럽트발생없이 PORTC 에연결된 LED 를왼쪽으로회전시키며점멸시킨다. 인터럽트를발생시키지않았기때문에 TOV1 는자동으로클리어되지 않기때문에오버플로가발생할때마다클리어시켜야됨을유의해야한다. 인터럽트플랙의클리어는 1을기록 해야된다. 시뮬레이션에서는 프로그램예 : #include <mega128.h> unsigned char led = 0xfe; 100 밀리초의간격으로회전시키면시간이너무많이걸리므로줄여서구현하라. - 100 -

void delay_i_ms(unsigned int i){ do{ while(!(tifr & 0x04)); // TOV1 가세트되었는지확인 TIFR = 0x04; /* 인터럽트발생없이타이머사용했으므로자동적으로클리어되지않으므로강제로클리어 */ TCNT1H = (65536-16000)/256; TCNT1L = (65536-16000) % 256; /* 재정의, 1msec 초를얻기위한시간정수 */ i--; while(i); void main(void){ DDRC = 0xff; // 포트C 를출력으로 TCCR1B = 1; // 분주비를 1로설정 TCNT1H = (65536-16000)/256; TCNT1L = (65536-16000) % 2; for(;;){ PORTC = led; if (led!= 0x7f) led = (led << 1 ) 0x01; else led = 0xfe; delay_i_ms(100); /* 100*1 msec 시간지연 */ 과제 : 1동일한일을타이머0,2,3 을이용하여수행하라. 2 0.1초간격으로 LED가증가하는형태로켜지도록 프로그램하라. 4.2.5. 실험 26 : 타이머를이용한 LED 점멸 3 예제 : 타이머 2의 CTC 모드를이용하여 500밀리초간격으로출력비교인터럽트를발생시켜 PORTC에연결 된 LED가 1 칸씩왼쪽으로회전시키며점멸시킨다. 회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 프로그램작성시유의점 : 그림 83과같이출력비교인터럽트는 16( 타이머0), 13( 타이머 1A), 14( 타이머 1B) 25( 타이머 1C), 10( 타이머 2), 27( 타이머 3A), 28( 타이머 3B), 29( 타이머3C) 번이다. CodeVisoinAVR 에서인터럽트 번호에따른이름을 TIMx_COMPn( 여기에서 x는 0~3, n은 A,B,C) 로 mega128.h 에정의해놓았다. 이를이용해 도된다. 시뮬레이션에서는 500 밀리초의간격으로회전시키면시간이너무많이걸리므로줄여서구현하라. 프로그램예 : #include <mega128.h> unsigned char led = 0xfe; unsigned int cnt; interrupt [10] void timerint(void){ // interrupt [TIM2_COMP] void timerint(void) 로해도됨 if(cnt++ >= 49999){ // 50000*10 = 500 msec cnt = 0; if(led!=0x7f) led = (led << 1) 0x01; // 비트7 을안켰으면 1비트씩좌로시프트하고빈자리에는 1 을채운다. else led = 0xfe; // 비트7 을켰으면다시처음으로와서비트 0 을켠다. PORTC = led; void main(void){ DDRC = 0xff; // 포트C 를출력으로 PORTC = led; SREG = 0x80; // 인터럽트전체허용 TIMSK = 0x80; // 타이머 2 출력비교인터럽트개별허용 TCCR2 = 1; // 분주비를 1로설정 TCCR2 = 0x20; // CTC mode OCR2 = 159; // 10usec = 1*(1+159)/16 16MHz 와분주비 1사용시 for(;;); 과제 : 1동일한일을타이머0,1,3 을이용해서수행하라. 2 동일한일을실험 25와비슷한요령으로인터럽트 발생없이 OCF2를감시하면서 LED 를회전시키면점멸시키는프로그램을구현해보라. - 101 -

4.2.6. 실험 27 : 타이머를이용한 LED 점멸 4 예제 : 타이머 3의 Fast PWM 모드를이용하여 500밀리초간격으로오버플로인터럽트플랙을감시하여인터 럽트발생없이 PORTC에연결된 LED가 1 칸씩왼쪽으로회전시키며점멸시킨다. 회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 프로그램작성시유의점 : 타이머 3는초기값에서시작하여 TOP( 모드번호에따라다른값을갖는다 ) 값까지 다세면( 오버플로가발생하면 ) TOV3 가 1 로세트된다. while 문을이용하여 TOV3 가세트되는것을감시하여인 터럽트발생없이 PORTC 에연결된 LED 를왼쪽으로회전시키며점멸시킨다. 인터럽트를발생시키지않았기때 문에 TOV3 는자동으로클리어되지않기때문에오버플로가발생할때마다클리어시켜야됨을유의해야한다. 인터럽트플랙의클리어는 1 을써주어야한다. 시뮬레이션에서는 500밀리초의간격으로회전시키면시간이너무 많이걸리므로줄여서구현하라. 프로그램예 : #include <mega128.h> unsigned char led = 0xfe; void delay_i_ms(unsigned int i){ do{ while(!(etifr & 0x04)); ETIFR =0x04; i--; while(i); // TOV3 가세트되었는지확인 /* 인터럽트발생없이타이머사용했으므로강제로클리어 */ void main(void){ DDRC = 0xff; // 포트C 를출력으로 TCCR3B = 1; // 분주비를 1로설정 TCCR3A = 0b00000011; // 고속 PWM 모드의 15번으로설정하여 TOP를 OCR3A 로설정 TCCR3B = 0b00011000; // 고속 PWM 모드의 15번으로설정하여 TOP를 OCR3A 로설정 ETIMSK = 0x04; // 타이머 3 오버플로인터럽트개별허용 OCR3AH = (unsigned char) 15999/256; OCR3AL = (unsigned char) 15999%256; // 1msec 시간지연 for(;;){ PORTC = led; if (led!= 0x7f) led = (led << 1 ) 0x01; else led = 0xfe; delay_i_ms(500); /* 500*1 msec 시간지연 */ 과제 : 1동일한일을타이머 1 을이용해서수행하라. 2 1초간격으로 LED가증가하는형태로켜지도록프로 그램하라. 3 인터럽트를사용해서동일한일을하도록구현해보라. 4.2.7. 실험 28 : 타이머를이용한 LED 점멸 5 예제 : 타이머 1의 Phase Correct PWM 모드를이용하여 500밀리초간격으로오버플로인터럽트을사용하여 PORTC에연결된 LED가 1 칸씩왼쪽으로회전시키며점멸시킨다. 회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 프로그램작성시유의점 : 타이머 1는초기값에서시작하여모드번호에따라다른값을갖는 TOP 값까지상향 카운팅을하다가다시하향카운팅을하여 0에도달하면 TOV1가 1 로세트된다. 시뮬레이션에서는 500밀리초의 간격으로회전시키면시간이너무많이걸리므로줄여서구현하라. 프로그램예 : #include <mega128.h> unsigned char led = 0xfe; unsigned int cnt; - 102 -

interrupt [15] void timerint(void){ // interrupt [TIM1_OVF] void timerint(void) 로해도됨 if(cnt++ == 499){ // 500*1 = 500 msec cnt = 0; if(led!=0x7f) led = (led << 1) 0x01; // 비트7 을안켰으면 1비트씩좌로시프트하고빈자리에는 1 을채운다. else led = 0xfe; // 비트7 을켰으면다시처음으로와서비트 0 을켠다. PORTC = led; void main(void){ DDRC = 0xff; // 포트C 를출력으로 PORTC = led; SREG = 0x80; // 인터럽트전체허용 TCCR1B = 1; // 분주비를 1로설정 TCCR1A = 0b00000011; // PC PWM 모드의 11번으로설정하여 TOP를 OCR1A 로설정 TCCR1B = 0b00010000; // PC PWM 모드의 11번으로설정하여 TOP를 OCR1A 로설정 TIMSK = 0x04; // 타이머 1 오버플로인터럽트개별허용과타이머스타트 OCR1A = 8000; // 1msec 시간지연 for(;;); 과제 : 1동일한일을타이머 3 를이용해서수행하라. 2 1초간격으로 LED가증가하는형태로켜지도록프로 그램하라. 3 인터럽트를사용하지말고인터럽트플랙을감시하여동일한일을하도록구현해보라. 4.2.8. 실험 29 : 워치독타이머 예제 : 타이머 0의일반모드를이용하여 1초간격으로오버플로인터럽트를발생시켜 PORTC에연결된 LED 로 0~9 를반복적으로쓴다. 워치독타이머의주기기완료되기전에워치독타이머를리셋하지않으면워치독리 셋이발생하는것을배워본다. 회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 프로그램작성시유의점 : 시뮬레이션에서는 1초의간격으로점멸시키면시간이너무많이걸리므로줄여서 구현하라. 프로그램예 : #include <mega128.h> unsigned char led = 0x00; unsigned int cnt; interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 if(cnt++ >= 999){ // 1000*1 = 1 sec cnt = 0; if(led++==9) led=0; // 9이면다시처음으로와서비트 0 을켠다. TCNT0 = 6; // 재정의 1msec = 64*(256-6)/16 16MHz 와분주비 64사용시 PORTC = ~led; #asm("wdr"); void main(void){ DDRC = 0xff; // 포트C 를출력으로 PORTC = ~led; SREG = 0x80; // 인터럽트전체허용 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 TCCR0 = 4; // 분주비를 64로설정 TCNT0 = 6; WDTCR = 0x18; WDTCR = 0x0f; // 워치독타이머타임아웃주기약 2 초로설정. while(1); 과제 : 1 #asm("wdr") 를없애고수행해보라. 2 동일한일을타이머 1~3 을이용하여수행하라. - 103 -

4.2.9. 실험 30 : 타이머를이용한카운터 예제 : 타이머2 를카운터로사용해 T2(PD7, 32 번핀) 에연결된스위치가눌릴때마다 PORTC 에연결된 LED 가증가형태로점멸한다. 회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 또한그림 80의 SW8 을누르면서실험한다. 프로그램작성시유의점 : 스위치가눌리면하강에지가발생한다. 이때입력캡쳐인터럽트플랙 ICF1을클리 어하고스위치가해제될때상승에지가발생하므로시뮬레이션에서는 많이걸리므로줄여서구현하라. 프로그램예 : #include <mega128.h> #include <delay.h> void main(void){ DDRC = 0xff; // 포트C 를출력으로 TCCR0 = 6; // 하강에지에서카운트 TCNT2 = 0; // TCNT2 초기화 while(1){ PORTC = ~TCNT2; delay_ms(5); 1초의간격으로점멸시키면시간이너무 과제 : 1 실제구현했을때한번누를때마다하나씩이동하지않고여러개가이동하는현상이발생할수 도있을것이다. 이는실험 16 에서도이야기한채터링에의한현상이다. delay_ms(5) 의값을변화시켜가면서 실험해보고적정한시간지연을찾아보아라. 2 그림 80의회로대신그림84 의회로를이용하되시간지연을 작게해서실험해보고비교해보라. 3 동일한일을타이머 1,3 을사용해서구현해보라. 4.2.10. 실험 31 : 펄스폭측정 예제 : IC1(PD4, 29 번핀) 에연결된스위치가눌린시간을즉펄스폭을측정하여 PORTC 에연결된 LED에 msec 단위로표시한다. 회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 또한그림 80의 SW5 을누르면서실험한다. 분주비를 64 로한다. 결국 4 usec의해상도로최대 64*65536/16 usec = 256msec 까지펄스폭을잴수있다. 대충 ICR1H 값만큼의 msec 로펄스폭이구해짐을알수있다. 프로그램예 : #include <mega128.h> #include <delay.h> void main(void){ unsigned char pwidth; DDRC = 0xff; while(1){ TCCR1B = 0x03; TIFR = 0x20; // 포트C 를출력으로 // 64분주타이머시작 // ICF1 클리어 while(!(tifr & 0x20)); // 하강에지가검출될때까지기다린다. TIFR = 0x20; // 하강에지가검출되었으므로 ICF1 을클리어 TCNT1 = 0; TCCR1B =0x40; // 상승에지에서캡춰하도록설정 TCCR1B = 0x03; // 64분주 while(!(tifr & 0x20)); // 상승에지가검출될때까지기다린다. pwidth = (unsigned char) (( 256*ICR1H + ICR1L )*4 /1000); PORTC = ~pwidth; delay_ms(50); 과제 : 타이머 3 를사용해서구현해보라. - 104 -

4.3. 인터럽트와타이머복합실험 4.3.1. 실험 32 : LED 점멸속도조절 예제 : PORTC 에연결된 LED가 0.1초간격으로왼쪽으로회전하며점멸하다가 INT0(PORTD.0, 핀25) 에연 결된스위치를누르면상승에지트리거에의한인터럽트가발생하여속도가느려지고 INT1(PORTD.1, 핀26) 에 연결된푸시버튼을누르면회전속도가빨라진다. 프로그램작성시유의점 : 일정한시간간격을얻기위해타이머 0 의일반모드인터럽트를사용한다. 최대로느 린회전속도간격은 0.15초이고빠른간격은 0.05 초로한다. 시뮬레이션에서는너무느리므로타이머인터럽트 서비스루틴의시간지연을조정한다. 실제하드웨어구현할때는제거한다. 회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 또한그림 80의 SW1, SW2 를누르면서실험한다. 프로그램예 : #include <mega128.h> unsigned char led=0xfe; unsigned int cnt, delaytime, step, delaymax, delaymin; interrupt [2] void exint0(void){ // interrupt [EXT_INT0] void exint0(void) 처럼 mega128.h 에저장된정의를사용해도됨 if( delaytime + step <= delaymax ) delaytime += step; interrupt [3] void exint1(void){ // interrupt [EXT_INT1] void exint1(void) 처럼 mega128.h 에저장된정의를사용해도됨 if( delaytime - step >= delaymin ) delaytime -= step; interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 if(cnt-- == 1){ // cnt = delaytime; if(led!=0x7f) led = (led << 1) 0x01; else led = 0xfe; TCNT0 = 6; PORTC = led; void main(void){ DDRC = 0xff; // 포트C 를출력으로 PORTC = led; SREG = 0x80; // 인터럽트전체허용 EIMSK = 0b00000011; // INT0, 1 개별허용 EICRA = 0x0f; // INT0, 1 상승에지트리거 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 TCCR0 = 4; // 분주비를 64로설정 TCNT0 = 6; // 64*(256-6)/16=1000usec = 1msec delaytime = 100; cnt = delaytime; /* 점멸회전주기를 100*0.001 = 0.1 초로초기화 */ delaymax = 1000; delaymin = 10; /* 점멸회전주기의최대값과최소값을 1초와 0.01 초로초기화 */ step = 10; /* 주기변경폭을 10 으로초기화 */ while(1); 과제 : 1동일한일을수행하되타이머 0 대신에타이머 1~3 을사용하는프로그램을작성하라. INT3(PORTD.2, 핀27)) 에연결된푸시버튼를누르면속도가변하지않고 LED 점멸회전방향이바뀌는프로그 램을작성하라. 4.3.2. 실험 33 : 스톱워치 예제 : INT0(PORTD.0, 핀25) 에연결된스위치를누르면상승에지트리거에의한인터럽트가발생하여타 이머 1 의카운팅이정지되고다시한번누르면카운팅을시작한다. 2-105 -

회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 또한그림 80의 SW1 를누르면서실험한다. 프로그램예 : #include <mega128.h> unsigned char led, onoff=1; interrupt [2] void exint0(void){ // interrupt [EXT_INT0] void exint0(void) 처럼 mega128.h 에저장된정의를사용해도됨 if(onoff == 0) onoff = 1; else onff=0; void delay_i_ms(unsigned int i){ do{ while(!(tifr & 0x04)); // TOV1 가세트되었는지확인 TIFR = 0x04; /* 인터럽트발생없이타이머사용했으므로자동적으로클리어되지않으므로강제로클리어 */ TCNT1H = (65536-16000)/256; TCNT1L = (65536-16000) % 256; /* 재정의, 1msec 초를얻기위한시간정수 */ i--; while(i); void main(void){ DDRC = 0xff; // 포트C 를출력으로 DDRD = 0x00; // 포트D 를입력으로디폴트입력으로설정되어있으므로필요하지는않음 SREG.7 = 1; // 인터럽트전체허용 EIMSK = 0x01; // INT0 개별허용 EICRA = 3; // 상승에지트리거 TCCR1B = 1; // 타이머에클록을 1분주로클록공급 TCNT1H = (65536-16000)/256; TCNT1L = (65536-16000) % 256; for(;;){ PORTC = ~led ; delay_i_ms(1000); /* 1 sec 시간지연 */ if(onoff==0) led++; 과제 : 1 타이머 0,2,3 를사용하는프로그램을작성하라. 2 타이머 0~3 의인터럽트를사용해서구현해보라. 4.3.3. 실험 34 : PWM 신호발생 1 예제 : PORTC 에연결된 LED가 INT0(PORTD.0, 핀25) 에연결된푸쉬버튼을누르면점점밝아지고 INT1(PORTD.1, 핀26) 에연결된푸시버튼을누르면어두워진다. 프로그램작성시유의점 : 일정한시간간격에서 1 이지속되는시간을조절하여밝기를조절한다. 일정한시간 간격을얻기위해타이머2 를사용한다. 회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 또한그림 80의 SW1, SW2 를누르면서실험한다. 프로그램예 : #include <mega128.h> unsigned char led; unsigned int cnt, step=10, duration=500, MAX=999; interrupt [2] void exint0(void){ // interrupt [EXT_INT0] void exint0(void) 처럼 mega128.h 에저장된정의를사용해도됨 if(max > duration+step ) duration += step; interrupt [3] void exint1(void){ // interrupt [EXT_INT1] void exint1(void) 처럼 mega128.h 에저장된정의를사용해도됨 if( duration-step >0 ) duration -=step; interrupt [10] void timerint(void){ // interrupt [TIM2_COMP] void timerint(void) 로해도됨 if(cnt < duration) led = 0xff; else led = 0x00; if(cnt++ >= MAX) cnt = 0; // 1000*10 = 10 msec - 106 -

void main(void){ DDRC = 0xff; // 포트C 를출력으로 SREG = 0x80; // 인터럽트전체허용 EIMSK = 0b00000011; // INT0, 1 개별허용 EICRA = 0x0f; // INT0, 1 상승에지트리거 TIMSK = 0x80; // 타이머 2 출력비교인터럽트개별허용 TCCR2 = 1; // 분주비를 1로설정 TCCR2 = 0x20; // CTC mode OCR2 = 159; // 1usec = 1*(1+159)/16 16MHz 와분주비 1사용시 for(;;) PORTC = led; 과제 : 1MAX 와 duration 을 10 배이상으로하고수행해보라. 어떤현상이일어나나살피고그원인에대하여 생각해보라. 2 타이머 0,1,3 으로구현해보아라. 4.3.4. 실험 35 : PWM 신호발생 2 예제 : 타이머의 PWM모드를이용해서 LED 의밝기를조절한다. INT0(PORTD.0, 핀25) 에연결된푸쉬버튼을 누르면점점밝아지고 INT1(PORTD.1, 핀26) 에연결된푸시버튼을누르면어두워진다. 프로그램작성시유의점 : 타이머0의 PWM신호는 OC0(14 번핀, PB4) 에서출력된다. 시뮬레이션을할때는타 이머의카운트가너무오래걸릴수있으므로분주비를적절하게조절해야한다. 회로도 : 그림 80의 SW_CON과그림 92의 L2를각각그림 79의 D_CON과 B_CON 에연결한다. 또한그림 80의 SW1, SW2 를누르면서실험한다. 그림 92. LED 배열회로. #include <mega128.h> unsigned int step=5; interrupt [2] void exint0(void){ // interrupt [EXT_INT0] void exint0(void) 처럼 mega128.h 에저장된정의를사용해도됨 if( OCR0 < 0xff - step ) OCR0 += step; interrupt [3] void exint1(void){ // interrupt [EXT_INT1] void exint1(void) 처럼 mega128.h 에저장된정의를사용해도됨 if( OCR0 > step ) OCR0 -=step; void main(void){ DDRB.4 = 1; // PORTB bit 4를출력으로 SREG = 0x80; // 인터럽트전체허용 EIMSK = 0b00000011; // INT0, 1 개별허용 EICRA = 0x0f; // INT0, 1 상승에지트리거 TCCR0 = 6; // 분주비를 256로설정 - 107 -

TCCR0 = 0b01001000; // 타이머 0 FAST PWM 모드로설정 TCCR0 = 0x20; // 출력비교모드설정 OCR0 = 0x7F; for(;;); 과제 : 1 타이머 1~3 으로구현해보아라. - 108 -

5. 응용실험 5.1. FND(Flexible Numeric Display) 5.1.1. FND 의개요 구성 : FND는 7세그먼트표시기로도불리며그림 93처럼보통 8개의 LED 중 7개의 LED를 8자형태로배열 하고 0-9까지의숫자와 ABCDEF(HEX 값) 을표시하는데사용한다. 나머지 LED 는소숫점의표시에사용한다. 종류 : 모든 LED 의양극을한데묶은양극공통형 (CA), 음극을묶은음극공통형 (CC) 형이있다. 핀배치 : 정면에서보았을때왼쪽아래에서부터핀번호가 1 번으로시작하여반시계방향으로배열되어있다( 그 림 49 참조). 만약 CA형의경우 1을표시하려면 3번과 8번핀에 Vcc를연결하고 6번과 4번핀에 0 을연결한다. 만약 CA형의경우 3을표시하려면 3번과 8번핀에 Vcc를연결하고 2,4,6,7,10 번핀에 0 을연결한다. 특성 : LED 는소형으로발열이거의없고, 수명이반영구적이며응답속도가빠르고발광효율이높고가격이 싸며보통 10mA 이상의구동전류가필요한데직류의저전압에서동작이가능하다는등의장점이있어 FND도 마찬가지의장점이있다. 또한 16x2 캐릭터 LCD가만원정도인데비해 FND는개당수백원꼴이라값싼시스템 을위한표시장치로쓰인다. CA형을위한디코딩용구동 TTL은 7447, CC형을위한디코딩용구동 TTL은 7446 이있다. 그림 93. FND의내부구성과핀배치 5.1.2. 실험 36 : 디코더없는 FND 구동 예제 : CA형의 FND를 C_CON 에직접연결시키고 00~FFH 값을넣었을때패턴을살핀다. 프로그램작성시유의점 : 너무빨리패턴이지나가지않도록시간지연을준다. 회로도 : 그림 94의왼쪽디코더없는회로를구현하고 FND_CON 을그림 79에보여진시스템의 C_CON 에 연결한다. 프로그램예 : #include <mega128.h> #include <delay.h> unsigned char int; void main(void){ - 109 -

DDRC = 0xff; // 포트C 를출력으로 for(;;) {delay_ms(500); PORTC = led++; 그림 94. FND 기초실험도( 왼쪽: 디코더비사용, 오른쪽: 디코더사용) 과제 : 1 0~9, A,B,C,D,E,F 값을표시하기위한입력패턴값을찾아라. 2 찾은패턴값을이용하여 0~9, A,B,C,D,E,F 값을 1 초간격으로표시하는프로그램을작성하라. 5.1.3. 실험 37 : 디코더를사용한 FND 구동 예제 : CA형의 FND를 7447 을이용하여구동하고패턴을살핀다. 프로그램작성시유의점 : 너무빨리패턴이지나가지않도록시간지연을준다. 회로도 : 그림 94의오른쪽회로를구현하고 FND_CON 을그림 79에보여진시스템의 C_CON 에연결한다. 프로그램예 : #include <mega128.h> #include <delay.h> unsigned char int; void main(void){ DDRC = 0xff; // 포트C 를출력으로 for(;;) {delay_ms(500); PORTC = led++; 과제 : 1 위의프로그램은 0x00~0xff 의오름차순으로표시하는것이다. 내림차순으로표시하는프로그램을 작성하라. 2 0~9 값을반복적으로표시하는프로그램을작성하라. 3 delay_ms() 를사용하지말고타이머를 0~3 을사용하여시간지연을주어표시하는프로그램을작성하라. 5.1.4. 실험 38 : FND 동적구동 예제 : CA형의 FND0~5 의 6개를 C_CON 하나만을할애하여동적으로구동한다. 2msec 마다각 FND들을 번갈아구동시켜잔상에의해 6 개모두가켜져동작하는것처럼보이게한다. 프로그램작성시유의점 : 2msec의주기를얻기위해타이머0 의일반모드인터럽트를이용한다. 각 FND에 표시할데이터값은 1,2,3,4,5,6 이라고가정한다. 시뮬레이션을수행할때는너무오래걸릴수있으므로시간지연 을적절히조절해서한다. PORTC 로출력되는값의상위4 비트가데이터값이고하위4비트로활성화될 FND를지 정한다. 회로도 : 그림 95의회로를구현하고 FND_CON 을그림 79에보여진시스템의 C_CON 에연결한다. 프로그램예 : #include <mega128.h> - 110 -

unsigned char dbuf[6], dbuf_index; unsigned int cnt; interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 unsigned char tmpbuf; if( ++cnt == 2 ){ cnt = 0; if( dbuf_index++ == 5 ) dbuf_index= 0; tmpbuf = dbuf[dbuf_index]; PORTC = (( tmpbuf << 4 )&0xf0) dbuf_index; /* 표시할데이터와 FND의위치는 tmpbuf 의상위비트와하위비트로 */ TCNT0 = 6; // 재정의 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 void main(void){ DDRC = 0xff; // 포트C 를출력으로 SREG = 0x80; // 인터럽트전체허용 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 TCCR0 = 4; // 분주비를 64로설정 시뮬레이션할때는조절할필요가있음 TCNT0 = 6; // 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 dbuf[0]= 1; dbuf[1] = 2; dbuf[2]=3; dbuf[3] = 4; dbuf[4] = 5; dbuf[5] = 6; /* 표시할데이터초기화 */ for(;;); /* 인터럽트발생할때까지대기 */ 그림 95. FND의동적구동을위한회로도 과제 : 1타이머 0 대신타이머1~3 을사용하고주기를 1 msec 로하여라. 2 주기를 12 msec 이상예로 40 msec 로하여하드웨어를구현해보고어떤현상이나타나나보아라. 5.1.5. 실험 39 : 시계 예제 : CA형의 FND5 에시간의 10 의자리값, FND4 에시간의 1 의자리값, FND3 에분의 10 의자리값, FND2 에분의 1 의자리값, FND1 에초의 10 의자리값, FND0 에초의 1 의자리값을표시하는시계를만든다. 프로그램작성시유의점 : 타이머 0의일반모드를사용하였고 1 msec를주기로 FND 를동적으로구동한다. - 111 -

회로도 : 그림 95의회로를구현하고 FND_CON 을그림 79에보여진시스템의 C_CON 에연결한다. 프로그램예 : #include <mega128.h> unsigned char dbuf[6], dbuf_index; unsigned char hou, min, sec; unsigned int cnt; void hex2bcd(unsigned char hex, unsigned char *ptr) { /* 0x63 이하의헥사값을 bcd 로바꾼다 */ *ptr = hex % 10; *(ptr+1) = hex / 10; void watch(void){ if( ++sec == 60) { sec = 0; if( ++min == 60 ) { min = 0; if( ++hou == 24 ) hou = 0; hex2bcd(sec, &dbuf[0]); hex2bcd(min, &dbuf[2]); hex2bcd(hou, &dbuf[4]); interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 unsigned char tmpbuf; if( ++cnt == 1000 ){ cnt = 0; watch(); if( dbuf_index++ == 5 ) dbuf_index= 0; tmpbuf = dbuf[dbuf_index]; PORTC = (( tmpbuf << 4 )&0xf0) dbuf_index; /* 표시할데이터와 FND의위치는 tmpbuf 의상위비트와하위비트로 */ TCNT0 = 6; // 재정의 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 void main(void){ DDRC = 0xff; // 포트C 를출력으로 SREG = 0x80; // 인터럽트전체허용 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 TCCR0 = 4; // 분주비를 64로설정 시뮬레이션할때는조절할필요가있음 TCNT0 = 6; // 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 for(;;); /* 인터럽트발생할때까지대기 */ 과제 : 타이머 0 대신타이머 1~3 을사용하여라. 5.1.6. 실험 40 : 스톱워치 예제 : CA형의 FND5 에시간의 10 의자리값, FND4 에시간의 1 의자리값, FND3 에분의 10 의자리값, FND2 에분의 1 의자리값, FND1 에초의 10 의자리값, FND0 에초의 1 의자리값을표시하는시계를만든다. INT0(PORTD.0, 핀25) 에연결된스위치를누르면상승에지트리거에의한인터럽트가발생하여타이머 1의카 운팅이정지되고다시한번누르면카운팅을시작한다. 회로도 : 그림 95의회로를구현하고 FND_CON 을그림 79에보여진시스템의 C_CON 에연결한다. 그림 80 의 SW_CON 을그림 79의 D_CON 에연결한다. 또한그림 80의 SW1 를누르면서실험한다. 프로그램작성시유의점 : 타이머0 의일반모드를사용하여 10 msec를주기로 FND 를동적으로구동한다. 그 리고타이머2 의일반모드를사용하여시간을잰다. 프로그램예 : #include <mega128.h> unsigned char dbuf[6], dbuf_index; - 112 -

unsigned char hou, min, sec, onoff; unsigned int cnt0, cnt2; void hex2bcd(unsigned char hex, unsigned char *ptr) { /* 0x63 이하의헥사값을 bcd 로바꾼다 */ *ptr = hex % 10; *(ptr+1) = hex / 10; void watch(void){ if( ++sec == 60) { sec = 0; if( ++min == 60 ) { min = 0; if( ++hou == 24 ) hou = 0; hex2bcd(sec, &dbuf[0]); hex2bcd(min, &dbuf[2]); hex2bcd(hou, &dbuf[4]); interrupt [2] void exint0(void){ // interrupt [EXT_INT0] void exint0(void) 처럼 mega128.h 에저장된정의를사용해도됨 if(onoff == 0) onoff = 1; else onoff = 0; interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 if(onoff == 0) if( ++cnt0 == 1000 ){ cnt0 = 0; watch(); TCNT0 = 6; // 재정의 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 interrupt [11] void timerint2(void){ // interrupt [TIM2_OVF] void timerint0(void) 로해도됨 unsigned char tmpbuf; if( ++cnt2 == 10 ){ if( dbuf_index++ == 5 ) dbuf_index= 0; tmpbuf = dbuf[dbuf_index]; PORTC = (( tmpbuf << 4 )&0xf0) dbuf_index; /* 표시할데이터와 FND의위치는 tmpbuf 의상위비트와하위비트로 */ TCNT2 = 6; // 재정의 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 void main(void){ DDRC = 0xff; // 포트C 를출력으로 DDRD = 0x00; // 포트D 를입력으로디폴트입력으로설정되어있으므로필요하지는않음 SREG.7 = 1; // 인터럽트전체허용 EIMSK = 0x01; // INT0 개별허용 EICRA = 3; // 상승에지트리거 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 TCCR0 = 4; // 분주비를 64로설정 시뮬레이션할때는조절할필요가있음 TCNT0 = 6; // 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 TIMSK = 0x40; // 타이머 2 오버플로인터럽트개별허용 TCCR2 = 3; // 분주비를 64로설정 시뮬레이션할때는조절할필요가있음 TCNT2 = 6; // 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 for(;;); /* 인터럽트발생할때까지대기 */ 과제 : 1 타이머 0과 2 의역할을바꿔프로그램하여라. 2 타이머 1,3 을이용하여구현해보라. 5.1.7. 실험 41 : 시간조정이가능한시계 예제 : CA형의 FND5 에시간의 10 의자리값, FND4 에시간의 1 의자리값, FND3 에분의 10 의자리값, FND2 에분의 1 의자리값, FND1 에초의 10 의자리값, FND0 에초의 1 의자리값을표시하는시계를만든다. INT0(PORTD.0, 핀25) 에연결된스위치를누르면상승에지트리거에의한인터럽트가발생하여타이머 1의카 운팅이정지되고다시한번누르면카운팅을시작한다. INT1(PORTD.1, 핀26) 에연결된스위치를누르면상승 에지트리거에의한인터럽트가발생하여분값이증가하고 INT2(PORTD.1, 핀27) 에연결된스위치를누르면상 승에지트리거에의한인터럽트가발생하여시간값이증가한다. - 113 -

회로도 : 그림 95의회로를구현하고 FND_CON 을그림 79에보여진시스템의 C_CON 에연결한다. 그림 80 의 SW_CON 을그림 79의 D_CON 에연결한다. 또한그림 80의 SW1~3 를누르면서실험한다. 프로그램예 : #include <mega128.h> unsigned char dbuf[6], dbuf_index; unsigned char hou, min, sec, onoff=1; unsigned int cnt0, cnt2; void hex2bcd(unsigned char hex, unsigned char *ptr) { /* 0x63 이하의헥사값을 bcd 로바꾼다 */ *ptr = hex % 10; *(ptr+1) = hex / 10; void watch(void){ if( ++sec == 60) { sec = 0; if( ++min == 60 ) { min = 0; if( ++hou == 24 ) hou = 0; hex2bcd(sec, &dbuf[0]); hex2bcd(min, &dbuf[2]); hex2bcd(hou, &dbuf[4]); interrupt [2] void exint0(void){ // interrupt [EXT_INT0] void exint0(void) 처럼 mega128.h 에저장된정의를사용해도됨 if(onoff == 0) onoff = 1; else onoff = 0; interrupt [3] void exint1(void){ // interrupt [EXT_INT1] void exint1(void) 처럼 mega128.h 에저장된정의를사용해도됨 if( ++min == 60 ) { min = 0; if( ++hou == 24 ) hou = 0; interrupt [4] void exint2(void){ // interrupt [EXT_INT2] void exint2(void) 처럼 mega128.h 에저장된정의를사용해도됨 if( ++hou == 24 ) hou = 0; interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 if(onoff == 0) if( ++cnt0 == 1000 ){ cnt0 = 0; watch(); TCNT0 = 6; // 재정의 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 interrupt [11] void timerint2(void){ // interrupt [TIM2_OVF] void timerint0(void) 로해도됨 unsigned char tmpbuf; if( ++cnt2 == 10 ){ if( dbuf_index++ == 5 ) dbuf_index= 0; tmpbuf = dbuf[dbuf_index]; PORTC = (( tmpbuf << 4 )&0xf0) dbuf_index; /* 표시할데이터와 FND의위치는 tmpbuf 의상위비트와하위비트로 */ TCNT2 = 6; // 재정의 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 void main(void){ DDRC = 0xff; // 포트C 를출력으로 DDRD = 0x00; // 포트D 를입력으로디폴트입력으로설정되어있으므로필요하지는않음 SREG.7 = 1; // 인터럽트전체허용 EIMSK = 0x01; // INT0 개별허용 EIMSK = 0x02; // INT0 개별허용 EIMSK = 0x04; // INT0 개별허용 EICRA = 3; // 상승에지트리거 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 TCCR0 = 4; // 분주비를 64로설정 시뮬레이션할때는조절할필요가있음 TCNT0 = 6; // 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 TIMSK = 0x40; // 타이머 2 오버플로인터럽트개별허용 TCCR2 = 3; // 분주비를 64로설정 시뮬레이션할때는조절할필요가있음 - 114 -

TCNT2 = 6; // 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 for(;;); /* 인터럽트발생할때까지대기 */ 과제 : 1타이머 1,3 를사용하여프로그램하여라. 2 초값은표시하지않아시간과분만을표시하여 FND 4개 만을사용하는시간조정이가능한시계용프로그램을작성해보아라. 5.2. 키보드스캐닝 5.2.1. 실험 42 : 단순키보드스캔 예제 : D_CON 에연결된 8개의누름키에서 PORTD.0 에연결된것부터차례대로 SW1, SW2,...SW8 의일련번 호를붙이고눌린번호키의 2진수값을 PORTC 에연결된 LED 에표시하는프로그램을작성한다. 프로그램작성시유의점 : 채터링현상을소프트웨어적으로처리하기위해유효한값을읽기위해그림 96의 순서도에주어진순서를따라한다. 먼저연속해서두번읽어같은값이감지되었는지확인한다. 그후감지된값 이키가눌린경우( 읽힌값은 0xff 가아니다 ) 인지여부를확인한다. 읽은값이 (20-50 msec) 이전에읽어 oldkey 에보관된값과같으면유효한키값으로 keybuf 에저장하고그렇지않으면 20-50 msec시간정도의지 연후에같은과정을반복한다. 즉두번확인하는방식을택한다. 회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 또한그림 80의 SW1 을누르면서실험한다. 프로그램예 : 그림 96. 키보드스캔을위한순서도 #include <mega128.h> #include <delay.h> // delay_ms(), delay_us() 를이용할것이다. unsigned char keybuf=0xff, oldkey=0xff; void scankey(void){ unsigned char tmp; do{ tmp = PIND; /* 첫번째읽은것을 tmp 에저장 */ while( tmp!= PIND ); /* 첫번째읽은값과두번째읽은값이일치하지않으면다시읽는다 */ if(tmp!= 0xff) { /* 두번읽은것이키가눌린경우이면 (0xff 이면아무키도안눌린상태임 ) 아래로 */ - 115 -

if(tmp == oldkey) { /* 현재읽어들인값(tmp) 와 oldkey 가같으면아래로 */ if(tmp == 0xfe) keybuf = 1; else if( tmp == 0xfd ) keybuf = 2; else if( tmp == 0xfb ) keybuf = 3; else if( tmp == 0xf7 ) keybuf = 4; else if( tmp == 0xef ) keybuf = 5; else if( tmp == 0xdf ) keybuf = 6; else if( tmp == 0xbf ) keybuf = 7; else if( tmp == 0x7f ) keybuf = 8; else oldkey = 0xff; oldkey = 0xff; else oldkey = tmp; /* 현재읽어들인값(tmp) 와 oldkey 가다르면 oldkey 를 tmp 로바꾼다. */ void main(void){ DDRC = 0xff; // 포트C 를출력으로 DDRD = 0x00; // 포트D 를입력으로디폴트입력으로설정되어있으므로필요하지는않음 for(;;){ scankey(); PORTC = keybuf; delay_ms(50); /* 50 msec 시간지연 */ 과제 : 타이머인터럽트를사용하여 30msec 마다키보드스캔을하는프로그램를작성하여라. 5.2.2. 실험 43 : 키매트릭스스캔 예제 : D_CON 에연결된 5X5 키매트릭스에차례대로 SW1, SW2,...SW25 의일련번호를붙이고눌린번호키 의 2진수값을 PORTC에연결된 LED 에표시하는프로그램을작성한다. 프로그램작성시유의점 : 채터링현상을소프트웨어적으로처리하기위해유효한값을읽기위해그림 96의 순서도에주어진순서를따라한다. 회로도 : 그림 80의 SW_CON 을그림 79의 D_CON 에연결하고실험할때는 LEDSW 를닫고한다. 또한그림 80의 SW1 을누르면서실험한다. 프로그램예 : #include <mega128.h> unsigned int cnt; unsigned char keybuf=0xff, oldkey=0xff; void scankey(void){ unsigned char tmp, row, cul; for(row=0; row<5 ;row++){ do{ PORTC = 0xf8 row; /* row에 1 을쓴다 */ tmp = PIND & 0xf8 ; /* 첫번째읽은포트3 의비트7~ 비트3 값을 tmp 에저장 */ PORTC = 0xf8 row; /* 두번째읽기위해 1 을쓴다 */ while( (PIND & 0xf8)!= tmp ); /* 첫번째와두번째읽은값이일치하지않으면다시읽는다 */ if(tmp!= 0xf8) { /* 두번읽은값이일치하고키눌림이있는경우라면아래로 */ tmp += row; if(tmp == oldkey) { /* 현재의키값(tmp) 이 oldkey 값과같으면아래로 */ tmp = (tmp >>3) &0x1f; if(tmp == 0x1e) cul = 1; else if( tmp == 0x1d ) cul = 2; else if( tmp == 0x1b ) cul = 3; else if( tmp == 0x17 ) cul = 4; else if( tmp == 0x0f ) cul = 5; else goto next; - 116 -

keybuf = row*6 + cul; next: oldkey = 0xff; else oldkey = tmp; /* 현재의키값과 oldkey 값이다르면 oldkey <- tmp */ interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 if( ++cnt == 50 ){ // 50값을시뮬레이션할때는조절할필요가있음 cnt = 0; scankey(); TCNT0 = 6; // 재정의 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 void main(void){ DDRC = 0xff; // 포트C 를출력으로 DDRD = 0x07; // 포트D 의비트0~2 를출력으로설정 SREG.7 = 1; // 인터럽트전체허용 TCCR0 = 4; // 분주비를 64로설정 시뮬레이션할때는조절할필요가있음 TCNT0 = 6; // 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 for(;;) PORTC = keybuf; 과제 : 타이머인터럽트 1~3 를사용하는프로그램를작성하여라. 그림 97. 5X5 키매트릭스 5.3. 음향발생 5.3.1. 음향발생개요 음향발생원리: 스피커에 1레벨과 0레벨신호를반복적으로주어온오프시키는데주기를바꾸어주면음의 고저가다른( 주파수가다른신호) 를발생시킬수있고지속시간을바꾸어주어장단이다른신호를발생시킨다. 음계발생프로그램기법 : 내고자하는음계의주파수 ( 주기의역수) 가주어지고내고자하는음계의지속시간 이주어지면반주기 ( 주파수역수의반) 동안스피커를온시켜주고반주기동안은스피커를오프시키는것을반복 하되지속시간 (1/32 박자를 1로정규화한 time_data) 이지나면끝내도록하면된다. 표13과표14에음계와박자 - 117 -

에따른시간정보를보였다. 표 13. 음계에따른 tone_data 값 음계 주파수x2(2/T) 반주기 (msec) 음계 주파수x2(2/T) 반주기 (msec) 도 1046.5 0.95 도 # 1100.7 0.90 레 1174.7 0.84 레 # 1244.5 0.80 미 1318.5 0.75 파 1396.9 0.71 파 # 1479.9 0.67 솔 1567.9 0.63 라 1760.0 0.56 라 # 1864.6 0.53 시 1975.6 0.50 도 2093.0 0.47 도 # 2201.4 0.45 레 2349.4 0.42 레 # 2489.0 0.39 미 2637.0 0.37 파 2793.8 0.35 파 # 2959.8 0.33 솔 3135.8 0.31 솔 # 3322.4 0.29 라 3520.0 0.28 라 # 3729.2 0.26 시 3951.2 0.25 도 4186.0 0.23 표 14. 박자에따른지속시간값 박자 시간 (msec) time_data 박자 시간 (msec) time_data 1/32 21.306 1 1/16 42.613 2 1/8 85.227 4 1/4 170.454 8 1/2 340.909 16 1 681.818 32 1과 1/2 1,022.727 48 2 1,363.636 64 2와 1/2 1,704.545 80 3 2,045.454 96 5.3.2. 실험 44 : 사이렌소리내기 예제 : 저주파의소리에서점점고주파의소리를변하게하는것을반복적으로한다. PORTD.0 에연결된스위 치를누르면 PORTC.0 에연결된스피커에서소리를내기시작한다. 3 박자마다주파수를변하게한다. 프로그램작성시유의점 : 이경우에는음계에따라반주기값을바꿔줄필요가없다. 회로도 : 그림 98의회로를구현하고 BUZZ_CON 을그림 79의 C_CON 에연결한다. 그림 80의 SW_CON 을 그림 79의 D_CON에연결하고그림 80의 SW1 을누르면서실험한다. 그림 98에서 2SC1815Y 와 PORTC.0 사 이에들어가는콘덴서와저항과다이오드는필터역할을하는것으로생략가능하다. 즉다이오드를없애 2SC1815Y 의베이스와에미터를개방시키고콘덴서와저항은없애고 PORTC.0 과 2SC1815Y 의베이스를연결 해서사용해도된다. 프로그램예 : #include <mega128.h> #include <delay.h> unsigned char time_data; interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 time_data--; TCNT0 = 77; // 21.306msec = 1024*(256-77)/16 시뮬레이션할때는조절할필요가있음 void playtone(unsigned int tone, unsigned char time){ // tone 는반주기값 1usec, time 는박자값 unsigned int buf; TCCR0 = 7; // 분주비를 1024 로설정 시뮬레이션할때는조절할필요가있음 TCNT0 = 77; // 21.306msec = 1024*(256-77)/16 시뮬레이션할때는조절할필요가있음 time_data = time; buf = tone; do{ - 118 -

PORTC.0 = 1; do{ delay_us(1); while(buf--); PORTC.0 = 0; do{ delay_us(1); while(tone--); while(time_data); time_data = time; TCNT0 = 77; // 21.306msec = 1024*(256-77)/16 시뮬레이션할때는조절할필요가있음 while(time_data); TCCR0 =0x00; void main(void){ unsigned int tone_data=0xffff; DDRC = 0xff; // 포트C 를출력으로 DDRD = 0x00; // 포트D 를입력으로디폴트입력으로설정되어있으므로필요하지는않음 SREG.7 = 1; // 인터럽트전체허용 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 for(;;){ loop: while(pind.0 == 1); /* PORTD.0 가눌릴때까지대기 */ delay_ms(50); if(pind.0 == 1) goto loop; /* 눌림이 50msec 동안지속안되면키입력은무시된다 */ while(pind.0!=1); /* PORTD.0 가해제될때까지대기 */ if(tone_data > 100){tone_data -=200; playtone(tone_data,250); else tone_data=0xffff; 그림 98. 음향발생을위한회로도 과제 : 1타이머 1~3 를사용해구현해보라. 2PORTD.0 에연결된스위치를누르면소리가나고 5초후에멈추 는프로그램을작성하라. 5.3.3. 실험 45 : 전화벨소리내기 예제 : PORTD.0 에연결된스위치가눌리면소리를내기시작하여 480Hz 1/32 박자, 320Hz 1/32박자를 20번 반복하여소리를내고멈춘다. 프로그램작성시유의점 : 480Hz와 320Hz의주기는각각 2.083msec 와 3.125msec 이다. 1/32박자만큼지속 하므로 time_data 를 1 로주면된다. 회로도 : 그림 98의회로를구현하고 BUZZ_CON 을그림 79의 C_CON 에연결한다. 그림 80의 SW_CON 을 그림 79의 D_CON 에연결하고그림 80의 SW1 을누르면서실험한다. 프로그램예 : #include <mega128.h> - 119 -

#include <delay.h> unsigned char time_data; interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 time_data--; TCNT0 = 77; // 21.306msec = 1024*(256-77)/16 시뮬레이션할때는조절할필요가있음 void playtone(unsigned char tone, unsigned char time){ // tone 는반주기값 10usec, time 는박자값 unsigned char buf; TCCR0 = 7; // 분주비를 1024 로설정 시뮬레이션할때는조절할필요가있음 TCNT0 = 77; // 21.306msec = 1024*(256-77)/16 시뮬레이션할때는조절할필요가있음 time_data = time; buf = tone; do{ PORTC.0 = 1; do{ delay_us(10); while(buf--); PORTC.0 = 0; do{ delay_us(10); while(tone--); while(time_data); time_data = time; TCNT0 = 77; // 21.306msec = 1024*(256-77)/16 시뮬레이션할때는조절할필요가있음 while(time_data); TCCR0 =0x00; void main(void){ unsigned char i; DDRC = 0xff; // 포트C 를출력으로 DDRD = 0x00; // 포트D 를입력으로디폴트입력으로설정되어있으므로필요하지는않음 SREG.7 = 1; // 인터럽트전체허용 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 for(;;){ loop: while(pind.0 == 1); /* PORTD.0 가눌릴때까지대기 */ delay_ms(50); if(pind.0 == 1) goto loop; /* 눌림이 50msec 동안지속안되면키입력은무시된다 */ while(pind.0!=1); for(i=0;i<20;i++){ playtone(208/2,1); playtone(313/2,1); /* PORTD.0 가해제될때까지대기 */ 과제 : 1타이머 1~3 를사용해구현해보라. 2 PORTC.0 에연결된스위치를누르면전화벨소리가나고 PORTC.1 에연결된스위치를누르면사이렌소리가나는프로그램을작성하라. 5.3.4. 실험 46 : 동요재생하기 예제 : PORTC.0 에연결된스위치를누르면동요곰세마리가연주한다. 회로도 : 그림 98의회로를구현하고 BUZZ_CON 을그림 79의 C_CON 에연결한다. 그림 80의 SW_CON 을 그림 79의 D_CON 에연결하고그림 80의 SW1 을누르면서실험한다. 프로그램작성시유의점 : 메모리에동요곰세마리의음계와박자를저장하되마지막에박자에 00가들어가 도록한다. 순서대로읽어들이되박자가 0이면연주가끝났으므로처음으로복귀하여스위치가눌리는지를감 시하도록한다. 프로그램예 : #include <mega128.h> #include <delay.h> unsigned char time_data; unsigned char timetone[ ]={32, 95, 16, 95, 32, 95, 32, 95, 32, 75, 16, 63, 16, 63, 32, 75, 32, 95, 16, 63, 16, 63, 32, 75, 16, 63, 16, 63, 32, 75, 32, 95, 32, 95, 64, 95, 32, 63, 32, 63, 32, 75, 32, 95, 32, 63, 32, 63, 64, 63, 32, 63, 32, 63, 32, 75, 32, 95, 32, 63, 32, 63, 64, 63, - 120 -

32, 63, 32, 63, 32, 75, 32, 95, 24, 63, 8, 63, 16, 63, 16, 63, 64, 63, 16, 31, 16, 0, 16, 63, 16, 0, 16, 31, 16, 0, 16, 63, 16, 0, 32, 75, 32, 84, 64, 95, 0; interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 time_data--; TCNT0 = 77; // 21.306msec = 1024*(256-77)/16 시뮬레이션할때는조절할필요가있음 void playtone(unsigned char tone, unsigned char time){ // tone 는반주기값 10usec, time 는박자값 unsigned char buf; TCCR0 = 7; // 분주비를 1024 로설정 시뮬레이션할때는조절할필요가있음 TCNT0 = 77; // 21.306msec = 1024*(256-77)/16 시뮬레이션할때는조절할필요가있음 time_data = time; buf = tone; do{ PORTC.0 = 1; do{ delay_us(10); while(buf--); PORTC.0 = 0; while(time_data); time_data = time; TCNT0 = 77; while(time_data); TCCR0 =0x00; void main(void){ unsigned char dataidx, tone_data, time; do{ delay_us(10); while(tone--); // 21.306msec = 1024*(256-77)/16 시뮬레이션할때는조절할필요가있음 DDRC = 0xff; // 포트C 를출력으로 DDRD = 0x00; // 포트D 를입력으로디폴트입력으로설정되어있으므로필요하지는않음 SREG.7 = 1; // 인터럽트전체허용 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 for(;;){ dataidx = 0; loop: while(pind.0 == 1); /* PORTD.0 가눌릴때까지대기 */ delay_ms(50); if(pind.0 == 1) goto loop; /* 눌림이 50msec 동안지속안되면키입력은무시된다 */ while(pind.0!=1); /* PORTD.0 가해제될때까지대기 */ while ( (time =timetone[dataidx++])!= 0) { tone_data=timetone[dataidx++]; playtone(tone_data, time); 과제 : 1타이머 1~3 를사용해구현해보라. 2다른동요를저장하고연주하는프로그램을작성해보라. 5.3.5. 실험 47 : 전자오르간 예제 : PORTD 에연결된스위치가눌리면맞는음계의소리를발생시킨다. 회로도 : 그림 98의회로를구현하고 BUZZ_CON 을그림 79의 C_CON 에연결한다. 그림 80의 SW_CON 을 그림 79의 D_CON 에연결하고그림 80의 SW1~8 을누르면서실험한다. 프로그램작성시유의점 : 박자를위해타이머를쓸필요없이눌림을감지해감지되면한주기동안만해당 음계의소리가나도록한다. SW1이눌리면도음계가발생하고 SW2가눌리면레음계가발생하는식으로짠 다. 프로그램예 : #include <mega128.h> #include <delay.h> unsigned char time_data; interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 time_data--; TCNT0 = 77; // 21.306msec = 1024*(256-77)/16 시뮬레이션할때는조절할필요가있음 - 121 -

void playtone(unsigned char tone, unsigned char time){ // tone 는반주기값 10usec, time 는박자값 unsigned char buf; TCCR0 = 7; // 분주비를 1024 로설정 시뮬레이션할때는조절할필요가있음 TCNT0 = 77; // 21.306msec = 1024*(256-77)/16 시뮬레이션할때는조절할필요가있음 time_data = time; buf = tone; do{ PORTC.0 = 1; do{ delay_us(10); while(buf--); PORTC.0 = 0; do{ delay_us(10); while(tone--); while(time_data); time_data = time; TCNT0 = 77; // 21.306msec = 1024*(256-77)/16 시뮬레이션할때는조절할필요가있음 while(time_data); TCCR0 =0x00; void main(void){ unsigned char tone_data, keybuf; DDRC = 0xff; // 포트C 를출력으로 DDRD = 0x00; // 포트D 를입력으로디폴트입력으로설정되어있으므로필요하지는않음 SREG.7 = 1; // 인터럽트전체허용 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 for(;;){ keybuf = PIND; /* 읽은값을 keybuf 에저장 */ if((keybuf == PIND) && (keybuf!=0xff) ) { /* 두번읽어같으며 0xff 가아니면유효한키입력이다 */ if(keybuf == 0xfe) tone_data= 95; else if (keybuf == 0xfd) tone_data = 84; else if (keybuf == 0xfb) tone_data = 75; else if (keybuf == 0xf7) tone_data = 71; else if (keybuf == 0xef) tone_data = 63; else if (keybuf == 0xef) tone_data = 56; else if (keybuf == 0xbf) tone_data = 50; else if (keybuf == 0x7f) tone_data = 47; else tone_data = 0; if(tone_data!=0)playtone(tone_data,1); 과제 : 타이머 1~3 를사용해구현해보라. 5.4. 16x2 문자 LCD 5.4.1. 16x2 문자 LCD 모듈개요 LCD 개요: 동적 LCD와전계효과 LCD 가있는데전계효과형이가장흔히사용되어전자계산기, 시계와컴퓨 터등에사용된다. 일반적으로약 300 μa 의작은구동전류에서작동하나교류전원을요구한다. LCD 표시부 와 LCD 제어부를하나로하여 LCD 모듈로시판된다. 문자형과그래픽형 2 가지가있다. 영문자와숫자표시에는 문자형이적당하며한글이나그래픽표시를자유롭게하려면그래픽형을사용해야한다. 문자형에는 8x1(8 문자 를 1 라인에표시), 8x2, 16x1,..., 16x4, 20x1,..., 20x4 등다양한종류가있다. HD44780 16x2 LCD 제어기특징 : 16x2 LCD 제어기에가장보편적으로사용되는히타치사의제어기, 5V 단일전원사용, 5x7 나 5x10 도트의내장폰트존재, 8비트나 4 비트데이터버스방식, 최대 80문자까지표 시할문자저장하는 80바이트 DDRAM(Display Data RAM) 내장, 5x7 폰트는 160개 5x10 폰트는 32개를수용 할수있는 CGROM(Character Generator ROM) 내장. 핀배치 : 1 번(Vss:GND), 2 번(Vdd: +5V), 3 번(Vo: 휘도조절, 보통 GND 에연결), 4 번(RS: Register Select핀 - 122 -

으로 1레벨이면데이터레지스터가선택되고 0 레벨이면명령레지스터가선택됨), 5 번(R/W: 읽기(H), 쓰기(L) 제 어), 6 번(E: Enable신호로 1레벨이면 LCD 에명령이나데이터를보낼수있다), 15 번(A: 백라이트양극 ), 16번 (K: 백라이트음극), 7-14 번(DB0-DB7: 데이터버스, 4비트모드의경우 D4-D7를사용하여상위4비트하위4비트 순으로읽고씀 ) 5.4.2. LCD 제어기의내부구성 명령(Instruction) 과데이터(Data) 를위한 2 개의레지스터, BF(Busy Flag), AC(Address Counter), 문자발생램 (CGRAM), 문자발생롬 (CGROM), 데이터표시램 (DDRAM) 이있다. 레지스터 명령레지스터 (IR): DDRAM과 CGRAM 에대한어드레스와클리어, 커서시프트등제어명령을보유 데이터레지스터 (DR): DDRAM 과 CGRAM 에쓴데이터나읽은데이터를일지적으로저장 레지스터선택방법 : RS(4 번핀) 과 R/W(5 번핀) 을사용하여선택 RS=0, R/W=0 : IR 쓰기( 각종제어명령쓰기) RS=0, R/W=1 : BF 읽기, AC읽기 RS=1, R/W=0 : DR 쓰기 RS=1, R/W=1 : DR 읽기 BF : 1이면 LCD 의콘트롤러가동작중으로명령수행불능, 0이면다음명령수행가능표시 AC : DDRAM 과 CGRAM 의주소를지정할때사용하는데 IR에주소정보를쓰면주소정보가 AC로전송되고 DDRAM 이나 DDROM 에데이터를쓰면 AC 는자동으로 +1혹은 -1 이된다. DDRAM(Data Display RAM) : 80x8비트용량으로 80개의 8 비트아스키코드를저장할수있다. 0x00-0F 주 소가 LCD 1행의 1-16 번째, 0x40-4F 주소가 LCD 2행의 1-16 번째문자로표시된다.(1행 2행의번호불연속임 에주의해야한다.) CGRAM(Character Generator RAM) : 사용자가자유로이문자를만들때사용하는램으로 5x7은 8 개, 5x10 은 4 개만들어저장가능하다. CGROM(Character Generator ROM) : 5x7, 5x10 도트의문자를내장하고있다. 특수기호, 숫자, 영문자의 문자코드는아스키코드와일치한다. 5.4.3. 명령어 4 번(RS), 5 번(R/W), 6 번(E: ENABLE 신호), 15 번(A: 백라이트양극 ), 16 번(K: 백라이트음극), 7-14번 (DB0-DB7) 값을이용하여제어한다. E=1 이어야명령이유효하다. 표시클리어 : RS=R/W=0, DB=0b00000001, 실행시간 1.64msec, 표시내용을소거하고커서는홈(1행 1 열, 0번 지) 로돌아감, DDRAM 에스페이스코드 (0x20) 가쓰여지고 AC=0 으로됨 커서홈 : RS=R/W=0, DB=0b0000001x, 실행시간 1.64msec, DDRAM의 AC=0x00 로세트되어커서가홈으로 가며 DDRAM 의내용은변동없음 엔트리모드설정: 커서의이동방향과표시내용의시프트여부설정, 실행시간 0.04msec RS=R/W=0, DB=0b00000101 : DDRAM 에데이터를써넣은후표시전체를좌로이동, 커서는이동안함 RS=R/W=0, DB=0b00000111 : DDRAM 에데이터를써넣은후표시전체를우로이동, 커서는이동안함 RS=R/W=0, DB=0b00000100 : 표시를이동하지않고 AC를감소시키고커서가좌측으로이동하게함 - 123 -

RS=R/W=0, DB=0b00000110 : 표시를이동하지않고 AC를증가시키고커서가우측으로이동하게함 표시온오프제어 : 커서나전체표시의온오프제어및커서위치문자의깜박임제어, 실행시간 0.04msec RS=R/W=0, DB=0b00001dcb : d=1 일때전체온, c=1 커서온, b=1 커서위치문자점멸 커서/ 표시시프트 : DDRAM 의내용을변경시키지않은상태에서커서를움직이거나전체문자를이동, 실행시간 0.04msec RS=R/W=0, DB=0b000100xx : AC를 1감소시키고커서를좌로이동 RS=R/W=0, DB=0b000101xx : AC를 1증가시키고커서를우로이동 RS=R/W=0, DB=0b000110xx : RS=R/W=0, DB=0b000111xx : 모든표시와커서를좌로이동 모든표시와커서를우로이동 기능설정: 표시행수와문자폰트, 인터페이스길이를설정, 실행시간 0.04msec RS=R/W=0, DB=0b0011NFxx : 8 비트인터페이스 RS=R/W=0, DB=0b0010NFxx : 4 비트인터페이스 여기에서 NF=00(1 행 5x7 폰트), NF=01(1 행 5x10 폰트), NF=1x(2 행 5x7 폰트) CGRAM 주소설정 : CGRAM 의 6 비트주소를설정, 설정후전송데이터는 CGRAM 의데이터로취급됨, 실행시 간 0.04msec RS=R/W=0, DB=0b01xxxxxx : xxxxxx 부분의값이 AC로설정됨 DDRAM 주소설정 : DDRAM 의 7 비트주소를설정, 설정후전송데이터는 DDRAM 의데이터로취급됨, 실행 시간 0.04msec RS=R/W=0, DB=0b1xxxxxxx : xxxxxxx 부분의값이 AC로설정됨 BF와 AC 읽기: BF의값이나 AC 의값을읽어들인다. 실행시간 0.04msec RS=0, R/W=1 : DB7이 BF의값이고 DB6-0 가 AC 값이다. CGRAM, DDRAM 에데이터쓰기: 이전에주소가설정된램에쓰고엔트리모드에따라주소값이 +1 혹은 -1 RS=1, R/W=0 : 기능설정의인터페이스길이에따라 DB 를통해쓴다. CGRAM, DDRAM 에데이터읽기: 읽기전에주소설정명령을해야함, 안그러면두번째데이터부터유효 RS=1, R/W=1 : 기능설정의인터페이스길이에따라 DB 를통해읽는다. 5.4.4. 초기화방법 (4 비트인터페이스경우 ) 전원온 -> Vdd가 4.5V 이상된후 15msec 지연 -> RS=R/W=0, DB=0b0010xxxx 출력 -> 5msec 지연 -> RS=R/W=0, DB=0b0010xxxx -> 0.1msec 지연 -> -> 4비트인터페이스기능설정 RS=R/W=0, DB=0b0010NFxx(NF 는적절한값) -> 표시온오프제어 RS=R/W=0, DB=0b00001100 -> 표시클리어 RS=R/W=0, DB=0b00000001 -> 엔트리모드설정 RS=R/W=0, DB=0b000001**(** 는적절한값) -> 초기화완료 5.4.5. 실험 48 : LCD 초기화 - 124 -

예제 : PORTC에연결된 LCD를 4비트인터페이스모드로초기화하고 Enjoy yourselves 라는문자열을 1행에 mega128 u-com라는문자열을 2 행에출력한다. 프로그램작성시유의점 : 다른응용에서도 include 시켜써먹을수있도록작성하였다. 그러므로작성된프로 그램으로실험할때에는 main() 의앞뒤에있는 /********* 과 *******/ 주석표시를제거한다. lcd.h 헤더파일을다 음처럼 include 시키면된다. #asm.equ lcd_port= 0x15 ; 포트C 에 LCD 위치 #endasm #include <lcd.h> 그러면다음함수를사용해서 lcd 를제어할수있다. lcd_init(unsigned char lcd_columns) : lcd_columns 개의열을갖는 LCD 를사용할수있도록초기화한다. lcd_clear() : LCD 에써진것을지운다. lcd_gotoxy(unsighed char x, unsigned char y) : 커서를 x+1 열, y+1 행위치로보낸다. lcd_putchar(char c) : LCD의현재커서에문자 c 를표시한다. lcd_putsf(char flash *str) : flash에위치한스트링을 LCD 의현재커서를시작점으로하여표시한다. 회로도 : 그림 99의회로를구현하고 LCD_CON 을그림 79의 C_CON 에연결한다. 프로그램예 1 : 그림 99. 16x2 문자 LCD 실험회로도 #include <mega128.h> #include <delay.h> #define CUR11 0x02 /* 커서홈에위치시키는명령어값 */ #define CUR21 0xC0 /* 커서 2라인 1 열에위치시키는명령어값 */ #define LCDON 0x0C /* LCD ON 명령어값 */ #define LCDOFF 0x08 /* LCD OFF 명령어값 */ #define MODE4 0x20 /* 4 비트인터페이스설정 */ #define FSET 0x28 /* 기능설정, 4 비트인터페이스, NF=10 : 2행 5x7 폰트 */ #define LCDCLR 0x01 /* LCD 클리어 */ #define MODENT 0x06 /* 엔트리모드설정, 표시는이동않고, AC 증가, 커서우측이동 */ void lcd_cmd(unsigned char ch){ /* LCD 에명령어값 1 바이트쓰는서브루틴, ch 는명령어값 */ unsigned char temp0, temp1; delay_ms(15); /* 약 15msec delay */ DDRC = 0xff; // 포트C 를출력으로 - 125 -

temp0 = ch & 0xf0; /* 상위4 비트마스크 */ temp1 = temp0 0x04; /* 하위 4비트에 0100b(RS=R/W=0, E=1) 써넣기 */ PORTC = temp1; /* LCD 에명령어값의상위 4 비트써넣기 */ temp1 = temp0 & 0xf0; /* 하위 4비트에 0000b(RS=R/W=0, E=0) 써넣기 */ PORTC = temp1; /* LCD 에입력불허 */ delay_us(10); /* 약 0.01 msec 시간지연 */ temp0 = (ch << 4) & 0xf0 ; /* 하위4 비트를상위로옮기고마스크 */ temp1 = temp0 0x04 ; /* 하위 4비트에 0100b(RS=R/W=0, E=1) 써넣기 */ PORTC = temp1; /* LCD 에명령어값의하위 4 비트써넣기 */ temp1 = temp0 & 0xf0; /* 하위 4비트에 0000b(RS=R/W=0, E=0) 써넣기 */ PORTC = temp1; /* LCD 에입력불허 */ delay_ms(1); /* 약 1 msec 시간지연 */ void lcd_ln11(void){ /* LCD 의 1행1 열에커서를위치시키는서브루틴 */ lcd_cmd(cur11); void lcd_ln21(void){ /* LCD 의 2행1 열에커서를위치시키는서브루틴 */ lcd_cmd(cur21); void lcd_dat(unsigned char ch){ /* LCD 에 1 글자쓰는서브루틴, ch 는글자의아스키코드값 */ unsigned char temp0, temp1; delay_ms(15); /* 약 15msec delay */ DDRC = 0xff; // 포트C 를출력으로 temp0 = ch & 0xf0; /* 상위4 비트마스크 */ temp1 = temp0 0x05; /* 하위 4비트에 0101b(RS=1, R/W=0, E=1) 써넣기 */ PORTC = temp1; /* LCD 에 DATA 값의상위 4 비트써넣기 */ temp1 = temp0 0x01; /* 하위 4비트에 0001b(RS=1, R/W=0, E=0) 써넣기 */ PORTC = temp1; /* LCD 에입력불허 */ delay_us(10); /* 약 0.01 msec 시간지연 */ temp0 = (ch << 4) & 0xf0 ; /* 하위4 비트를상위로옮기고마스크 */ temp1 = temp0 0x05; /* 하위 4비트에 0101b(RS=1, R/W=0, E=1) 써넣기 */ PORTC = temp1; /* LCD 에 DATA 값의하위 4 비트써넣기 */ temp1 = temp0 0x01; /* 하위 4비트에 0001b(RS=1, R/W=0, E=0) 써넣기 */ PORTC = temp1; /* LCD 에입력불허 */ delay_ms(1); /* 약 1 msec 시간지연 */ void lcd_init(void){ /* LCD 초기화서브루틴 */ delay_ms(15); /* 약 15msec delay */ lcd_cmd(mode4); delay_ms(5); /* 약 5msec delay */ lcd_cmd(mode4); delay_us(100); lcd_cmd(mode4); lcd_cmd(fset); /* 기능설정, 4 비트인터페이스, NF=10 : 2행 5x7 폰트 */ lcd_cmd(lcdon); /* LCD ON 명령어값 */ lcd_cmd(lcdclr); /* LCD Clear 명령어값 */ lcd_cmd(modent); /* 엔트리모드설정, 표시는이동않고, AC 증가, 커서우측이동 */ void lcd_str(char flash *str){ /* LCD 에 flash 에저장된문자열을출력하는함수 */ unsigned int i=0; for(;str[i]!= 0; i++) lcd_dat(str[i]); /************************************* void main(void){ lcd_init(); lcd_ln11(); lcd_str("enjoy yourselves"); lcd_ln21(); lcd_str("mega128 u-com"); - 126 -

*********************************/ 프로그램예2 : lcd.h 를사용하면다음처럼쉽게짤수있다. #include <mega128.h> #include <delay.h> #asm.equ lcd_port= 0x15 ; 포트C 에 LCD 위치 #endasm #include <lcd.h> void main(void){ lcd_init(16); lcd_gotoxy(0,0); lcd_putsf("enjoy yourselves"); lcd_gotoxy(0,1); lcd_putsf("mega128 u-com"); 5.4.6. 실험 49 : 점멸하며문자표시하기 예제 : PORTC에연결된 LCD를 4비트인터페이스모드로초기화하고 Enjoy yourselves 라는문자열을 1행에 mega128 u-com 라는문자열을 2행에출력하되 1 초정도간격으로깜박이도록한다. 회로도 : 그림 99의회로를구현하고 LCD_CON 을그림 79의 C_CON 에연결한다. 프로그램작성시유의점 : 실험45 의프로그램 (main() 함수를제거해버린 ) 을 lcdchoi.h 라고저장하고이를 include 시켜초기화하기위한서브루틴 lcd_init, 커서위치를위한서브루틴 lcd_ln11 과 lcd_ln21, 명령출력을위 한서브루틴 lcd_cmd, 데이터출력을위한서브루틴 lcd_dat() 을재정의없이사용한다. 프로그램예 : #include "lcdchoi.h" void main(void){ lcd_init(); lcd_ln11(); lcd_str("enjoy yourselves"); lcd_ln21(); lcd_str("mega128 u-com"); for(;;){ lcd_cmd(lcdoff); delay_ms(1000); /* 약 1 초시간지연 */ lcd_cmd(lcdon); delay_ms(1000); 5.4.7. 실험 50 : 사용자폰트이용하기 예제 : 최한호라는폰트를만들고등록하여 LCD의 1 행에는 Choi Han Ho is' 라는문자열을출력하고 2행에 는 최한호' 라는문자열을출력한다. 프로그램작성시유의점 : CGRAM 은 5x8 폰트 8 개, 5x10 폰트 4개를사용자가정의해서자유롭게사용할수 있다. 폰트의패턴제작은그림 100 을참조하면알수있다. 5x8의행렬에원하는문자를형상화한다고생각하고 채워야하는곳은 1을써넣고공백으로남겨야하는곳에 0 을써서만든다( 그림 100에서 x는무정의조건으로 1 이되도상관없다. 그러므로패턴값 0x09나 0x49나 0x89 나같다). 문자폰트를등록하기위해서는 CGRAM 번 지설정명령을 LCD 에보내고패턴값데이터를보내주면된다. 한개의문자폰트를등록하기위해서는 5x8 폰 트의경우번지설정명령과패턴값데이터보내는것을 8 번수행해야한다. 문자폰트의등록은한문자당 8개 번지가소요되면 0~7, 8~15, 16~23 번지등등처럼등록이된다. 등록된문자폰트의코드는차례로 0부터일련 번호가붙으므로두번째로등록된문자폰트 (8~15 번지에등록이되어있는문자폰트 ) 를불러쓸려면 lcd_dat(0x01) (lcdchoi.h 에있는서브루틴 ) 명령을사용하면된다. 회로도 : 그림 99의회로를구현하고 LCD_CON 을그림 79의 C_CON 에연결한다. 프로그램예 : #include "lcdchoi.h" void main(void){ - 127 -

unsigned char i, chhcode[24] = { 0x09, 0x1D, 0x09, 0x15, 0x15, 0x01, 0x09, 0x1D, 0x0A, 0x1E, 0x0A, 0x17, 0x0A, 0x02, 0x10, 0x1E, 0x04, 0x1F, 0x0E, 0x11, 0x11, 0x0E, 0x04, 0x1F; lcd_init(); for(i=0;i<24;i++){ /* CGRAM 에패턴저장하기 */ lcd_cmd(0x40+i); /* CGRAM 주소는 0x40 부터시작 */ lcd_dat(chhcode[i]); /* data write */ lcd_ln11(); lcd_str("choi Han Ho is "); lcd_ln21(); lcd_dat(0x00); lcd_dat(0x01); lcd_dat(0x02); 과제 그림 100. LCD에문자등록을위해패턴값구하는예 : 다른글자를등록하고이를표시하는프로그램를작성하여라. 5.4.8. 실험 51 : 시간조정이가능한시계 예제 : INT0(PORTD.0, 핀25) 에연결된스위치를누르면상승에지트리거에의한인터럽트가발생하여타이 머 1 의카운팅이정지되고다시한번누르면카운팅을시작한다. INT1(PORTD.1, 핀26) 에연결된스위치를누 르면상승에지트리거에의한인터럽트가발생하여분값이증가하고 INT2(PORTD.1, 핀27) 에연결된스위치를 누르면상승에지트리거에의한인터럽트가발생하여시간값이증가한다. LCD의 1 행에는 Hour Min Sec ' 라는문자열을출력하고 2 행에는 hh mm ss ' 형태로시간, 분, 초가나타난다. 회로도 : 그림 99의회로를구현하고 LCD_CON 을그림 79의 C_CON 에연결한다. 그림 80의 SW_CON 을그림 79의 D_CON 에연결한다. 또한그림 80의 SW1~3 를누르면서실험한다. 프로그램작성시유의점 : 타이머 0의모드1 을사용하였고메인프로그램에서는키가눌렸는지를감시한다. lcdchoi.h 라고저장하고이를 include 시켜초기화하기위한서브루틴 lcd_init, 커서위치를위한서브루틴 lcd_ln11() 과 lcd_ln21(), 명령출력을위한서브루틴 lcd_cmd(), 데이터출력을위한서브루틴 lcd_dat(), 그리고 시간지연서브루틴 delay() 를재정의없이사용한다. 타이머로계산한시간데이터숫자값을출력하기위해서는 숫자에해당하는코드를 LCD 에써줘야하는데 0 의코드는 0x30, '1' 의코드는 0x31, 2 의코드는 0x32식이 다. 그러므로이를감안해서 lcd_dat() 서브루틴을콜해야 LCD 에표시된다. 프로그램예 : #include "lcdchoi.h" unsigned char hou, min, sec, onoff=1; unsigned char dbufh[2], dbufm[2], dbufs[2]; unsigned int cnt0; void h2b2asc(unsigned char hex, unsigned char *ptr) { *ptr = (hex / 10) + '0'; void watch(void){ if( ++sec == 60) { sec = 0; if( ++min == 60 ) { min = 0; if( ++hou == 24 ) hou = 0; /* lcd 에출력하기위해아스키코드로변환 */ *(ptr+1) = (hex % 10) + '0'; - 128 -

h2b2asc(sec, dbufs); h2b2asc(min, dbufm); h2b2asc(hou, dbufh); lcd_ln21(); // lcd 2행 1 렬에커서를위치시킨다. lcd_str(" "); lcd_dat(dbufh[0]); lcd_dat(dbufh[1]); /* 시간값출력 */ lcd_str(" "); lcd_dat(dbufm[0]); lcd_dat(dbufm[1]); /* 분값출력 */ lcd_str(" "); lcd_dat(dbufs[0]); lcd_dat(dbufs[1]); /* 초값출력 */ interrupt [2] void exint0(void){ // interrupt [EXT_INT0] void exint0(void) 처럼 mega128.h 에저장된정의를사용해도됨 if(onoff == 0) onoff = 1; else onoff = 0; interrupt [3] void exint1(void){ // interrupt [EXT_INT1] void exint1(void) 처럼 mega128.h 에저장된정의를사용해도됨 if( ++min == 60 ) { min = 0; if( ++hou == 24 ) hou = 0; interrupt [4] void exint2(void){ // interrupt [EXT_INT2] void exint2(void) 처럼 mega128.h 에저장된정의를사용해도됨 if( ++hou == 24 ) hou = 0; interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 if(onoff == 0) if( ++cnt0 == 1000 ){ cnt0 = 0; watch(); TCNT0 = 6; // 재정의 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 void main(void){ DDRC = 0xff; // 포트C 를출력으로 DDRD = 0x00; // 포트D 를입력으로디폴트입력으로설정되어있으므로필요하지는않음 SREG.7 = 1; // 인터럽트전체허용 EIMSK = 0x07; // INT0,1,2 개별허용 EICRA = 0x3f; // 상승에지트리거 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 TCCR0 = 4; // 분주비를 64로설정 시뮬레이션할때는조절할필요가있음 TCNT0 = 6; // 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 lcd_init(); lcd_str(" Hour Min Sec "); for(;;); 과제 : 1 lcd.h 를사용하여같은기능의프로그램을작성해보라. 2타이머 1~3 를사용하여프로그램하여라. 3 초값은표시하지않아시간과분만을표시하는시간조정이가능한시계용프로그램을작성해보아라. 5.5. 모터제어 5.5.1. 스텝모터개요 5.5.1.1. 특징 모터의총회전각은입력펄스수의총수에비례한다. 모터의속도는 1 초당입력펄스수 ( 펄스레이트 ) 에비례( 보통수십 kpps 정도가사용됨) 한다. 기동, 정지, 회전방향변경, 변속이쉽고응답특성도양호하다. 높은유지토크를내어특정위치에정지할수있고기동정지응답특성이양호하여서보모터로사용가능하다. 1 스텝당각도오차가 5% 이내이며회전각의오차가누적되지않는다. 회전각검출이필요없어제어기가간단하고가격이상대적으로저렴하다. 직류모터에서와같이브러쉬교환등보수를필요로하지않아유지보수가쉽고부품수가적어신뢰성이높다. - 129 -

진동, 공진이발생하기쉽고관성이있는부하에약하다. 모터가정지할때흔들이와같이진동하면서정지. 진동음이큰경우도종종발생한다. 펄스레이트가모터의고유진동수의정수분의 통상 1 일때큰진동이발생한다. 100pps 이하에서공진이발생하는경우가많고탈조등의현상이발생한다. 고속운전시모터인덕턴스의영향으로권선에충분한전류가흐르지않아토크가저하하고탈조하기쉽다. 5.5.1.2. 종류 고정자권선에따른종류 : 고정자에있는독립된권선의개수에따라 2 상,3 상,4상등의모터가있고 2상은저 출력, 3상은가변릴럭턴스형모터 4 상은고출력장치에적용된다. 구조에따른종류 : 1영구자석형 : 회전자가영구자석으로고정자에감긴코일에전류를흘리면회전자가전류가흘러진고정자와 정렬하면서회전하게됨. 보통스텝각이 1.8, 7.5, 15, 30, 34, 90 도이다. 2가변릴럭턴스형 : 회전자가연강재질로톱니바퀴형태. 고정자권선에전류를가하면회전자는최소자기저항 을갖도록정렬하면서회전하게됨. 보통스텝각이 7.5, 15 도이다. 회전자의관성이작고고속응답특성이우수하나 권선에전류를흘리지않을때유지토크가 3하이브리드형 0임 : 영구자석형의높은효율과가변릴럭턴스형의작은스텝각의장점을조합. 회전자가원통형의 영구자석위에톱니형의규소강판이적층되어있음. 스텝각은 0.8, 1.8 도임. 고정밀, 고출력토크용 그림 101. 스텝모터의토크속도특성 5.5.1.3. 특성과사양 그림 101 에스텝모터의속도와토크의관계가보여졌다. 스텝각 : 한입력펄스당회전각 유지토크 (holding torque): 정지상태에서모터에작용가능한최대부하토크 슬루영역 (slew range) : 가감속회전, 역회전, 정지, 기동이펄스입력에동기가능한범위 최대인입속도 : 무부하시펄스입력에동기되어기동가능한최대입력펄스수 최대이탈속도 : 무부하시입력펄스에동기되어회전가능한최대입력펄스수 5.5.1.4. 4 상스텝모터의결선확인법 4상스텝모터의경우선이 6개혹은 5 개나와있다. 전원을 A-B-C-D 순서로가하면시계방향으로회전한다 고가정하고선이 6 개나와있다고가정하자. 이럴경우결선들의상은아래에따라결정하면된다. 1먼저 Ground 공통선 G(G1,G2) 를찾기위해저항계를사용하여저항이무한대가아닌짝들을찾아낼수있 - 130 -

을것이다. 6개의선이나와있는경우는 3개의선들로이루어진짝들을찾아 X짝 Y 짝이라하자. 그림 60의경 우에는 (A,G1,C) 와 (B,G1,D) 짝을찾을수있다. 2먼저 X짝에서저항계를다시이용하여공통선을찾고다음 Y 짝에서공통선을찾는다. 그림 102에서 (A,G1,C) 짝의경우 (A,C) 간의저항은 (A,G1) 그리고 (G1,C) 간의저항의 2 배정도가될것이다. 3Ground 공통선 G(G1,G2) 를연결하고단계 1) 에서찾은 X와 Y짝중 X짝에서공통선이아닌두선을 Xa와 Xb라하고 Y짝에서도마찬가지로 Ya와 Yb 라하자. 먼저 Xa 와공통선간에정격전원을가해본다. 전원을끊고 Ya 와공통선간에정격전원을가하면회전을하게되는데시계방향으로회전하면 Xa는 A상 Xb는 C상 Ya는 B상 Yb는 D 상으로하면된다. 반시계방향으로회전하면 Xa는 A상 Xb는 C상 Ya는 D상 Yb는 B 상이다. 5.5.2. 4 상스텝모터의구동원리 5.5.2.1. 1 상여자방법 그림 102. 4상스텝모터의결선도 각스위치를닫아각상에전류가흐르면 S 극이회전축방향으로자화가된다고하자. 먼저 sw1을닫으면그림 103의왼쪽과같이되고다음 sw1을열고 sw2만닫으면회전자가 90도회전하여그림 103의오른쪽과같이된 다. 마찬가지로 sw2를열고 sw3만닫으면회전자가 90 도회전한다. 결국 A-B-C-D 상순서로전류를흘리면모 터가회전함을알수있다. 마찬가지로 D-C-B-A 순서로전류를흘리면모터가반시계방향으로회전한다. 1개의 상만전류를흘려서( 여자시켰는데 ) 회전시켜 1 상여자방법이라한다. 5.5.2.2. 2 상여자방법 sw1과 sw2 만닫혔다고하자. 그러면그림 104 의왼쪽과같이될것이다. 다음 sw1이열리고 sw2와 sw3가 닫혔다고하자. 그러면회전자는 90도회전하여그림 104 의오른쪽과같이된다. 마찬가지로 sw2가열고 sw3와 sw4가닫으면회전자는 90 도회전하게된다. 결국 AB-BC-CD-DA 상순서로전류를흘리면모터가회전함을알 수있다. 마찬가지로 AB-AD-DC-CB-BA 순서로전류를흘리면모터가반시계방향으로회전한다. 이처럼 2개의 상을여자시켜스텝모터를구동하는방법을 2 상여자방법이라한다. 1상여자에비해두배의전력을요하나그만 큼힘이좋은구동방법이다 5.5.2.3. 1-2 상여자방법 처음에 sw1만닫고그다음 sw1과 sw2만닫고그다음은 sw1을열고 sw2만닫고이런식으로 A-AB-B-BC-C-CD-D-DA-... 식으로여자하면 45 도씩회전하게된다. 이처럼 1개의상그다음은 2개의상을 번갈아여자시켜스텝모터를구동하는방법을 1-2 상여자방법이라한다. 여자순서가복잡해지나회전각도의 resolution 을증가시킬수있는방법이다 그림 103. 1 상여자방법( 왼쪽: sw1 만닫힌경우, 오른쪽 : sw2 만닫힌경우) - 131 -

그림 104. 2 상여자방법( 왼쪽: sw1, sw2 만닫힌경우, 오른쪽 : sw2, sw3 만닫힌경우) 5.5.3. 스텝모터의위치제어법 스텝모터는여자를 A상에서 B 상, B상에서 C상이렇게순서대로함에따라스텝각이라불리는각도만큼씩회 전하게되기때문에각도의정밀도는스텝각에따라의존하게된다. 1상여자나 2상여자를사용하여구동하는경 우에는스텝각도가그정밀도한계가되고 1-2상여자의경우에는스텝각의 1/2가위치제어의정밀도한계가된 다. 원하는각도만큼회전시키기위해서는그각도를정밀도한계로나누어얻어진값과가장근사한정수만큼여 자순서를바꾸어주면원하는각도만큼회전시켜회전자를위치시킬수있다. 4상의스텝모터 1 상여자방법 : 에의해시계방향으로스텝각의 n 배만큼회전시키는경우를생각해보자. 이 를위해마이콤을사용하여 이여자패턴을 sw1, sw2, sw3, sw4를열고닫는여자패턴을생성시켜제어하는경우다음과같 n번만들어출력포트로내보내주면될것이다 10001000 -> 01000100(1 번) -> 00100010(2 번) -> 00010001(3 번) ->...(n 번) sw1, sw2, sw3, sw4의작동은출력포트값중하위4bit 나상위4bit 중아무신호를사용하여작동시키면된다. 그리고위의패턴으로부터시계방향으로 n번회전시킬경우시작값 10001000 을어떤레지스터에저장해서출력 하고레지스터값을왼쪽으로회전시켜서어느시간간격후에출력시키고또레지스터값을왼쪽으로회전시켜서 어느시간간격후에출력시키는과정을 계방향의경우는오른쪽으로레지스터값을회전시켜서출력하면된다. 2 상여자의경우 : 다음과같은여자패턴을사용한다. n 번반복수행하는식으로마이콤프로그램을짜면됨을알수있다. 반시 11001100 -> 01100110(1 번) -> 00110011(2 번) -> 10011001(3 번) ->...(n 번) 1-2 상여자의경우 : 다음과같이여자패턴을발생시킨다. sw1, sw2, sw3, sw4의작동은출력포트값중 1,3,5,7 번째 bit 의신호를사용하여작동시키면된다. 위의 1-2상여자패턴으로부터처음에는 sw1만닫히고그 다음은 sw1과 sw2가닫히고그다음은 sw2만닫히고그다음은 sw2와 sw3가닫히도록하는식으로신호가 발생됨을확인할수있다. 11100000 -> 01110000(1 번) -> 00111000(2 번) -> 00011100(3 번) ->...(n 번) 5.5.4. 스텝모터의속도제어법 스텝모터의속도는여자시키기위해각상에전원을순서대로끊고연결시키는간격에따라좌우된다. 즉한 여자패턴에서다음스텝각으로회전시키기위한여자패턴으로의이동시간간격에따라좌우된다. 예로 1상여자방 식으로스텝모터를마이콤을사용하여스텝각의 n배만큼회전시키는경우다음과같은신호들이출력되고 10001000 -> 01000100(1 번) -> 00100010(2 번) -> 00010001(3 번) ->...(n 번) 각신호의값들이생성되어출력되는간격이좁으면회전속도는빠르고간격이넓으면늦을것이다. 만약일정 하다면정속도운전이될것이고간격이넓었다고좁아지면가속운전이되고좁았다고넓어지면감속운전이될 - 132 -

것이다. 스텝모터는기계적인한계로인해최저속도와최고속도가사양으로주어지기때문에원하는응용에맞 는규격을갖는스텝모터를선정하고이한도내에서여자간격을줌으로써안정적인속도를갖도록제어할수 있다. 5.5.5. 스텝모터의가감속제어시펄스레이트결정법 가감속제어를위해서는여자패턴의이동시간간격을제어해야하는데간격을결정하는법을설명하겠다. 속도 f 1, 최종속도 f N, 최종속도에도달에필요한스텝수 N 이주어졌고그림 105와같은가속패턴이요구 된다고가정하자. 감속의경우는 f N 과 f 1 을바꿔놓으면된다. 초기 그림 105. 스텝모터의가속패턴 t 1 = 1/f 1, t k - t k - 1 = 1/f k, f k -f 1 = ( f N -f 1 ) ( t N -t 1 ) ( t k -t 1 ), k = 2,...,N, 이성립하고각시간간격 마다한스텝씩움직이는것이므로각각의마름모의면적은 2(k-1) = (f k +f 1 )(t k -t 1 ), 2( N-1) = (f 1 +f N )(t N -t 1 ) 결국다음의수식을얻을수있다. f 2 k -f 2 1 = (f2 N -f2 1 )( k-1) (N-1), t k -t k - 1 = f 2 1 + 1 이되어야한다. 그러므로다음의수식이성립한다. 1 )( k-1) (N-1) ( f2 N -f2 1 예로최종속도에도달에필요한스텝수 N = 10 으로초기속도와최종속도가 pps로각각 f 1 = 500, f 10 = 1000 일때스텝인덱스 k와이에따른각스텝에서의속도와시간간격은표15 과같다. 5.5.6. 모터구동용 H 브리지회로 표 15. f 1 = 500, f 10 = 1000 일때 k에따른속도 k f k (pps) t k -t k - 1 (msec) t k (msec) 1 500.0 2.0000 2.0000 2 577.4 1.7321 3.7321 3 645.5 1.5491 5.2812 4 707.1 1.4142 6.6955 5 763.8 1.3093 8.0048 6 816.5 1.2247 9.2295 7 866.0 1.1547 10.3842 8 912.9 1.0954 11.4797 9 957.4 1.0445 12.5241 10 1000 1.0000 13.5241-133 -

그림 106에보여진회로는 H 브리지회로로여러가지모터를구동하기위해쓰일수있다. C3205Y 와 A1273Y 쌍의역할 : 출력으로유출입되는전류의흐름을통제하는 on-off 스위치의역할을한다. IN1 입력이 1(5V level) 일때 C3205Y은 off 상태 A1273Y는 on 상태로되어 OUT1 출력이 GND 에연결되고, IN1 입력이 0(0V level) 일때 C3205Y 은켜지고 A1273Y 는꺼져 OUT1 출력은 VCC 에연결된다. 그래서부하 를 OUT1 과 OUT2 사이에연결하고 IN1에 1레벨을입력시키고 IN2에 0레벨을입력시키면부하에는전류가 OUT2 측에서흘러들어가 OUT1 측으로흘러나가게된다. 2SD560 ( 파워TR:npn) 과 2SB601 쌍으로혹은 BDX53C(npn) 과 BDX54C 쌍으로대체가능하다. (0.5 옴[1W], 2SC1815Y) 과 (0.5 옴[1W], 2SA1015Y) 의역할 : 출력으로유출( 유입) 되는전류가어느한도를 넘으면 2SC1815Y( 혹은 2SA1015Y) 가도통이되고 C3205Y( 혹은 A1273Y) 이꺼지게되어출력으로유출( 유입) 되는전류를제한한다. 주어진회로도에서는 1.2 A(=0.6V/0.5 옴) 가한도가된다. 저항값을조정함으로써출력쪽 으로의유출입전류상한값을설정할수있다. FR105 의역할 : 스위치역할을하는 C3205Y( 혹은 A1273Y) 가손상되는것을방지하는환류다이오드의역할 은한다. 이들트랜지스터가켜져있다가갑자기꺼지게되면출력의부하가인덕턴스성분을갖는모타의경우 부하전류가급격히변화할수없는상황에서전류가흐를곳이없어트랜지스터를파괴하고흐를소지가있다. 이때다이오드 FR105 가전류의통로를마련해준다. 그림 106. 다목적 H브리지회로의예 5.5.7. 모터구동용 IC L298 의개요 특징: A와 B 두개의 H 브리지회로내장, 회로가간단하고부피가적음, 최대전류 2.5A, 평균전류 0.2-0.25A, 2000~4000 pps 구동이가능. 환류다이오드를외부에서달아주어야함. 핀배치 : 8 번(GND), 6 번(ENA:A 브리지회로의인에블단자로 1 레벨이면동작허용 ), 5 번(IN1:A 브리지회로의 입력1), 2 번(OUT1:A 브리지회로의출력1), 7 번(IN2: A 브리지회로의입력2), 3 번(OUT1:A 브리지회로의출력 2), 10 번(IN3:B 브리지회로의입력1), 11 번(ENB:B 브리지회로의인에블단자로 1 레벨이면동작허용 ),13번 (OUT3:B 브리지회로의출력1), 12 번(IN4: B 브리지회로의입력2), 14 번(OUT4:B 브리지회로의출력2), 4번 (VS: 모터측전원으로마이컴측전원보다 2.5V 이상커야함, GND와사이에 100nF 콘덴서를필히연결해야 함), 9 번(VSS: 마이컴측전원단자. GND와사이에 100nF 콘덴서를필히연결해야함), 1 번(ISENA:A 브리지회로 에흐르는부하전류를측정하기위해 나 PWM 제어에활용가능), 15 번(ISENB) GND 와사이에저항을삽입하기위한단자, 과부하전류차단용제어회로 동작방법 : IN1=1 레벨, IN2=0 레벨, ENA=1 레벨시 A브리지회로가동작하고 OUT1 에서전류가흘러나와 OUT2 쪽으로전류가흘러들어간다. IN1=0 레벨, IN2=1 레벨, ENA=1레벨시 A브리지회로가동작하고 OUT2에서 전류가흘러나와 OUT1 쪽으로전류가흘러들어간다. IN1=IN2이며 ENA=1레벨시급속하게정지되고 ENA=0레 벨시입력에관계없이천천히정지한다. B 브리지회로도마찬가지이다. 결국 ENx를 1레벨로고정시키고 INx입력 - 134 -

을조정하여모터의정지, 운전, 회전방향을제어할수도있고, INx를어느한방향으로전류가흘러들어가게고 정시키고 ENx 를조정하여회전방향은일정하게놓고모터의정지와운전만을제어할수도있고, ENx와 INx를 모두조정하여모터의정지, 운전, 회전방향을제어할수도있다. 5.5.8. 실험 52 : 스텝모터정속제어 예제 : PORTD.0 에연결된스위치가홀수번눌리면 C포트에연결된스텝모터를 500pps 로스텝모터를회전시 킨다. 짝수번눌리면정지한다. 프로그램작성시유의점 : 500pps 로회전시키기위해서는 2msec 마다여자패턴을바꾸어주어야한다. 타이 머 0의노말모드를이용하여 2msec 마다인터럽트를발생시키고여자패턴을바꾸어준다. 1상여자로한다고가 정한다. 그림 107의회로에서는 ENx를 1 레벨에고정시켰음에유의해서작성해야한다. 그림 107. 모터실험회로도 회로도 : 그림 107의회로를구현하고 L_CON을그림 79의 C_CON 에연결한다. 그림 107의 MOTOR_CON 을 모터측전원과 A,B,C,D 상과 GND 에연결한다. ISENx 단자를 GND에직접연결하여부하전류의궤환을하지 않는다. 그림 80의 SW_CON 을그림 79의 D_CON 에연결한다. 또한그림 80의 SW1 를누르면서실험한다. 프로그램예 : #include <mega128.h> unsigned int cnt0; unsigned char led=0x88, onoff=1; interrupt [2] void exint0(void){ // interrupt [EXT_INT0] void exint0(void) 처럼 mega128.h 에저장된정의를사용해도됨 if(onoff == 0) onoff = 1; else onoff = 0; interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 if(onoff == 0) if( ++cnt0 == 2 ){ cnt0 = 0; led >>= 1; if(led == 0x08) led=0x88; PORTC = led; TCNT0 = 6; // 재정의 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 void main(void){ DDRC = 0xff; DDRD = 0x00; SREG.7 = 1; // 포트C 를출력으로 // 포트D 를입력으로디폴트입력으로설정되어있으므로필요하지는않음 // 인터럽트전체허용 - 135 -

EIMSK = 0x01; // INT0 개별허용 EICRA = 3; // 상승에지트리거 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 TCCR0 = 4; // 분주비를 64로설정 시뮬레이션할때는조절할필요가있음 TCNT0 = 6; // 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 for(;;); 과제 : 타이머 1~3 을이용하여작성해보라. 5.5.9. 실험 53 : 스텝모터속도제어 예제 : PORTD.0 에연결된스위치가홀수번눌리면 C포트에연결된스텝모터를 500pps 로스텝모터를회전 시킨다. 짝수번눌리면정지한다. PORTD.1 에연결된스위치가눌리면속도가증가하고 PORTD.2 에연결된스 위치가눌리면감속된다. 프로그램작성시유의점 : 500pps 로회전시키기위해서는 2msec 마다여자패턴을바꾸어주어야한다. 타이 머 0 의노말모드를이용하여인터럽트를발생시키고여자패턴을바꾸어준다. 1 상여자로한다고가정한다. 외부 인터럽트를사용하여가감속을제어한다. 회로도 : 그림 107의회로를구현하고 L_CON을그림 79의 C_CON 에연결한다. 그림 107의 MOTOR_CON 을 모터측전원과 A,B,C,D 상과 GND 에연결한다. ISENx 단자를 GND에직접연결하여부하전류의궤환을하지 않는다. 그림 80의 SW_CON 을그림 79의 D_CON 에연결한다. 또한그림 80의 SW1~3 를누르면서실험한다. 프로그램예 : #include <mega128.h> unsigned int cnt, delaytime, step, delaymax, delaymin; unsigned char led=0x88, onoff=1; interrupt [2] void exint0(void){ // interrupt [EXT_INT0] void exint0(void) 처럼 mega128.h 에저장된정의를사용해도됨 if(onoff == 0) onoff = 1; else onoff = 0; interrupt [3] void exint1(void){ // interrupt [EXT_INT1] void exint1(void) 처럼 mega128.h 에저장된정의를사용해도됨 if( delaytime + step <= delaymax ) delaytime += step; interrupt [4] void exint2(void){ // interrupt [EXT_INT2] void exint2(void) 처럼 mega128.h 에저장된정의를사용해도됨 if( delaytime - step >= delaymin ) delaytime -= step; interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 if(onoff == 0) if( cnt-- == 1 ){ cnt = delaytime; led >>= 1; if(led == 0x08) led=0x88; TCNT0 = 231; // 재정의 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 PORTC = led; void main(void){ DDRC = 0xff; // 포트C 를출력으로 PORTC = led; SREG = 0x80; // 인터럽트전체허용 EIMSK = 0b00000111; // INT0, 1,2 개별허용 EICRA = 0x3f; // INT0, 1,2 상승에지트리거 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 TCCR0 = 4; // 분주비를 64로설정 TCNT0 = 231; // 64*(256-231)/16=100usec = 0.1msec delaytime = 20; cnt = delaytime; /* 점멸주기를 20*0.0001 = 2msec 로초기화 */ delaymax = 40; delaymin = 1; /* 점멸회전주기의최대, 최소값을 4m, 0.1m 초로초기화 */ step = 2; /* 주기변경폭을 10 으로초기화 */ while(1); - 136 -

과제 : 최소 200pps 최대 2000pps 사이에서작동하도록프로그램을변경하여보아라. 5.5.10. 실험 54 : 스텝모터가감속제어 예제 : PORTD.0 에연결된스위치가한번눌리면포트C 에연결된스텝모터를 500pps 에서 1000pps 로 10단계 에걸쳐가속시켜그이후에 1000pps 로운전하고또눌리면반대로감속시켜정지시킨다. 프로그램작성시유의점 : 표15에주어진 t k -t k - 1 를프로그램메모리에저장시키고이를불러다가사용한다. 회로도 : 회로도 : 그림 107의회로를구현하고 L_CON 을그림 79의 C_CON 에연결한다. 그림 107의 MOTOR_CON 을모터측전원과 A,B,C,D 상과 GND 에연결한다. ISENx 단자를 GND에직접연결하여부하전 류의궤환을하지않는다. 그림 80의 SW_CON 을그림 79의 D_CON 에연결한다. 또한그림 80의 SW1를누르 면서실험한다. 프로그램예 : #include <mega128.h> #include <delay.h> unsigned char led=0x88, status, vtblidx; unsigned int vtbl[ ] = {2000,1732,1549,1414,1309,1225,1155,1095,1045,1000 ; unsigned int cnt, cvt; interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 if(cnt++ >= cvt){ cnt = 0; if(status!=0){ if(vtblidx<=8) vtblidx++; led >>= 1; if(led == 0x08) led=0x88; else { if(vtblidx>0) { vtblidx--; led >>= 1; if(led == 0x08) led=0x88; TCNT0 = 240; // 재정의 1usec = 1*(256-240)/16 16MHz 와분주비 1사용시 PORTC = led; void main(void){ DDRC = 0xff; // 포트C 를출력으로 PORTC = led; SREG = 0x80; // 인터럽트전체허용 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 TCCR0 = 1; // 분주비를 1로설정 TCNT0 = 240; for(;;){ loop: while(pind.0 == 1); /* PORTD.0 가눌릴때까지대기 */ delay_ms(50); /* 50msec 시간지연 */ if(pind.0 == 1) goto loop; /* 눌림이 50msec 동안지속안되면무효다시키입력을받는다 */ while(pind.0!=1); /* PORTD.0 가해제될때까지대기 */ cvt = vtbl[vtblidx]; status = ~status; 5.5.11. 직류모터개요 5.5.11.1. 특징 기동토크가크고입력전압에비례하는회전속도를얻을수있다. - 137 -

토크에대하여회전속도는반비례하는특성을갖고있다. 입력전류에대하여출력토크가직선적이며출력효율도양호하며가격이저렴하다. 양호한토크- 속도, 토크- 전류특성으로광범위한속도제어와여러다양한제어방법의적용이가능하다. 직류모터는높은회전력, 광범위한속도제어능력, 휴대용이, 속도회전력특성양호, 여러다양한제어방 법적용가능등의특성때문에로봇, 카셋트테이프, 하드디스크, 기계공구등광범위하게사용되고있다. 브러시와정류자의기계식접점때문에소음과노이즈, 먼지가많이발생하며브러시등을교환해주어야하기 때문에유지보수가스텝모터에비해쉽지않다 ( 브리시리스직류모터는제외). 5.5.11.2. 직류모터구동원리 그림 108의왼쪽그림에서만약 AB 단자에 +Vcc 를걸면플레밍의왼손법칙에의해 A단자측도선은아래쪽으 로힘이작용하고 B단자측도선은위쪽으로힘이작용하여 aa' 축에대하여반시계방향으로회전력이발생한다. 만약도선을여러개로하여 aa' 회전축으로회전가능한원통에방사상으로배치하여고정시킨그림108 의오른쪽 과같은경우 bb' 의좌측도선은지면으로흘러들어가는방향으로전류를흘리고 bb' 의우측도선은지면에서흘 러나오는방향으로전류를흘리면 aa' 축을중심으로하여반시계방향으로회전력이발생하여도선이고정된원 통은반시계방향으로회전할수있다. 어떤장치를사용하여 bb' 의좌측에위치하는도선은항상지면으로흘러 들어가게전류를주고 회전하게할수있다. bb' 의우측에위치하는도선은항상지면에서흘러나오게전류를주면계속적으로원통을 5.5.11.3. 직류모터구조 그림 그림 108. 직류모터의구동원리 108에보여진것과구조가유사하여영구자석으로이루어진고정자가있고도선이감긴원통형의회전자 가있으며회전자의도선에흐르는전류의방향을 bb' 축의좌측또는우측에위치하느냐에따라일정한방향으로 흘러들어가게하는정류자와브러시라는장치로구성되어있다. 회전자가영구자석으로이루어지고고정자에도 선을감은형태의직류모터도있다. 5.5.12. 실험 55 : 직류모터속도제어 1 예제 : PORTD.0 에연결된스위치가홀수번눌리면 C 포트에연결된직류모터를회전시킨다. 짝수번눌리면 정지한다. PORTD.1 에연결된스위치가눌리면속도가증가하고 PORTD.2 에연결된스위치가눌리면감속된다. 프로그램작성시유의점 : 타이머 0 의노말모드를이용하여인터럽트를발생시켜출력을온오프시킨다. 외부 인터럽트를사용하여온오프의듀티비를조절하여가감속을제어한다. 회로도 : 그림 107의회로를구현하고 L_CON을그림 79의 C_CON 에연결한다. 그림 107의 MOTOR_CON 의 2번을모터측 A단자에 GND를모터측 B 단자에연결한다. ISENx 단자를 GND에직접연결하여부하전류의 궤환을하지않는다. 그림 80의 SW_CON 을그림 79의 D_CON 에연결한다. 또한그림 80의 SW1~3 를누르면 서실험한다. 프로그램예 : - 138 -

#include <mega128.h> unsigned int cnt, step=1, delaymax=10, delaymin=1, speed=5; unsigned char onoff=1; interrupt [2] void exint0(void){ // interrupt [EXT_INT0] void exint0(void) 처럼 mega128.h 에저장된정의를사용해도됨 if(onoff == 0) onoff = 1; else onoff = 0; interrupt [3] void exint1(void){ // interrupt [EXT_INT1] void exint1(void) 처럼 mega128.h 에저장된정의를사용해도됨 if( speed + step < delaymax ) speed += step; interrupt [4] void exint2(void){ // interrupt [EXT_INT2] void exint2(void) 처럼 mega128.h 에저장된정의를사용해도됨 if( speed - step >= delaymin ) speed -= step; interrupt [17] void timerint0(void){ // interrupt [TIM0_OVF] void timerint0(void) 로해도됨 if(onoff == 0) { if( cnt-- == 0 ) cnt = delaymax; if(speed <= cnt ) PORTC.0 = 1; else PORTC.0 = 0; else PORTC.0 = 0; TCNT0 = 6; // 재정의 1msec = 64*(256-6)/16 시뮬레이션할때는조절할필요가있음 void main(void){ DDRC = 0xff; // 포트C 를출력으로 PORTC = 0x00; SREG = 0x80; // 인터럽트전체허용 EIMSK = 0b00000111; // INT0, 1,2 개별허용 EICRA = 0x3f; // INT0, 1,2 상승에지트리거 TIMSK = 1; // 타이머 0 오버플로인터럽트개별허용 TCCR0 = 4; // 분주비를 64로설정 TCNT0 = 6; // 64*(256-6)/16=1000usec = 1msec while(1); 과제 : 타이머 0 대신타이머 1~3 을사용해서작성해보아라. 5.5.13. 실험 56 : 직류모터속도제어 2 예제 : 타이머3의 PWM 모드를이용해서직류모터의속도를제어한다. PORTD.0 에연결된스위치가눌리면속 도가감소하고 PORTD.2 에연결된스위치가눌리면증가된다. 프로그램작성시유의점 : 타이머 3의출력비교모드를이용하여 PWM 신호를발생시켜출력을온오프시킨다. 외부인터럽트를사용하여온오프의듀티비를조절하여가감속을제어한다. 회로도 : 그림 107의회로를구현하고 L_CON을그림 79의 E_CON 에연결한다. 그림 107의 MOTOR_CON 의 2번을모터측 A단자에 GND를모터측 B 단자에연결한다. ISENx 단자를 GND에직접연결하여부하전류의 궤환을하지않는다. 그림 80의 SW_CON 을그림 79의 D_CON 에연결한다. 또한그림 80의 SW1~2 를누르면 서실험한다. 프로그램예 : #include <mega128.h> unsigned int step=50; interrupt [2] void exint0(void){ // interrupt [EXT_INT0] void exint0(void) 처럼 mega128.h 에저장된정의를사용해도됨 unsigned int ocr3a; ocr3a = 256*OCR3AH+OCR3AL; if( ocr3a > step ) { ocr3a -= step; OCR3AH = ocr3a/256; OCR3AL = ocr3a%256; interrupt [3] void exint1(void){ // interrupt [EXT_INT1] void exint1(void) 처럼 mega128.h 에저장된정의를사용해도됨 - 139 -

unsigned int ocr3a; ocr3a = 256*OCR3AH+OCR3AL; if( ocr3a < 0xffff - step ) { ocr3a += step; OCR3AH = ocr3a/256; OCR3AL = ocr3a%256; void main(void){ DDRE.3 = 1; // PORTE bit 4를출력으로 SREG = 0x80; // 인터럽트전체허용 EIMSK = 0b00000111; // INT0, 1,2 개별허용 EICRA = 0x3f; // INT0, 1,2 상승에지트리거 TCCR3B = 2; // 분주비를 8로설정 TCCR3A =2; // 타이머 3 PC PWM 모드 14로설정 TCCR3B = 0x10; // 타이머 3 PC PWM 모드 14로설정 TCCR3A = 0x80; OCR3AH = 0x7f; OCR3AL = 0xff; ICR3H = 0xff; ICR3L = 0xff; for(;;); 5.6. DA 변환 5.6.1. DA 변환기의종류 // 출력비교모드설정 디지털- 아날로그변환기는 2진부호로표현된디지털량을그에대응하는직류전압으로변환하는회로로그림 109 에보여진것처럼가산형과사다리형이있다. 1가산형 (2 진하중저항형): n 비트의디지털값을아날로그량으로변환하기위해 R,2R,4R,, 2 n - 1 R 값의 저항들과연산증폭기를사용하여가산증폭기형태로구성한 D/A변환기로정밀한변환을위해서는최대저항과최 소저항사이의저항비가정밀해야하고비트수가많아지면최대저항과최소저항사이의저항비가너무커지며각 디지털입력은서로다른부하를갖는단점을지녀 4비트이상의 D/A 변환에거의사용되지않는다. 그림 109( 왼 쪽) 에 4비트의디지털값을아날로그량으로변환하기위한가산형 D/A 변환기가보여졌다. 1레벨입력전압이 V r 일때출력값 V o 는디지털값 b i 에의존하여다음과같이주어진다 V o =- R F R ( b 1 1 + b 2 2 + b 3 4 + b 4 8 )V r 2사다리형 (R-2R 형): R, 2R 두종류의저항과연산증폭기를사용하여구성한 D/A 변환기로고정도로만들수 있다. 저가로많이사용되는내셔날세미컨덕터사의 DAC08시리즈 D/A 변환기가사다리형의대표적인예이다. 그림 62( 오른쪽 ) 에 4비트의디지털값을아날로그량으로변환하기위한사다리형 D/A 변환기가보여졌다. 1레벨입력전 압이 V r 일때출력값 V o 는디지털값 b i 에의존하여다음과같이주어진다. V o = ( b 1 2 + b 2 4 + b 3 8 + b 4 16 )V r - 140 -

5.6.2. DAC 0800 소개 그림 109. D/A 변환기의종류. 가산형 ( 왼쪽) 과사다리형 ( 오른쪽 ) 특징: 8 비트분해능, 넓은범위의전원(4.5~18V), TTL이나 CMOS 와직접연결가능, 100 nsec 의변환시간, 저전력소비 (5V에서 33mW) 핀배치 : 1 번(VLC: 논리임계값제어핀으로보통 GND 에연결한다.), 2 번(/IOUT: 전류출력핀 ), 3 번(V-:- 전원단 자), 4 번(IOUT: 전류출력핀 ), 5-12 번(D7-D0 입력단자 ) 13 번(V+:+ 전원단자 ), 14 번(VREF+: 최대출력전압 ), 15번 (VREF-: 최저출력전압 ), 16 번(COMP: 보정용단자로콘덴서를통해 V- 에연결) 5.6.3. 실험 57 : 톱니파발생 예제 : PORTD.0 에연결된누름스위치가눌리면톱니파가발생한다. 회로도 : 그림 110의회로를구현하고 DAC_CON 을그림 79의 C_CON 에연결한다. 또한그림 80의회로를 그림 79의 D_CON 에연결한다. SW1 을누르면서실험한다. 프로그램예 : #include <mega128.h> #include <delay.h> void main(void){ unsigned char i=0xff; DDRC = 0xff; // PORTC 를출력으로 loop: while(pind.0 == 1); /* PORTD.0 가눌릴때까지대기 */ delay_ms(50); /* 50msec 시간지연 */ if(pind.0 == 1) goto loop; /* 눌림이 50msec 동안지속안되면무효다시키입력을받는다 */ while(pind.0!=1); for(;;i--){ PORTC = i; delay_ms(20); 5.6.4. 실험 58 : 사인파발생 예제 /* PORTD.0 가해제될때까지대기 */ /* 20msec 시간지연 */ :PORTD.0 에연결된누름스위치가눌리면사인파가발생한다. 프로그램작성시유의점 : 삼각함수와관련된명령을사용하지않고사인값을 100등분하여구하고표로만들 어롬에저장시켜놓고사용한다. 그림 110의회로를구현하고 DAC_CON 을그림 79의 C_CON 에연결한다. 또한그림 80의회로를그림 79의 - 141 -

D_CON 에연결한다. SW1 을누르면서실험한다. 프로그램예 : #include <mega128.h> #include <delay.h> flash unsigned char sin_tbl[ ] = {128, 136, 144, 151, 159, 167, 175, 182, 189, 196, 203, 209, 215, 221, 226, 249, 247, 243, 240, 236, 231, 226, 221, 215, 209, 203, 196, 189, 182, 175, 167, 159, 151, 144, 136, 127, 119, 111, 104, 96, 88, 80, 73, 66, 59, 52, 46, 40, 34, 29, 24, 19, 15, 12, 8, 6, 4, 2, 1, 0, 0, 0, 1, 2, 4, 6, 8, 12, 15, 19, 24, 29, 34, 40, 46, 52, 59, 66, 73, 80, 88, 96, 104, 111, 119 ; void main(void){ unsigned char i=0; DDRC = 0xff; // PORTC 를출력으로 loop: while(pind.0 == 1); /* PORTD.0 가눌릴때까지대기 */ delay_ms(50); /* 50msec 시간지연 */ if(pind.0 == 1) goto loop; /* 눌림이 50msec 동안지속안되면무효다시키입력을받는다 */ while(pind.0!=1); for(;;){ PORTC = sin_tbl[i]; delay_ms(20); if(i<=98) i++; else i=0; /* PORTD.0 가해제될때까지대기 */ /* 20msec 시간지연 */ 그림 110. D/A 변환실험회로도 5.7. AD 변환 5.7.1. AD 변환과정 AD 의변환은다음과정을통해이루어진다. 1전처리 : 아날로그신호에포함된잡음을제거하고신호의대역폭을제한하여엘리어싱 (aliasing) 을줄인다. 2표본화 : 신호대역폭두배이상의일정한샘플링(sampling) 주파수에따라신호값을취하여, 즉신호에포함된 최고주파수성분주기의 1/2 보다작은주기로신호값을취하여저장한다. - 142 -

3양자화 : 표본화된아날로그신호는연속적인양으로이를 2 진화하면무한한자리수를요구할수도있다. 그러 므로표본화된값을소구간으로분할하여유한한단계의유한한자리수를갖는불연속적인대표값에할당할필요 가있는데이것을양자화라한다. 양자화단계의갯수가많으면실제값과대표값의차인양자화오차를줄일수 있으나디지털출력의비트수가증가하여이를처리하기위한시간과장치가많이요구된다. 4부호화 : 양자화된값에 2 진디지털코드를부여하는것을부호화라한다. 5.7.2. AD 변환기의종류 AD 변환기는적분방식과비교방식으로크게나뉠수있고적분방식은저속으로변환이이루어지는데전압시 간변환, 이중적분, 전압주파수변환형이있고비교방식은적분방식에비해고속으로변환이이루어지는데축차비 교, 추종비교, 병렬비교형이있다. 1전압시간변환형 : 기준신호를적분한것과샘플링된입력전압을비교하여입력전압의크기에비례하는계수시 간을결정하고그시간동안기준펄스의수를계수하여변환하는방식으로비교적간단하나빠른속도와높은정 도를기대하기힘들다. 2이중적분형 : 샘플링된 + 의입력전압을미리설정된일정한시간동안적분한값을초기치로하여 -의기준신 호를적분한값이 0에도달할때까지기준펄스의수를계수하여변환하는방식으로전압시간변환형보다는안정되 어디지털전압계등에많이활용된다. 3전압주파수변환형 : 샘플링된입력신호에비례하는반복주파수펄스를발생시키고카운터로계수하여 A/D 환한다. 변 을 4계수비교형 : 샘플링회로, D/A 변환기, 업카운터, 비교기로구성되어있다. 0부터차례로증가시킨카운터의값 D/A 팅을중지시켜 변환기로아날로그값으로변환하여샘플링된입력신호와비교기에서비교하여같아지면업카운터의카운 A/D 변환한다. 최악의경우 n 비트형의경우 2 n -1 번비교를실행해야하므로변환속도가느리 나회로구성이비교적간단하고가격이저렴하다. 5축차비교형 ( 연속근사형 ): 샘플링회로, D/A 변환기, 연속근사레지스터, 비교기로구성되어있다. 계수비교형과 달리카운터의최상위비트값만 위비트값들의값을결정해나가는방식의 1로세트해놓고입력신호와비교하여최상위비트값을결정하기시작하여다음상 A/D변환기로 n 비트형의경우 n 번의비교로변환이완료되어변환시 간은백 μ s 이하로계수비교형에비해작고일반적인응용범위에널리사용된다. 저가로많이사용되는내셔날 세미컨덕터사의 ADC08시리즈는 8비트축차비교형 A/D 변환기의대표적예이다. 6병렬비교형 : 샘플링회로, 사다리형저항기, 다수개의비교기, 디코더로구성되어있다. n 비트변환기의경우 2 n -1 개의비교기를사용하여사다리형저항기에따라적절히분압된입력전압을동시에병렬처리하여디코더 를통해디지털출력값을만들어내기때문에현재변환기중변환속도가수십 ns이하로가장빠르나가장고가 이다. 아날로그디바이스사의 AD5010 이나 AD6020은 6비트병렬비교형 A/D 변환기의대표적예이다. 5.7.3. ATmega128 의 ADC 5.7.3.1. 특징 10비트 8 채널(PF0~7, 핀번호 61~54) 의축차비교형단극성변환기제공 7채널의차동입력변환기로사용가능 10배또는 200배의증폭률을가진 2채널의차동입력변환기능제공 0~Vref 범위의전압을입력으로갖을수있다. 차동의경우 -Vref ~ Vref 까지가능하다. 기준전압 Vref는 VCC 를초과할수없다. 변환완료인터럽트가제공된다. 완료시 ADCSRA 레지스터의 ADIF 플랙이세트된다. - 143 -

13~260 usec 의변환시간을사용자가설정할수있다. 5.7.3.2. ADCH, ADCL 레지스터 ADC 결과를단극성의경우 로 0~1023 범위값으로, 차동입력의경우 2의보수를사용하여 로 -512~ 511 범위의값으로저장한다. 초기값은 0x0000 이다. ADMMUX 레지스 터의 ADLAR 값에따라그림 111 에보여진방식으로정렬하여저장한다. 5.7.3.3. ADMUX 레지스터 그림 111. ADCH, ADCL 레지스터 ( 출처:ATMEL) ADSC, ADEN이 1로세트되어 AD변환이시작될때마다 ADMUX 의설정값에따라 AD 변환이진행된다. 설정값 의변환은차동입력을사용하는경우에는 AD변환을시작한후적어도 125usec 가경과한후에한다. 비트7~6(REFS1~0 : REFerence Selection 1~0) : 입력전압의범위의기준전압 Vref 를선택한다. 1 00 : 외부의 AREF 단자(62 번핀) 로입력된전압을기준전압으로사용. 2 01 : 외부의 AVCC 단자(64 번핀) 로입력된전압을기준전압으로사용. 3 10 : 보류 4 11 : 내부의 2.56V 를기준전압으로사용. 비트5(ADLAR : ADC Left Adjust Result) : 변환결과가 ADC 데이터레지스터에저장될때모양을그림 111 의경우처럼결정한다. 비트4~0(MUX4~0) : 그림 112처럼 ADC의입력단자를선택하고차동입력의경우이득을선택하는데사용 한다. 5.7.3.4. ADCSRA 레지스터 비트7(ADEN : ADc ENable) : 1로설정하여동작을허용하고 0 으로하여중지시킨다. 비트6(ADSC : ADc Start Conversion) : 1 로설정하면변환이시작된다. 변환이완료되면자동적으로클리어 된다. 비트5(ADFR : ADc Free Running select) : 1로하면 Free running 모드로설정한다. 비트4(ADIF : ADc Interrupt Flag) : ADCH, ADCL 레지스터가갱신되면 ADIF가 1로세트되며인터럽트를 요청한다. 비트3(ADIE : ADc Interrupt Enable) : 1 로세트된경우변환완료인터럽트를개별적으로허용한다. 비트2~0(ADPS2~0 : ADc Prescaleer Select 2~0) : 시스템클럭을분주하여 를만들때분주비를 결정한다. 000, 001이면분주비를 2 로, 010이면분주비를 4 로, 011이면분주비를 8 로, 100이면분주비를 16으 로, 101이면 32 로, 110이면 64 로, 111이면분주비를 128 로한다. 5.7.3.5. 동작 단일변환모드 : ADCSRA 레지스터에서 ADEN, ADSC 플랙을 1 로설정하여변환을시작시킬수있다. 최초 - 144 -

변환에 25개의 클록이필요하다. 변환이완료되면변환결과가 ADCH, ADCL 레지스터에결과가저장되 면 ADIF가 1로세트되며 AD 변환완료인터럽트가요청되고 ADSC 비트는자동적으로클리어된다. 다시변환을 시작시키려면 ADSC플랙을 1 로하면된다. 그리고이때부터는 13개의 클록이필요하다. Free Running 모드 : ADCSRA 레지스터에서 ADEN, ADSC, ADFR 플랙을 1로설정하여변환을시작시킬수 있다. 변환완료에 13개의 클록이필요하다. 변환이완료되면변환결과가 ADCH, ADCL 레지스터에결 과가저장되면서즉시그다음차례의 AD 변환이자동적으로시작된다. 5.7.3.6. 잡음제거방법 아날로그입력신호선을최소한으로짧게한다. 그림 112. ADC 채널과 Gain 의설정( 출처:ATMEL) AVCC 단자에는디지털전원 VCC를 LC 필터로안정화시켜인가한다 ( 그림 113 참조). - 145 -