본문 바로가기
카테고리 없음

[AVR] AsynchronosCommunication - printf, scanf

by TSpoons 2024. 12. 4.

2. 새로운 project를 만들고 필요한 파일과 코드를 모두 추가하여라. 또한 uart_init()을 포함하여 필요한
초기화 함수를 모두 호출하여라. 초기화 작업을 마친 후 while() 루프에 추가한 후 실행시켜 보고 그 결과를 설명하여라. 물론 main() 함수에서 변수 ch를 미리 선언해야 한다.


 

 

 

3. 2 번의 코드에서 uart_putch(ch) 대신 uart_putch(ch+1)을 대입해서 실행시켜 보고 그 결과를 설
명하여라. 2번과 다르게 아스키코드가 1 더한 값이 대응되어 출력 되므로 입력: a -> 출력: b 식으로 나온다.

 

 

4. 다시 2 번의 코드로 복원한 후 터미널에서 엔터키를 치면 어떤 현상이 나타나는지 살펴보아라. 엔터키를
칠 때 RXD0 핀 (PE0)으로 수신되는 신호를 오실로스코우프로 포착하고 수신되는 값의 ASCII 코드를 찾아
라. start bit을 찾기 위해서는 트리거의 경사를 하강 에지로 선택하고 트리거 모드를 ‘Normal’로 두면 된다.
일단 파형을 포착한 다음에는 cursor를 x1과 x2 사이의 거리를 1/baud rate로 설정하고 두 커서 사이의 거
리가 고정된 채 함께 움직이는 모드로 설정하고 옆으로 한 비트씩 옮겨가면 각 비트의 값을 쉽게 파악할
수 있다. ASCII 문자 표에서 이 ASCII 값에 대응되는 문자가 무엇인지 찾아보아라.

 

엔터를 누르면 제일 앞으로 가는 동작을 한다. 

트리거의 조건을 하강 엣지로 선택하고 오실로스코프를 확인하면 다음과 같이 된다.

 

프레임은 다음과 같아서 0이 될 때, start bit이고, 1은 stop bit이다.

커서를 이용해서 구간의 신호의 주기를 파악 후 샘플링 과정을 거치면 다음과 같다.

0101100001 -> 0001101 = 13- vertical tap

 

 

5. 4 번에서 구한 값을 사용하여 사용자가 엔터 키를 쳤을 때에는 커서가 다음 줄 첫 번째 칸으로 이동하도록
2 번의 코드를 수정하고 그 내용을 설명하여라.

 

 

6. 사용자가 엔터 키를 치면 커서가 다음 줄 첫 번째 칸으로 이동한 후
>> UCSR0B: 0x??[줄바꿈]
와 같은 내용을 출력하도록 5 번의 코드에 필요한 내용을 추가하여라. 즉 키보드에서 엔터를 치면 줄을 바
꾼 다음 모니터 화면 “>> UCSR0B: 0x”란 문자열을 출력하고 그 다음에 UCSR0B 레지스터의 값을 출력한
다음 다시 줄을 바꾸어 커서를 새 줄의 맨 앞에 위치시켜야 한다. 예비 과제에서 작성한 uart_puts()
함수와 num2ascii() 함수를 사용하면 된다.

 

 

7. 모니터라는 표준 출력 장치를 가진 PC와 달리 임베디드 시스템에서 printf() 함수를 사용하려면 어떤
디바이스에 어떤 방식으로 내용을 출력해야 하는지 미리 설정해 주어야 한다. PC는 제조 업체와 상관없이
인터페이스가 표준화되어 있지만 임베디드 시스템은 그렇지 않기 때문이다. printf()와 scanf() 함수가
값을 출력하거나 값을 입력 받을 때 각각 uart_putch() 함수와 uart_getch() 함수를 사용하도록 쉽
게 등록할 수 있다. main() 함수에서 각 주변 장치를 초기화하는 곳에 fdevopen(uart_putch, uart_getch);
명령을 추가하여라. 이 함수를 호출하면 표준 출력과 표준 입력이 UART를 사용하도록 설정된다. 이 명령
을 실행한 후에는 printf()와 scanf() 함수를 PC에서 사용하던 것과 같은 방법으로 사용할 수 있다.
(한 가지 차이가 있다면 scanf() 함수를 실행시켰을 때 키보드로 입력한 내용이 화면에 표시되지는 않는
다.) printf() 함수를 사용할 수 있다면 예비 과제에서 작성한 num2ascii() 함수는 더 이상 필요 없
어진다. 6 번에서 추가한 내용을 printf() 함수를 사용하여 수정하고 내용을 설명하여라. printf(),
scanf(), fdevopen() 함수의 원형은 모두 stdio.h에 선언되어 있으므로 이 헤더 파일을 include해야
한다.

 

8. 이제 UART 수신 기능을 인터럽트로 처리해 보자. 이를 위하여 USART0의 수신 완료 인터럽트를 활성화시
키도록 uart_init() 함수를 수정하여라. 그리고 USART0의 수신 완료 인터럽트의 ISR을 파일에 추가하
여라. USART0의 수신 완료 인터럽트를 사용하면 더 이상 uart_getch() 함수를 사용해서는 안 된다. 그
기능이 겹치기 때문이다. 2 번 코드의 while() 루프 내용을 모두 지우고 이 기능을 ISR로 구현하자. ISR
에서 uart_putch() 함수를 사용하는 것은 바람직하지 않다. 아무 일도 하지 않고 기다리는 코드가 ISR에
들어가서는 안되기 때문이다. while() 루프 내용을 모두 지운 다음 ISR 에 다음 명령어만 추가한 후
UDR0 = UDR0


프로그램을 실행시켜 보고 그 결과를 자세하게 설명하여라. 왜 데이터를 보내기 전에 송신 버퍼가 비었는
지 여부를 검사하지 않아도 문제가 없는가? 

인터럽트 발생 여부에 따라 데이터를 받기 때문에 송신이 완료 될 때, 데이터를 다시 쓰므로 버퍼가 필요가 없다.

 

 

AsynchronousCommunication.zip
0.04MB