ATmega128 교재 - 8장 EEPROM.hwp

Similar documents
<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A638C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A636C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

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

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

2주차: 입출력 제어 복습

슬라이드 1

<BDC7C7E83720BFB9BAF1BAB8B0EDBCAD2E687770>

PowerPoint 프레젠테이션

(Asynchronous Mode) ( 1, 5~8, 1~2) & (Parity) 1 ; * S erial Port (BIOS INT 14H) - 1 -

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202834C1D6C2F7207E2038C1D6C2F729>

MAX232 MAXIM사에서생산되는 RS-232통신을가능토록해주는송수신 IC이다. 송수신드라이브를각각 2개씩가지고있다. AVR과컴퓨터가인식하는 0과 1의값이다르기때문에.. 마이컴컴퓨터 이차이를해결해주는것이다. 0 0V -10V 1 5V 10V TTL IC 의전원단자와다

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

목차 1. UART와 RS232 개요 2. ATMega128의 USART 포트 3. UART로 Hello 보내기 4. UART로 PC와데이터주고받기

K&R2 Reference Manual 번역본

Microsoft PowerPoint - chap06-2pointer.ppt

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A634C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

버퍼오버플로우-왕기초편 10. 메모리를 Hex dump 뜨기 앞서우리는버퍼오버플로우로인해리턴어드레스 (return address) 가변조될수있음을알았습니다. 이제곧리턴어드레스를원하는값으로변경하는실습을해볼것인데요, 그전에앞서, 메모리에저장된값들을살펴보는방법에대해배워보겠습

슬라이드 1

API 매뉴얼

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074>

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

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

학습목차 2.1 다차원배열이란 차원배열의주소와값의참조

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202834C1D6C2F7207E2038C1D6C2F729>

