기본적으로 인터럽트를 이용해 데이터를 받고, 이를 큐에 저장합니다.
실제 받은 데이터 처리는 main()문안에서 하며 이 방식이 인터럽트에서 바로 받은데이터를 처리하는 방법보다 훨씬 더 안전하게 수신 데이터를 처리 할 수 있습니다.
usart.h 파일과
usart.c 파일로 나눴습니다.

CodevisionAVR 1.25.8 에서 작성된 소스이며, 이 소스를 AVRStudio 에서 사용하시려면 딜레이함수를 새로 만들어 주시고, 인터럽트 처리루틴의 함수명을 바꿔주시면 됩니다.

긁어다 쓸려고 하지 마시고 소스내용과 알고리즘을 이해하려고 하세요.

그럼 쉽게 짜실 수 있습니다.


프로그램은 USART 통신을 통해 아래 명령을 입력하면 해당 커맨드를 수행하는 식입니다.
led on<엔터> -> 모든 LED켜기
led off<엔터> -> 모든 LED끄기
set <16진수><엔터> -> 16진수에 해당되는 LED켜기 ex> set 0F -> 하위4개 켜고 상위4개 끄기

//--------------------------usart.c--------------------

#include <mega128.h>

#include <delay.h>

#include <usart.h>

// Declare your global variables here

void SystemInit();


void main(void)

{

// Declare your local variables here

char cmd[20];

char index=0,data;

SystemInit();

while (1){

delay_ms(10);

while(rx_counter0){

data=getchar();

if(data != 0x0A && data != 0x0D && index < 20){

putchar(data);

cmd[index] = data;

index++;

}

if(data==0x0D){

cmd[index]=NULL;

if(!strcmpf(cmd,"led on")){

PORTD = 0x00;

}

if(!strcmpf(cmd,"led off")){

PORTD = 0xFF;

}

if(cmd[0]=='s' && cmd[1]=='e' && cmd[2]=='t' && cmd[3]==' '){

PORTD=(char2hex(cmd[4])<<4) | char2hex(cmd[5]);

}

index=0;

putchar(0x0D);

}

}

};

}

//-------------------uart.c-------------- END



//-----------------------USART.H-----------------------

#define RXB8 1

#define TXB8 0

#define UPE 2

#define OVR 3

#define FE 4

#define UDRE 5

#define RXC 7


#define FRAMING_ERROR (1<<FE)

#define PARITY_ERROR (1<<UPE)

#define DATA_OVERRUN (1<<OVR)

#define DATA_REGISTER_EMPTY (1<<UDRE)

#define RX_COMPLETE (1<<RXC)


// USART0 Receiver buffer

#define RX_BUFFER_SIZE0 20

char rx_buffer0[RX_BUFFER_SIZE0];


#if RX_BUFFER_SIZE0<256

unsigned char rx_wr_index0,rx_rd_index0,rx_counter0;

#else

unsigned int rx_wr_index0,rx_rd_index0,rx_counter0;

#endif


// This flag is set on USART0 Receiver buffer overflow

bit rx_buffer_overflow0;

// Standard Input/Output functions

#include <stdio.h>

#include <string.h>


char char2hex(char data){

if(data>='0' && data <='9'){

return (data & 0x0F);

}else if(data>='a' && data <='f'){

return (data-0x61+10);

}else if(data>='A' && data <='F'){

return (data-0x41+10);

}else{

return 0;

}


}

// USART0 Receiver interrupt service routine

interrupt [USART0_RXC] void usart0_rx_isr(void)

{

char status,data;


status=UCSR0A;

data=UDR0;

if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)

{

rx_buffer0[rx_wr_index0]=data;

if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;

if (++rx_counter0 == RX_BUFFER_SIZE0)

{

rx_counter0=0;

rx_buffer_overflow0=1;

};

};

}


#ifndef _DEBUG_TERMINAL_IO_

// Get a character from the USART0 Receiver buffer

#define _ALTERNATE_GETCHAR_

#pragma used+

char getchar(void)

{

char data;

while (rx_counter0==0);

data=rx_buffer0[rx_rd_index0];

if (++rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0;

#asm("cli")

--rx_counter0;

#asm("sei")

return data;

}

#pragma used-

#endif

void SystemInit(){


DDRD=0xff;

DDRE=0x01;


// USART0 initialization

// Communication Parameters: 8 Data, 1 Stop, No Parity

// USART0 Receiver: On

// USART0 Transmitter: On

// USART0 Mode: Asynchronous

// USART0 Baud Rate: 9600

UCSR0A=0x00;

UCSR0B=0x98;

UCSR0C=0x06;

UBRR0H=0x00;

UBRR0L=0x67;


// Global enable interrupts

#asm("sei")


}


//-----------------------USART.H-----------------------END






http://magicom9.tistory.com/33

'Old category > 비밀의방' 카테고리의 다른 글

PS/2 키보드  (0) 2011.10.15
시리얼통신 (synchronous)  (0) 2011.10.15
시리얼통신 (unsynchronous)  (0) 2011.10.15
AVR 내부 EEPROM 사용 함수  (0) 2011.10.15
AVR을 이용한 PID 제어 소스  (0) 2011.10.15

+ Recent posts