본문 바로가기

AVR/AVR 연습, Tutorial

AVR UART 비동기 통신 인터럽트 방식 문자 비교 LED ON/OFF 제어하기 - AVR 연습



들어가면서..


이번 포스팅은 UART통신을 AVR에서 제공하는 인터럽트 방식으로 제어해 봤는데요, 사용되는 인터럽트는 수신 인터럽트와 수신된 데이터가 없을때 인터럽트가 발생하는 버퍼상태 인터럽트를 사용해 봤습니다. 수신인터럽트는 위 사진과 같은 순서로 동작하고 버퍼상태 인터럽트도 위와 유사하게 UDR레지스터에 아무것도 없을때 인터럽트가 걸리게 되며, 인터럽트를 처리하는 부분에서 UDR 레지스터에 쓰기를 함으로서 데이터를 전송할 수 있습니다.


 계속해서 UART만 포스팅하다 보니 지루하고 사용하는 이미지가 계속해서 중복되서 재미가 없네요, 그래서 이번엔 시작 사진을 이론에서 사용하던 식으로 바꾸어 보았습니다. 그리고 이제 UART 포스팅은 한개만 더하면 끝이랍니다. :<



회로도는 이렇습니다.




회로도는 역시 USB to UART와 AVR 보드간에 연결되는 이전 포스팅과 동일한 회로도 입니다.



CodeVision AVR용 소스코드


#include <tiny2313.h>    // tiny2313 입출력과 관계된 헤더파일을 포함합니다.


unsigned char data, receive;    // Char형 전역변수 data, receive를 생성합니다.


interrupt [USART_RXC] void usart_rx_isr(void)    // USART 데이터 수신시 이 부분으로 점프합니다.

{

receive = 1;    // receive 변수를 1로 설정합니다.

data = UDR;    // data 변수에 UDR레지스터 값을 저장합니다.

}


interrupt [USART_DRE] void usart_dre_isr(void)    // UDR 레지스터가 비었을 때 이 부분으로 점프합니다.

{

if(receive == 1)    // receive 변수가 1이면

{

UDR = '_';    // UDR레지스터에 '_' 문자 쓰기 ('_' 문자 전송)

while((UCSRA&0x20) == 0);    // UDR 레지스터가 비게 되면 다음라인으로

UDR = 'o';    // UDR레지스터에 'o' 문자 쓰기 ('o' 문자 전송)

while((UCSRA&0x20) == 0);    // UDR 레지스터가 비게 되면 다음라인으로

UDR = 'k';    // UDR 레지스터에 'k' 문자 쓰기 ('k' 문자 전송)


receive = 0;    // receive 변수를 0으로 설정합니다.

}

UCSRB = 0x98;    // UART 수신, 송신 및 수신인터럽트를 허용하고, UDR 버퍼상태 인터럽트를 차단합니다. 

}


void main(void)    // main 함수를 호출합니다.

{

DDRB=0xFF;    // B포트 전체를 논리상태 1 (5V)로 설정합니다.

PORTB=0x00;    // B포트 전체 초기상태를 논리상태 0 (0V)로 설정합니다.


UCSRA=0x00;    // UCSRA 초기화 (별도 옵션 없음)

UCSRB=0x98;    // UCSRB UART 수신, 송신 및 수신인터럽트를 허용하고, UDR 버퍼상태 인터럽트를 차단합니다.

UCSRC=0x06;    // 데이터 전송 비트 수를 8비트로 설정합니다.

UBRRH=0x00;    // 통신속도 설정 상위 바이트 (하위에서 255를 초과하지 않으므로 사용하지 않습니다.)

UBRRL=0xCF;    // 통신속도 설정 하위 바이트 207로 설정 2400bps의 통신속도를 가집니다.


#asm("sei")    // 전체 인터럽트를 허용합니다.


while(1)    // 아래 구문을 무한 반복합니다.

{

if(data == 'y')    // data 변수가 문자'y'와 같으면

{

PORTB=0xFF;    // B포트 전체 논리상태 1 (5V) 출력

UCSRB = 0xB8;    // UART 수신, 송신, 수신인터럽트를 허용하고, UDR 버퍼상태 인터럽트를 허용합니다.

}

if(data == 'n')    // data 변수가 문자 'n'과 같으면

{

PORTB=0x00;    // B포트 전체 논리상태 0 (0V) 출력

UCSRB = 0xB8;    // UART 수신, 송신, 수신인터럽트를 허용하고, UDR 버퍼상태 인터럽트를 허용합니다.

}

}

}



