20140425 -

c언어 2014. 4. 25. 17:17 Posted by Owen.K

파일과 스트림 그리고 기본적인 파일의 입출력


파일에 저장되어 있는 데이터를 참조하길 원한다고 가정한다면 구현한 프로그램과 참조할 데이터가 저장되어 있는 파일 사이에 데이터가 이동할수 있는 다리를 놓는 일. 그 데이터 이동의 경로가 되는 다리를 가리켜 '스트림(stream)'이라 한다. 


fopen함수 호출을 통한 파일과의 스트림 형성과 FILE 구조체


스트림을 형성할 때는 호출하는 함수. 굳이 알 필요는 없다.



입력 스트림과 출력 스트림의 생성


스트림은 한 방향으로 흐르는 데이터의 흐름을 의미한다. 스트림은 데이터를 파일로부터 읽어 들이기 위한 입력 스트림과 데이터를 파일에 쓰기 위한 출력 스트림으로 구분된다. 스트림 형성을 위한 fopen 함수의 호출방법은 두 가지가 인자로 전달되어야 한다.

첫 번째 전달인자            스트림을 형성할 파일의 이름

두 번째 전달인자            형성하고자 하는 스트림의 종류

ex) FILE * fp = fopen("data.txt", "wt");        //출력 스트림의 형성

"파일 data.txt와 스트림을 형성하되 wt모드로 스트림을 형성해라!" -> wt모드의 스트림은 텍스트 데이터를 쓰기 위한 출력 스트림을 뜻한다.

위의 스트림은 출력 스트림이기 때문에 파일에 데이터를 쓸 수는 있어도 읽지는 못한다. 만일 파일로부터 데이터를 읽기 원한다면 입력 스트림을 형성해야 한다.


FILE * fp = fopen("data.txt", "rt");            //입력 스트림 형성

"파일 data.txt와 스트림을 형성하되 rt모드로 스트림을 형성하라!" -> rt모드의 스트림은 텍스트 데이터를 읽기 위한 입력 스트림을 뜻한다.


fopen함수의 호출을 통해서 파일과의 스트림이 형성되었을 때 파일이 오픈되었다라고 표현하는 것이 일반적이다.


파일에 데이터를 써보자.

FirstFileWrite.c

해당 파일이 생성되는데 실행방법에 따라, 실행환경 및 설정에 따라서 파일이 생성되는 위치는 달라진다. 그래서 경로를 포함해서 이름을 지정해도 된다.

ex) FILE * fp = fopen("C:\\Project\\data.txt", "wt");

이런식으로, 경로도 설정할 수 있다. 여튼 이렇게 스트림이 형성되면, fp는 파일 data.txt를 지칭하는 포인터가 된다. 

fputc('A', fp);

 fp가 지칭하는 파일 data.txt에 문자 A가 저장되고 B 등등이 저장된다. fclose함수가 호출되면 데이터는 저장이 되고, data.txt와 연결되었던 출력 스트림은 소멸된다. 저장된 data파일을 찾아 실행 해보자.


스트림의 소멸을 요청하는 fclose 함수


fclose 함수의 호출을 통해서 개방되었던 파일을 닫아줘야 하는 이유는,

운영체제가 할당한 자원의 반환

버퍼링 되었던 데이터의 출력

함수 호출을 통해 스트림의 형성을 요청하는 것은 프로그래머지만 실제로 스트림을 형성하는 주체는 운영체제이다. 그리고 스트림의 형성을 위해서 시스템의 자원(메모리 등)을 할당한다.  이 자원은 파일을 닫아주지 않으면 할당된 채로 남아있게 되어, 그만큼의 자원손실을 초래, 파일의 사용이 끝나는 즉시 자원을 반환해줘야 한다. 



fflush함수

출력버퍼를 비운다는 것은 출력버퍼에 저장된 데이터를 목적지로 전송한다는 의미

입력버퍼를 비운다는 것은 입력버퍼에 저장된 데이터를 소멸시킨다는 의미

fflush 함수는 출력버퍼를 비우는 함수.    fflush 함수는 입력버퍼를 대상으로 호출할 수 없다.

파일대상의 입력버퍼를 비워야한 하는 상황이라는 것이 특별히 존재하지 않는다.


파일로 부터 데이터를 읽기.


FirstFileRead



파일의 개방 모드

스트림을 구분하는 기준1 : 읽기 위한 스트림..쓰기 위한 스트림 앞서 언급했기 때문에 넘어가도록 하겠다.


