ATmega8535 – 시리얼통신 (UART)

Code Vison AVR C

ATmega 8535

 

RS232 시리얼 통신

 

컨넥터와 신호선

RS232 통신을 위한 컨넥터는 9핀과 25핀 컨넥터가 있으나, 최근에는 9핀 컨넥터를 많이 사용한다. 실제 데이터가 송 수신 되는 핀은 TXD(3) 와 RXD(2) 이고 기능은 다음과 같다.

9핀 컨넥터의 모습

 

TXD – Transmit Data

비동기식 직렬 통신 장치가 외부 장치로 데이터를 보낼 때, 직렬 통신 데이터가 나오는 신호선

RXD – Receive Data

외부 장치에서 들어오는 직렬 통신 데이터를 입력받는 신호선

케이블을 만들 때에는 반대쪽 커넥터에 연결하기 전에 한번 교차 시켜야 한다. (Rx ->Tx , Tx->Rx)

ATmega8535에서의 RXD, TXD

MAX232

 

MAXIM사에서 생산되는 RS-232통신을 가능토록 해주는 송수신 IC이다. 송수신 드라이브를 각각 2개씩 가지고 있다.

AVR과 컴퓨터가 인식하는 0과 1의 값이 다르기 때문에..

 

마이컴

컴퓨터

0

0V

-10V

1

5V

10V

이 차이를 해결해주는 것이다.

 

TTL IC의 전원단자와 다르게 15번 핀이 GND, 16번이 VCC이므로 주의하자

 

 

IC 내부에는 VOLTAGE DOUBLER와 VOLTAGE INVERTER가 있다.

DOUBLER는 5V를 10V로 증폭 INVERTER는 증폭된 신호를 반전

내부에 5V를 충전했다 10V로 보내기 위한 콘덴서가 있다.

 

MAX232는 전압을 바꾸어 주는 역할만을 하며 통신을 하는것은 아님에 주의!

 

 

 

프레임 형식

 

직렬 데이터 프레임은 동기비트 (스타트, 스톱 비트) 와 에러 검사를 위한 패리티 비트(선택가능)와 데이터 비트를 포함하는 1문자를 의미한다.

 

컴퓨터 쪽에서는 다음과 같이 설정한다.

 

 

보레이트 9600 데이터 비트는 8비트 패리티 비트 사용 안 함 STOP비트는 1로 설정한 모습

 

시리얼 통신을 위한 레지스터

 

ATmega8535에는 시리얼 통신용 컨트롤러가 포함 되어 있다.

CPU 내부에서 CPU의 코어 부분과 시리얼 통신용 컨트롤러가 데이터를 주고 받고, 컨트롤러는 RxD, TxD의 핀을 통해 외부와 통신을 하고 있다.

시리얼 통신을 위한 레지스터에는 설정용 레지스터와 데이터 통신용 레지스터가 있고 설정용 레지스터를 이용해 설정을 하고 통신용 레지스터를 이용해 실제 통신을 한다

 

 

UDR

7

6

5

4

3

2

1

0

RXB (Read)

TXB (Write)

 

UDR레지스터는 데이터를 입력하면 설정한 값에 맞게 데이터를 전송하는 레지스터이다.

UDR레지스터를 읽으면 수신 데이터 버퍼 레지스터(RXD)의 내용을 볼수 있다. 즉, 송신 데이터를 UDR레지스터에 쓰기하면 송신데이터 버퍼 (TXB)에 저장하고, 수신 데이터를 UDR 레지스터에 쓰기하면 수신 데이터 버퍼(RXB)에 수신되어 있는 값이 읽혀진다.

 

 

 

UCSR 레지스터

UCSR은 A,B,C세 개로 구성 되어 있고, 상태 설정과 제어의 기능을 한다.

 

UCSRA

7

6

5

4

3

2

1

0

RXC

TXC

UDRE

FE

DOR

PE

U2X

MPCM

7. RXC : 수신 완료 표시 비트

6. TXC : 송신 완료 표시 비트

5. UDRE : 송신 데이터 레지스터 준비 완료 표시 비트

4. FE : 프레임 에러 표시 비트

3. DOR : 데이터 오버런 에러 표시 비트

2. PE : 패리티 에러 표시 비트

1. USX : 송신 속도 2배 설정

0. MPCM : 멀티 프로세서 통신 모드

    *1번과 0번을 설정하고 나머지는 읽기 전용이다. (사용 할 때 1 아닐 때 0)

 

UCSRB

7

6

5

4

3

2

1

0

RXCIE

TXCIE

UDRIE

RXEN

TXEN

UCSZ2

RXB8

TXB8

7. RXCIE 수신 완료 인터럽트 인에이블 비트

6. TXCIE 송신 완료 인터럽트 인에이블 비트

5. UDRIE 송신 데이터 레지스터 준비 완료 인터럽트 인에이블 비트

4. RXEN 수신기 인에이블

3. TXEN 송신기 인에이블

2. UCSZ2 전송 데이터 길이 선택 비트

