★ USART 통신 코드 분석 - ATmega128

Posted by yizg
2011. 3. 16. 15:21 Edu/유비쿼터스설비제어과정



 

 USART 통신을 CodeVision 코드소스를

ATmega128  datasheet과 비교하면서 분석해 보았다.

 

 


 

 

 

 

( 차례 )
 

  • (가) UCSRnA
  • (나) UCSRnB
  • (다) UCSRnC
  • (라) UBRRn
  • (마) ( UCSR0A & 0x80 ) != 0
  • (바) UDR0
  • (사) FND Table
  • (아) FND Setting
  • (자) FND 출력
  • (차) 0~9, a~f, A~F

 


 

 

(가) UCSRnA

 

 

 

[ UCSR0A에서 수신된 데이터 확인 유무를 확인한다. ]
 

이번 프로그램에서는 초기값을 UCSR0A = 0x00 로 놓았다.  ( 2진수로는  0b00000000 )

여기에서는 Bit 7의 값만 사용한다.

  • RXCn = 1  :   UDRn의 수신버퍼에 아직 읽지 않은 데이터가 존재하는 상태
  • RXCn = 0  :   UDRn의  수신버퍼를 읽어서 비워져 있는 상태

[ (마) ( UCSR0A & 0x80 ) != 0 ] 에서 다시 한번 설명이 된다.

 

Bit 0의 MPCMn = 1 이면 멀티프로세서 통신모드가 설정된다. ( 해봐야 하는 기능인가?)

 

Bit 1U2Xn = 1 이면 비동기 모드에서만 유효한 것, 클럭의 분주비를 16에서 8로 절반만큼 낮추어 전송속도를 2배 높이는 기능을 수행함.  여기에서는 synchronous operation (동기화) 기능인 U2Xn = 0 의 값을 사용.

그리고 U2Xn의 값은 UBRRn에서 Baud Rate를 선택할때 참조된다.

 

 


 

 

(나) UCSRnB

 

 

[ UCSR0B에서 송수신 상태를 가능하게 만든다. ]

 

이번 프로그램에서는 UCSR0B = 0b00011000 으로 설정되어 있다.

( 2진수로 표시를 하면 16진수보다 보다 직관적이다.)

세번째와 네번째의 2진수의 값이 1로 되어 있다. 따라서 TXENn과 RXENn의 값이 1이 되었다.

 

  • Bit 3 의  TXENn = 1 이면  송신부 동작이 활성화 된다.
  • Bit 4 의  RXENn = 1 이면 수신부 동작이 활성화 된다.



 



 

(다) UCSRnC

  

 

[ UCSR0C에서 Character Size를 8bit로 선택한다. ]

 

우리 프로그램에서는 8bit 모드를 사용하기 위해,  UCSR0C = 0b00000110 을 사용하였다.

 

UCSR0CBit 1, 2 와 UCSRnB의 Bit2의 조합으로 Character Size를 결정하게 된다.

UCSRnB, Bit2의 UCSZn2 = 0 이므로,

여기에서는 8bit의 문자크기를 가지기 위해,

  • Bit 1 의  UCSZn0 = 1
  • Bit 2  UCSZn1 = 1

를 사용한다.

 

Bit 7 은 예비 Bit이며, 지금은 반드시 0 의 값을 사용해야 한다. ( 책에서 1로 되어 있어서 찾아본 것임 )


 



 

(라) UBRRn

 

 

 

[ UBRRn에서 USART의 송/수신 속도를 설정한다. ]

 

우리는 fosc = 16 MHz, Baud Rate(bps) = 9600을 사용한다.

UBRR값을 정하기 위해 다음의 공식을 사용한다.

 

통신속도 계산 공식 : Baud = fosc / { 16 x ( UBRR + 1 ) }

 

(계산)

UBRR =  { fosc / (16 x Baud) }  -  1

          =  { 16 x 10^6 / 16 x 9600 } - 1

          =  { 10000 / 96 } - 1

          = 103.16  =  103.2


 



 

(마) ( UCSR0A & 0x80 ) != 0  

 

UCSR0A의 값은 초기에 0b00000000 로 설정하였다.

 

여기에서 어떠한 ★ 값이 수신이 된다면 UCSR0A의 Bit 7 인 RXCn = 1 이 된다.

