본문 바로가기

AVR/AVR 연습, Tutorial

AVR UART 비동기 통신 사용자 함수 문자열 비교 LED ON/OFF 제어하기 - AVR 연습


한 2회 포스팅 정도 더 보게될 사진입니다. 다른사진을 쓰고 싶어도, USB to UART, 모듈로 구성이 비슷해서요.^


사용된 회로도를 볼까요!




역시 2회정도 다음 포스팅에서 계속해서 나올 회로도 입니다. PC부분은 USB to UART 부분과 PC를 통틀어 의미합니다.


 이거 이번 포스팅은 너무 거저 포스팅 하는것 같지만... 가겠습니다. ㅎ



CodeVisionAVR용 소스코드


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

#include <delay.h>    // 지연함수 관련 헤더파일을 포함합니다.

#include <string.h>    // 문자열 관련 헤더파일을 포함합니다.


char rx_char(void)    // UART 수신관련 사용자 함수를 생성합니다.

{

while((UCSRA&0x80) == 0);    // UCSRA 레지스터에서 RXC 수신완료 비트가 1이 되면 다음라인으로

return UDR;    // 수신된 8비트 값 UDR 데이터 반환

}


void tx_char(char tx_data)    // UART 송신관련 사용자 함수를 생성합니다.

{

while((UCSRA&0x20) == 0);    // UCSRA 레지스터에서 UDR이 빌 때 UDRE 레지스터 비트가 1이 되면 다음라인으로

UDR = tx_data;    // UDR 레지스터에 tx_data값 쓰기

}


void rx_string(char *str)    // UART 문자열 수신관련 사용자 함수를 생성합니다.

{

int i=0;    // 초기값이 0인 정수형 변수 i 생성


while((str[i]=rx_char()) != '\n')    // str[i] 배열에 문자수신을 한 후 해당 문자가 개행문자 '\n' 일 때까지

{

i++;    // 변수 i 값 1 증가

}

str[i] = '\0';    // str[i] 배열에 '\0' 널문자 쓰기

}

void tx_string(char *str)    // UART 문자열 송신관련 사용자 함수를 생성합니다.

{

int i=0;    // 초기값이 0인 정수형 변수 i 생성


while(str[i] != '\0')    // str[i] 배열 값이 '\0' 문자일 때까지

{

tx_char(str[i]);    // 문자 송신 함수를 이용 str[i]배열에 저장된 문자 송신

i++;    // 변수 i 값 1 증가

}

}


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

{

unsigned char k;    // 부호없는 문자형 변수 k 를 생성합니다.

char data[6];    // 문자형 배열 data[6]을 생성합니다.


DDRB=0xFF;    // B포트 전체를 출력으로 설정합니다.

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


UCSRA=0x00;    // UART 설정 레지스터A 별도 설정없음 (입력하지 않아도 초기화 됩니다.)

UCSRB=0x18;    // UART설정 레지스터B RXEN과 TXEN을 비트1로 설정해서 송수신기능을 활성화 합니다.

UCSRC=0x06;    // UART설정 레지스터C UCSZ1과 UCSZ0을 비트1로 설정해서 8비트 데이터 전송으로 설정합니다.

UBRRH=0x00;    // UBBR 통신속도 설정레지스터 상위 바이트로 8비트를 초과하지 않아 UBRRL에 모두 입력됩니다.

UBRRL=0xCF;    // UBRR 통신속도 설정레지스터 하위 바이트로 8Mhz크리스탈 2400bps속도로 207로 설정합니다.


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

{

rx_string(data);    // 문자열 수신 사용자 함수 사용 data변수에 문자열 저장

 

if(!strcmp(data, "on"))    // 문자열 비교 함수 strcmp 사용 data배열값과 문자열 "on"이 같으면

{

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

tx_string("Light On");    // 문자열 송신 사용자 함수 사용 "Light On" 문자열 송신

}

if(!strcmp(data, "off"))    // 문자열 비교 함수 strcmp 사용 data배열값과 문자열 "off"이 같으면

{

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

tx_string("Light Off");    // 문자열 송신 사용자 함수 사용 "Light Off" 문자열 송신

}

if(!strcmp(data, "blink"))    // 문자열 비교 함수 strcmp 사용 data배열값과 문자열 "blink"이 같으면

{

for(k=0; k<10; k++)    // 아래 구문을 10회 반복

{

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

delay_ms(200);    // 위 상태를 약 0.2초간 유지

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

delay_ms(200);    // 위 상태를 약 0.2초간 유지

}

tx_string("Blink OK");    // 문자열 송신 사용자 함수 사용 "Blink OK" 문자열 송신

}

}

}



