본문 바로가기

ATMEGA

ATmega 단방향 직렬통신 응용 문제

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));
  }
}




#include <test.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 uart_send_byte(unsigned char byte) // 1 byte 전송함수 
{
  while (!(UCSR1A & (1<< UDRE)));
  UDR1 = byte;
}


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));
  }
  
}

int main(void)
{
  unsigned char buf[] = "Hello DK128!"//전송할 문자열
  unsigned int i;  //반복 제어 변수 
  
  UBRR1L = (unsigned char)BAUD_RATE_L; // baud rate 설정
  UBRR1H = (unsigned char)BAUD_RATE_H;
  
  //no parity, 1 stop bit, 8bit 설정
  UCSR1C = (0 << UPM1) | (0 << UPM0) | (0 << USBS) |
        (1 << UCSZ1) | (1 << UCSZ0);
  
  //rx/tx interrupt 설정, 8bit 설정      
  UCSR1B = (1 << TXEN) | (1 << RXEN) | (0 << UCSZ2);
  
  
  
  //for(;;)
  
    uart_send_string(buf,sizeof(buf));
  
  //for (j = 0 ; j < sizeof(buf) ; j++) // 문자단위로 전제 문자열 전송
  //{
  //  uart_send_byte(buf[j]); //문자 1개를 직렬포트로 전송
  //}
  return 1// 종료
}


2. 파이퍼터미널대신PC프로그램을실행시켜통신하시오.

수신부를 저번에 만들었던 프로그램으로 COM1 사용 dcb.BaudRate = 4800;dcb.ByteSize = 8;
dcb.Parity = 0;dcb.StopBits = 1; 사용


#include <stdio.h>
#include <windows.h>

int main(void)
{
  char szPort[15];
  wsprintf(szPort, "COM%d",1);


  HANDLE m_hComm = NULL;
  m_hComm = CreateFile(szPort,
    GENERIC_READ | GENERIC_WRITE,
    0,NULL,OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,NULL);

  if(m_hComm == INVALID_HANDLE_VALUE)
  {
    printf("(!) failed to create a Comm Device file");
    return FALSE;
  }


  DCB dcb;
  dcb.DCBlength = sizeof(DCB);

  GetCommState(m_hComm, &dcb);

  dcb.BaudRate = 4800;
  dcb.ByteSize = 8;
  dcb.Parity = 0;
  dcb.StopBits = 1;

  SetCommState(m_hComm, &dcb);

  OVERLAPPED osRead;
  osRead.Offset = 0;
  osRead.OffsetHigh = 0;
  osRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
  
  
  
  while(1)
  {
    char buf[100]={'\0',};
    ReadFile(m_hComm,buf,sizeof(buf),NULL,&osRead); //sizeof 로 읽을 파일의 크기 설정
    printf("%s\n",buf);
    Sleep(1000);
    
  }

  CloseHandle(m_hComm);

  return 0;
}



for문으로 반복시켜서 보내기

#include <test.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
#define TICK_PER_SEC  1000
#define PRESCALER    64

//통신속도의 결과 값을 입력하기 위해 상하위 비트로 구분
// 16l 은 16+L 이며, 연산 시 값이 너무 커져 overflow가 발생하므로
//32비트 연산을 위해 16에 Long을 의미하는 l을 붙인다.




void uart_send_byte(unsigned char byte) // 1 byte 전송함수 
{
  while (!(UCSR1A & (1<< UDRE)));
  UDR1 = byte;
}


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));
  }
  
}

volatile unsigned int g_elapsed_time;

void sleep(unsigned int elapsed_time);

void init_TC0(void);

int main(void)
{
  init_TC0();
  SREG=SREG|(1<<7);
  unsigned char buf[] = "Hello DK128!"//전송할 문자열
  unsigned int i;  //반복 제어 변수 
  
  UBRR1L = (unsigned char)BAUD_RATE_L; // baud rate 설정
  UBRR1H = (unsigned char)BAUD_RATE_H;
  
  //no parity, 1 stop bit, 8bit 설정
  UCSR1C = (0 << UPM1) | (0 << UPM0) | (0 << USBS) |
        (1 << UCSZ1) | (1 << UCSZ0);
  
  //rx/tx interrupt 설정, 8bit 설정      
  UCSR1B = (1 << TXEN) | (1 << RXEN) | (0 << UCSZ2);
  
  
  
  while(1)
  {
    uart_send_string(buf,sizeof(buf));
    sleep(1000);
  }  
  
  //for (j = 0 ; j < sizeof(buf) ; j++) // 문자단위로 전제 문자열 전송
  //{
  //  uart_send_byte(buf[j]); //문자 1개를 직렬포트로 전송
  //}
  return 1// 종료
}



void sleep(unsigned int elapsed_time) 
{
  
  for(g_elapsed_time=0;g_elapsed_time<elapsed_time;);
}

void __vector_16 (void
{
  TCNT0=256-(CPU_CLOCK/TICK_PER_SEC/PRESCALER);
  ++g_elapsed_time;
}

void init_TC0(void)
{
  
  TCCR0=1<<CS02|0<<CS01|0<<CS00;
  
  
  TCNT0=256-(CPU_CLOCK/TICK_PER_SEC/PRESCALER);
  
  
  TIMSK=TIMSK|1<<TOIE0;
}






'ATMEGA' 카테고리의 다른 글

11월 3일 ATMEGA  (0) 2010.11.03
ATmega 8장_1 직렬통신 응용 실습문제  (0) 2010.11.03
11월 2일 ATMEGA  (0) 2010.11.02
VC++ 시리얼 통신 함수 분석  (0) 2010.11.01
11월 1일 ATMEGA  (0) 2010.11.01