시리얼통신 (USART) 범용동기및비동기시리얼수신기와송신기 (USART) 는매우유연한시리얼통신장치이다. 주요특징은다음과같다. w 송수신레지스터가독립적으로운용되는전이중방식. w 비동기또는동기동작. w 마스터또는슬레이브동기동작. w 고해상도전송속도생성기. w 5, 6, 7

Similar documents
<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

Microsoft PowerPoint - Chapter 8_USART Serial Communication

2주차: 입출력 제어 복습

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

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

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202834C1D6C2F7207E2038C1D6C2F729>

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A638C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A634C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

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

슬라이드 1

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202834C1D6C2F7207E2038C1D6C2F729>

ATmega128

<4D F736F F D20BDBAC5D7C7CE20B6F3C0CEC6AEB7B9C0CCBCADB0ADC1C2202D203420C7C1B7CEB1D7B7A1B9D62E646F63>

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

<BDC7C7E83720BFB9BAF1BAB8B0EDBCAD2E687770>

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

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

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

BY-FDP-4-70.hwp

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

가. 도트매트릭스제어하기 단일 LED와는다르게도트매트릭스를구동시는구동전류가프로세서에서출력되는전류보다사용량을더많이필요하기때문에 TTL 계열의 IC로구동시키기에는무리가따른다. 이러한문제를해결하기위해서사용전압, 전류정격이높은달링턴트랜지스터가어레이형태로들어있는 ULN2803을

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202831C1D6C2F72C2032C1D6C2F729>

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

데이터 통신

ATmega128 교재 - 8장 EEPROM.hwp

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

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

개요

슬라이드 1

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

C & System

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

[8051] 강의자료.PDF

목차 1. 키패드 (KeyPAD) 2. KeyPAD 를이용한비밀번호입력기

<4D F736F F D20C0DBC7B0C6ED5FBDBAC5D7C7CE20B6F3C0CEC6AEB7B9C0CCBCAD20B0B3B9DF2E646F63>

OCW_C언어 기초

CANTUS Evaluation Board Ap. Note

OSTSen-PIR100 사용자설명서 Ver 1.1 Onsystech OSTSen-PIR100 V1.1 1 of 8 Onsystech

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

OSTSen-THL100 사용자설명서 Ver 1.1 Onsystech OSTSen-THL100 Ver1.1 1 of 8 Onsystech

Microsoft PowerPoint - 9.Serial.pptx

2 Mitsubishi FX Series Computer Link MITSUBISHI FX SERIES COMPUTER LINK 시스템구성 시스템설정 사용예 사용예 사용예

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

DSP_MON 프로그램 메뉴얼

<4D F736F F F696E74202D2037C0E55FC0CEC5CDB7B4C6AEC0C720B5BFC0DB2E707074>

Microsoft PowerPoint Android-SDK설치.HelloAndroid(1.0h).pptx

OSTSen-MOS100 사용자설명서 Ver 1.1 Onsystech OSTSen-MOS100 Ver of 8 Onsystech

목차 윈도우드라이버 1. 매뉴얼안내 운영체제 (OS) 환경 윈도우드라이버준비 윈도우드라이버설치 Windows XP/Server 2003 에서설치 Serial 또는 Parallel 포트의경우.

슬라이드 제목 없음

ISP and CodeVisionAVR C Compiler.hwp

Mango-E-Toi Board Developer Manual

lecture4(6.범용IO).hwp

중간고사

목차 1. A/D 컨버터개요 2. ATMega128 의 A/D 컨버터기능 3. A/D 컨버터로광센서읽기

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

Microsoft Word _whitepaper_latency_throughput_v1.0.1_for_

<4D F736F F D20B1E2BCFAC0DAB7E1202D20454F435220B8F0B5E5B9F6BDBA20C5EBBDC5C1A6C7B020BBE7BFEBB9FD202D F302E646F63>

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

<4D F736F F F696E74202D2037C0E55FC0CCC0C0C7F55FBFCFBCBA205BC8A3C8AF20B8F0B5E55D>

AVR Atmega128

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

API 매뉴얼

<BDC7C7E83520BFB9BAF1BAB8B0EDBCAD2E687770>

-. Data Field 의, 개수, data 등으로구성되며, 각 에따라구성이달라집니다. -. Data 모든 의 data는 2byte로구성됩니다. Data Type는 Integer, Float형에따라다르게처리됩니다. ( 부호가없는 data 0~65535 까지부호가있는

Requirement Definition Wheel Motor 작동하는경우장애물인식후 - Ultrasonic Sensor 홀수번누를경우 +10 Touch Sensor 누를경우 TouchSensor 계속누르고있을경우 (0.5) +10 짝수번누를경우 -10 빛이어두워졌다다

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

Microsoft Word - ntasFrameBuilderInstallGuide2.5.doc

1. 제품규격및특징 구분 규격및특징 입력전압 DC 12~30V 모터구동방식 Bipolar 방식 최대모터전류 Max 3.0A 초기설정정지전류 :4(0.46A), 구동전류 :18(1.75A) 분주비 0(x256), 1(x128), 2(x64), 3(x32), 4(x16),

Microsoft PowerPoint - es-arduino-lecture-03

Chapter ...

PowerPoint Template

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

SRC PLUS 제어기 MANUAL

Microsoft Word - EWKit-RS232.doc

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074>

(8)

Microsoft PowerPoint - chap06-2pointer.ppt

Microsoft PowerPoint - chap05-제어문.pptx

T100MD+

슬라이드 1

1

PowerPoint 프레젠테이션

<4D F736F F F696E74202D203137C0E55FBFACBDC0B9AEC1A6BCD6B7E7BCC72E707074>

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

고급 프로그래밍 설계

V. 통신망 기술

Microsoft Word doc

AN_0005B_UART

API 매뉴얼

(MHT-SB112\273\347\276\347\274\255.hwp)

Microsoft PowerPoint - 제7장 타이머와 PWM (HBE-MCU-Multi AVR).ppt [호환 모드]

Microsoft Word - IRM9600x Spec.doc

Microsoft PowerPoint - polling.pptx

윈도우즈프로그래밍(1)

PowerPoint 프레젠테이션

Nordic Chipset BLE Test Application Note

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

I/O (GPIO) 제어 I/0 제어 ATmega128의 I/O 구성및특징 I/O PORT 구성 8비트 / 양방향 / 범용 / 병렬 I/O포트 (PORT A ~PORT F) 6개 5비트 / 양방향 / 범용 / 병렬 I/O포트 (PORT G) 1개 I/O PORT 특징

K&R2 Reference Manual 번역본

Transcription:

CHAPTER 12 시리얼통신 가. 레지스터구조이해하기 나. 하이퍼터미널을이용하여로봇제어하기

시리얼통신 (USART) 범용동기및비동기시리얼수신기와송신기 (USART) 는매우유연한시리얼통신장치이다. 주요특징은다음과같다. w 송수신레지스터가독립적으로운용되는전이중방식. w 비동기또는동기동작. w 마스터또는슬레이브동기동작. w 고해상도전송속도생성기. w 5, 6, 7, 8, 또는 9 비트의데이터와 1 개또는 2 개의정지비트직렬프레임 을지원. w 홀수또는짝수패리티비트생성및하드웨어에의한패리티검사지원. w 데이터오버런 (Overrun) 검출장치. w 오류감지 (Framing error) 를도용. w 노이즈필터링검출및디지털저역통과필터지원. w TX Complete, TX Data Register Empty, RX Complete 별도의세가지인터 럽트지원. w 멀티프로세서통신모드. w 비동기통신모드에서의보율더블러 (Baud rate doubler) USART 송신기의단순블록다이어그램은그림 8.1에나타낸다. CPU 접근 I/O 레지스터및 I/O 핀은굵은글씨로표시된다. 그림 8.1에서점선으로처리된부분은 Clock generator, Transmitter, Receiver 세부분으로구성되어있으며, 이세부분은제어레지스터를공통으로사용하고있다. Clock generator는동기슬레이브동작에서사용하는외부클록입력과, 보율발생장치로구성되어있고, Transmitter는단일쓰기버퍼, 시프트레지스터, 패리티발생기등으로이루어져있으며, 단일쓰기버퍼는프레임간에지연시간없이연속적인데이터를보낼수있게해준다. Receiver는 USART 모듈의가장복잡한구조이며, 클록및데이터복구장치로이루어져있다. 여기서데이터복구장치는비동기데이터수신에서사용하고, 패리티검사기와제어로직, 시프트레지스터와두개의수신버퍼 (UDR) 로이루어져있다.

[ 그림 8.1] USART 블록다이어그램 가. 레지스터구조이해하기 1) 클록발생장치 클록발생장치는송신및수신의가장기본적인클록을만들어낸다. USART 모듈은 Normal Asynchronous mode, Double Speed Astnchronous mode, Master Synchronous mode, Slave Synchronous mode 등네가지의모드가있다. UCSRC 레지스터의 UMSEL 비트를설정하여동기및비동기방식을선택할수있다. 비동기모드에서만지원되는보율더블러는 UCSRA 레지스터의 U2X를설정하여속도를두배로증가할수있다. 동기모드로설정되었을경우에 (UMSEL=1), XCK 핀 (DDR_XCK) 의데이터방향레지스터는클록소스가내부 (Master mode) 에있는지, 아니면외부 (Slave mode) 에있는지를결정한다. 즉, XCK 핀은동기모드에서만활용된다. 그림 8.2에클록발생장치를나타낸다.