AVR Studio용 소스코드


#include <avr/io.h>    // AVR 입출력에 관한 헤더파일을 포함합니다.

#include <avr/interrupt.h>    // 인터럽트 관련 헤더 파일을 포함합니다.


unsigned char data, receive;    // Char형 전역 변수 data, receive를 생성합니다.


ISR(USART_RX_vect)    // USART 데이터 수신시 이 부분으로 점프합니다.

{

receive = 1;    // receive 변수를 1로 설정합니다.

data = UDR;    // data 변수에 UDR레지스터 값을 저장합니다.

}


ISR(USART_UDRE_vect)    // UDR 레지스터가 비었을 때 이 부분으로 점프합니다.

{

if(receive == 1)    // receive 변수가 1이면

{

UDR = '_';    // UDR레지스터에 '_' 문자 쓰기 ('_' 문자 전송)

while((UCSRA&0x20) == 0);    // UDR 레지스터가 비게 되면 다음라인으로

UDR = 'o';    // UDR레지스터에 'o' 문자 쓰기 ('o' 문자 전송)

while((UCSRA&0x20) == 0);    // UDR 레지스터가 비게 되면 다음라인으로

UDR = 'k';    // UDR 레지스터에 'k' 문자 쓰기 ('k' 문자 전송)


receive = 0;    // receive 변수를 0으로 설정합니다.

}

UCSRB = 0x98;    // UART 수신, 송신 및 수신인터럽트를 허용하고, UDR 버퍼상태 인터럽트를 차단합니다. 

}


int main(void)    // main 함수를 호출합니다.

{

DDRB=0xFF;    // B포트 전체를 논리상태 1 (5V)로 설정합니다.

PORTB=0x00;    // B포트 전체 초기상태를 논리상태 0 (0V)로 설정합니다.


UCSRA=0x00;    // UCSRA 초기화 (별도 옵션 없음)

UCSRB=0x98;    // UCSRB UART 수신, 송신 및 수신인터럽트를 허용하고, UDR 버퍼상태 인터럽트를 차단합니다.

UCSRC=0x06;    // 데이터 전송 비트 수를 8비트로 설정합니다.

UBRRH=0x00;    // 통신속도 설정 상위 바이트 (하위에서 255를 초과하지 않으므로 사용하지 않습니다.)

UBRRL=0xCF;    // 통신속도 설정 하위 바이트 207로 설정 2400bps의 통신속도를 가집니다.


sei();    // 전체 인터럽트를 허용합니다.


while(1)    // 아래 구문을 무한 반복합니다.

{

if(data == 'y')    // data 변수가 문자'y'와 같으면

{

PORTB=0xFF;    // B포트 전체 논리상태 1 (5V) 출력

UCSRB = 0xB8;    // UART 수신, 송신, 수신인터럽트를 허용하고, UDR 버퍼상태 인터럽트를 허용합니다.

}

if(data == 'n')    // data 변수가 문자 'n'과 같으면

{

PORTB=0x00;    // B포트 전체 논리상태 0 (0V) 출력

UCSRB = 0xB8;    // UART 수신, 송신, 수신인터럽트를 허용하고, UDR 버퍼상태 인터럽트를 허용합니다.

}

}

return 0;    // main 함수에 프로그램 정상 종료 0을 리턴합니다.

}



정리하면서..


짜잔.. 포스팅을 거저 했습니다.

이 소스코드의 동작은 http://binworld.kr/61 다음 포스팅의 동영상과 동일하게 동작합니다.

빨리 UART 포스팅 한가지 더 끝내고 곧 ADC와, 아날로그 비교기로 돌아오겠습니다.^^