본문 바로가기
코스웨어/10년 시스템제어

[시스템제어]4월 21일 일일업무 이창민(20번)

by 알 수 없는 사용자 2010. 4. 26.
728x90
반응형
       ★ ArtMega  < 양방향 통신 >
   <main.h>          < 주       석>  
       
10 #include <avr/io.h>    IO제어 HeaderFile  
20      
30 #define CPU_CLOCK   16000000    MCU의 속도  
40 #define BAUD_RATE   19200    통신시 사용할 속도  
50 #define BAUD_RATE_L (CPU_CLOCK/(16l*BAUD_RATE))-1  통신속도 값 입력
 (하기에 부연설명)
 
60 #define BAUD_RATE_H ((CPU_CLOCK/(16l*BAUD_RATE))-1)>>8    
70      
80 void uart_send_byte(unsigned char byte)     통신시 데이터 송신함수
  (하기에 부연설명)
90 {      
100   while(!(UCSR1A & (1<<UDRE)));      
110   UDR1=byte;      
120 }      
130      
140 unsigned char USART_Receive(void)    통신시 데이터 수신함수
 (하기에 부연설명
)
150 {      
160   while(!(UCSR1A & (1<<RXC)));      
170   return UDR1;      
180 }      
                   
  < Code 분석 >                
40 #define BAUD_RATE   19200                
 - 통신속도의 단위(bit/s)                 
 -2400, 4800, 9600, 19200등 여러가지 값 중 상황에 맞는 속도값을 선택할 수 있다.  
   -> ArtMega실습시 가장 이상적인(경험상) 속도값은 4800bps이다.  
   -> 통신속도가 빠르면 문자열 전송시 문자가 깨지는 현상 발생.                
50 #define BAUD_RATE_L (CPU_CLOCK/(16l*BAUD_RATE))-1            
60 #define BAUD_RATE_H ((CPU_CLOCK/(16l*BAUD_RATE))-1)>>8          
 - Resister UBRR 설정  
 
 
 - UBRR 값 구하기   
    -> manual의 Talbe20-1에 각 모드별 UBRR레지스터 값 구하는 식이 나와있다.(노멀모드, 더블스피드모드, 마스터모드)
    -> 실습시에는 노멀모드로 사용하였기 때문에 UBRR = (fosc/16BOUD) -1 이 된다.  
    -> fOSC(System Oscillator clock frequency)란 시스템의 클럭 수 이다.  
   
 - UBRR값 대입하기.  
    -> UBRR의 값은 0~4095이다.  
    -> 4095를 표현하기 위해서는 최소 12bit가 필요하다. (2^12=4096)  
    -> 따라서 ArtMega128의 UBRR 레지스터에는 12bit가 할당되어있다.   
   -> 50행과 60행의 코드에서 BURR에 값을 대입하는 연산을 하고있다.  
   -> 두 줄에 걸쳐 연산을 해야하는 이유는 UBRR의 값이 12bit이기 때문이다.(8bit라면 1번의 연산이면 충분함)  
   -> 50행의 연산이 0~7비트에 값을 대입하는 연산이고 60행의 연산이 8~11비트에 값을 대입하는 연산.
                 
 
   -> 즉, UBRR을 high부(8~11비트)와 low부(0~7비트)로 나누어서 두번에 걸쳐 대입.  
  -> 즉 UBRR을  (UBRR%256)  +  (UBRR-UBRR%256)  의 두 부분으로 나누어서 연산  
                   
80 void uart_send_byte(unsigned char byte) 140 unsigned char USART_Receive(void)
90 { 150 {  
100   while(!(UCSR1A & (1<<UDRE))); 160   while(!(UCSR1A & (1<<RXC)));  
110   UDR1=byte; 170   return UDR1;  
120 }  
   - 데이터 송신함수( uart_send_byte )                
   - 데이터 수신함수( USART_Receive )  
  - UCSRnA Resistor 
      
 
   -  UDRE   
    -> 송신버퍼가 비어있는지 아닌지를 나타내주는 비트(0이면 비어있음, 1이면 비어있지않음)  
   - while(!(UCSR1A & (1<<UDRE)))  ->  UCSR1A의 UDRE비트가 0일때만 수행.  
   - RXC  
     -> 수신버퍼가 비어있는지 아닌지를 나타내주는 비트(수신가능 0, 수신불가 1)   
   - while(!(UCSR1A & (1<<RXC)))  ->  UCSR1A의 RXC비트가 0일때만 수행.  
  - UDR1                
    -> I/O Data Resistor                
                   
  < main.c>         < 주   석 >    
  int main(void)    
  {    
    DDRF=0xFF;   F Port 를 출력 포트설정  
    PORTF=0xFF;   F Port 초기화.  
        
        
    UBRR1L = (unsigned char) BAUD_RATE_L;   UBRR값 대입.  
     UBRR1H = (unsigned char) BAUD_RATE_H;    
        
    UCSR1C = (0<<UPM1) |(0<<UPM0) | (0<< USBS) |   통신설정  
          (1<<UCSZ1) | (1<<UCSZ0);    
              
    UCSR1B = (1<<TXEN) | (1<<RXEN) | (0<<UCSZ2);    
        
        
        
      while(1)      //직렬포트의 값으로 LED제어    <LED제어 및 데이터 통신>  
      {      데이터 'ch'의 값을 수신  
        unsigned char ch=USART_Receive();      데이터 'ch' 의 값을 LED로 출력 후 
        PORTF=ch^0xFF;      데이터'ch' 값을 송신.  
        uart_send_byte(ch);    
        asm("NOP");    
      }    
    return 1;    
  }                

728x90