[ 그림 8.2] 클록발생장치 그림 8.2의신호에대한설명은아래와같다. w txclk : 송신클록 ( 내부신호 ). w rxclk : 수신클록 ( 내부신호 ). w xcki : XCX 핀으로부터의입력 ( 내부신호 ), Slave Synchronous mode에서지원. w xcko : XCK 핀에대한출력 ( 내부신호 ), Master Synchronous mode에서지원. w fosc : XTAL 핀주파수 ( 시스템클록 ) 내부클록발생장치는 Asynchronous 및 Synchronous Master mode에서사용되며, USART 모듈의보율발생레지스터 (UBRR) 는다운카운터로동작하며프리스케일러또는보율발생장치의기능을한다. 시스템클록 ( ) 과동기해서동작하는다운카운터는 UBRRL 레지스터에서새로운값을쓰던지아니면카운터가 0 이되면값이로드된다. 이클록이바로보율발생장치클록의출력이된다. ( ) 송신기는보율발생클록의 2, 4, 8 분주로, 수신기는 2, 8, 16 분주로동작하며, UMSEL, U2X 그리고 DDR_XCK 비트의설정에따라서달라진다. 그림 8.3에보율발생계산식및각보드에따른 UBRR 값을나타낸다. [ 그림 8.3] Baud Rate Register 계산식

여기서, BAUD는 Baud rate(bps) 이고, 는시스템클록을의미하며, UBRR은 UBRRH와 UBRRL 레지스터를의미한다. Synchronous Master Mode에서지원하는외부클록은 XCK 핀으로입력되는외부클록으로송신및수신기로사용될때에지검출기에의해서검출된다. 이과정에서두개의 CPU 클록지연과최대외부 XCK 주파수는다음식으로제한이된다. UMSEL=1 로설정하여동기모드인경우에, XCK 핀은클록입력 (Slave) 또는클록 출력 (Master) 으로사용된다. RXD 의데이터입력은 XCK 클록에지에서샘플링되며 이과정을그림 8.4 에나타낸다. [ 그림 8.4] 동기모드에서의 XCK 타이밍 UCSRC 레지스터의 UCPOL은 XCK 클록에지가어떤데이터샘플링에서사용되는지또는데이터변환에사용되는지를결정한다. 그림 118에나타냈듯이 UCPOL이 0 이면, 데이터는 XCK의상승에지에서변하고, XCK의하강에지에서샘플링된다. 반대로 UCPOL이 1 로설정되면, 데이터는 XCK의하강에지에서변하고 XCK의상승에지에서샘플링된다. 2) Frame format 직렬데이터프레임은동기비트인시작과정지비트를포함한문자를의미하는 것으로여기에는에러검출을위한패리티비트가추가될수도있다. ATmega128 의 USART 의프레임은다음과같다. w w 1 start bit 5, 6, 7, 9 data bit

w w no, even or odd parity bit 1 or 2 stop bit 데이터프레임은 start bit로시작하여 LSB 비트순서대로전송하며, 전체 9비트인 MSB가전송되면완료된다. 패리티비트가있으면 MSB비트다음에위치하고 stop bit가위치한다. 프레임전체가송신이완료되면, 새로운프레임이오거나 idle 상태가된다. 그림 8.5에프레임조압을나타낸다. [ 그림 8.5] 데이터프레임 w w w w St : start bit(low) (n) : Data bit(0~8) P : Parity bit(even 또는 odd) Sp : Stop bit(high) w IDLE : 데이터가없는경우로언제나 High 상태가된다. 패리티비트는모든데이터비트의 exclusive-or 를이용하여계산하는데, odd parity 가설정되면 exclusive-or 결과같의역이되고, 다음과같은식이성립된다. 여기서, 은 even parity 를이용한패리티비트이고, 는 odd parity 를이용 한패리티비트이다. 3) USART 초기화 USART 의초기화는통신이시작되기전에설정되어야만한다. 일반적인초기화는 보율을설정하고, 프레임및송수신을결정하면되며, 초기화과정에는인터럽트를 disable 하여야한다. 아래의예제는초기화과정을나타낸다. void USART_Init(unsigned int baud)

/* Set baud rate */ UBRRH = (unsigned char)(baud>>8); UBRRH = (unsigned char)baud; /* Enable receiver and transmitter */ UCSRB = (1<<RXEN) (1<<TXEN); /* Set frame format : 8 bit data, 2stop bit */ UCSRC = (1<<USBS) (3<<UCSZ0); 4) USART 의송신장치 USART의송신기는 UCSRB 레지스터의 TXEN 비트를 1 로설정함으로써 enable된다. 송신기가 enable된경우에는 TXD 핀의범용포트의동작은되지않으며, USART의데이터출력용으로이용된다. 보율, 동작모드, 데이터프레임등의설정은송신을하기전에설정되어야만하고, 동기모드로동작하는경우에는 XCK의클록은송신클록으로사용된다. 데이터송신은전송할데이터가송신버퍼에로드되면초기화된다. 그러면 CPU는 UDR에값을써서송신버퍼의내용을로드한다. 시프트레지스터가다음데이터를송신할준비가되어있으면, 송신버퍼에있는데이터가시프트레지스터로이동한다. 다음예제에 USART의송신기가 Data Register Empty(UDRE) 플래그를이용하여송신하는과정을나타냈다. void USART_Transmit(unsigned char data) /* Wait for empty transmit buffer */ while (!(UCSRA & (1<<UDRE))); /* Put data into buffer, sends the data */ UDR = data; UCSZ=7 인경우, 즉 9 비트데이터인경우에는 9 번째비트는 UCSRB 레지스터의 TXB8 비트가 1 로설정되어있어야한다. 다음예제에 9 번째비트를송신하는 과정을나타낸다. void USART_Transmit(unsigned char data)

/* Wait for empty transmit buffer */ while (!(UCSRA & (1<<UDRE))); /* Copy 9 th bit from r17 to TXB8 */ UCSRB &= ~(1<<TXB8); if (data & 0x0100) UCSRB = (1<<TXB8); /* Put LSB data(r16) into buffer, sends the data */ UDR = data; USART의송신기는 USART Data Register Empty(UDRE), Transmit Complete(TXC) 등의상태를나타내는 2개의플래그레지스터가있다. UDRE 플래그는송신버퍼가새로운데이터를받을준비가되어있다고알려주는역할을하며, 송신버퍼가비어있을때 1 로 Set 되며, 아직시프트레지스터에옮겨지지않은송신할데이터가있는경우에는 0 으로클리어된다. UCSRB 레지스터의 Data Register Empty Interrupt Enable(UDRIE) 비트를 1 로설정하면 UDRE 인터럽트가수행된다. 물론여기서전체인터럽트는 enable되어있어야만한다. UDRE 플래그는 UDR 에새로운값을쓰게되면 0 으로클리어된다. 인터럽트에의해서데이터가전송이되면, UDR 인터럽트서비스루틴은 UDRE 플래그를클리어하기위해서 UDR 에새로운데이터를써넣든지아니면 UDR 인터럽트를 disable해야만한다. 그렇지않으면, 인터럽트가종료한후에도새로운인터럽트가발생하게된다. Transmit Complete(TXC) 플래그는송신시프트레지스터에있는전체프레임이시프트로출력하고송신버퍼에현재새로운데이터가존재하지않으면, 1 로 Set 된다. TXC플래그비트는송신완료인터럽트가실행되거나, TXC 비트에 1 로덮어쓰면 0 으로클리어된다. TXC 플래그가 RS485 방식과같은반이중통신방식에서사용된다. UCSRB 레지스터의 Transmit Complete Interrupt Enable(TXCIE) 비트가 1 로 Set 되면, USART Transmit Complete 인터럽트가실행된다. 물론여기서전체인터럽트는 enable되어있어야만한다. USART Transmit Complete 인터럽트를사용할경우에는인터럽트가수행되고나면 TXC 비트는자동으로클리어되므로 TXC 플래그를클리어할필요는없다. 5) USART 의수신장치 UASRT의수신기는 UCSRB 레지스터의 Receive Enable(RXEN) 비트를 1 로설정함으로써 enable된다. 수신기가 enable된경우에는 RXD 핀의범용포트의동작은되지않으며, USART의데이터입력용으로이용된다. 보율, 동작모드, 데이터프레임등의설정은수신을하기전에설정되어야만하고, 동기모드로동작하는경우