1. 기본설정 목차 1-1. 설치해야할프로그램및파일 1-2. 프로그램올리기 1-3. MAKEFILE 2. 캐릭터 LCD(PORT) 3-1. 개요 3-2. 사용하는레지스터 3-3. Source Code 3-4. 실습사진 3. 타이머카운터및초음파센서활용 (PORT, TIM

C 언어 프로그래밊 과제 풀이

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

BMP 파일 처리

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

PowerPoint 프레젠테이션

CANTUS Evaluation Board Ap. Note

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

Microsoft PowerPoint - AVR 시리얼 통신.ppt [호환 모드]

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

PowerPoint 프레젠테이션

// 변수선언 unsigned char i; unsigned char FONT[]={0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xD8, 0x80, 0x98}; //PORTA 를출력으로설정하고초기값은모두 0 PORTA = 0x00; DD

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

API 매뉴얼

PowerPoint 프레젠테이션

0. 표지에이름과학번을적으시오. (6) 1. 변수 x, y 가 integer type 이라가정하고다음빈칸에 x 와 y 의계산결과값을적으시오. (5) x = (3 + 7) * 6; x = 60 x = (12 + 6) / 2 * 3; x = 27 x = 3 * (8 / 4

프로그램을 학교 등지에서 조금이라도 배운 사람들을 위한 프로그래밍 노트 입니다. 저 역시 그 사람들 중 하나 입니다. 중고등학교 시절 학교 도서관, 새로 생긴 시립 도서관 등을 다니며 책을 보 고 정리하며 어느정도 독학으르 공부하긴 했지만, 자주 안하다 보면 금방 잊어

PowerPoint Presentation

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

untitled

Microsoft PowerPoint - ch07 - 포인터 pm0415

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

Microsoft PowerPoint - chap10-함수의활용.pptx

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

ATmega128

Microsoft PowerPoint - polling.pptx

The Pocket Guide to TCP/IP Sockets: C Version


비트와바이트 비트와바이트 비트 (Bit) : 2진수값하나 (0 또는 1) 를저장할수있는최소메모리공간 1비트 2비트 3비트... n비트 2^1 = 2개 2^2 = 4개 2^3 = 8개... 2^n 개 1 바이트는 8 비트 2 2

Microsoft PowerPoint - chap05-제어문.pptx

11장 포인터

PowerPoint 프레젠테이션

OCW_C언어 기초

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

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

[8051] 강의자료.PDF

설계란 무엇인가?

11장 포인터

Microsoft PowerPoint - ch09_파이프 [호환 모드]

2009년 상반기 사업계획

C 프로그램의 기본

UI TASK & KEY EVENT

T100MD+

KEY 디바이스 드라이버

USB3-FRM01 API 매뉴얼

중간고사

PowerPoint 프레젠테이션

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

목차 포인터의개요 배열과포인터 포인터의구조 실무응용예제 C 2

2009년 상반기 사업계획

Microsoft PowerPoint - chap06-1Array.ppt

lecture4(6.범용IO).hwp

Microsoft PowerPoint - [2009] 02.pptx

쉽게 풀어쓴 C 프로그래밍

이번장에서학습할내용 동적메모리란? malloc() 와 calloc() 연결리스트 파일을이용하면보다많은데이터를유용하고지속적으로사용및관리할수있습니다. 2

Microsoft Word - LKP-RTD 사용자 설명서

제1장 Unix란 무엇인가?

Microsoft PowerPoint - IOControl [호환 모드]

Microsoft PowerPoint - es-arduino-lecture-03

OCW_C언어 기초

Microsoft PowerPoint APUE(Intro).ppt

ABC 11장

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

Microsoft PowerPoint - chap06-8.ppt

프로그래밍개론및실습 2015 년 2 학기프로그래밍개론및실습과목으로본내용은강의교재인생능출판사, 두근두근 C 언어수업, 천인국지음을발췌수정하였음

제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

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

C 프로그래밊 개요

Microsoft PowerPoint - 제11장 포인터

OCW_C언어 기초

AVR-GCC SRAM 에서의변수및상수특별히속성을정하지않고변수를정의하면 SRAM 영역에저장된다. 이것들은외부메모리에저장되는경우에비하여빠르게엑세스할수있다. 축약표현은 <stdio.h> 에정의되어있다. 그러나, <io.h> 를인클루드하면내부적으로 <stdio.h> 파일을자

인터럽트 * 인터럽트처리메커니즘 ATmega128 인터럽트 2

Microsoft PowerPoint - Chapter_04.pptx

Transcription:

8.1 EEPROM 과 Flash Memory ATmega128에는프로그램메모리로서 128KB의플래시메모리를내장하고있고데이터메모리로서 4KB의 EEPROM을내장하고있다. EEPROM과플래시메모리는하나의뿌리에서발전해온매우유사한메모리이지만사용방법이서로다르다. 이것들은오늘날독립된메모리소자로서도널리사용되고있으므로충분히알아둘필요가있다. EEPROM(Electrically Erasable PROM) 은온보드 (on-board) 상태에서사용자가내용을바이트단위로 read 하거나 write할수있으므로사실상 SRAM처럼사용할수있는비휘발성메모리이며, 따라서제조회사에따라서는이를 EEPROM이라고부르지않고 EAPROM(Electrically Alterable PROM) 또는 NVRAM (Non-Volatile RAM) 이라고부르기도한다. 그러나이것의리드동작은액세스시간이다소느리기는하더라도 SRAM과유사하므로별문제가없는데비하여, Write 동작을수행하는경우에는 1바이트를 write할때마다수 [ms] 이상의시간지연이필요하므로 SRAM과동일하게사용할수는없다. 따라서, EEPROM은실시간으로사용되는변수를저장하는메모리나스택메모리로는사용될수없으며, 한번내용을저장하면비교적오랫동안이를기억하고있으면서주로이를읽어사용하기만하거나전원을꺼도지워져서는안되는중요한데이터를백업하여두어야하는설정값저장용메모리로적합하다. 이메모리소자는 28Cxxx의형태로이름을짓는경우가많다. 플래시메몰 (flash memory) 는온보드상태에서사용자가내용을바이트단위로자유로이리드할수는있지만, Write는페이지 (page) 또는섹터 (sector) 라고불리는블록 (block) 단위로만수행할수있는변형된 EEPROM 이다. 블록의크기는메모리소자나메이커에따라다르지만대체로 64바이트, 128바이트, 256바이트등에서부터 128KB까지도사용한다. 이렇게플래시메모리는 EEPROM과매우유사하지만바이트단위로 Write 하는것이불가능하므로 Page mode write 기능만을가지는 EEPROM 이라고생각하면되며, 따라서역시 SRAM처럼실시간데이터메모리로사용하는것은불가능하다. 그러나, 플래시메모리는 EEPROM보다메모리셀의구조가간단하여훨씬대용량의메모리소자를만드는데적합하며, 1개의블록전체를 Write 하는데수 [ms] 정도가걸리므로대용량데이터를라이트할때는 EEPROM보다훨씬속도가빠르다는장점을가진다. 그런데, 플래시메모리는내부구조에따라서 NOR형플래시와 NAND형플래시메모리로나눌수있다. NOR형플래시는다른메모리소자와같이외부구조가어드레스버스, 데이터버스, 그리고몇가지의제어신호및전원으로되어있어서프로그램저장용으로널리사용된다. NOR형플래시메모리는대부분 29Cxxx 형태의이름을가지고있다. 그러나, NAND형플래시메모리는어드레스버스와데이터버스가따로있는것이아니고 8개 ( 또는 16개 ) 의데이터신호와몇개의제어신호및전원핀을가지고있다. 8개의데이터신호선은어드레스및제어명령을 Write하거나데이터값을읽고쓰는용도로사용된다. 이렇게하면메모리를읽고쓰는동작은좀번거로워지지만메모리용량이증가하더라도핀수가늘어나지않으므로하드웨어규격을통일할수있어서플래시메모리를마치하드디스크처럼사용하는것이가능하다. 특히, 요즈음에는휴대용기기를염두에두고 1.8V 나 3.3V의저전압에서동작하는수십MB~ 수 GB짜리대용량의 NAND형플래시메모리가많이개발되어휴대용통신기기, 디지털카메라, MP3 플레이어, 이동형 USB 메모리등과같은용도에널리사용되고있다.

8.1.1 내부 EEPROM의이해 ATmega128은바이트단위로읽고쓰기가가능한 4K의내부 EEPROM을가지고있다. 이 EEPROM은최소 10만번이상의쓰고지우기가가능하다. 관련된레지스터는 EEPROM Address 레지스터, Data 레지스터, Control 레지스터가있다. 8.1.2 EEARH/EEARL (EEPROM Address Register) EEARH/EEARL (EEPROM Address Register) 0x1F(0x3F), 0x1E(0x3E) bit 7 6 5 4 3 2 1 0 - - - - EEARH[11:8] EEARL[7:0] Read/Write R/W R/W R/W R/W R/W R/W R/W R/W 초기값 0 0 0 0 x x x x x x x x x x x x ATmega128의 4K EEPROM 공간이있고바이트단위로읽고쓰기때문에주소공간이 12비트가필요하다. 그래서상위와하위로구분되는두개의레지스터를사용해서필요한주소를지정할수있다. 8.1.3 EEDR (EEPROM Data Register) EEDR (EEPROM Data Register) 0x1F(0x3F), 0x1E(0x3E) bit 7 6 5 4 3 2 1 0 MSB LSB Read/Write R/W R/W R/W R/W R/W R/W R/W R/W 초기값 0 0 0 0 0 0 0 0 실제로읽거나쓰기위해사용되는바이트단위의데이터가저장되어있는레지스터이다. 8.1.4 EECR (EEPROM Control Register) EECR (EEPROM Control Register) 0x1C(0x3C) bit 7 6 5 4 3 2 1 0 - - - - EERIE EEMWE EEWE EERE Read/Write R/W R/W R/W R/W R/W R/W R/W R/W 초기값 0 0 0 0 0 0 0 0 Bit 3 : EERIE (EEPROM Ready Interrupt Enable) 이비트가 1 로설정되고 SREG 레지스터의 I 비트가 1 로설정되면 EEPROM Ready 인터럽트가활성화되고 0 으로설정되면비활성화된다. EEPROM Ready 인터럽트는 EEWE 가클리어되었을때발생한다.

Bit 2 : EEMWE (EEPROM Master Write Enable) EEMWE (EEPROM Master Write Enable) 레지스터가 1 로설정되고나서, EEWE가설정되면 4클럭사이클이지나고난후선택된주소에데이터가써지게된다. EEMWE가 0 이면 EEWE는효과를볼수없다. EEMWE는소프트웨어에의해서 1로설정되고 4클럭사이클이지난후에하드웨어에의해서클리어된다. Bit 1 : EEWE (EEPROM Wirte Enable) EEMWE 레지스터가 1로설정되어있다면 EEWE를 1로설정해야쓰기기능이동작한다. 쓰기가완료되면하드웨어에의해서클리어된다. EEWE가 1로설정되고나면다음인스트럭션이실행되기전에 CPU는 2클럭사이클동안멈추고있는다. Bit 0 : EERE (EEPROM Read Enable) 정상적으로 EEAR 레지스터에주소값이설정되면 EERE 레지스터를 1로설정하여읽기를한다. 읽기동작은한인스트럭션 (instruction) 으로끝나기때문에바로데이터를읽을수있다. 읽기가실행되고나면다음인스트럭션이실행되기전에 CPU는 4클럭사이클동안멈추고있는다. 8.1.4 쓰기예제 아래의예제소스는데이터시트에서나오는간단한쓰기예제이다. void EEPROM_write(unsigned int uiaddress, unsigned char ucdata) // 이번의쓰기가완료되기를기다린다 while(eecr & (1<<EEWE)) // 주소와데이터레지스터를설정한다. EEAR = uiaddress EEDR = ucdata // EEMWE 에 1을설정한다. EECR = (1<<EEMWE) //EEWE를설정하여쓰기를시작한다. EECR = (1<<EEWE) EEWE가클리어될때까지기다리고있다가, 주소와데이터를설정하고 EEMWE를 1로설정하여기다린후 EEWE를설정하여쓰기를시작하면된다.

8.1.5 읽기예제 void EEPROM_read(unsigned int uiaddress) // 이번의쓰기가완료되기를기다린다 while(eecr & (1 << EEWE)) // 주소레지스터를설정한다. EEAR =uiaddress //EERE를설정하여읽기를시작한다. EECR = (1<<EERE) // 데이터레지스터에서데이터를읽는다. return EEDR 쓰기와같이 EEWE가클리어되는것을기다리다가, 주소를설정하고 EERE를 1로설정하여읽기동작을한후에데이터를읽어오면된다. 8.1.6 avr-gcc에서지원하는함수위와같이레지스터를사용하는방법외에 avr-gcc에서지원하는내부 EEPROM 관련함수들이있다. 이함수들은 avr/eeprom.h 에정의가되어있다. 헤더파일에는다양한종류의함수들을지원하고있고, 그중주요함수는다음과같다. 함수원형 함수기능 eeprom_is_ready() EECR 레지스터에서 EEWE 비트가클리어될때까지대기 eeprom_write_byte(addr, val) 해당주소에값을쓰기가가능하다 eeprom_read_byte(addr) 해당주소에바이트단위로읽기가가능하다.

8.1.7 학습예제 8.1.7.1 내부 EEPROM 에 Hello DK128" 을쓰고읽어서하이퍼터미널에출력하라.. ex5_1.c 내부 EEPROM 에 Hello DK128" 을쓰고, 읽어서하이퍼터미널에출력하는예제 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #include <avr/io.h> #include <stdlib.h> #include <stdio.h> #include <avr/eeprom.h> #define CPU_CLOCK 16000000 #define BAUD_RATE 19200 #define BAUD_RATE_L (CPU_CLOCK / (16l * BAUD_RATE)) - 1 #define BAUD_RATE_H ((CPU_CLOCK / (16l * BAUD_RATE)) - 1) >> 8 #define UART_RX_BUFLEN 128 #define BS 0x08 #define CR 0x0D void uart_send_byte(unsigned char byte) while (!(UCSR1A & (1 << UDRE))) UDR1 = byte void eeprom_write(unsigned int addr, unsigned char data) // EEPROM 쓰기함수 while (EECR & (1 << EEWE))// 이번의쓰기가완료되기를기다린다. EEAR = addr // 주소와데이터레지스터를설정한다. EEDR = data EECR = (1 << EEMWE) // EEMWE에 1을설정한다. EECR = (1 << EEWE) // EEWE를설정하여쓰기를시작한다. unsigned char eeprom_read(unsigned int addr) // EEPROM 읽기함수 while (EECR & (1 << EEWE)) // 이번의쓰기가완료되기를기다린다. EEAR = addr // 주소레지스터를설정한다. EECR = (1 << EERE) // EERE를설정하여읽기를시작한다. // 데이터레지스터에서데이터를읽는다. return EEDR

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 int main(void) unsigned char data unsigned char buf[] = "Hello DK128!" unsigned int i // baud rate 설정 UBRR1L = (unsigned char)baud_rate_l UBRR1H = (unsigned char)baud_rate_h // no parity, 1 stop bit, 8bit 설정 UCSR1C = (0 << UPM1) (0 << UPM0) (0 << USBS) (1 << UCSZ1) (1 << UCSZ0) // rx/tx interrupt 설정, 8bit 설정 UCSR1B = (1 << TXEN) (1 << RXEN) (0 << UCSZ2) for (i = 0 i < sizeof(buf) i++) // 문자열의길이만큼 EEPROM의 0번지부터쓴다. eeprom_write(i, buf[i]) for (i = 0 i < sizeof(buf) i++) // EEPROM의 0번지부터바이트단위로읽는다. data = eeprom_read(i) // 읽은값을터미널에보여준다. uart_send_byte(data) return 1 21~29행 : 주소값과 1 바이트의데이터를인자로하는 EEPROM 쓰기함수이다. 우선전송이가능한지확인하기위해서 EECR 레지스터의 EEWE 비트가 0이될때까지기다린다. EEWE 비트가클리어되면 EEAR 레지스터에쓰고자하는위치의주소값을쓴다. 그리고레지스터에쓸데이터값을쓰면내부 EEPROM으로데이터가전송된다. 32~41행 : 주소값을인자로하는 EEPROM 읽기함수이다. 현재사용중인지를확인하기위해서쓰기동작과마찬가지로 EEWE 비트가클리어될때까지기다린다. 읽고자하는주소값을 EEAR 레지스터에써주고 EERE 비트를 1로설정하여 EEDR 레지스터에저장된데이터를가져온다.

60~64행 : EEPROM의첫주소인 0x00 번지부터문자열길이만큼반복문을사용하여해당번지에값을써준다. 66~73행 : EEPROM의 0번지부터읽을문자열의길이만큼문자를읽어서해당문자를하이퍼터미널에보여준다.

8.1.7.1 아래와같은메뉴를구성하고각해당하는번호에따라동작수행하는프로그램을 작성하라.( 단, 레지스터만사용 ) 메뉴 1. Internal EEPROM Initializing 2. Internal EEPROM Reading 3. Internal EEPROM Writing Input number (1-3) : 동작 1. Internal EEPROM Initializing EEPROM의내용을모두 0x00으로만들기 (0x00번지부터 0xFF 번지까지만동작 ) 2. Internal EEPROM Reading EEPROM의내용을번지단위로 16진수로표현하여 RS232 터미널에출력 (0x00번지부터 0xFF번지까지만동작 ) 3. Internal EEPROM Writing RS232를통해받은한라인의데이터를첫번째번지부터 EEPROM에저장 ( 기존의데이터는덮어쓰기 ) ex5_2.c 메뉴를구성하고각해당하는번호에따라동작수행하는예제 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <avr/io.h> #include <stdlib.h> #include <stdio.h> #define CPU_CLOCK 16000000 #define BAUD_RATE 19200 #define BAUD_RATE_L (CPU_CLOCK / (16l * BAUD_RATE)) - 1 #define BAUD_RATE_H ((CPU_CLOCK / (16l * BAUD_RATE)) - 1) >> 8 #define UART_RX_BUFLEN 128 #define BS 0x08 #define CR 0x0D void uart_send_byte(unsigned char byte) // 1 byte 전송함수 while (!(UCSR1A & (1 << UDRE))) // 전송버퍼가빌때까지기다린다. UDR1 = byte void uart_send_string(unsigned char *str, unsigned char len) // 문자열전송함수 int i for (i = 0 i < len i++) if (!(*(str + i))) break uart_send_byte(*(str + i))

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 unsigned char uart_recv_byte(void) // 1 byte 수신함수 while (!(UCSR1A & (1 << RXC)))// 수신버퍼가찰때까지기다린다. return UDR1 void menu_display(void) // 메뉴를보여준다 uart_send_string("1. Internal EEPROM Initializing n r", 33) uart_send_string("2. Internal EEPROM Reading n r", 28) uart_send_string("3. Internal EEPROM Writing n r", 28) uart_send_string("input number(1-3): ", 19) unsigned char uart_recv_string(unsigned char *str) // 문자열수신함수 unsigned char len = 0 unsigned char byte for () if (len >= UART_RX_BUFLEN) // 글자수제한 break byte = uart_recv_byte() // 1 byte씩읽어들인다. if (byte == 0x0D) // carriage return (ENTER Key) uart_send_byte(' n') uart_send_byte(' r') break // 수신종료 else if (byte == 0x08) // back space if (len) len-- uart_send_byte(byte) uart_send_byte(' ') uart_send_byte(byte) else str[len++] = byte uart_send_byte(byte) // 받은데이터보여주기 str[len] = ' 0' return len

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 void eeprom_write(unsigned int addr, unsigned char data) // EEPROM 쓰기함수 while (EECR & (1 << EEWE))// EEMWE에 1을설정한다. // 주소와데이터레지스터를설정한다. EEAR = addr EEDR = data EECR = (1 << EEMWE) // EEMWE에 1을설정한다. EECR = (1 << EEWE) // EEWE를설정하여쓰기를시작한다. unsigned char eeprom_read(unsigned int addr) // EEPROM 읽기함수 while (EECR & (1 << EEWE)) // 이번의쓰기가완료되기를기다린다. EEAR = addr // 주소레지스터를설정한다. EECR = (1 << EERE) // EERE를설정하여읽기를시작한다. // 데이터레지스터에서데이터를읽는다. return EEDR int main(void) unsigned char eeprom_data[5] unsigned char buf[uart_rx_buflen] unsigned int i, len unsigned char data // baud rate 설정 UBRR1L = (unsigned char)baud_rate_l UBRR1H = (unsigned char)baud_rate_h // no parity, 1 stop bit, 8bit 설정 UCSR1C = (0 << UPM1) (0 << UPM0) (0 << USBS) (1 << UCSZ1) (1 << UCSZ0) // rx/tx interrupt 설정, 8bit 설정 UCSR1B = (1 << TXEN) (1 << RXEN) (0 << UCSZ2)

124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 for () menu_display() uart_recv_string(buf) switch (atoi(buf)) case 1: // 0x00부터 0xFF 까지만 0x00으로초기화 for (i = 0x00 i < 0xFF i++) eeprom_write(i, 0x00) uart_send_string("ok. r n", 5) break case 2: // 0x00부터 0xFF 까지만읽어서출력 for (i = 0x00 i < 0xFF i++) data = eeprom_read(i) sprintf(eeprom_data, "0x%02X ", data) uart_send_string(eeprom_data, sizeof(eeprom_data)) if (((i + 1) % 15) == 0) // 15개씩한라인에출력 uart_send_string(" n r", 2) uart_send_string("ok. r n", 5) break case 3: // 읽은데이터를 0x00부터저장 len = uart_recv_string(buf) for (i = 0 i < len i++) eeprom_write(i, buf[i]) uart_send_string("ok. r n", 5) break default: uart_send_string("invalid arguments. r n", 20) break return 1

127행 : 해당메뉴를출력하는함수를호출한다. 명령이한번실행되고나면다시실행되도록반복문안에넣는다. 128 행 : 메뉴번호를입력받도록한다. 해당메뉴번호가아닌것인지는그뒤에체크한다. 130행 : switch 반복문을사용한다. 인자로는받은데이터를숫자로변환하는함수인 atoi() 를사용하여숫자로변환하여사용한다. Case문을사용하여실행가능한메뉴번호가아니라면잘못된인자라는메시지를출력하고무시한다. 132~137행 : 모든공간에쓰기동작을하기에는무리가있기때문에 EEPROM 의 0x00 번지부터 0xFF 번지까지만대상으로하여 0x00 값을저장한다. 동작이완료되면완료가되었다는메시지를출력하고다시메인메뉴로돌아가서새로운동작을기다린다. 138~150행 : 1번메뉴와마찬가지로 0x00 번지부터 0xFF 번지에만해당하는값을읽어서모두출력한다. 다만한라인에 15 단위로출력을하기위해서 % ( 나머지 ) 연산을사용하여 15개의데이터를출력하고나면개행문자를출력하여새로운행에데이터가출력되도록한다. 여기도마찬가지로완료가되면완료되었다는메시지를출력한다. 151~159행 : 우선하이퍼터미널로데이터가입력되길기다리다가데이터가입력되면해당데이터의길이를리턴받아서저장하고있다가해당길이만큼내부 EEPROM에저장한다. 0x00 번지부터저장을하기시작하므로저장되는범위는 0x00 번지부터문자열길이만큼이다. 마찬가지로완료메시지를출력한다. 161~162행 : 1, 2, 3번메뉴가아닌다른번호이거나전혀상관없는데이터를입력받았을때는잘못된인자라고메시지를출력한후다시데이터입력을대기하는모드로돌아간다. 8.1.8 실습예제 8.1.8.1 학습예제 2 와같은기능을하되, avr-gcc 에서제공하는함수를사용하여작성하라.