04. UART 시리얼 통신

안양진·2022년 8월 22일
0

ATmega128

목록 보기
6/7
post-custom-banner

1. UART

* 범용 비동기식 수신 송신
* Universal Asynchronous Receive Transmit
  • 시리얼 통신 방법중 하나로 이외 흔히 사용되는 방법으론 SPI와 I2C등이 있다

  • 가장 오래된 통신방법

2. 보율

마이크로컨트롤러는 0과 1만을 처리할 수있다. 따라서 송신이나 수신 둘다모두 0과 1로 정보를 처리하며 서로간의 처리속도를 맟춰야만한다. 같은정보를 1초마다 받냐 2초마다 받냐에 따라 수신한 정보가 달라지기떄문이다.

그렇게 하여 나온것이 보율(baud rate)이다.
이는 프랑스의 과학자 장 모리스 에밀 보도(Jean Maurice Emile Baudot)의 이름을 따온 것이다.

초기 데이터 통신에 있어서 보통 1초 동안 전달되는 데이터 비트의 수를 나타내는 단위로 모뎀 등의 데이터 단위를 사용하였다, 이 경우는 보율의 단위가 bps(bit per second)가 된다. 하지만 기술발전에 따라 많은 정보 표현이 가능해졌기에 bps는 보율과 같거나 더 크게 된다.

만약 데이터의 변화는 4번이지만 변할떄마다 받는 정보가 2비트라면 8bps라는 보율을 가지게 된다.

송, 수신의 보율이 같다가 항상 정확하게 통신이 이루어지는것은 아니다.
송신의 경우 필요할떄만 이루어지는데, 이떄 어느떄부터가 송신을 보낸것인지 수신부에서는 이해하지 못하기떄문이다. 이를 위해 '0'이 시작 비트, '1'이 정지 비트로 사용된다. UART는 바이트 단위(8 bit)로 통신하며, 여기에 시작, 정지 비트를 추가하여 총 10비트를 전송하는 것이 일반적이다.

데이터를 받지 않을떄는 '1'신호를 받지만, 받는 시점부터 '0'의 신호를 받으며, 실제 데이터인 8비트 데이터 수신후 끝 신호인 '1'의 신호를 받게된다.

ATmega128의 경우 2개의 UART가 있다.
흔히 UART0, UART1이라고 한다.

UARTRXTX
UART0PE0PE1
UART1PD2PD3

연결시 RX, TX는 서로 교차해서 연결 해야한다.

연결컴퓨터ATmega128
-RXTX
-TXRX

3. UART 레지스터

1. UDRn (n=0,1)

비트76543210
READRXB7RXB6RXB5RXB4RXB3RXB2RXB1RXB0
WRITETXB7TXB6TXB5TXB4TXB3TXB2TXB1TXB0
초기값00000000

송수신된 데이터가 저장되는 버퍼 레지스터
TXB=전송
RXB=수신
이둘의 레지스터는 동일한 입출력 주소를 사용한다.
송신할 경우 TXB에 저장되고, 수신할 경우 RXB로 저장된다.

2. UCSRnA (n=0,1)

비트76543210
이름RXCnTXCnUDREnFEnDORnUPEnU2XnMPCMn

이름비트역할
RXCn7수신버퍼(UDRn의 RXB)에서 아직 읽지 않은 데이터가 있을 경우 1 읽을 경우 0이 된다
이 비트가 1일 경우 수신 완료 인터럽트 발생
TXCn6송신 버퍼가 비면 (다 보냈을경우) 1이 된다.
이 비트가 1일 경우 송신 완료 인터럽트 발생 처리 후 0이 된다.
UDREn5UDRn이 비어 있을(송수신 공간이 전부 비었을) 경우
새로운 데이터를 받을수 있게 1이되는 상태 플레그
FEn4수신데이터가 없을 경우 HIGH 상태이며,
데이터 프레임 수신이 시작되는 순간부터 LOW 가 된다.
DORn3수신 버퍼가 가득 찬 상태에서 수신 시프트 레지스터에 새로운 문자가 수신되고
다시 그 다음 문자의 시작 비트가 검출되는 오버런 상황이 발생할때 1이 된다.
UPEn2수신 버퍼에 저장된 문자 데이터에 패리티 오류가 발생시 1의 값을 가짐.
패리티 비트사용이 설정된 경우만 사용가능
U2Xn1비동기 전송 모드에서만 사용되며, 2배속이면 1, 1배속이면 0의 값을 가짐
MPCMn0멀티 프로세서 모드 1, 일반 모드 0