에 XCK의클록은송신클록으로사용된다. 수신기는유효한시작비트가입력되면수신하기시작하고, 각각의데이터비트는보율또는 XCK 핀에서샘플링하여프레임의철번째정지비트가수신될때까지수신시프트레지스터에데이터를시프트한다. 첫번째정지비트가수신되면, 즉전체직렬프레임이수신시프트레지스터에수신완료되면, 수신시프트레지스터의내용을 UDR 레지스터를통하여읽을수있다. 다음예제는 Receive Complete(RXC) 플래그를기초로하여간단한 USART 수신기능을나타낸다. void USART_Transmit(unsigned char data) /* Wait for data to be received */ while (!(UCSRA & (1<<RXC))); /* Get and return received data from buffer */ return UDR; UCSZ=7 인경우, 즉 9 비트데이터인경우에는 9 번째비트는 UCSRB 레지스터의 RXB8 비트가 1 로설정되어있어야한다. 다음예제는 9 번째비트를수신하는 과정을나타낸다. unsigned int USART_Receive(void) unsigned char status, resh, resl; /* Wait for data to be received */ while (!(UCSRA & (1<<RXC))); /* Get status and 9 th bit, then data */ /* from buffer */ status = UCSRA; resh = UCSRB; resl = UDR; /* If error, return 1 */ if (status & (1<<FE) (1<<DOR) (1<<PE) return 1; /* Filter the 9 th bit, then return */ resh = (resh>>1) & 0x01; return((resh<<8) resl);

USART 수신기는수신의상태를나타내는 Receive Complete(RXC) 플래그가있어서수신버퍼에아직읽지않은데이터가있는지를나타낸다. 아직읽지않은데이터가있으면 1 로표시되고, 수신버퍼가비어있는경우에는 0 으로표시된다. UCSRB 레지스터의 Receive Complete Interrupt Enable(RXCIE) 비트가 1 로 Set 되면, USART Receive Complete 인터럽트가수행된다. 물론전체인터럽트는수행되어있어야만한다. 수신완료인터럽트가수행되면, 수신완료인터럽트서비스루틴에서 RXC 플래그를클리어하기위해서는 UDR에있는수신데이터를읽으면된다. 그렇지않으면인터럽트가종료하여도새로운인터럽트가발생하게된다. USART의수신기는 Frame Error(FE), Data OverRun(DOR), Parity Error(PE) 등의세가지에러플래그가있으며, UCSRA를읽어서접근할수있다. FE 플래그 PE 플래그 DOR 플래그 수신버퍼에저장된다음프레임의첫정지비트의상태를나타낸다. 정지비트가정상적으로읽혀지면 FE 플래그는 0 으로된 다. 수신버퍼에있는다음프레임에패리티에러가발생한경우에표 시된다. 수신버퍼가꽉찬경우에데이터의손실상태를나타낸다. DOR은수신버퍼가가득찬경우, 수신시프트레지스터에새로운대기문자가있는경우, 새로운시작비트가검출된경우에발생된다. 6) 멀티프로세서통신모드 UCRSA 레지스터의 Multi-processor Communication Mode(MPCM) 비트를 1 로설정하여멀티프로세서기능을사용할수있다. 멀티프로세서통신모드를 1개의마스터 MCU가여러개의슬래이브 MCU에게특정주소를전송함으로써 1개의슬레이브를지정하여데이터를전송하는동작모드이다. 만약에수신기가 5~8 비트로설정된데이터프레임으로설정되어있으면, 첫번째정지비트는프레임이데이터정보인지어드레스정보인지를가리킨다. 만약수신기가 9비트로설정되어있으면, 9번째비트 (RXB8) 는어드레스또는데이터를표시하게된다. 프레임지정비트 ( 첫번째비트또는 9번째비트 ) 가 1 로설정되면프레임은어드레스정보를나타내고, 0 으로설정하면데이터프레임이다. 다음순서에의해서진행된다. w 송신을담당한마스터 MCU 는특별한모드설정이필요없고, 여러개의수 신을하는슬레이브 MCU 는 UCSRA 레지스터의 MPCM 비트를 1 로설정 하여어드레스프레임이수신되기를기다린다.

w w w w 마스터 MCU는 8개의데이터비트에지정하려고하는어드레스와 UCSRA 레지스터의 TXB8을 1 로만든어드레스프레임을송신한다. 모슬레이브 MCU는이어드레스프레임을수신하여자신에게해당되는어드레스인지를판별하, 이것이자신의어드레스인것을확인한 1개의슬레이브 MCU만이 MPCM비트를 0: 으로클리어하여이후에전송될데이터프레임을수신할수있도록한다. 나머지의선택되지않은슬레이브 MCU들은계속하여 MPCM비트를 1 로유지하여어드레스프레임이수신되기를기다린다. 선택된슬레이브 MCU는데이터프레임을수신하고이것이완료되면다시 MPCM비트를 1 로설정하여어드레스프레임의수신대기상태로진입하게된다. 7) USARTn 레지스터 Atmega128에는두개의 Universal Synchronous and Asynchronous serial Receiver and Transmitter(USART) 가있다. 구분은 0 과 1 로하고있으며각각의 USART는독립적인송수신버퍼를가지고있고하드웨어적으로분리되어있지만 UDR이라는명칭은동일하게사용된다. 우선 USART에대해이해하기전에 UART 비동기통신에대해서이해하여야한다. 일반적인통신은 Serial방식과 Parallel방식의통신방식이있다. 시간을기준으로데이터가순차적으로전송되면 Serial방식이고, 같은시간에한번의데이터가여러개의전송선로를통해서전송되면 Parallel 이다. 이때어떤것이좋다고는말할수없다. 일반적으로 PC에서사용되는 USB COM 단자, SATA등과같은방식은 Serial방식이고 CPU에서 RAM과같은곳의데이터를읽기위한선로는여러개의선로에데이터가동시에전달되고, 일반적으로부르는 BUS방식은 Parallel방식이다. 두가지통신방식중 ATmega128에서사용할통신방식은 Serial방식이다. 시리얼통신방식에서도두가지의방식이세부적으로나누어진다. 첫번째동기통신과비동기통신으로나누어지는데동기통신방식은데이터가전송될때전기적으로신호선에신호가전달될때는 Analog신호가전송되는것이아니라 Digital신호를전달하는방식을사용한다. 이때 On과 Off의신호의조합으로 8bit를전송하여데이터를만드는방법과 16bit의데이터를조합하여데이터를만드는방법등과같은여러가지방법적은구분으로나누어진다. 이때 On과 Off신호가송신측과수신측에서언제보내는지확인할수있도록타이밍을만들어주는선로가존재하여신호를보내주면동기방식의통신이되고, 수신측에서언제들어올지모르는데이터를기다리며송신측에서는시간에상관없이데이터를송신하면

비동기받는측에서는언제올지모르는통신을사용하게된다. 비동기와동기의가장큰차이는동기는데이터선외에추가적으로동기를맞춰주는전송선로가존재하게되고일반적인컴퓨터에서사용하는 Dsub-9pin의경우동기를맞춰주는 PIN이할당되어있다. 그러면비동기통신방법에서의문이발생될것이다언제데이터가수신될지모르는과정에서어떻게신호를잡아낼수있을까항상그신호만감지하고있는것이아닌데라고생각이들것이다. 이러한에러를피하기위해서소프트웨어적인방법이아닌하드웨어적인방법을마이크로컨트롤러에서는사용된다. 일반적으로비동기통신방식의가장기본적인방법으로양방향통신조건에서 Tx, Rx, GND 세가지의신호선연결만으로통신을수행한다. 통신의발전과전송데이터증가에따른신호선의전압레벨및조건이변했을뿐기본적인바탕은위의방법만으로충분하다. 비동기통신방법에서가장중요한요소는전송통신의규약이다. 일반적으로사용하는데이터형태는전송을알리는스타트비트 1bit 데이터 8bit Stop비트, 1bit등과같은형태로전송된다. 실제로 8bit를전송하기위해서 10비트를사용하고전송된데이터의결함을검사하기위해서결함검사를목적으로한패리티비트를추가적으로넣는경우, Stop비트는 2bit를넣어다양한형태로데이터전송의무결성을입증할만한정보들을포함하여보낸다. 이같은이유는고속으로많은데이터를송수신할때믿을만한정보인가를판단하여사용유무를검사하기위함이다. 하지만일반적으로 8bit를한개씩전송하는경우는없다고생각해도무방하다. 시스템의용도와크기에따라다르지만 frame 이라는부르는형태의데이터조합을순차적으로보내어그안에서다시시작을알리는바이트형태의데이터와데이터무결성을검사하기위한 checksum, CRC코드등을추가하여무결성을검사한다. ATmega128에서 TxD핀에출력을내보내기위해서는전송 UDR 버퍼에보내고자하는데이터를쓰면된다. 쉬프트레지스터에서시간에따라자동적으로신호를전송해준다. 이같은기능은내부에하드웨어적으로수행되며, 소프트웨어에서는 UDR에단순히보내고자하는데이터를쓰기만하면된다. 이때내부에서패리티비트제너레이터가있어설정에따라자동적으로계산해서출력을구성한다. 반대로수신할때는마이크로컨트롤러가기능을수행해도수신측에서하드웨어적으로신호를검출한다. 신호검출은전송속도와상관관계를가지며, 수신측과송신측은송수신속도를알고있어야만정확한데이터를검출할수있다. RxD포트를통해서신호 (On, Off) 가들어오게되고, 이때스타트비트데이터패리티비트등과같은신호를검출하여수신쉬프트레지스터로한비트씩전송하게되고, 이때규약에따라다르지만 8비트설정 7비트 6비트등과같이설정된비트가전송이완료되면, 인터럽트가발생되거나수신완료레지스터를검색하여사용자로하여금수신이완료되었음을확인할수있다. 예제를이용하여사용될통신방식은비동기, 양방향통신을사용하고, Start비트는 1비트 Stop비트, 1비트패리티

비트는 0, 데이터크기 8bit, 통신속도는 115200bps으로가장범용적으로사용하는통신방식을구현해보도록하겠다. 우선그림 8.6과같이레지스터를살펴보면 UDRn 레지스터는데이터를송신수신할때사용되는레지스터로데이터를입력시키는데사용된다. [ 그림 8.6] UDRn 레지스터 그림 8.7과같이 UCSRnA 레지스터는사용중인 UART기능에서버퍼의송신및수신이완료되었는지에대한상태를읽을수있다. 특히인터럽트방식을쓰지않고수신상태를확인하기위해서반드시확인할수있는레지스터이며, 송신시버퍼에데이터가시간차를가지고전송되어지기때문에전송이완료되지않은상태에서데이터를다시 UDRn에다시쓰게되면버퍼에이중으로쓰이게되고전송시데이터가제대로전달되지않기때문에송신시에도반드시체크해야되는레지스터다. [ 그림 8.7] UCSRnA 레지스터 그림 8.8과같이 USCRnB 레지스터는통신사용시발생되는인터럽트를제어할수있다. 송신완료인터럽트, 수신완료인터럽트를설정할수있도록비트 7번과 6 번에설정할수있고설정값은 1 로설정함으로서사용가능하다반드시인터럽트사용을설정해놓으면 AVR Studio 4에서지원하는 WinAVR에 signal.h 파일인헤더파일을참조하여인터럽트벡터영역의함수를추가해야한다. 만약함수가없을경우마이크로컨트롤러는동작을멈추고정지하게된다. [ 그림 8.8] UCSRnB 레지스터