개행은 환경마다 다 틀리다.

MS-DOS의 파일 내 개행            \r\n

Mac의 파일 내 개행                  \r

UNIX                                      \n


스트림을 구분하는 기준 : 텍스트 모드, 바이너리 모드


파일 입출력 함수의 기본

int fputc(int c, FILE * stream)                        //문자출력

int fgetc(FILE * stream)                                //문자입력

int fputs(const char * s, FILE * stream)        //문자열 출력

char * fgets(char *s, int n, FILE * stream);    //문자열 입력



fprintf(fp, "123");

fprintf(fp, "567");            123567이 출력되는데 출력이 되는 순서위치를 기억하고 있다.

123567..EOF

feof함수 기반의 파일복사 프로그램

feof(fp) 파일 끝이 아니면 0이 반환

파일 끝이면 0이 아닌 값을 반환

20140425 - UBRRnH and UBRRnL - UBRR

ATMega128 2014. 4. 25. 14:26 Posted by Owen.K

UBRRnH and UBRRnL은 뭘까

 

서로 통신 하고자하는 장치끼리 데이터를 전달받고 전달할 때 서로 간에 통신속도는 같아야한다.

윈도우 BPS설정

우리는 윈도우와 ATMEGA를 이용해 통신을 한다.

윈도우에는 921600까지 bps를 지원한다.

ATMega는 2M bps를 제공한다.

115200 이 제일 빠른 bps다 

왜냐하면 아트메가는 아무리 빠른 pbs를 설정해봣자 2M이고

윈도우에서 지원하는 pbs인 115200 다음에는 230400이기때문에 2M를 넘는다

그러므로 115200이 가장 근접하므로 제일 빠른 속도 일 수 밖에 없다.

 

ATMEGA BPS설정



데이터 시트의 p177에 비동기 통신방식에 대한 BAUD 구하는 공식이 나온다.
UBRR에 대한 통신속도를 제어하기 위해서 그 값을 알고자 한다.

해당공식을 위와 같이 보면 UBRR = (fosc/(BAUD*16)-1)인데 문제는 fosc의 값과 BAUD의 값을 어디서 가져오느냐이다. fosc는 Oscillator를 의미한다. 따라서 기본적인 ATMega의 속도는 16MHz이다.

고로 16000000의 값이 들어가게 되는 것이며 BAUD는 통신속도를 의미하는데 이는 ATMega와 Window의 각각 속도를 비교해주고 정해주면 된다.

ATMega와 윈도우의 bps를 맞추고 비교하는 방법은 시작->보조프로그램->통신->하이퍼터미널에서 비교해보면 된다.

코딩에 의해 ATMega통신을 설정해보면

UBRR0L = 0x08;

UBRR0H = 0x00;

보면 계산해서 구한 UBRR의 값은 7.680556 데이터에 들어가면서 반올림되어 8이 입력된다. 

 

 UBRR0H

 UBRR0L

 0

 0

 0

 0

 0

 0

 0

 0

 1

 0

 0

 0

하지만 위의 소스는 bps를 바꿔줄 때 속도에 따라 값을 바꿔야해서 비효율적이다.

 USART.c

위와 같이 USART.c에서 UCSR의 세팅값을 바꾸기위한 각각의 비트를 만든거라고 보면 된다.

각 레지스터들의 bit역할에 대해 알아보려면 데이터 시트에 잘 설명 되어있다.(p.193)

A, B, C중 오늘은 A, B만 알아보자.

 

RXC(bit7) : 데이터의 수신이 완료되면 완료되었다는 신호를 보내기 위해 1의 값을 돌려주는 비트이며 Read Only이기 때문에 프로그래머가 건들수는 없다.

TXC(bit6) : 데이터의 전송왈료를 확인하는 비트이다. 해당 값이 0으로 되어있으면 끝나지 않음을 뜻하므로 초기값을 0으로 설정.

UDRE(bit5) : 송신버퍼로써 새로운 데이터를 받을 준비가 되었는지를 확인하는 bit이다.

FE(bit4) : 에러가 발생할 때 1이된다.

DOR(bit3) : 기존 데이터가 있는 번지에 다음 데이터가 오면 계속해서 덮어쓰며 사용할 것인지에 대한 bit.

UPE(bit2) : 패리티 에러를 검출하는 bit.

U2X(Double the USART Transmission Speed bit1) : 통신속도를 2배로 설정할 것인지에 대한 사용 bit (ATMega는 실제 1Mbps까지 가능하지만 해당 bit사용 여부로 2Mbps까지 사용가능 하다.)

