본문 바로가기

Embeded/ATmega128

2010년 11월 03일 수요일 (직렬 포트 통신 이용한 LED 컨트롤)

/* 직렬 포트 통신을 이용한 LED 컨트롤 */

#include <avr/io.h>

#define CPU_CLOCK 16000000  // MCU의 속도
#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을 붙임

void init_USART1(void);
unsigned char USART_Receive(void);
void uart_send_byte(unsigned char byte);
void uart_send_string(unsigned char *str, unsigned char len);

int main(void)
{
  unsigned char buf[]="Hellow DK128!";
  unsigned int i;
  unsigned char ch;
  
  DDRF=0xff;
  PORTF=0xff;
  
  init_USART1();
  
  while(1)
  {
  ch =((USART_Receive())-48);
  if(ch==0)
  {
  PORTF=0xff;
  }
  else
  {
  PORTF=~(1<<(ch-1));
  uart_send_byte(ch+48);
  }
  asm("NOP");
  }
  return 1;
}

/* 전체 문자를 전송하기 위한 함수 */
void uart_send_string(unsigned char *str, unsigned char len)
{
  int i;
  for(i=0; i<len; i++)
  {
    if( !(*(str+i)))
    {
      break;
    }
    uart_send_byte(*(str+i));
  }
}

/* 시리얼 통신을 송신 함수 */
void uart_send_byte(unsigned char byte)
{
  while (!(UCSR1A&(1<<UDRE)));  // 전송 버퍼가 비었을 때 까지 대기
  UDR1 = byte;  // 문자 1개씩 전송
}

/* 시리얼 통신을 수신 함수 */
unsigned char USART_Receive(void)
{
  /* 데이터 수신 대기 */
  while(!(UCSR1A&(1<<RXC)))
  {
  
  }
  /* 버퍼에 수신된 데이터를 가져와 리턴 */
  return UDR1;
}

/* 시리얼 통신 포트 1번 사용 함수 */
void init_USART1(void)
{
  UBRR1L = (unsigned char)BAUD_RATE_L;
  UBRR1H = (unsigned char)BAUD_RATE_H;
  
  UCSR1C = (0<<UPM1)|(0<<UPM0)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);
  UCSR1B = (1<<TXEN)|(1<<RXEN)|(0<<UCSZ2);
}