TXENn와 RXENn비트는송수신에대해각각사용이가능하게할것인가에대한사용성을결정하는레지스터비트이다. 송수신은각각의설정이별개로가능하기때문에송신만쓰는경우, 수신만쓰는경우와두가지를모두쓰는경우등에대해서설정할수있다. 그외에특별히비트 1(RXB8n) 은 9비트송신시 UDRn은 8비트레지스터이기때문에 8번째비트를읽어낼수없다. 그래서특별히 USCRnB의비트 1(RXB8n) 을읽으면수신된 8번째비트를읽어낼수있다. 이와반대로 0번비트 (TXB8n) 는 9비트전송시 8번째비트를전송할버퍼가없기때문에반대로 USCRnB의 0번에써주고전송하면된다. 이때수신시 UDRn을먼저읽고다음으로 USCRnB의 1번비트를읽어야하며, 송신시 USCRnB의 0번비트에데이터를먼저쓰고 UDRn에써야전송이된다. 그림 8.9와같이 UCSRnC 레지스터는상태제어용레지스터이다. 위에서언급한동기 / 비동기, Stop비트, 패리티비트, 전송데이터비트수등을설정할수있다. [ 그림 8.9] UCSRnC 레지스터 그림 8.10 과같이 UMSELn(USARTn Mode Select) 비트는그림 8.6 과같이 1 이면 USARTn 모듈을동기전송모드로설정하고, 0 이면비동기전송모드로 설정한다. [ 그림 8.10] UMSELn Bit 설정 UPMn1, 0(Parity Mode) 비트는그림 8.11과같이 1 로설정하면패리티를발생시키고검사를할수있다. 송신기는자동적으로각프레임의송신데이터에패리티비트를더하여송신한다. 수신기는 UPM0 비트와수신된데이터를비교한다. 만약에오류가발생하면 UCSRnA 레지스터의 PE 플래그가 1 로 Set 된다.

[ 그림 8.11] UPMn Bit 설정 USBSn(Stop Bit Select) 비트는그림 8.12 와같이 0 이면 USARTn 모듈에서데 이터포맷을구성하는 Stop 비트를 1 개로설정하고, 1 이면 Stop 비트를 2 개로설 정한다. [ 그림 8.12] USBSn Bit 설정 UCPOLn 비트는그림 8.13 과같이설정한다. [ 그림 8.13] UCPOLn Bit 설정 UCSZn1, 0(Chracter Size) 비트는그림 8.14 와같이 UCSRnB 레지스터의 UCSZn2 비트와함께전송문자의데이터비트수를설정하는데사용된다. [ 그림 8.14] UCSZn Bit 설정

마지막으로그림 8.15와같이 UBRRnL, UBRRnH 레지스터이다. 비동기통신에서가장중요한요소를설정하는 Baud Rate Register이다. 즉통신속도를정의하는레지스터로 H는상위 L은하위를나타내고총길이로보면 16비트레지스터라고할수있다. [ 그림 8.15] UBRRnL, UBRRnH 레지스터 많은사용자들이이러한기능을먼저설명하고나면복잡해지기시작한다. 많은기능중에사용자가원하는기능은단순할때가많기때문이다. 시리얼통신도이와마찬가지일것이다. 일반적인통신에서 Stop 1비트패리티는경우에따라쓰이는곳과쓰지않는곳이있고, 데이터크기는대부분의많은프로그램에서 8비트의데이터크기를가진다. 이때자주쓰이는통신속도는 9600bps와 38400bps, 115200bps 등과같이몇가지만주로쓰이기때문이다. 9600bps이하로전송하면통신의속도가느리기때문에자주쓰이지않는다. bps 란초당보내는비트수이며, 가령 Start 1비트, Data 8비트, Stop 2비트, Parity 1비트를합치면 12비트가된다. 이때 9600bps로전송하면초당 800개의 8비트데이터를보낼수있다. 하지만 115200bps로전송시 9600개의 8비트데이터를전송한다. 최근에쓰이는통신속도및데이터크기에비해서작은용량이지만이정도로도많은시스템에서필요한정보는전달가능한속도이다. 115200bps이상전송속도를증가하게되면전송선로길이에따른감쇠에따른문제와상관관계가발생되지만, 데이터가손실되거나왜곡등과같은변형의문제와관련이발생하여통신상의문제가발생할수있다. 자그럼본격적으로역으로프로그램을작성해보도록하자. 설정은아래와같다. w 시리얼통신포트0 사용. w 전송속도 115200bps. w Stop 비트 1 비트. w 패리티비트없음.

w 데이터비트 8비트. w 송수신동시에가능. w 송신인터럽트사용안함, 수신인터럽트사용함. 위의사실을바탕으로프로그램을해보도록하겠다. 우선통신속도설정을먼저하도록하자통신속도는 115200bps이다. 실제로통신속도또한메인클록주파수와상관관계를가지고있다. 그만큼메인클록주파수는중요함을한번더상기하도록하자. 이때계산방법은그림 8.16과같이계산하는방법이있지만특별한경우범용으로사용하지않는속도의경우계산하여연결해야하지만범용적으로사용하는속도는이미다계산을해서테이블화해서제공된다. [ 그림 8.16] 보율설정수식표 [ 그림 8.16.1] 자주사용되는주파수에대한 UBRR 값

[ 그림 8.16.2] 자주사용되는주파수에대한 UBRR 값 (1) [ 그림 8.16.3] 자주사용되는주파수에대한 UBRR 값 (2) 보율설정은메인클록주파수에따라서설정값이달라지며, Timer/Counter와같이계산하였을때카운터값이소수점자리에오차가발생하였던것과동일하게통신에서도메인클록주파수에따라송수신간의에러가그림 8.14와같이존재한다. 통신의에러가발생하지않도록 CRX10에서는 14.7456MHz라는클록을사용하게된이유이다.

그림 8.17에서확인한봐와같이 115200bps 사용시 16MHz에서도 -3.5% 라는에러가존재한다. 통신에서설계상의에러율은데이터가많으면많을수록더많은에러를발생시킨다. 그렇기때문에완벽한통신을위해서는 Error가 0% 인영역에서사용하는것이마이크로컨트롤러를사용하여통신을하게되는기본동작에서최종적으로에러를줄일수있는요소로작용한다. [ 그림 8.17] 일반적으로사용되는발진기주파수에대한 UBRR 설정값과오차율 14.7456MHz에서 115200bps를전송할때 UCSRnA의 1번비트 (U2Xn) 설정값에따라서 UBRR의값이변하게된다. U2Xn을 0 으로설정하면 UBRR에 7 을 U2Xn에 1 로설정시 UBRR에 15 로설정해야한다. 테이블을보고간단히값을대입해서입력만시키면된다. 이때표의값은 10진수이다. UCSR0A레지스터는 5번비트 (UDRE0) 을 1 로설정해주어야한다. 기본적으로리셋이후에초기화되지만확인차원에서한번더 1 로설정해주자. UCSR0A 는 0x20으로설정하고, UCSR0B는아래와같이설정할수있다. Bit7 RXCIEn : RX Complete Interrupt Enable 수신완료시인터럽트사용여부. Bit6 TXCIEn : TX Complete Interrupt Enable 송신완료시인터럽트사용여부. Bit4 RXENn : Receiver Enable 수신기능을사용여부. Bit3 TXENn : Transmitter Enable 송신기능사용여부.

UCSR0B는위 4가지비트에대해서체크해준다. 하지만 Bit6번은송신시인터럽트는사용하지않는다고했기때문에설정하지않는다. UCSR0B은 0x98로설정한다. 이제마지막으로 UCSR0C을설정하여야한다. UCSR0C는아래와같이설정할수있다. bit6 bit5~4 bit3 bit2~1 UMSELn: USART Mode Select. UPMn1:0 : Parity Mode. USBSn : Stop Bit Select. UCSZn1:0 : Character Size. bit6의경우 0 일때 Asynchronous Operation 비동기통신으로동작하고 1 일때 Synchronous Operation 동기통신으로동작한다. 이미언급했듯이비동기통신으로설정하기때문에 0 으로설정된다. bit5번과 bit4번은패리티비트를체크한다. 패리티비트란보내는데이터에서이진수로계산하였을때 1의개수가짝수나홀수로개수를조정하여마지막에 1bit를더해서전송하는방식이다. 만약 0x0a를전송하고패리티를짝수패리티로설정할경우 0x0a를이진수로변경하면 0b00001010으로 1의개수가 2개이므로짝수가된다. 이때패리티는 0 으로설정된다. 만약 0x1a일경우이진수로표기하면 0b00011010 으로 1의개수가 3개가된다. 이때패리티는짝수를맞추기위해서마지막에 1을더붙여서보내게된다. 현재에는패리티를쓰지않기때문에 bit5번과 bit4번은각각 0 으로설정한다. bit3은 Stop비트와관련된비트이다. Stop비트는데이터전송이완료된후끝에 1 을붙여서보내는통신데이터전송완료를나타내는비트로 1비트를전송하는방법과 2비트를전송하는방법두가지로나누어진다. Stop비트는 1비트를한다. 그러므로 0 이된다. bit2~1은 UCSR0B의 bit2와연결된다. 표를보면전송할데이터의비트수를정의할수있다. 특별한경우를제외하고는 8bit를거의대부분에서장치나시스템에서사용된다. UCSZ12에는 0, UCSZ11에는 1, UCSZ10에는 1 을설정한다. 최종적으로 UCSR0C에 0x06으로설정한다. 예제를통해실질적으로동작해본다. 아래와같이프로그램을입력한다. 1. 2. 3. 4. 5. #include <avr/io.h> #include <avr/iom128.h> #include <avr/interrupt.h> #include <avr/signal.h> SIGNAL(SIG_UART0_RECV)