MPCM(Mlti-Processor Communication Mode bit0) : ATMega를 2개로 연결해서 통신장비로 설정하는지에 대해서 세팅하는 bit이다. 해당 비트를 사용하고 ATMega를 여러 개로 연결해서 사용한다면 연결된 장치수만큼 속도가 배로 빨라진다.

위의 소스와 같이 우리가 설정가능한 bit는 6번 1번 0번만 세팅이 가능하므로

UCSR0A = (0>>TXC)|(0>>U2X)|(0>>MPCM)

 

다음 Register B를 알아보면,

 

 

bit 7~5번 까지는 interrupt에 해당하는 bit이다. 현재는 사용하지 않으니 언급 안하겠다.

RXEN(bit4) : 데이터를 수신하기 위한 수신기를 켜는 bit이다. 당연히 사용해야하므로 1값이다.

TXEN(bit3) : 데이터를 송신하기 위한 송신기를 켜는 bit이다. 당연히 사용해야하므로 1값이다.

UCSZn2(bit2) : 해당 bit는 홀로 사용되는 것이 아니라 UCSRnC의 2bit와 함께 사용하는 bit이다. UCSRnC에 내용과 함께 관련 표가 나온다. 문자열 사이즈를 bit로 사용하려고 하기에 해당 bit는 2번 bit이므로 0의값을 넣는다.

RXB8(bit1) : 데이터를 받을 때 9번 bit의 값을 사용하기 위한 bit이다. 실제 ATMega는 8bit 밖에 사용할 수 없다. 고로 해당 bit를 사용하므로 8번 bit자리를 의미

TXB8(bit0) : RXB8과 마찬가지로 데이터를 송신할 때 사용하는 bit이다. 송신 시 8번 bit의 자리를 의미한다.

 

UCSR0B = (1>>RXEN)|(1>>TXEN)|(0>>UCSZ2);


fclose(stdout)에 대한 설명


main1.c

fclose(stdin)에 대한 설명


main3.c


fopen 함수 호출을 통한 파일과의 스트림 형성과 FILE 구조체



위 함수의 첫 번째 인자로는 스트림을 형성할 파일의 이름을, 두 번째 인자로는 형성할 스트림의 종류에 대한 정보를 문자열의 형태로 전달한다. 이 함수는 해당 파일과의 스트림을 형성하고 스트림 정보를 FILE 구조체 변수에 담아서 그 변수의 주소 값을 반환한다.

FILE 구조체가 어떻게 정의되어 있는지 알 필요는 없다.


main2.c



데이터 전송에 대한 전반적인 루트


RS-232  -   선 전압 방법 5v의 잡음 때문에 12v로 확실히 전달하기 위해 12v를 쓴다. 

high는 12v, low는 -12v

RS-232에 대한 검색결과에 의한 정의 

PC와 음향 커플러, 모뎀 등을 접속하는 직렬 방식의 인터페이스의 하나이다. 인터페이스는 포트라고도 하여 일반적으로 직렬 포트라고 불리기도 한다. 


번호대로 살펴  보면

1. OSC(Osillator) : 오실레이터에서 기본적으로 최대출력을 9600bps의 속도를 유지한다. 여기서 오실레이터는 ATMega Chip의 속도이며 그 속도는 16Mhz이다. 이 속도를 기준으로 안정적인 통신 속도는 9600bps가 MAX이다.


아래 그림은 16MHz에 대한 내용이다. 실제로 오실레이터는 클럭속도를 전달한다.



2. UBRR : UBRR의 주소값을 통해서 제어하면 통신속도를 조절하도록 명령을 BAUD RATE GENERATOR에게 내린다. 이를 통해 전달하는 통신의 속도나 전달 받는 통신속도를 정한다.


3. BAUD RATE GENERATOR : 통신속도 제어 코드를 생성하는 장치이다. UBRR을 제어함으로써 UBRR이 BRG(BAUD RATE GENERATOR)에게 명령을 전달하면 전달된 명령을 바탕으로 BRG가 통신속도를 제어하는 것이다. 그리고 통신속도 조절한 것을 TRANSMIT SHIFT REGISTER와 CLOCK RECEIVE로 전달된다.


4. UDR : UDR은 UBRR과 마찬가지로 프로그래머가 제어하는 장치이다. 프로그래머가 전달하는 값을 통해 TRANSMIT SHIFT REGISTER를 제어하는 것이다.


