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와, 아날로그 비교기로 돌아오겠습니다.^^