6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 설명 usinged char uart_buffer; uart_buffer = UDR0; PORTB = ~PORTB; void main(void) cli(); DDRE = 0x20; DDRB = 0x80; UBRR0H = 0; UBBR0L = 7; UCSR0A = 0x20; UCSR0B = 0x98; UCSR0C = 0x06; sei(); while(1) while((ucsr0a & 0x20) == 0x00); UDR0 = 0x30; 5. : 시리얼통신데이터수신이완료되면인터럽트가요청되고함수로프로그램이점프하여 안의구문을수행하게된다. 7. : 캐릭터형의 uart_buffer의지역변수를할당한다. 8. : uart_buffer 의변수에 UDR0의데이터를옮긴다. 이때수신완료와관련된레지스터들이초기화되어새로운데이터를수신할수있다. 만약이때다른데이터가수신되어옮기기전에데이터가수신되면데이터 Overflow 레지스터비트가 Set 되어검사를할수있다. 인터럽트방식을사용하였기때문에수신이완료된상태에서데이터를바로옮기기때문에검사를할필요가없다. 9. : PORTB의출력을반전하여출력한다. 14. : DDRE에 0x20을설정하였다. USART포트 RXD0 가 PORTE 0번에 TXD0 가 PORTE 1번에연결되어있기때문에 PORTE 0번은입력으로 PORTE 1번은출력으로설정하였다. 15. : DDRB 에 0x80을설정하여 PORTB 7번에연결되어있는 LED를활성화한다.

16, 17. : USART0 를사용하기위하여제일먼저 Baud Rate를설정한다. 설정값은 14.7456MHz를기준으로 UCSR0A의 1번비트 U2X1의설정값을 0 으로설정하였고, 표에의해서 10진수 7이라는값을하위바이트에설정한다. 만약설정표에서 400이라는값을입력해야한다면, 16진수로바꾸어상위값은 UBBR0H 에하위값은 UBBT0L 에설정해야한다. 18. : UCSR0A에 0x20을설정하여 UDRE0에 1 로설정하여 UDR0에데이터가없음을설정한다. 19. : UCSR0B 에 0x98을설정하여수신완료시인터럽트사용, 송수신을동시에사용하겠다고설정한다. 20. : UCSR0C 에 0x06을설정하여비동기통신, 패리티비트없음, Stop비트 1비트, 전송데이터 Size 8비트로설정한다. 24. : while문을사용하여루프조건을발생시킨다. 발생조건은 UCSR0A와 0x20을엔드연산하여 0 과같으면참인조건으로루프를수행하게되고만약참이아니면루프를빠져나오게된다. 이렇게조건을걸어서검사하는이유는마이크로프로세서수행시간이빠르기때문에 UDR0에데이터를중복해서써버리면데이터가전송하기전에 UDR0의값을바꿔버리는현상으로데이터가전송중에겹쳐버리게된다. 이러한점을없애기위해서사용자가데이터를검사하여전송할수있도록 UCSR0A 의 5번비트가전송이완료되고 UDR0가비어있으면 1 로설정되게한다. 바로이점을이용하여 UDR0에데이터를쓰고, 전송이되기전까지기다리거나프로그램에서 UDR0 에데이터를써야할때다른쪽프로그램에서만약데이터를전송하기위해서쓴상태에바로써버리면중복되어서온전한데이터전송이불가능하여검사를한다. 25. : 검사를마치고 UDR0에 0x30이라는데이터를전송하라는의미이다. 이때 UDR0에는데이터가존재하고전송쉬프트레지스터에서전송을메인클록동기에맞춰서스스로전송하고사용자의프로그램은다른작업을전송중에수행할수있으며, 전송이완료되면인터럽트를발생시켜수신과마찬가지로특정함수로빠뜨릴수있지만여기에서는인터럽트를발생시키지않고전송할때검사를하는방법을사용하여전송하였다. 0x30은 ASCII코드에서숫자 0 을의미한다. USART0을이용하여레지스터를설정하고동작시켜보았다. UDR0에 0x30이라는데이터를전송하였지만전송상대가 PC가될수도있고, 다른마이크로컨트롤러가될수도있다. 기본적으로 C언어는 ASCII코드를이용하여문자를전송할수있는시스템구비하였다. 만약 ASCII데이터전송목적이아니라면사용자가원하는데이터를전송하여도상관없지만문자를전송해야한다면, ASCII데이터를전송하여데이터를보내야한다. 일반적으로 PC에서사용되는방식은 ASCII코드방식으로텔넷이

나모뎀등과통신을할때일반적인 16진수의 HEX데이터를전송하면이상한문자로깨져서나오게됨을알수있다. ASCII코드는부록을참조한다. USART0번의통신을이용하여컴퓨터에서 'b' 를입력받을때마다 LED를 On, Off 를반복하는프로그램을아래조건에맞추어전프로젝트의소스를주석처리한후에작성한다. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. w w w w w w w 시리얼통신포트0 사용전송속도 115200bps 스탑비트 1비트패리티비트없음데이터비트 8비트송수신동시에가능송신인터럽트사용안함, 수신인터럽트사용함 #include <avr/io.h> #include <avr/iom128.h> #include <avr/interrupt.h> #include <avr/signal.h> SIGNAL(SIG_UART0_RECV) usinged char uart_buffer; uart_buffer = UDR0; if(uart_buffer == ' b') PORTB = ~PORTB; void main(void) cli(); DDRE = 0x20; DDRB = 0x80; UBRR0H = 0; UBBR0L = 7; UCSR0A = 0x20;

22. 23. 24. 25. 26. 27. 28. 설명 UCSR0B = 0x98; UCSR0C = 0x06; sei(); while(1) 5. : USART0 가수신이완료되어인터럽트가발생하면이곳으로점프하여 의프로그램이수행된다. 7. : 캐릭터형태의변수 uart_buffer를만든다. 8. : 만들어진캐릭터형변수에 UDR0의값을이동시킨다. 9. : 만약 uart_buffer 에캐릭터형 b 와같다면아래 를수행한다. 데이터수신시 HEX값으로 8비트를수신하지만 C언어에서 ASCII값을받아들이고문자를쓸수있도록 를써서문자를검색하도록하였다. 이때 b는소문자영어 b이므로 0x63이라는숫자로대입된다. 11. : PORTB의출력을반전시킨다. 17. : DDRE에 0x20을설정한다. USART포트 RXD0 가 PORTE 0번에 TXD0 가 PORTE 1번에연결되어있기때문에 PORTE 0번은입력으로 PORTE 1번은출력으로설정한다. 18. : DDRB 에 0x80을설정하여 PORTB 7번에연결되어있는 LED를활성화한다. 19, 20. : USART0 을사용하기위하여제일먼저 Baud Rate를설정한다. 설정값은 14.7456MHz를기준으로 UCSR0A의 1번비트 U2X1의설정값을 0 으로설정하였고, 표에의해서 10진수 7이라는값을하위바이트에설정한다. 만약설정표에서 400이라는값을입력해야한다면, 16진수로바꾸어상위값은 UBBR0H 에하위값은 UBBT0L 에설정해야한다. 21. : UCSR0A 에 0x20을설정하여 UDRE0에 1 로설정하여 UDR0에데이터가없음을설정한다. 22. : UCSR0B 에 0x98을설정하여수신완료시인터럽트사용, 송수신을동시에사용하겠다고설정한다. 23. : UCSR0C에 0x06을설정하여비동기통신, 패리티비트없음, Stop비트 1비트, 전송데이터 Size 8비트로설정하였다. 응용예제로 1 초마다동작하는타이머를 Timer/Counter0 서비스를이용해만들고, 매 1 초일때모니터상에 1second 라는문구를발생시킨다. 이때 USART 설정은 아래기준에따른다. w 시리얼통신포트 0 사용

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. w w w w w w 전송속도 115200bps 스탑비트 1비트패리티비트없음데이터비트 8비트송수신동시에가능송신인터럽트사용안함, 수신인터럽트사용함 #include <avr/io.h> #include <avr/iom128.h> #include <avr/interrupt.h> #include <avr/signal.h> unsigned int time_interval; SIGNAL(SIG_UART0_RECV) unsigned char uart_buffer; uart_buffer = UDR0; SIGNAL(SIG_OVERFLOW0) TCNT0 = 0xff - 115; time_interval++; int main(void) cli(); DDRE = 0x20; UBRR0H = 0; UBBR0L = 7; UCSR0A = 0x20; UCSR0B = 0x98; UCSR0C = 0x06; TCCR0 = 0x06; TCNT0 = 0xff - 115; sei(); TIMSK = 0x01;

29. while(1) 30. 31. while(time_interval <= 500); 32. while((ucsr0a & 0x20) == 0x00); 33. UDR0 = '1'; //-15 34. while((ucsr0a & 0x20) == 0x00); 35. UDR0 = 's'; //-17 36. while((ucsr0a & 0x20) == 0x00); 37. UDR0 = 'e'; //-19 38. while((ucsr0a & 0x20) == 0x00); 39. UDR0 = 'c'; //-21 40. while((ucsr0a & 0x20) == 0x00); 41. UDR0 = 'o'; //-23 42. while((ucsr0a & 0x20) == 0x00); 43. UDR0 = 'n'; //-25 44. while((ucsr0a & 0x20) == 0x00); 45. UDR0 = 'd'; 46. time_interval = 0; 47. 48. 5. : time_interval 이라는 int 형변수를만든다. 6. : USART0 수신완료시수신인터럽트발생하고, 점프하여 안의수행한다. 11. : Timer/Counter0 서비스인터럽트발생시수행중문작업을중단하고 안을수행한다. 14. : time_interval 값을증가시킨다. 20~24. : 시리얼통신비동기 115200bps 의속도 Stop비트1 비트패리티비트없음데이터크기 8비트, 송수신동시에사용, 수신인터럽트사용의설정이다. 25~28. : Timer/Counter0 을 256분주에카운터값 256으로설정하여 2ms의타이설머카운터이벤트를 TIMSK에 0x01로설정하여활성화한다. 명 31. : time_interval 의값이 500이하일때참조건이므로루프를수행한다. 하지만 500과같거나높아지면거짓의조건이되므로아래프로그램을수행한다. 500이라는 time_interval 은타이머서비스인터럽트루틴발생시 11번으로점프하고 14번에서증가한다. 즉타이머서비스인터럽트루틴에서는증가만시키고메인함수내의 while문에서검사한다. 32. : USART0 의전송버퍼 UDR0의데이터를쓸수있는지검사한다. 33. : UDR0에 1 이라는 ASCII값을써준다. 코드값은 0x31이다. 34. : USART0 의전송버퍼 UDR0의데이터를쓸수있는지검사한다. 현재조