1. RXB8 수신 데이터 비트 8

0. TXB8 송신 데이터 비트 8

 

UCSRC

7

6

5

4

3

2

1

0

URSEL

UMSEL

UPM1

UPM0

USBS

UCSZ1

UCSZ0

UCPOL

7. UREL 레지스터 선택 비트

6. UMSEL 시리얼 통신 모드 설정 비트

5. UPM1 패리티 모드 설정 비트

4. UPM0 패리티 모드 설정 비트

3. USBS 정지 비트 선택

2. UCSZ1 전송 데이터 비트 수 설정

1. UCSZ0 전송 데이터 비트 수 설정

0. UCPOL 클럭 극성 선택

 

보레이트 속도 설정 관련 레지스터

 

보레이트 – 신호 하나의 속도

보레이트 속도를 조절 하는 레지스터는 UBRRH와 UBRRL 2개로 이루어져 있다. UBRRH의 4비트와 UBRRL의 8비트를 합친 12비트를 이용하여 속도를 설정한다.

 

UBBRH

7

6

5

4

3

2

1

0

URSEL

사용하지 않음 ( 0 )

UBRR의 값 (11 ~8 비트)

 

UBBRL

7

6

5

4

3

2

1

0

UBRR의 값 (7 ~0 비트)

 

UBRRH는 UCSRC레지스터와 같은 번지를 사용 하고 있다. 그렇기 때문에 UCSRC로 사용 할 것인지 UBRRH로 사용 할 것인지 선택을 해야 하는데, 이 기능을 하는 것이 7번 URSEL비트이다.

URSEL이 0일 때 UBRRH의 기능을 갖고 1일 때 UCSRC의 기능을 갖는다.

 

UBRR의 값은 보레이트와 시스템 클럭을 이용하여 계산 한다.

예를 들어 시스템 클럭이 16Mhz 이고 보레이트를 9600 bps로 잡았을 때

 

UBRR의 값은 103.1666…. 이 된다.

여기서 소수점 이하를 버리고 103을 2진수로 변환하면 1100111이 된다.

결국 UBRRH의 4 비트에는 모두 0이 들어가고 UBRRL에는 01100111이 들어가므로, 다음과 같이 입력 한다.

    UBRRH=0;

    UBRRH=103;    //물론 0b01100111으로도
입력
가능하다.

 

데이터 전송 레지스터

 

직렬 통신에 사용하는 입출력 함수

 

void puts(char *str)

 

외부로 SRAM의 문자열을 출력 하는 기능을 가진다. 문자열의 끝 부분에는 null(0x0A)를 추가하여 출력한다. null 문자는 터미널 화면에서 줄바꾸기를 한다.

하지만 줄의 맨 앞이 아닌 최종 출력지점의 바로 다음 줄로 출력 된다.

 

Ex)    Hello NClab!

         Hello NClab!

 

터미널의 제일 첫줄로 줄바꿈을 하기 위해서는 제어 문자인 “r”=>”0x0D+0x0A”를 끝 부분에 첨가하거나 다음 문장에 “0x0D”를 출력 하여 커서를 맨앞으로 이동 시킨다.

 

void putsf(char flash *str)

 

외부로 Flash의 문자열을 출력 하는 기능을 가진다.

줄바꿈 형식은 puts와 동일

 

void printf(char flash *fmtstr [,arg1,arg2,….])

fmtstr 문자열에 있는 문자열을 출력 하는 기능을 가진다. 특히, fmtstr은 상수이며 Flash 메모리에 위치해 있어야 한다.

Ex) int_val = 112;

    printf(“Interger value =%5i”, int_val);

    // %5i 는 5칸에 정수를 출력 하라는 뜻

 

 

직렬 통신 프로그램

 

출력 함수들을 사용해보자

 

#include <mega8535.h>

#include <stdio.h>

 

void rs232_putchar(void)        //한글자씩
출력하는 putchar()
사용한
함수

{

putchar(‘I’);

putchar(‘ ‘);

putchar(‘L’);

putchar(‘O’);

putchar(‘V’);

putchar(‘E’);

putchar(‘ ‘);

putchar(‘N’);

putchar(‘C’);

putchar(0x0A);        //줄바꿈

putchar(0x0D);        //커서
제일
앞으로

}

 

 

void main(void)

{

char data[] = “I LOVE NC 2”;    //SRAM
문자열을
출력
하기
위한
문자열
배열

 

// USART initialization

// Communication Parameters: 8 Data, 1 Stop, No Parity

// USART Receiver: On

// USART Transmitter: On

// USART Mode: Asynchronous

// USART Baud Rate: 9600

UCSRA=0x00;

UCSRB=0x18;

UCSRC=0x86;

UBRRH=0x00;

UBRRL=0x33;

 

    rs232_putchar();    //한글자씩
출력
하는
함수
호출

    

    puts(data);    //SRAM
문자열
출력

    putchar(0x0D);    //줄바꿈

 

    putsf(“I LOVE NC 3 r”);    //Flash
문자열
출력 (줄바꿈
문자 r)포함

}

 