3. UCSRnB (n=0,1)

비트76543210
이름RXCIEnTXCIEnUDRIEnRXENnTXENnUCSZn2RXB8nTXB8n

이름비트역할
RXCIEn7수신 완료 인터럽트 허용 비트
TXCIEn6송신 완료 인터럽트 허용 비트
UDRIEn5송신데이터 레지스터 준비 완료 인터럽트 발생 허용 비트
RXENn4수신 허용 비트
TXENn3송신 허용 비트
UCSZn22UCSRnC의 1,2 번 비트와 함께 전송 문자 길시 설정 비트 (일반적으론 8비트사용)
RXB8n1수신 데이터가 9비트인 경우
데이터의 9번째 비트 반드시 UDRn 레지스터보다 먼저 읽어야 한다
TXB8n0송신 데이터가 9비트인 경우
데이터의 9번째 비트 반드시 UDRn 레지스터보다 먼저 써야 한다

4. UCSRnC (n=0,1)

비트76543210
이름-UMSELnUPMn1UPMn0USBSnUCSZn1UCSZn0UCPOLn

이름비트역할
-7-
UMSELn6동기 or 비동기 설정 비트
UPMn15패리티 모드 설정 비트
UPMn04패리티 모드 설정 비트
USBSn3정지 비트수 지정 0 : 1비트 , 1 : 2비트
UCSZn12UCSRnB의 UCZn2와 같이 쓰이는 비트들로 데이터 비트수를 정하는 비트들이다.
UCSZn01UCSRnB의 UCZn2와 같이 쓰이는 비트들로 데이터 비트수를 정하는 비트들이다.
UCPOLn0동기식 모드일때 1로 설정 클록(XCK)의 극성을 지정한다.

4.1. UPMnX 표

UPMn1UPMn0
00없음
01-
10짝수 패리티
11홀수 패리티

4.2. UCSZn 표
UCSZn2UCSZn1UCSZn0비트
0005
0016
0107
0118
100-
101-
110-
1119

5. 보율 설정 레시트터

UBRRnH
UBRRnL: 보율 설정용 비트

UART1.c

#include <avr/io.h>

void UART1_init(void)
{
	UBRR1H=0x00;
	UBRR1L=0x16;
	
	UCSR1A|=_BV(U2X1);
	
	UCSR1C|=0x06;
	
	UCSR1B|=_BV(RXEN1);
	UCSR1B|=_BV(TXEN1);
}

void UART1_transmit(char data)
{
	while(!(UCSR1A&(1<<UDRE1)));
	UDR1=data;
}

unsigned char UART1_receive(void)
{
	while(!(UCSR1A&(1<<RXC1)));
	
	return UDR1;
}

void UART1_print_string(char *str)
{
	for(int i=0; str[i];i++){
		UART1_transmit(str[i]);
	}
}

void UART1_print_1_byte_number(uint8_t n)
{
	char numString[4]="0";
	int i,index=0;
	
	if(n>0){
		for(i=0;n!=0;i++){
			numString[i]=n%10+'0';
			n=n/10;
		}
		
		numString[i]='\0';
		index=i-1;
	}
	
	for(i=index;i>=0;i--){
		UART1_transmit(numString[i]);
	}
}

UART1.h

#ifndef UART1_H_
#define UART1_H_

void UART1_init(void);
void UART1_transmit(char data);
unsigned char UART1_receive(void);
void UART1_print_string(char *str);
void UART1_print_1_byte_number(uint8_t n);

#endif

main.c

#include <avr/io.h>
#include "UART1.h"

int main()
{
	UART1_init();

	char str[]="Test using UART1 Library";
	uint8_t num=128;

	UART1_print_string(str);
	UART1_print_string("\n\r");

	UART1_print_1_byte_number(num);
	UART1_print_string(str);

	while(1){
		UART1_print_string(str);
		UART1_print_string("\n\r");
	}

	return 0;
}
post-custom-banner

0개의 댓글