건에서는 33번에서 UDR0에데이터를쓰고바로내려왔기때문에검사조건이초기에는참으로루프에머물게될것이다. 하지만 1 의전송이완료되면검사조건이거짓이되면서아래구문을수행한다. 35. : UDR0에 s 이라는 ASCII값을써준다. 코드값은 0x73이다. 36. : USART0 의전송버퍼 UDR0의데이터를쓸수있는지검사한다. 37. : UDR0에 e 이라는 ASCII값을써준다. 코드값은 0x65이다. 38. : USART0 의전송버퍼 UDR0의데이터를쓸수있는지검사한다. 39. : UDR0에 c 이라는 ASCII값을써준다. 코드값은 0x63이다. 40. : USART0 의전송버퍼 UDR0의데이터를쓸수있는지검사한다. 41. : UDR0에 o 이라는 ASCII값을써준다. 코드값은 0x6f이다. 42. : USART0 의전송버퍼 UDR0의데이터를쓸수있는지검사한다. 43. : UDR0에 n 이라는 ASCII값을써준다. 코드값은 0x6e이다. 44. : USART0 의전송버퍼 UDR0의데이터를쓸수있는지검사한다. 45. : UDR0에 n 이라는 ASCII값을써준다. 코드값은 0x64이다. 46. : time_interval 값을 0 으로초기화하여, 다음또메인함수의루프가돌때다시 1초를만들어주기위한시간을검사할수있도록시간을초기화해준다. 나. 하이퍼터미널을이용하여로봇제어하기 하이퍼터미널이란프로그램은 Serial 통신을지원하며 TCP/IP도지원한다. 윈도우기반의 C++ 또는 C# 으로통신프로그램을개발하여로봇과의통신테스트를진행하지만먼저간단한기본적인테스트는보통하이퍼터미널을이용한다. Window XP OS는하이퍼터미널이기본프로그램으로등록되어있어바로사용할수있지만 Window 7에서는제공하지않아외부에서다운받아사용한다. 로봇을사용하기에앞서먼저준비해야할것은 USB To Serial 케이블또는사용자의컴퓨터에 Serial 단자가존재한다면 Serial To Serial 케이블을준비하여로봇에연결한다. 단, 그림 8.18과같이 Serial 단자는수놈이어야한다. [ 그림 8.18] Serial 단자

하이퍼터미널프로그램을실행하면그림 8.19 와같이나타나며, 로봇과커넥션하 기위해커넥션이름을입력한다. [ 그림 8.19] 하이퍼터미널프로그램 그림 8.20 과같이현재연결된 Serial 케이블의 ComPort 를선택하고통신속도외 에설정값을선택하여 확인 버튼을클릭한다. [ 그림 8.20] 하이퍼터미널프로그램커넥션설정 만약연결된케이블의 ComPort 를모른다면그림 8.21 과같이오른쪽클릭한다. [ 그림 8.21] 내컴퓨터오른쪽클릭

다음으로그림 8.22 와같이 장치관리자 를클릭한다. [ 그림 8.22] 내컴퓨터오른쪽클릭 장치관리자를보면포트 (COM & LPT) 가있으며, 활성화시키면그림 8.23 과같 이나타난다. CRX10 에는블루투스가장착되어있어컴퓨터에블루투스동글을연결 하여사용해도무방하다. 블루투스동글을이용할시 유선케이블을이용할시 [ 그림 8.23] 내컴퓨터오른쪽클릭 그림 8.24 와같이연결이완료된모습을볼수있다. [ 그림 8.24] 내컴퓨터오른쪽클릭

간단한 Serial 통신예제를이용하여로봇을제어해보자. 1) 활용실습 Q : 8.1_ 문자 A 를하이퍼터미널출력창에출력하기 A : #include <avr/io.h> #include <avr/iom128.h> #include <avr/interrupt.h> #include <avr/signal.h> volatile unsigned char u8_make_time_var; unsigned char u8_usart_receive_data; SIGNAL(SIG_OVERFLOW0) TCNT0 = 0xff - 115; u8_make_time_var++; SIGNAL(SIG_UART0_RECV) u8_usart_receive_data = UDR0; void port_initial() DDRA = 0xff; DDRB = 0xf7; DDRC = 0xff; DDRD = 0x00; DDRE = 0xfb; DDRF = 0x00; DDRG = 0x00;

void basic_timer_initial(void) TCCR0 = 0x06; TCNT0 = 0xff - 115; TIMSK = 0x01; void uart_initial(void) UBRR0H = 0; UBRR0L = 7; UCSR0A = (0<<RXC0) (1<<UDRE0); UCSR0B = 0x98; UCSR0C = 0x06; void usart_tx_data(unsigned char tx_data) while((ucsr0a & 0x20) == 0x00); UDR0 = tx_data; void make_time(void) while(u8_make_time_var <= 50) u8_make_time_var = 0; int main(void) unsigned char uartdata; cli(); port_initial(); basic_timer_initial(); uart_initial(); sei();

make_time(); make_time(); make_time(); uartdata='a'; while(1) usart_tx_data(uartdata); make_time(); Q : 8.2_ 3 개의 PSD 센서의데이터를하이퍼터미널에출력하기 A : #include <avr/io.h> #include <avr/iom128.h> #include <avr/interrupt.h> #include <avr/signal.h> volatile unsigned char u8_make_time_var; unsigned char u8_usart_receive_data; unsigned char adc_result[3]; SIGNAL(SIG_OVERFLOW0) TCNT0 = 0xff - 115; u8_make_time_var++; SIGNAL(SIG_UART0_RECV) u8_usart_receive_data = UDR0;

void port_initial() DDRA = 0xff; DDRB = 0xf7; DDRC = 0xff; DDRD = 0x00; DDRE = 0xfb; DDRF = 0x00; DDRG = 0x00; void basic_timer_initial(void) TCCR0 = 0x06; TCNT0 = 0xff - 115; TIMSK = 0x01; void uart_initial(void) UBRR0H = 0; UBRR0L = 7; UCSR0A = (0<<RXC0) (1<<UDRE0); UCSR0B = 0x98; UCSR0C = 0x06; void adc_initial(void) ADCSRA = 0x86; void usart_tx_data(unsigned char tx_data) while((ucsr0a & 0x20) == 0x00); UDR0 = tx_data;

void adc_read(void) ADCSRA &= 0x7f; ADMUX = 0x20; ADCSRA = 0xc0; while((adcsra & 0x10)!= 0x10); adc_result[0] = ADCL; adc_result[0] = ADCH; void make_time(void) while(u8_make_time_var <= 50) u8_make_time_var = 0; int main(void) unsigned char uartdata; cli(); port_initial(); basic_timer_initial(); uart_initial(); sei(); make_time(); make_time(); make_time(); uartdata=','; while(1) adc_read(); usart_tx_data(adc_result[0]); usart_tx_data(uartdata); usart_tx_data(adc_result[1]); usart_tx_data(uartdata);

usart_tx_data(adc_result[2]); usart_tx_data(uartdata); make_time(); Q : 8.3_ PSD 센서의데이터를 Cm 로변환하여하이퍼터미널출력창에출력 하기 A : #include <avr/io.h> #include <avr/iom128.h> #include <avr/interrupt.h> #include <avr/signal.h> volatile unsigned char u8_make_time_var; unsigned char u8_usart_receive_data; unsigned char adc_result[3]; SIGNAL(SIG_OVERFLOW0) TCNT0 = 0xff - 115; u8_make_time_var++; SIGNAL(SIG_UART0_RECV) u8_usart_receive_data = UDR0; void port_initial() DDRA = 0xff; DDRB = 0xf7;

DDRC = 0xff; DDRD = 0x00; DDRE = 0xfb; DDRF = 0x00; DDRG = 0x00; void basic_timer_initial(void) TCCR0 = 0x06; TCNT0 = 0xff - 115; TIMSK = 0x01; void uart_initial(void) UBRR0H = 0; UBRR0L = 7; UCSR0A = (0<<RXC0) (1<<UDRE0); UCSR0B = 0x98; UCSR0C = 0x06; void adc_initial(void) ADCSRA = 0x86; void usart_tx_data(unsigned char tx_data) while((ucsr0a & 0x20) == 0x00); UDR0 = tx_data; void adc_read(void) ADCSRA &= 0x7f;

ADMUX = 0x20; ADCSRA = 0xc0; while((adcsra & 0x10)!= 0x10); adc_result[0] = ADCL; adc_result[0] = ADCH; ADCSRA &= 0x7f; ADMUX = 0x21; ADCSRA = 0xc0; while((adcsra & 0x10)!= 0x10); adc_result[1] = ADCL; adc_result[1] = ADCH; ADCSRA &= 0x7f; ADMUX = 0x22; ADCSRA = 0xc0; while((adcsra & 0x10)!= 0x10); adc_result[2] = ADCL; adc_result[2] = ADCH; void make_time(void) while(u8_make_time_var <= 50) u8_make_time_var = 0; double PSDADC(double adc) double k, returnk; int k1; k = 5 * adc / 255; if (k >= 1.3) k1 = (int)(-(k - 3.87) * 14 / 1.8); else if (k >= 0.9 && k < 1.3)