5. TRANSMIT SHIFT REGISTER : BRG를 통해서 전달된 통신속도제어와 OSC를 통해서 전달된 통신속도를 바탕으로 데이터를 SHIFT(비트를 한칸 이동)하는 레지스터이다.

전송하는 통신속도와 전달받는 통신속도가 서로 상이하면 전달되는 데이터 자체가 오류난다.



-> URD로 부터 전달된 데이터의 값을 TSR로 전달하면 전달된 데이터는 왼쪽부터 1bit단위로 전압으로 변경하여 전달한다. 현재 셋팅된 통신속도는 8bps이다. 하지만 전달받는 장치의 셋팅된 통신속도가 16bps로 서로 다르다면 실제 위의 값이 HHLLHHLLHHHHLLHH(H:High, L : Low)와 같은 방식으로 전달 받을 것이다. 

그 때문에 정확한 데이터의 전송을 위해서는 전송하는 데이터의 통신속도와 받는 데이터의 통신속도를 맞추어야 한다.


6. PARITY GENERATOR : 패리티 코드를 사용하는지 여부에 대해서 제어해주는 장치 

패리티 코드란 오류를 검출하기 위한 패리티 비트를 추가해주는 코드를 의미. 이러한 패리티 비트는 

EVEN Parity(짝수 패리티)와 ODD Parity(홀수 패리티)로 나뉘어지는데 각 bps속도에 맞추어서 끝에 패리티 코드를 삽입해주는 것이다.

예) ODD Parity로 하겠다고 한다면 8bps의 통신속도에 맞추어서 11010110의 데이터를 전달한다해서 해당 데이터에 High가 총 5개가 있게 된다. High값을 기준으로 Odd Parity로 추가되는 비트에 0이나 1의 값을 주는 것이다. 위의 경우는 1이 5개로 홀수이므로 추가되는 데이터의 제일 끝자리에 0을 추가해서 9개의 bit를 전송해주면 되는 것이다.  이같은 방법은 해당 bit의 숫자를 받는쪽에서 같이 셋팅을 해줌으로써 전달된 데이터가 정확하게 전달이 되었는지 확인을 할 수 있게 된다.

다만 이러한 패리티 코드는 잘못된 데이터를 검출할 수 있으면 수정은 불가능하고 짝수개의 정보가 11로 수정이 된다면 오류검출을 하지 못한다는 단점이 있다.(2개 이상의 잡음(noise)가 발생하면)


7. CLOCK RECOVERY : 클럭 리커버리는 전달받은 데이터를 클럭속도에 맞추어서 데이터를 읽어내는데 도움을 주는 장치. BRG를 통해서 들어오는 통신속도 제어값과 같이 RECEIVE SHIFT REGISTER에 전달되어 정확하게 데이터를 읽어낼 수 있게 된다.


8. DATA RECOVERY : 데이터를 전달받는 장치라 보면 된다.


9. PARITY CHECKER : 패리티 코드가 사용되면 PARITY CHECKER를 통해서 오류가 있는 데이터인지 검출해준다.


10. RECEIVE SHIFT REGISTER : 최종적으로 전달되어 들어온 신호를 SHIFT로 하나씩 읽어가는 것이다. 이렇게 전달받은 데이터는 최종적으로 UDR로 들어와서 프로그래머에게 데이터를 전달 해준다.


참고)

UDR이 전달하는 UDR과 전달받는 UDR이 두 개인 이유는 데이터 시트에서 나오는 해당 UDR에 대한 정보이다. 전달할 때는 TSR의 기능으로 작동하며 전달받을 때는 RSR로 작동이 된다.


USART BLOCK Diagram에 대한 해석


클록 생성 논리 회로는 동기화 에 사용되는 외부 클럭 입력 동기화 논리로 구성 되어 있습니다. 

슬레이브 동작 및 전송 속도 생성기. 

XCK ( 전송 클락 ) 핀이있을 뿐 동기 전송 모드에서 사용 된다. 

송신기는 단일 쓰기 버퍼 직렬 로 구성되어 있습니다

등록 패리티 발생기, 다른 직렬 프레임 유형을 다루기위한 제어 로직을 이동. 

더 쓰기 버퍼는 어떤 프레임 사이 의 지연 도없이 데이터 의 연속 전송이 가능 합니다. 

더 수신기 는 클럭 및 데이터 복구 에 USART 모듈 중 가장 복잡한 부분입니다.

유닛. 회수 장치는 비동기 데이터 수신 을 위해 사용 된다. 복구 이외에, 단위 수신기 는 패리티 검사기 , 