AVR Studio 4용 소스코드


#include <avr/io.h>    

#define F_CPU 8000000UL    

#include <util/delay.h>   

#include <string.h>


char rx_char(void)    

{

while((UCSRA&0x80) == 0);    

return UDR;  

}


void tx_char(char tx_data)    

{

while((UCSRA&0x20) == 0);    

UDR = tx_data;

}


void rx_string(char *str)

{

int i=0;


while((str[i]=rx_char()) != '\n')

{

i++;

}

str[i] = '\0';

}

void tx_string(char *str)

{

int i=0;


while(str[i] != '\0')

{

tx_char(str[i]);

i++;

}

}



int main(void)

{

unsigned char k;

char data[6];


DDRB=0xFF;    

PORTB=0x00;


UCSRA=0x00;  

UCSRB=0x18;  

UCSRC=0x06;  

UBRRH=0x00; 

UBRRL=0xCF; 


while(1)   

{

rx_string(data);

 

if(!strcmp(data, "on"))

{

PORTB=0xFF;

tx_string("Light On");

}

if(!strcmp(data, "off"))

{

PORTB=0x00;

tx_string("Light Off");

}

if(!strcmp(data, "blink"))

{

for(k=0; k<10; k++)

{

PORTB=0xFF;

_delay_ms(200);

PORTB=0x00;

_delay_ms(200);

}

tx_string("Blink OK");

}

}

return 0;

}




알고리즘


먼저 하이퍼터미널에 대한 사용방법은 이전 포스팅 UART 문자 제어 다음 링크에서 확인하실수 있습니다. 

 AVR UART 문자비교 LED 제어 포스팅


해당 코드의 알고리즘은 기존에 구성한 문자 송수신 함수를 응용해서 문자열을 처리하는데요, 문자열 송신 함수의 경우 "Hello"라는 문자열을 송신하게 되면 입력한 문자열은


str[0]

str[1]

str[2]

str[3]

str[4]

str[5]

H

e

l

l

o

\0


다음 표 처럼 각각 한 문자씩 송신을 하게 됩니다. 그러면 송신함수에서는 기존 문자 송신 함수로 한 문자씩 보내되 문자열의 경우 끝에 문자열 종료를 알리는 \0 (Null문자)가 추가로 쓰여지게 되는데 이값이 들어오면 보내는 것을 종료하면 됩니다.


문자열 수신의 경우에는 PC측에서 문자열을 입력하고 Enter를 누르는 입력을 누름으로서 수신되는 개행문자(\n)이 있어야 합니다. 만약 Hello를 누르고 Enter 입력을 했다면.


str[0]

str[1]

str[2]

str[3]

str[4]

str[5]

H

e

l

l

o

\n


처음에는 다음과 같이 입력되게 됩니다. 그런데 문자열에서는 문자열 끝에 문자열의 끝을 알리는 \0 (Null문자)값이 들어가야 하는데 끝 라인에 Enter (개행문자 \n)가 들어가 있고 배열 참조 변수 i 는 5이므로 str[5]에 \0 널 문자를 덮어씌워 줍니다.



동작영상




AVR 연습 포스팅 또하나 끝~~ 다음에는 인터럽트 방식 UART 포스팅으로 찾아 오겠습니다.^