k1 = (int)(-(k - 2.1) * 10 / 0.4); else if (k >= 0.5 && k < 0.9) k1 = (int)(-(k - 1.3) * 30 / 0.4); else if (k >= 0.4 && k < 0.5) k1 = (int)(-(k - 0.95) * 20 / 0.15); else k1 = 80; returnk = (double)k1; return returnk; int main(void) unsigned char uartdata; cli(); port_initial(); basic_timer_initial(); uart_initial(); sei(); make_time(); make_time(); make_time(); uartdata=','; while(1) adc_read(); usart_tx_data((int)psdadc(adc_result[0])); usart_tx_data(uartdata); usart_tx_data((int)psdadc(adc_result[1]));

usart_tx_data(uartdata); usart_tx_data((int)psdadc(adc_result[2])); usart_tx_data(uartdata); make_time(); Q : 8.4_ 로봇에장착된 4 개의버튼을 1, 2, 3, 4 로지정하여 버튼을눌렀을때하이퍼터미널출력창에출력하기 A : #include <avr/io.h> #include <avr/iom128.h> #include <avr/interrupt.h> #include <avr/signal.h> volatile unsigned char u8_make_time_var; unsigned char u8_usart_receive_data; unsigned char u8_io_read; SIGNAL(SIG_OVERFLOW0) TCNT0 = 0xff - 115; u8_make_time_var++; SIGNAL(SIG_UART0_RECV) u8_usart_receive_data = UDR0; void port_initial() DDRA = 0xff;

DDRB = 0xf7; DDRC = 0xff; DDRD = 0x00; DDRE = 0xfb; DDRF = 0x00; DDRG = 0x00; void basic_timer_initial(void) TCCR0 = 0x06; TCNT0 = 0xff - 115; TIMSK = 0x01; void uart_initial(void) UBRR0H = 0; UBRR0L = 7; UCSR0A = (0<<RXC0) (1<<UDRE0); UCSR0B = 0x98; UCSR0C = 0x06; void adc_initial(void) ADCSRA = 0x86; void port_read(void) u8_io_read = PIND & 0xf0; void usart_tx_data(unsigned char tx_data) while((ucsr0a & 0x20) == 0x00);

UDR0 = tx_data; void make_time(void) while(u8_make_time_var <= 50) u8_make_time_var = 0; int main(void) unsigned char uartdata; cli(); port_initial(); basic_timer_initial(); uart_initial(); sei(); make_time(); make_time(); make_time(); uartdata='a'; while(1) port_read(); usart_tx_data(u8_io_read); make_time(); Q : 8.5_ 키보드에서 C 를입력하며로봇의도트매트릭스에서 C 를출력 하기 A : #include <avr/io.h>

#include <avr/iom128.h> #include <avr/interrupt.h> #include <avr/signal.h> #include<util/delay.h> volatile unsigned char u8_make_time_var; unsigned char u8_usart_receive_data; unsigned char u8_io_read; #define dot_o 0 #define dot_x 1 #define dot_c 2 unsigned char ccc[8] = 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 ; unsigned char row[3][8] = 0x3C,0x7E,0xC3,0xC3,0xC3,0xC3,0x7E,0x3C, 0x81,0xC3,0x66,0x3C,0x3C,0x66,0xC3,0x81, 0x3C,0x7E,0xC3,0xC3,0xC3,0xC3,0x66,0x66 ; void print(int n,int time) int i,l; for(l=0;l<time;l++) for(i=0;i<8;i++) PORTA=ccc[i]; PORTC=row[n][i]; _delay_ms(1); SIGNAL(SIG_OVERFLOW0) TCNT0 = 0xff - 115; u8_make_time_var++; SIGNAL(SIG_UART0_RECV) u8_usart_receive_data = UDR0;

void port_initial() DDRA = 0xff; DDRB = 0xf7; DDRC = 0xff; DDRD = 0x00; DDRE = 0xfb; DDRF = 0x00; DDRG = 0x00; void basic_timer_initial(void) TCCR0 = 0x06; TCNT0 = 0xff - 115; TIMSK = 0x01; void uart_initial(void) UBRR0H = 0; UBRR0L = 7; UCSR0A = (0<<RXC0) (1<<UDRE0); UCSR0B = 0x98; UCSR0C = 0x06; void adc_initial(void) ADCSRA = 0x86; void port_read(void) u8_io_read = PIND & 0xf0;

void usart_tx_data(unsigned char tx_data) while((ucsr0a & 0x20) == 0x00); UDR0 = tx_data; void make_time(void) while(u8_make_time_var <= 50) u8_make_time_var = 0; int main(void) unsigned char uartdata; cli(); port_initial(); basic_timer_initial(); uart_initial(); sei(); make_time(); make_time(); make_time(); uartdata='a'; while(1) if(u8_usart_receive_data=='c') print( dot_c, 500); make_time();

Q : 8.6_ 키보드의방향키중 W 를누르면로봇이전진하게하기 A : #include <avr/io.h> #include <avr/iom128.h> #include <avr/interrupt.h> #include <avr/signal.h> #include<util/delay.h> volatile unsigned char u8_make_time_var; volatile unsigned int cnt; unsigned char adc_result[8]; unsigned char u8_usart_receive_data; SIGNAL(SIG_OVERFLOW0) TCNT0 = 0xff - 115; u8_make_time_var++; SIGNAL(SIG_UART0_RECV) u8_usart_receive_data = UDR0; void port_initial() DDRA = 0xff; DDRB = 0xf7; DDRC = 0xff; DDRD = 0x00; DDRE = 0xfb; DDRF = 0x00; DDRG = 0x00;

void basic_timer_initial(void) TCCR0 = 0x06; TCNT0 = 0xff - 115; TIMSK = 0x01; void uart_initial(void) UBRR0H = 0; UBRR0L = 7; UCSR0A = (0<<RXC0) (1<<UDRE0); UCSR0B = 0x98; UCSR0C = 0x06; void pwm_initial(void) TCCR1A = 0xa2; TCCR1B = 0x19; TCCR1C = 0x00; ICR1 = 200; OCR1A = 0; OCR1B = 0; OCR1C = 0; TCCR3A = 0xc2; TCCR3B = 0x1a; TCCR3C = 0x00; ICR3 = 1000; OCR3A = 500; OCR3B = 100; OCR3C = 0; void usart_tx_data(unsigned char tx_data)

while((ucsr0a & 0x20) == 0x00); UDR0 = tx_data; void motor_r_foward(void) PORTE = PORTE & 0x3f; PORTE = PORTE 0x80; void motor_r_back(void) PORTE = PORTE & 0x3f; PORTE = PORTE 0x40; void motor_l_foward(void) PORTG = PORTG & 0xe7; PORTG = PORTG 0x08; void motor_l_back(void) PORTG = PORTG & 0xe7; PORTG = PORTG 0x10; void Motor_control_Forwards(unsigned char right, unsigned char left) motor_r_foward(); motor_l_foward(); OCR1A = right; OCR1B = left; void Motor_control_Backwards(unsigned char right, unsigned char left)

motor_r_back(); motor_l_back(); OCR1A = right; OCR1B = left; void Motor_control_Left(unsigned char right, unsigned char left) motor_r_foward(); motor_l_back(); OCR1A = right; OCR1B = left; void Motor_control_Right(unsigned char right, unsigned char left) motor_r_back(); motor_l_foward(); OCR1A = right; OCR1B = left; void make_time(void) while(u8_make_time_var <= 50) u8_make_time_var = 0; cnt++; int main(void) cli(); port_initial();

basic_timer_initial(); pwm_initial(); uart_initial(); sei(); make_time(); make_time(); while(1) if(u8_usart_receive_data=='w') Motor_control_Forwards(130,130); else Motor_control_Forwards(0,0); make_time(); Q : 8.7_ 키보드의방향키중 S 를누르면로봇이후진하게하기 A : #include <avr/io.h> #include <avr/iom128.h> #include <avr/interrupt.h> #include <avr/signal.h> #include<util/delay.h> volatile unsigned char u8_make_time_var; volatile unsigned int cnt; unsigned char adc_result[8]; unsigned char u8_usart_receive_data;

SIGNAL(SIG_OVERFLOW0) TCNT0 = 0xff - 115; u8_make_time_var++; SIGNAL(SIG_UART0_RECV) u8_usart_receive_data = UDR0; void port_initial() DDRA = 0xff; DDRB = 0xf7; DDRC = 0xff; DDRD = 0x00; DDRE = 0xfb; DDRF = 0x00; DDRG = 0x00; void basic_timer_initial(void) TCCR0 = 0x06; TCNT0 = 0xff - 115; TIMSK = 0x01; void uart_initial(void) UBRR0H = 0; UBRR0L = 7; UCSR0A = (0<<RXC0) (1<<UDRE0); UCSR0B = 0x98; UCSR0C = 0x06;

void pwm_initial(void) TCCR1A = 0xa2; TCCR1B = 0x19; TCCR1C = 0x00; ICR1 = 200; OCR1A = 0; OCR1B = 0; OCR1C = 0; TCCR3A = 0xc2; TCCR3B = 0x1a; TCCR3C = 0x00; ICR3 = 1000; OCR3A = 500; OCR3B = 100; OCR3C = 0; void usart_tx_data(unsigned char tx_data) while((ucsr0a & 0x20) == 0x00); UDR0 = tx_data; void motor_r_foward(void) PORTE = PORTE & 0x3f; PORTE = PORTE 0x80; void motor_r_back(void) PORTE = PORTE & 0x3f; PORTE = PORTE 0x40;

void motor_l_foward(void) PORTG = PORTG & 0xe7; PORTG = PORTG 0x08; void motor_l_back(void) PORTG = PORTG & 0xe7; PORTG = PORTG 0x10; void Motor_control_Forwards(unsigned char right, unsigned char left) motor_r_foward(); motor_l_foward(); OCR1A = right; OCR1B = left; void Motor_control_Backwards(unsigned char right, unsigned char left) motor_r_back(); motor_l_back(); OCR1A = right; OCR1B = left; void Motor_control_Left(unsigned char right, unsigned char left) motor_r_foward(); motor_l_back(); OCR1A = right; OCR1B = left;