제어 논리 시프트 레지스터 두 수준을 포함 버퍼 ( UDR ) 을 받는다. 수신기 는 송신기와

동일한 프레임 포맷을 지원 및 CAN 프레임 오류 데이터 오버런 패리티 오류 를 검출한다.



LCD.c와 LCD.h를 만들어 분할 컴파일 하기


LCD.c

LCD.h

main.c

Makefile

smart.h

USART.c

USART.h

Text 자체가 Text로 실행되는 것을 script파일이라 한다.






파일입출력


고수준 (fpintf, fscanf) :효율좋음, 응답속도안좋음, 버퍼 사용   

->fprintf(stdout, "..."), file, fscanf(stdin, "%d",&)

저수준(read, write) : 효율안좋음, 응답속도빠름, 버퍼 사용 안해서 CPU 사용률 증가

 

 

 

 

 

main4.c

 

열거형(Enumerated Type)의 정의와 의미


구조체나 공용체와 마찬가지로 자료형을 정의하는 방법. 열거형 기반의 자료형 정의방법은 

구조체 및 공용체와 유사하고 정의된 열거형 기반의 변수 선언 방법은 구조체 및 공용체와 완전히 동일


열거형의 정의와 변수의 선언

열거형으로 syllable이라는 이름의 자료형을 정의한다는 것은 syllable형 변수에 저장이 가능한

정수 값들을 결정하겠다. 변수에 저장이 가능한 값들을 열거하여 정의한다고 해서 열거형이라고 한다.


열거형 상수의 값이 결정되는 방식

enum smart

{

Test,

Apple,

Car

};

#define Test    0이라고 정의한 것과 동일하다. 

#define Apple  1이라고 정의한 것과 동일하다.

#define Car  2이라고 정의한 것과 동일하다.    메모리 차지 하지 않는다.

초기값을 정의 할 수 있다. 


enum smart

{

Test,

Apple=30,

Car

};

각각 출력해보면

0, 30, 31이 출력된다.


열겨형의 유용함은 이름있는 상수의 정의를 통한 의미 부여에 있다.

열거형은 구조체 및 공용체와 정의하는 방식이 유사함에도 불구하고 정의하는 목적에서 큰 차이가 있다. 

구조체와 공용체는 자료형의 정의에 의미가 있다. 변수를 성언하기 위해서 자료형을 정의하는 것이다.

열거형도 정의하고 나면 해당 열거형의 변수 선언이 가능하지만 이유는, 연관있는 이름을 동시에 상수로

선언할 수 있다. 

열거형의 유용함은 둘 이상의 연관이 있는 이름을 상수로 선언함으로써 프로그램의 가독성을 

높이는데 있다.


main1.c


main2.c


main3.c





Delay 최적화 시키기


main.c

Makefile

smart.h




직렬 병렬 통신


직렬 통신(Serial Signal) - 선이 적고, 시간증가, 비용 작음.

USB는 고속 시리얼,

