J 창고

[Atmega128] UART Tx 본문

컴퓨터/Firmware

[Atmega128] UART Tx

JSFamily 2015. 1. 7. 14:33






UART 통신을 하려면 Baudrate 설정이 필수적이다.


계산 식은 위의 표와 같이 하면 된다.


ex) 9600bps로 통신을 한다면 


UBRR = ( 16Mhz / ( 16 x 9600bps) ) -1 = 106.167 이 되므로


UBRR에는 106즉 0x67을 넣어줘야 한다.


물론 UBRR0H와 UBRR0L로 되어 있어 상위바이트와 하위바이트에 나눠서 넣어주면 된다.

(9600은 하위 8비트 안에 들어가므로 상위에는 0x00을 넣는다.









UDRn 레지스터는 Tx일 때는 Tx로 보낼 데이터를 저장할 Buffer로 사용되고

Rx일 땐 데이터를 받을 Buffer로 사용된다.


이 버퍼가 보낼 준비가 되거나

받을 준비가 된다면

UCSRnA에 있는 UDREn 레지스터가 Set 된다.

















TXENn 을 통하여 Tx Enable과 

RXENn 을 통하여 Rx Enable을

설정할 수 있다.







보통 UART 통신을 셋팅하는 레지스터가 많다




비동기 신호냐 동기 신호냐 선택 레지스터









페리티비트를 넣을지 말지 선택








스탑비트를 몇 비트로 넣을 건가









캐릭터 사이즈 선택(보통 8bit 선택)










Baudrate 설정 레지스터




다만 아래의 표와 같이 


외부 크리스탈에 따른 클럭으로 인하여


통신 에러율이 발생한다.


특히 16Mhz 를 사용하면 통신 오차가 심하다.


그래서 통신용으로 사용한다면 14.7456Mhz 크리스탈로 교체하여 사용한다.













Atmega128에서 UART를 통해 아스키코드 48번부터 122번까지 보내는 코드



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
42
43
/*
 * USART_Test2.c
 *
 * Created: 2015-01-07 오전 10:49:51
 *  Author: user
 */ 
 
#include <avr/io.h>
#include <util/delay.h>
 
void putchar1(char c){
    
    while( (UCSR0A & (1<<UDRE0)) == 0 );            
    UDR0 = c;
}
    /*  
    UCSR0A의 5bit에 있는 UDRE0는 Transmit Buffer를 가리키는 Indicator이다.
    만약 Buffer에 있는 데이터를 다 전송하면 UDRE0는 1로 Set된다.
    */
 
int main(void)
{
    unsigned char i=48;
    
    UCSR0A = 0x00;
    
    UCSR0B    = (1<<TXEN);                // Tx Enable
    
    //Asynchronous Mode
    UCSR0C = (1<<UCSZ1)|(1<<UCSZ0);        // 8bit, 1stopbit, no parity
    
    UBRR0H = 0x00;        // UBRR = (16/(16*9600))-1 = 103.167
    UBRR0L = 0x67;        // Baudrate = 9600
    
    
    while(1)
    {
        putchar1(i++);
        _delay_ms(500);
        putchar1(10);
        if(i == 122) i = 48;   
    }
}
cs









Atmega128에서 Hello World! 를 보내는 코드


putString을 통해 캐릭터 하나씩 보내는 방식



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
42
43
44
45
46
47
48
49
50
51
52
53
54
/*
 * USART_Test2.c
 *
 * Created: 2015-01-07 오전 10:49:51
 *  Author: user
 */ 
 
 
#include <avr/io.h>
#include <stdio.h>
#include <util/delay.h>
 
 
void putChar1(char c){
    
    while( (UCSR0A & (1<<UDRE0)) == 0 );            
    UDR0 = c;
}
    /*  
    UCSR0A의 5bit에 있는 UDRE0는 Transmit Buffer를 가리키는 Indicator이다.
    만약 Buffer에 있는 데이터를 다 전송하면 UDRE0는 1로 Set된다.
    */
    
void putString(char *string){
    unsigned char i=0;
 
    while(string[i] != 0){        // 문자열의 맨 마지막엔 항상 NULL문자가 있으므로
        putChar1(string[i++]);    // NULL문자가 나올때 까지 1byte씩(캐릭터문자) 보냄
    }                            // 마지막에 Line Feed 보내숴 시리얼 모니터의 뉴라인 생성
    putChar1(0x0A);                
}
 
int main(void)
{
    //unsigned char i=48;
    char *string = "Hello World!";
    
    UCSR0A = 0x00;
    
    UCSR0B    = (1<<TXEN);                // Tx Enable
    
    //Asynchronous Mode
    UCSR0C = (1<<UCSZ1)|(1<<UCSZ0);        // 8bit, 1stopbit, no parity
    
    UBRR0H = 0x00;        // UBRR = (16/(16*9600))-1 = 103.167
    UBRR0L = 0x67;        // Baudrate = 9600
    
    while(1)
    {
        putString(string);
        _delay_ms(1000);
    }
}
 
cs





Comments