void Motor_control_Right(unsigned char right, unsigned char left) motor_r_back(); motor_l_foward(); OCR1A = right; OCR1B = left; void make_time(void) while(u8_make_time_var <= 50) u8_make_time_var = 0; cnt++; int main(void) cli(); port_initial(); basic_timer_initial(); pwm_initial(); uart_initial(); sei(); make_time(); make_time(); while(1) if(u8_usart_receive_data=='s') Motor_control_Backwards(130,130); else

Motor_control_Forwards(0,0); make_time(); Q : 8.8_ 키보드의방향키중 A 를누르면로봇이좌로회전하게하기 A : #include <avr/io.h> #include <avr/iom128.h> #include <avr/interrupt.h> #include <avr/signal.h> #include<util/delay.h> volatile unsigned char u8_make_time_var; volatile unsigned int cnt; unsigned char adc_result[8]; unsigned char u8_usart_receive_data; SIGNAL(SIG_OVERFLOW0) TCNT0 = 0xff - 115; u8_make_time_var++; SIGNAL(SIG_UART0_RECV) u8_usart_receive_data = UDR0; void port_initial()

DDRA = 0xff; DDRB = 0xf7; DDRC = 0xff; DDRD = 0x00; DDRE = 0xfb; DDRF = 0x00; DDRG = 0x00; void basic_timer_initial(void) TCCR0 = 0x06; TCNT0 = 0xff - 115; TIMSK = 0x01; void uart_initial(void) UBRR0H = 0; UBRR0L = 7; UCSR0A = (0<<RXC0) (1<<UDRE0); UCSR0B = 0x98; UCSR0C = 0x06; void pwm_initial(void) TCCR1A = 0xa2; TCCR1B = 0x19; TCCR1C = 0x00; ICR1 = 200; OCR1A = 0; OCR1B = 0; OCR1C = 0; TCCR3A = 0xc2;

TCCR3B = 0x1a; TCCR3C = 0x00; ICR3 = 1000; OCR3A = 500; OCR3B = 100; OCR3C = 0; void usart_tx_data(unsigned char tx_data) while((ucsr0a & 0x20) == 0x00); UDR0 = tx_data; void motor_r_foward(void) PORTE = PORTE & 0x3f; PORTE = PORTE 0x80; void motor_r_back(void) PORTE = PORTE & 0x3f; PORTE = PORTE 0x40; void motor_l_foward(void) PORTG = PORTG & 0xe7; PORTG = PORTG 0x08; void motor_l_back(void) PORTG = PORTG & 0xe7; PORTG = PORTG 0x10;

void Motor_control_Forwards(unsigned char right, unsigned char left) motor_r_foward(); motor_l_foward(); OCR1A = right; OCR1B = left; void Motor_control_Backwards(unsigned char right, unsigned char left) motor_r_back(); motor_l_back(); OCR1A = right; OCR1B = left; void Motor_control_Left(unsigned char right, unsigned char left) motor_r_foward(); motor_l_back(); OCR1A = right; OCR1B = left; void Motor_control_Right(unsigned char right, unsigned char left) motor_r_back(); motor_l_foward(); OCR1A = right; OCR1B = left; void make_time(void)

while(u8_make_time_var <= 50) u8_make_time_var = 0; cnt++; int main(void) cli(); port_initial(); basic_timer_initial(); pwm_initial(); uart_initial(); sei(); make_time(); make_time(); while(1) if(u8_usart_receive_data=='a') Motor_control_Left(130,130); else Motor_control_Forwards(0,0); make_time(); Q : 8.9_ 키보드의방향키중 D 를누르면로봇이우로회전하게하기 A : #include <avr/io.h>

#include <avr/iom128.h> #include <avr/interrupt.h> #include <avr/signal.h> #include<util/delay.h> volatile unsigned char u8_make_time_var; volatile unsigned int cnt; unsigned char adc_result[8]; unsigned char u8_usart_receive_data; SIGNAL(SIG_OVERFLOW0) TCNT0 = 0xff - 115; u8_make_time_var++; SIGNAL(SIG_UART0_RECV) u8_usart_receive_data = UDR0; void port_initial() DDRA = 0xff; DDRB = 0xf7; DDRC = 0xff; DDRD = 0x00; DDRE = 0xfb; DDRF = 0x00; DDRG = 0x00; void basic_timer_initial(void) TCCR0 = 0x06; TCNT0 = 0xff - 115; TIMSK = 0x01;

void uart_initial(void) UBRR0H = 0; UBRR0L = 7; UCSR0A = (0<<RXC0) (1<<UDRE0); UCSR0B = 0x98; UCSR0C = 0x06; void pwm_initial(void) TCCR1A = 0xa2; TCCR1B = 0x19; TCCR1C = 0x00; ICR1 = 200; OCR1A = 0; OCR1B = 0; OCR1C = 0; TCCR3A = 0xc2; TCCR3B = 0x1a; TCCR3C = 0x00; ICR3 = 1000; OCR3A = 500; OCR3B = 100; OCR3C = 0; void usart_tx_data(unsigned char tx_data) while((ucsr0a & 0x20) == 0x00); UDR0 = tx_data; void motor_r_foward(void)

PORTE = PORTE & 0x3f; PORTE = PORTE 0x80; void motor_r_back(void) PORTE = PORTE & 0x3f; PORTE = PORTE 0x40; void motor_l_foward(void) PORTG = PORTG & 0xe7; PORTG = PORTG 0x08; void motor_l_back(void) PORTG = PORTG & 0xe7; PORTG = PORTG 0x10; void Motor_control_Forwards(unsigned char right, unsigned char left) motor_r_foward(); motor_l_foward(); OCR1A = right; OCR1B = left; void Motor_control_Backwards(unsigned char right, unsigned char left) motor_r_back(); motor_l_back(); OCR1A = right; OCR1B = left;

void Motor_control_Left(unsigned char right, unsigned char left) motor_r_foward(); motor_l_back(); OCR1A = right; OCR1B = left; void Motor_control_Right(unsigned char right, unsigned char left) motor_r_back(); motor_l_foward(); OCR1A = right; OCR1B = left; void make_time(void) while(u8_make_time_var <= 50) u8_make_time_var = 0; cnt++; int main(void) cli(); port_initial(); basic_timer_initial(); pwm_initial(); uart_initial(); sei(); make_time(); make_time();

while(1) if(u8_usart_receive_data=='d') Motor_control_Right(130,130); else Motor_control_Forwards(0,0); make_time(); Q : 8.10_ 키보드의방향키를조이스틱으로활용하여로봇을자유롭게움직이 기 A : #include <avr/io.h> #include <avr/iom128.h> #include <avr/interrupt.h> #include <avr/signal.h> #include<util/delay.h> volatile unsigned char u8_make_time_var; volatile unsigned int cnt; unsigned char adc_result[8]; unsigned char u8_usart_receive_data; SIGNAL(SIG_OVERFLOW0) TCNT0 = 0xff - 115; u8_make_time_var++;

SIGNAL(SIG_UART0_RECV) u8_usart_receive_data = UDR0; void port_initial() DDRA = 0xff; DDRB = 0xf7; DDRC = 0xff; DDRD = 0x00; DDRE = 0xfb; DDRF = 0x00; DDRG = 0x00; void basic_timer_initial(void) TCCR0 = 0x06; TCNT0 = 0xff - 115; TIMSK = 0x01; void uart_initial(void) UBRR0H = 0; UBRR0L = 7; UCSR0A = (0<<RXC0) (1<<UDRE0); UCSR0B = 0x98; UCSR0C = 0x06; void pwm_initial(void) TCCR1A = 0xa2; TCCR1B = 0x19;

TCCR1C = 0x00; ICR1 = 200; OCR1A = 0; OCR1B = 0; OCR1C = 0; TCCR3A = 0xc2; TCCR3B = 0x1a; TCCR3C = 0x00; ICR3 = 1000; OCR3A = 500; OCR3B = 100; OCR3C = 0; void usart_tx_data(unsigned char tx_data) while((ucsr0a & 0x20) == 0x00); UDR0 = tx_data; void motor_r_foward(void) PORTE = PORTE & 0x3f; PORTE = PORTE 0x80; void motor_r_back(void) PORTE = PORTE & 0x3f; PORTE = PORTE 0x40; void motor_l_foward(void) PORTG = PORTG & 0xe7; PORTG = PORTG 0x08;

void motor_l_back(void) PORTG = PORTG & 0xe7; PORTG = PORTG 0x10; void Motor_control_Forwards(unsigned char right, unsigned char left) motor_r_foward(); motor_l_foward(); OCR1A = right; OCR1B = left; void Motor_control_Backwards(unsigned char right, unsigned char left) motor_r_back(); motor_l_back(); OCR1A = right; OCR1B = left; void Motor_control_Left(unsigned char right, unsigned char left) motor_r_foward(); motor_l_back(); OCR1A = right; OCR1B = left; void Motor_control_Right(unsigned char right, unsigned char left) motor_r_back();

motor_l_foward(); OCR1A = right; OCR1B = left; void make_time(void) while(u8_make_time_var <= 50) u8_make_time_var = 0; cnt++; 2) 응용문제 1 시리얼통신을이용하여두개의숫자를 PC 에서전송하고, 마이크로컨트롤러 는두개의수신데이터의차를구해서다시 PC 에전송하기 2 로봇에장착된 4 개의버튼을 1, 2, 3, 4 로지정하여버튼을 눌렀을때하이퍼터미널출력창에출력하기 3 키보드에서 C 를입력하며로봇의도트매트릭스에서 C 를출력하기 4 키보드의 W 를누르면로봇이전진하게하기 5 키보드의 S 를누르면로봇이후진하게하기 6 키보드의 A 를누르면로봇이좌로회전하게하기 7 키보드의 D 를누르면로봇이우로회전하게하기 8 키보드의활용하여로봇을자유롭게움직이기