UART(Universal Synchronous and Asynchronous serial Receiver and Transmitter

- 일반적인 비동기 송.수신 장치 저속 시리얼 Tx(본인 입장에서 가는선), 

   Rx(본인 입장에서 오는선),GND(그라운드선)로 구성되어 있다.

  UDRn에서 n은 0이나 1 number를 뜻함. 

대표적으로 USB가 직렬통신이다. 그리고

UART(Universal Synchronous and Asynchronous serial Receiver and Transmitter)이다.

UART는 일반적인 동기 비동기 수신 송신 장치의 양자이다. 보통 UART라고 부르지만 우리가 사용하는 

ATMega 제조사에서는 USART라고 한다. 수신과 송신을 하는 장치의 약자로써 UART는 

쓰기와 읽기 두 가지의 선이 존재한다고 본다. 

Data sheet에서 보면 Dual Programmable Serial USARTs라고 2개의 USART가 있다.

(USART가 2개 있는 것은 읽기 쓰기의 선이 2개가 아닌 실제로 2개가 존재한다.)

실제 주소값을 알아보면 같음을 알 수 있다. 

다만 ATMega가 읽기명령을 하게 되면 읽기 bit를 쓰기 명령을 하게 되면 쓰기 bit로 나타나며

이것은 프로그래머가 신경쓰지 않아도 자체적인 CPU에서 알아서 처리한다.

병렬 통신 - 버스통신으로 보면 되고, 많이 보낼 수 있지만 비용이 증가한다.

일반적으로 CPU내에 BUS로 각각의 장치들이 연결되어 있는데 이것을 병렬통신이라고 한다.



20140422 - LinkedList 삽입. LinkedList 삭제

c언어 2014. 4. 22. 17:50 Posted by Owen.K

LinkedList 앞삽입

LinkedList.c

LinkedList.h

main.c


중간삽입은 stpRear가 먼저 돌게 된다. 삽입 위치 탐색을 하여 와일문에서 빠져나오게 되면

head가 가리키는 곳과 stpRear가 가리키는 곳이 틀리다면 중간 삽입을 수행하고,

head가 가리키는 곳과 stpRear가 가리키는 곳이 같다면 앞 삽입을 수행한다.

stpRear가 가지는 주소값이 0이 될 때까지 반복되는 와일문에서 stpRear의 데이터와 stpNew의 데이터 중 stpRear가 더 클때 반복문을 빠져나온다. 이렇게 삽입할 위치는 판단하며 검색해 나가다가 삽입할 위치로 판단되면 break로 while문 탈출.

만약 head의 주소와 stpRear의 주소가 다르다면 중간/끝 삽입으로 들어가서 stpNew의 꼬리부분인 next가 stpRear 주소값을 가지고 stpFront의 next는 stpNew의 주소를 가지게 되어 중간 삽입이 완료된다.

만약 head의 주소와 stpRear의 주소가 같다면 처음 삽입으로 들어가서 stpNew의 꼬리 부분인 next가 head가 가리키는 주소를 가지게 되고 head는 stpNew의 주소를 가지게 되어 처음 삽입이 완료된다.



LinkedList 처음 중간 끝 삭제



포인터 주소로 이해할 수 있도록 노력하자 포인터는 엄연하게 주소값을

저장하는 변수이다. 헷갈려서 멘붕하지 않도록 하자

삭제 할것이 없을 떄는 바로 head를 리턴하여 그대로 내보내고,

만약 head와 stpRear가 가지는 주소값이 틀리다면 stpFront가 가지는 주소값의

next부분에 stpRear가 가지는 주소값의 next의 주소가 저장된다. 그리고 

stpRear가 가지는 주소값(동적할당)을 해제하면 중간/끝 삭제가 완료된다.

만약 head와 stpRear가 가지는 주소값이 같다면 head가 가지는 주소값의 

next가 가지는 주소를 head에 저장하고 stpRear가 가지는 주소값(동적할당)을 해제하면서

처음 삭제가 완료된다.


중복되는 소스 최적화 시키기

main.c

Makefile

smart.h


소스 컴패어로 함수의 소스들을 비교해 보면 PORTC부분만 달라진다는 걸 확인할 수 있다.

이를 정의하고 다듬어서 최적화 시켜보겠다.


LCD_Inst함수를 만들어서 smart.h파일에 같은 소스들을 정의하고 PORTC부분만 

ucInst인자값으로 넘긴다. 그리고 인자값들을 clear, return등의 PORTC부분을 #define으로 정의 후

해당하는 부분에 넣어준다.


Data함수 a만 쓰는 함수에서 쓰는 함수로 정의 하기


AVR Studio를 이용한 LCD출력



LCD_Data를 이용하여 LCD_Str로 문자열 출력하기


AVR Studio를 이용한 LCD출력



LCD_Str을 이용한 LCD_Num으로 숫자 출력하기


AVR Studio를 이용한 LCD출력



주소를 세팅하는 DDRAM


DDRAM의 주소를 세팅한다. LCD의 출력 위치를 자유자제로 바꿀 수 있다.

00.....................0F번지    16개

40.....................4F번지    16개    (LCD의 번지를 32개의 번지들)

AVR Studio를 이용한 LCD출력

0x40이면 주소의 두번째 줄 첫칸의 주소부터 출력이 된다.


Linked List 새롭게 변신


LinkedList.c

LinkedList.h

main.c

Free해제 하는 함수 만들기

1. 분리 head=head->next

2. 삭제 free(Temp);

3. 원래 Temp=head;

순서로 반복하게 되어 삭제 시키도록 한다.

printf하는 함수 만들기

1. 출력 printf("%c->",head->data);

2. 다음 연결 가리킴 head=head->next;

3. 반복을 head가 다음 값을 가리키지 않을 때까지

           0!=head;


insert의 중간 삽입하는 함수 만들기



LinkedList.c

LinkedList.h

main.c


전제 조건으로 알파벳들은 정렬이 되어 있어야 한다.