결과

I LOVE NC

I LOVE NC 2

I LOVE NC 3

 

 

입력은 어떻게 받는지 알아보자

 

#include <mega8535.h>

#include <stdio.h>

 

unsigned char rx_data;        //수신된
문자를
받기
위한
전역
변수

 

void led_control(void)

{

rx_data = getchar();    //getchar()
수신
데이터를
받는
함수
이다(UDR).

putchar(rx_data);        //받은
문자를
출력
함으로써
에코
효과

switch (rx_data) {    //받은
문자에
따라
행동

case 0x30: PORTA = 0x00;        //0X30 ‘0’
해당하는 ASCII코드임

break;                //’0′일때 PORTA 0
출력

case 0x31: PORTA = 0x01;        //0X31 ‘1’
해당하는 ASCII코드임

break;

case 0x32: PORTA = 0x02;        //0X32 ‘2’
해당하는 ASCII코드임

break;

case ‘3’: PORTA = 0x03;    //직접 ‘3’이라는
문자를
적어


있음


break;

case ‘4’ :PORTA = 0x04;

break;

case ‘5’: PORTA = 0x05;

break;

case ‘6’: PORTA = 0b00110011;    //물론
출력은 2진수로도
쓸수
있다.

break;

default: PORTA = 0x00;

};

}

 

void main(void)

{

PORTA=0x00;

DDRA=0xFF;        //PORTA
모두
출력
모드

 

// USART initialization

// Communication Parameters: 8 Data, 1 Stop, No Parity

// USART Receiver: On

// USART Transmitter: On

// USART Mode: Asynchronous

// USART Baud Rate: 9600

UCSRA=0x00;

UCSRB=0x18;

UCSRC=0x86;

UBRRH=0x00;

UBRRL=0x33;

 

while (1)        //무한루프로
입력을
감지
한다.

{

led_control();    //함수
호출

};

}

 

결과

0~6까지의 입력에 따라 LED가 반응한다.

응용 프로그램 : 입력을 받아 LCD에 표시 해보자

#include <mega8535.h>

#asm

.equ __lcd_port=0x15

#endasm

#include <lcd.h>

#include <stdio.h>

 

unsigned char getdata;        //입력된 ASCII코드를
담을
변수

 

void char_input (void)        //입력
받은
문자에
따라
행돌할
함수

{

    getdata = getchar();    //입력된
문자를
받고

switch (getdata){

case 0x0D:        //Enter

    lcd_gotoxy(0,1);    //2 1열로
커서
옮김 (줄바꿈
)

    break;

case 0x1B:        //Esc

    _lcd_ready();    //LCD 데이터
수신
준비

    _lcd_write_data(0b00000001);    //클리어
명령

    break;

case 0x09:                //TAB

    _lcd_ready();

    _lcd_write_data(0b00011000);    //전체
화면
왼쪽으로
쉬프트

    break;

    case 0x08: _lcd_ready();            //BackSpace

        _lcd_write_data(0b00010000);    //커서를
왼쪽으로
한칸
옮김

        lcd_putchar(0x20);        //공백문자
입력

        _lcd_ready();

        _lcd_write_data(0b00010000);    //커서를
왼쪽으로
한칸
옮김

        break;

default:

    lcd_putchar(getdata);    //받은
문자를 LCD
출력

    putchar(getdata);        //컴퓨터
화면에
출력 (에코
)

    PORTA = getdata;    //LED
출력 (ASCII code
볼수
있다
.)

};

 

}        

 

void main(void)

{

PORTA=0x00;

DDRA=0xFF;     //LED ASCII code출력을
위해
모두
출력모드로

 

// USART initialization

// Communication Parameters: 8 Data, 1 Stop, No Parity

// USART Receiver: On

// USART Transmitter: On

// USART Mode: Asynchronous

// USART Baud rate: 9600

UCSRA=0x00;

UCSRB=0x18;

UCSRC=0x86;

UBRRH=0x00;

UBRRL=0x33;

 

lcd_init(16);

_lcd_ready();

_lcd_write_data(0b00001111);    //표시 ON/OFF제어
표시,커서,점멸
모두
ON

printf(“Enter : “);        //입력하라는
안내문
표시

while (1)                //무한루프로
입력을
감지

{

    char_input();    //함수
호출
    

};

}

 

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

This program was produced by Talsu

RS232시리얼 통신을 이용하여 키보드의 입력을 받아

LCD화면에 표시 해주는 프로그램 입니다.

키 입력이 자유 롭게 되고.

Enter키 = 줄바꿈

Backspace = 한글자 지우기

space = 띄우기

TAB = 화면 쉬프트

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

ik55.pdf

One thought on “ATmega8535 – 시리얼통신 (UART)

  1. 좋은 정보 감사합니다~ 이런걸 찾고있었음

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url=""> 

This site uses Akismet to reduce spam. Learn how your comment data is processed.