따라서 UCSR0A = 0b10000000 이 된다.

 

0x80를 2진수로 표현하면, 0b10000000이다.

 

UCSR0A & 0x80 = 0b10000000 & 0b10000000 이 된다.

(AND 계산은 같은 것만 남긴다. )

따라서 UCSR0A & 0x80 = 0b10000000 이 된다.

 

if( ( UCSR0A & 0x80 ) != 0 )  → 값이 0 이 아니라면, if문을 실행하여라~


 



 

(바) UDRn

 

  

  

[ UDRn에서는 송/수신되는 데이터값을 저장하는 버퍼역활을 한다. ]

 

UDR0 값에 수신되는 데이터값을 저장시킨다.

입력하는 값이 UDR0에 저장이 된다는 말이다.

 

  • RXBn : Read, 수신되는 데이터 저장
  • TXBn : Write, 송신되는 데이터 전송


(질문) UDB0 대신에 RXB0 라고 쓰면 않되는가(?)


 





 

(사) FND ( 7-Segment ) Table

 

교제 P.105에 보면 FND값 Table이 있다.

Cathode Type와 Anode Type가 있는데, FND kit은 Anode Type로 움직인다.

하지만, 우리가 사용하는 ATmega128 Kit에는 UDN2981을 사용하였다.\

UDN2981에 Not Gate가 붙어 있어서, FND를 Cathode Type으로 사용해야 한다.

 

FND Table ( Cathode Type )

FND 표시  : 0 ,  2진수 표현 : 0000,  16진수표현 :  0x3f

FND 표시  : 1 ,  2진수 표현 : 0001,  16진수표현 :  0x06

FND 표시  : 2 ,  2진수 표현 : 0010,  16진수표현 :  0x5b

FND 표시  : 3 ,  2진수 표현 : 0011,  16진수표현 :  0x4f

FND 표시  : 4 ,  2진수 표현 : 0100,  16진수표현 :  0x66

FND 표시  : 5 ,  2진수 표현 : 0101,  16진수표현 :  0x6d

FND 표시  : 6 ,  2진수 표현 : 0110,  16진수표현 :  0x7d

FND 표시  : 7 ,  2진수 표현 : 0111,  16진수표현 :  0x27

FND 표시  : 8 ,  2진수 표현 : 1000,  16진수표현 :  0x7f

FND 표시  : 9 ,  2진수 표현 : 1001,  16진수표현 :  0x6f

FND 표시  : A ,  2진수 표현 : 1010,  16진수표현 :  0x77

FND 표시  : b ,  2진수 표현 : 1011,  16진수표현 :  0x7c

FND 표시  : C ,  2진수 표현 : 1100,  16진수표현 :  0x39

FND 표시  : d ,  2진수 표현 : 1101,  16진수표현 :  0x5e

FND 표시  : E ,  2진수 표현 : 1110,  16진수표현 :  0x79

FND 표시  : F ,  2진수 표현 : 1111,  16진수표현 :  0x71


 

 



 

(아) FND Setting

 

DDRB = 0xff;                             // Port B 출력 설정
DDRF = 0xff;                             // PF4 - PF7 출력 설정
PORTF = 0b00000000;                // FND 4개 사용,  0b11100000 이면 오른쪽 하나 사용
CD = 0;                                    


 



 

(자) FND 출력

 

PORTB = Seg_Cathode[CD];

 

아래의 (차)에서 올라오는 CD값의 위치에 있는  Seg_Cathode 값을 찾는다.

그 FND Table 값을  PORTB로 출력하거라!


 


  

(차) 0~9, a~f, A~F

 

if( AA >= '0' && AA <= '9' ) CD = AA - '0';  

( AA >= '0' && AA <= '9' ) 값을 만족하면 다음을 실행하거라! if의 명령.

CD = AA - '0'

( AA - '0' ) 를 CD에 값을 대입시킨다.

 

(질문)  AA 저장소에서 ?????

 

( 아래의 것들도 같은 수순 )


else if( AA >= 'a' && AA <= 'f' ) CD = AA - 'a' + 10;


else if( AA >= 'A' && AA <= 'F') CD = AA - 'A' + 10;

 

(질문)  ( AA - 'a' + 10 ) 는 어떤 뜻인가....????