Microprocessor/ATMEGA 128 아트메가128 (DK-128 / 직렬 통신 / 양방향 직렬 통신 ) [20120605]
  • 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
    반응형
상단으로