Microprocessor/ATMEGA 128

아트메가128 (DK-128 / 직렬 통신 / 양방향 직렬 통신 ) [20120605]

Dexter_- 2016. 9. 30. 09:38
728x90
반응형

   

   

   

안녕하세요 L입니다.   

오늘은 DK-128 PC 연결하는 직렬통신에 대해 알아보겠습니다 !!   

본문내용 PDF파일은 첨부파일에 있음돠 !!   

   

   

9장_1 직렬통신 실습.pdf



  

 DK-128 직렬통신 실습     

 Serial port 사용   

     

PD2, PD3 활성화 시켜야한다. (위치는 아래 그림 참조)   

      

pc  수신버퍼  Atmega128 →송신버퍼  PC   

수신버퍼  RXD1 (27) = 수신단자   

송신버퍼  TXD1(28) = 송신단자  

   

< Atmega128 USART >   

   

USART0 과 USART1 이 있는데 USART1만 직렬통신으로 사용가능  

   

< UDR 레지스터 >   

     

8bit 레지스터 이다.   

UDR1(0x9C) = 8bit 크기이고, 송신 Buffer(write)와 수신 Buffer(read)로 나누어져있다.   

UDR1 : DATA가 담기는 레지스터 ( 수신버퍼, 송신버퍼 )  

   

   

< UCSRnA레지스터 >   

 

   

UCSR1A : 수신버퍼에 외부data 들어왔는지 확인.

       송신버퍼에 비어있는지 확인.  

UDREn (bit 5번) : 송신버퍼가 비어있으면 1이고 data가 들어있으면 0   

RXcn (bit 7번) : 1이면 수신할 data가있다 0이면 수신할 data가 없다.   

   

< UCSRnB레지스터 >   

     

UCSR1B : RXD1 을 수신단자로 설정, TXD1을 송신단자로 설정   

RXENn ( bit 4 번 ) : 1이들어가면 수신단자 설정   

TXENn ( bit 3 번 ) : 1 이 들어가면 직렬통신요 송신단자로 설정   

양방향 통신이 가능하다.   

1방향 통신일경우 : TXEn 에 1을 넣어준다.   

   

< UCSRnC레지스터 >  

  

   

UCSR1C : PC와 Atmega128 간의 통신설정   

아래 내용들이 이미 초기화 되어있음으로 따로 설정 할 필요가 없다. 

   

   

   

UMSEL : 비동기모드 0값   

   

   

0, 0이 들어갈경우 사용안함.

     

   

stop bit 에 0이 들어가면 1-bit  

   

   

문자size 설정 1일경우 8-bit문자 size이다.

     

< UBRRn H/L 레지스터 >   

   

UBRR1H/L : 통신속도를 설정 ( HIGH/LOW 2가지 )   

H/L 는 각각 8bit 레지스터이다. High 비트는 4비트만 사용한다.   

High 값에 Data를 넣을때는 쉬프트 해서 넣어준다 ex) a>>8  

   

   

통신속도 설정 fosc = 16mhz, BAUD = 4800세팅 으로 위 테이블 공식으로 세팅.  

   

< USART Block Diageam >  

      

Ex) 단방향 직렬통신   


< 헤더 파일 >   

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#define UBRR1L *((volatile unsigned char *)0x99)
#define UBRR1H *((volatile unsigned char *)0x98)
#define UCSR1A *((volatile unsigned char *)0x9B)
#define UCSR1B *((volatile unsigned char *)0x9A)
#define UCSR1C *((volatile unsigned char *)0x9D)
#define UDR1 *((volatile unsigned char *)0x9C)   
 
#define UDRE  5
#define UPM1  5
#define UPM0  4
#define USBS  3
#define UCSZ1 2
#define UCSZ0 1
#define TXEN  3
#define UCSZ2 2
#define RXEN  4
#define TOIE0 0
#define CPU_CLOCK            16000000    // MCU의속도
#define TICKS_PER_SEC        1000
#define PRESCALER            64
 
/*    직렬통신    */
#define BAUD_RATE    4800    // 통신시이용할속도
#define BAUD_RATE_L    (CPU_CLOCK / (16l * BAUD_RATE)) - 1
#define BAUD_RATE_H ((CPU_CLOCK / (16l * BAUD_RATE)) -1>> 8
 
// 통신속도의결과값을입력하기위해상하위비트로구분
// 16l 은16 + L 이며, 연산시값이너무커져overflow가발생하므로
// 32비트연산을위해16에Long을의미하는l을붙인다.
//========================================================  
 
/*        1byte 전송함수        */
void uart_send_byte(unsigned char byte);
 
void uart_send_byte(unsigned char byte)
{
    while (!(UCSR1A & (<< UDRE)));    // 전송버퍼가빌때까지기다린다  
    UDR1 = byte;    // 문자1개를전송한다.      
}   
 
//========================================================  
/*        delay        */    
volatile unsigned int g_elapsed_time; 
void sleep(unsigned int elapsed_time)
{
    g_elapsed_time = 0;
    for(;g_elapsed_time<elapsed_time;);      
}   
 
void __vector_16 (void) __attribute__ ((signal, used, externally_visible));
void __vector_16 (void)
{
    TCNT0 = 6;
    ++g_elapsed_time;
}   
 
//========================================================
/*        Timer/counter Control regi초기화        */
void init_TC0(void)
{
    TCCR0 = 0x04;
    TCNT0 = 6;
    TIMSK = TIMSK | (1<<TOIE0);
    
    /*전체인터럽트활성화*/
    SREG = SREG | (1<<7);
    /*전체인터럽트활성화*/
}
cs


< 소스 코드 >

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
#include <L.h>
 
int main(void)
{
    unsigned char buf[] = "Hello DK128!\r\n";    // 전송할문자열
    unsigned int i;        // 반복제어변수
    init_TC0();   
 
    UBRR1L = (unsigned char)BAUD_RATE_L;    // baud rate 설정
    UBRR1H = (unsigned char)BAUD_RATE_H;   
 
    // no parity, 1 stop bit, 8bit 설정
    UCSR1C = ( << UPM1) | (<< UPM0) | (<< USBS)
     | (<< UCSZ1) | (<< UCSZ0);   
 
    // rx/tx interrupt 설정, 8bit 설정
    UCSR1B = (<< TXEN) | (<< RXEN) | ( << UCSZ2);
 
    while(1)
    {
        for(i = ; i < sizeof(buf) ; i++// 문자단위로전체문자열전송
        {
            uart_send_byte(buf[i]);    // 문자1개를직렬포트로전송
        }
 
        sleep(1000); // 1초대기
    }
 
    return 1;
}
cs

   

     

결과   

   

   

Ex) 다음 같은 문자열전송하는 함수를 구현하여 앞의

     실습 예제에 적용하여 실행시켜보시오.

      

문자열전송함수선언   

void uart_send_string(unsigned char *str, unsigned char len);   

    str: 전송하려는문자열의시작주소

    len: 전송하려는문자열의길이

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
#include <L.h>
 
void uart_send_string(unsigned char *str, unsigned char len);   
 
int main(void)
{
    unsigned char ch;
    unsigned char buf[] = "Hello DK128!\r\n";    // 전송할문자열         
 
    init_TC0();   
 
    UBRR1L = (unsigned char)BAUD_RATE_L;    // baud rate 설정
    UBRR1H = (unsigned char)BAUD_RATE_H;      
 
    // no parity, 1 stop bit, 8bit 설정
    UCSR1C = ( << UPM1) | (<< UPM0) | (<< USBS)
     | (<< UCSZ1) | (<< UCSZ0);  
     
    // rx/tx interrupt 설정, 8bit 설정
    UCSR1B = (<< TXEN) | (<< RXEN) | ( << UCSZ2); 
    uart_send_string(buf, sizeof(buf));    // 함수호출              
 
    return 1;
}
 
// 문자열전송함수선언
void uart_send_string(unsigned char *str, unsigned char len)
{   
    while(1)
    {
        for(unsigned int i = ; i < len ; i++// 문자단위로전체문자열전송
        {
            uart_send_byte(*(str+i));    // 문자1개를직렬포트로전송
        }  
 
        sleep(1000); // 1초대기     
    }
}
cs

결과는 위와 동일

      

   

Ex) 양방향 직렬 통신   

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
#include <L.h>
 
#define RXC    // 추가   
 
unsigned char USART_Receive( void );
void uart_send_string(unsigned char *str, unsigned char len);   
 
int main(void)
{
    unsigned char ch;
    init_TC0();
    UBR_UCSR();
    init_LED();   
 
    while(1)
    {
        ch = USART_Receive();
        PORTF = ch^0xFF;
        uart_send_byte(ch);
        sleep(1000);  
    }    
 
    return 1;
}
 
unsigned char USART_Receive( void )
{
    while(!(UCSR1A & (1<<RXC)));
    
    return (UDR1);
}   
cs


     

      

결과 : 하이퍼터미날에 입력된 값이

       아스키코드 10진수로 LED 출력된다.

 (동영상 참고)       

 

 

   

   

   

   

궁금하신 점은 댓글로 남겨 주세요 !!   

오늘도 좋은 하루 되세열 

   

   

   

   

   

   

   

   

728x90
반응형