20140423 (LCD 속도 최적화, 직렬 병렬 통신, USART Reg, 열거형, 파일입출력, read, write)
48일차
------------------------
ATMega128 LCD 제어
------------------------
- 소스코드 속도 최적화
Timing 그래프에서 각 명령 후 처리시간이 있다.
지금 소스에서는 그 시간을 10000, 500 등 충분할 것 같은 시간을
넣어 뒀으나, 최적 속도를 맞추는 작업을 한다.
LCD마다 속도가 조금씩 다르기에 수치가 다 똑같이 않다.
원본에 블럭친 곳이 수정할 부분.
- main.c
블럭친 부분이 수정된 부분
- smart.h
- main.c
조금 더 수정이 쉽도록 DNUM1,2 로 선언해 뒀다.
타이밍도를 참고하여
각 구역에 따라 비슷한 수치로 값을 줘보니
동작하지 않아서 계속 값을 올려 저 수치를 찾았다.
좀 깨름직한게 각각 다른 값을 줘야 할 터인데
강사님께서 ①, ③짝 ②, ④짝을 맞춰 넣으셨다.
아직 설명을 안해주셔서 이유는 확실히 모르겠으나
이유가 있겠지...
--- 통신
각 장비간 통신하는 방식이 직렬과 병렬이 있다.
병렬 : BUS...등등, 비용이 비쌈, 속도 빠름, 구현이 복잡.
직렬 : Serial..등등, 비용이 쌈, 속도 느림, 구현이 쉬움.
예전에는 외부병렬포트도 사용했지만 고속시리얼(USB)가 등장하면서
점차 사용 빈도수가 줄어 요즘은 보기 힘들어졌다고 한다.
- UART, USART
The Universal Asynchronous serial Receiver and Transmitter의 줄임말로
범용 비동기 통신. 직렬통신의 표준이다.
The Universal Synchronous and Asynchronous serial Receiver and Transmitter의 줄임말
범용 동기/비동기 통신을 지칭하는데 ATMel사에서 사용하는 직렬통신 방식.
비동기 : TX, RX, G가 있고, 동기에 비해 저속.
동기 : TX, RX, G, 클럭신호선 있고, 비동기에 비해 고속.
동기ㄴ 일정 시간마다 서로 통신인 상태를 유지 중인 신호를 주고 받기 때문에
통신 신호에 통신 시작과 끝을 알리는 비트자리를 확보하기 때문에
비동기에 비해 빠르다.
비동기는 매 신호마다 시작과 끝을 알리는 비트를 포함하기에 동기에 비해 좀 느리다.
- USART 관련 Reg
UDR0 : 0x2C
UDR1 : 0x9C
UCSR0A : 0x2B
UCSR1A : 0x9B
UCSR0B : 0x2A
UCSR1B : 0x9A
UCSR0C : 0x95
UCSR1C : 0x9D
UBRR0L : 0x29
UBRR1L : 0x99
UBRR0H : 0x90
UBRR1H : 0x98
- C
----------------
열 거 형
----------------
- 열거형도 자료형을 정의하는 것인데 아래 예제를 참고하자
ex) 소스
#include <stdio.h>
enum smart
{
test,
apple,
car,
};
int main()
{
printf("%d \n", test);
printf("%d \n", apple);
printf("%d \n", car);
return 0;
}
출력 화면
#include <stdio.h>
enum smart
{
test = 100,
apple,
car,
};
int main()
{
printf("%d \n", test);
printf("%d \n", apple);
printf("%d \n", car);
return 0;
}
출력 화면
#include <stdio.h>
enum smart
{
test,
apple = 50,
car,
};
int main()
{
printf("%d \n", test);
printf("%d \n", apple);
printf("%d \n", car);
return 0;
}
출력 화면
위의 예제를 보니 1씩 증가한다.
실제로 사용하는 경우 이렇게 사용한다고 한다.
ex) 소스
#include <stdio.h>
enum smart
{
test,
apple,
star,
car,
house,
money,
smart_END
};
char str[smart_END][6] =
{
"test", "apple","star", "car", "house", "money"
};
int main()
{
int iCnt;
char Val[200];
printf("단어를 입력하세요\n");
scanf("%s", Val);
for(iCnt = test; smart_END > iCnt; ++iCnt)
{
if(0 == strcmp(Val, str[iCnt]) )
{
printf("입력한 단어와 일치하는 숫자는 %d 입니다.\n", iCnt);
break;
}
}
return 0;
}
이런식으로 사용한다고 한다.
위 소스에서 자세히 볼게 블럭친 부분이다.
smart_END가 최대 수를 저장하고 있으니
또 새로 추가되는 사항이 있을 시 변경할 필요가 없어져 유용하다.
--- 파일 입출력
파일 입출력은 고수준과 저수준이 있다.
고수준 : 효율 ↑ 응답속도↓ 버퍼 사용
저수준 : 효율 ↓ 응답속도↑ 버퍼 비사용
운영체제 입장에선 고수준 (버퍼 사용으로 CPU 점유율이 낮다.)
프로그램 입장에선 저수준 (버퍼 비사용으로 응답속도가 높지만 CPU 점유율이 높아진다)
고수준 함수 : fprintf, fscanf
저수준 함수 : write, read
고수준에서는 stdin, stdout, stderr을 인식하지만
저수준에서는 0, 1, 2만 인식한다.
read함수는 scanf에 비해 보안성이 좋다만,
프로그래머가 실수할 시 그 만큼 메모리를 덮어 씌우게 되니 주의해야 한다.
- 원형
ssize_t write(int fd, const void *buf, size_t count);
ssize_t read(int fd, void *buf, size_t count);
fd : 파일 디스크립터
buf : 저장 버퍼
count : 입출력 문자 갯수
--- read()
#include <fcntl.h>
int read( int handle, void *buffer, int nbyte );
The read() function attempts to read nbytes from the file associated with handle, and places the characters read into buffer. If the file is opened using O_TEXT, it removes carriage returns and detects the end of the file.
The function returns the number of bytes read. On end-of-file, 0 is returned, on error it returns -1, setting errno to indicate the type of error that occurred.
enter 까지 입력 받는다.
--- write()
#include <fcntl.h>
int write( int handle, void *buffer, int nbyte );
The write() function attempts to write nbytes from buffer to the file associated with handle. On text files, it expands each LF to a CR/LF.
The function returns the number of bytes written to the file. A return value of -1 indicates an error, with errno set appropriately.