반응형

Atmega128의 시리얼 통신(USART)에 대해 다룹니다.

2016. 6. 25 최초작성

 

1. Baud rate (in bits per second, bps)와 시스템 클록을 정의한다.

        #define 9600

        #define F_CPU 16000000UL



2. 시스템 클록과 원하는 baud rate를 이용하여 USART Baud Rate Register(UBRR)을 계산한다.

BAUD Baud rate (in bits per second, bps)

fOSC System Oscillator clock frequency

UBRR Contents of the UBRRH and UBRRL Registers, (0 - 4095)

        UBRR_VALUE = (((F_CPU / (9600 * 16UL))) - 1);



3. UBRR0은 12비트 레지스터이기 때문에 나누어서 넣어야 한다.

        UBRR0H = (uint8_t)(UBRR_VALUE>>8);

        UBRR0L = (uint8_t) UBRR_VALUE;



4. USART 설정을 한다. 

        UCSR0C |= (1<<UCSZ00)|(1<<UCSZ01); //Charecter size : 8비트

        UCSR0C &= ~(1<<USBS0); //stop  bit : 1비트

        UCSR0C &= ~((1<<UPM01)|(1<<UPM00)); // no parity mode



5. USARTn Receiver와 USARTn Transmitter를 인에이블시킨다. 

        UCSR0B=(1<<RXEN0)|(1<<TXEN0);



6. 데이터 전송

전송 버퍼(UDRn)이 비어있다면 1값을 가지며 새로운 데이터를 받아서 전송할 준비가 된 것이다. 

    //이전 전송이 끝나기를 기다림

    while(!(UCSR0A&(1<<UDRE0))){};

 

    UDR0 = data;                                        /* send data */



7. 데이터 수신

수신버퍼가 비어있다면 0으로 클리어된다. 1이되면 데이터를 수신받았다는 것이다.

    // 수신 되기를 기다림

    while(!(UCSR0A&(1<<RXC0))){};

    return UDR0;                            /* return register value */



전체 소스코드..

PC에서 실행시킨 터미널에서 입력한 것을 avr에서 에코해서 보내줍니다.

#define F_CPU 16000000UL

//1. baud rate를 선택
#define USART_BAUDRATE 9600

//2.시스템 클록과 원하는 baud rate를 이용하여 UBRR 값을 계산한다.
#define UBRR_VALUE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)


#include <avr/io.h>
#include <stdio.h>


void usartInit()
{
    //3. UBRR0은 16비트 레지스터이기 때문에 8비트씩 나누어서 넣어야 한다.
    UBRR0H = (uint8_t)(UBRR_VALUE>>8);
    UBRR0L = (uint8_t) UBRR_VALUE;
   
    //4. USART 설정
    UCSR0C |= (1<<UCSZ00)|(1<<UCSZ01); //Charecter size : 8비트
    UCSR0C &= ~(1<<USBS0); //stop  bit : 1비트
    UCSR0C &= ~((1<<UPM01)|(1<<UPM00)); // no parity mode
   
    //5. 송수신을 가능하게 한다.
    UCSR0B=(1<<RXEN0)|(1<<TXEN0);
}

void transmitByte(uint8_t data) {

    //이전 전송이 끝나기를 기다림
    while(!(UCSR0A&(1<<UDRE0))){};

    UDR0 = data;                                            /* send data */
}

uint8_t receiveByte(void) {
    // 수신 되기를 기다림
    while(!(UCSR0A&(1<<RXC0))){};
    return UDR0;                                /* return register value */
}


void printString(const char str[]) {
    uint8_t i = 0;
    while (str[i]) {
        transmitByte(str[i]);
        i++;
    }
}

void readString(char str[], uint8_t maxLength) {
    char response;
    uint8_t i;
    i = 0;
    while (i < (maxLength - 1)) {                   /* prevent over-runs */
        response = receiveByte();
        transmitByte(response);                                    /* echo */
        if (response == '\r') {                     /* enter marks the end */
            break;
        }
        else {
            str[i] = response;                       /* add in a letter */
            i++;
        }
    }
    str[i] = 0;                          /* terminal NULL character */
}

int main(void)
{
    usartInit();
   
    char ch;

    while(1)
    {
        ch = receiveByte();
       
        if ( ch == '\r') {
            transmitByte('\r');
            transmitByte('\n');
        }

        transmitByte(ch);
    }
}



반응형

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.

도움이 되셨다면 토스아이디로 후원해주세요.
https://toss.me/momo2024


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts