ATmega128 LCD 숫자 출력 - ATmega128 LCD susja chullyeog

47일차

------------------------

ATMega128 LCD 제어

------------------------

- 코드 최적화

소스 코드에 중복된 부분이 많으니

중복된 부분을 지워주는 최적화

- main.c

소스코드에서           으로 된 부분은 다 중복된 부분이다.

- 이것을 간결화 한 코드

           으로 된 부분이 수정된 곳.

- smart.h (헤더파일에 추가된 부분)

......

#define INST_CLEAR      0x01  //  Clear
#define INST_RETURN    0x02  //  Return
#define INST_ENTRY      0x06  //  I/D = 1(Increase 1, Decrease 0), S = 0
#define INST_FUNCTION 0x3C  //  8bit, 2Line, 5x11
#define INST_CURSOR   0x14  //  Cursor SET, Moving right.
#define INST_DISPLAY   0x0F  //  Display light ON, cursor ON, blinking of cursor ON
......

- main.c

         으로 블록된 부분만 수정하면 인자로 문자를 받아 출력이 가능하다.

- 좀 더 기능을 추가해 문자열을 출력.

void LCD_Str(const unsigned char * cString)
{
  while(0 != *cString)
  {
    LCD_Data(*cString);
    ++cString;
  }
}

- 또 기능을 추가해 숫자를 출력.

숫자의 경우 153이란 숫자를 출력하려면

문자 3글자가 출력되어야 한다.

간단히 char형으로 (최대 255까지 가능하니 3글자만 필요) 구현해 보자.

void LCD_Num(unsigned char ucNum)
{
  static unsigned char ucBuff[] = "123";    //  3자리 확보 보기 쉽게

  ucBuff[

0= '0' + (ucNum / 100);
  ucBuff[1= '0' + ( (ucNum % 100) / 10);
  ucBuff[2= '0' + ( (ucNum % 100) % 10);

  LCD_Str(ucBuff);
}

ucBuff[] = "123" 초기값을 123으로 넣어준 이유는

3글자를 받는데 이것도 문자열로 취급해야 하니 맨 마지막에 NULL이 들어가야 하므로

"123" 해주면 3자리 확보하고 맨 마지막에 NULL이 들어간다.

static을 붙여준 이유는 자주 쓰게 되면 메모리를 계속 할당 해제할 경우

느려지게 되므로 속도를 높이고자 사용하였다.

자주 쓰지 않는다면 static을 붙이지 않는게 좋다.

실습 화면

ATmega128 LCD 숫자 출력 - ATmega128 LCD susja chullyeog

- LCD_Num을 이용해 자료형들의 크기 확인

int main(void)
{
  LCD_Init();
  LCD_Num(sizeof(char));
  LCD_Num(sizeof(int));
  LCD_Num(sizeof(double));
  LCD_Num(sizeof(char *));
  LCD_Num(sizeof(int *));
  LCD_Str("                         ");
  LCD_Num(sizeof(short));
  LCD_Num(sizeof(float));
  LCD_Num(sizeof(long));
  LCD_Num(sizeof(long double));
  LCD_Num(sizeof(long long));
  
  while(1);
  return 0;
}

char                 :    1

char *              :    2

int                    :    2

int *                 :    2

short                :    2

long                 :    4

float                 :    4

double             :    4

long double      :    4

long long         :    8            (단위 : byte)

- DDRAM

LCD_Inst(INST_SET_DDRAM | 0x40);

이런식으로 명령을 주게 되면 2번째 줄부터 출력을 실행한다.

--------------------------------------------------

--- Cursor or Display R/L, S/C 옵션에 대하여...

도대체 R/L, S/C 의 옵션이 뭘 하는지 알아보기

우선 Cursor or Display 옵션은 DDRAM의 메모리를

바꾸지 않고 화면에 출력하는 위치를 조절할 수 있다.

  LCD_Init();

//  LCD_Inst(0x06);  // entry I/D = 1(2 1/0),   S = 0(1 ON(1)/OFF(0))
//  LCD_Inst(0x14);  //  S/C = 0(8 1/0), R/L =  1(4 1/0)

//  여기까지 이게 적용됨.
  LCD_Inst(INST_SET_DDRAM | 0x02);
  LCD_Str("abc");
  LCD_Inst(INST_SET_DDRAM | 0x42);
  LCD_Inst(0x06);  // entry I/D = 1(2 1/0),   S = 0(1 ON(1)/OFF(0))
  LCD_Inst(0x??);  //  S/C = (8자릿수 1/0), R/L =  (4자릿수 1/0).
  LCD_Str("123");

- C, R 옵션을 줬을 경우

123이 C,R 옵션이 적용됨.

원래 옵션에서 R의 옵션이 더 더해져 오른쪽으로 한 칸 더 이동했다.

- C, L 옵션을 줬을 경우

123이 C,R 옵션에서 L 옵션이 더해져 왼쪽으로 한 칸 더 이동했다.

- S, R 옵션을 줬을 경우

123 뿐만 아니라 abc 까지. 화면 전체가 오른쪽으로 더 이동했다.

- S, L 옵션을 줬을 경우

위와 마찬가지로 abc, 123 화면 전체가 왼쪽으로 더 이동했다.

- C

--------------------------

Single Linked List

--------------------------

--- 리스트에 삽입과 삭제

- 삽입의 경우

1. 중간에 삽입

2. 맨 뒤에 삽입

3. 맨 앞에 삽입

이 세가지 경우의 순서에 따라 코드를 작성.

각 앞뒤의 리스트를 잃어버리지 않고 잘 연결하는 것이 중요.

- 삭제의 경우

1. 중간에 삭제

2. 맨 끝 삭제

3. 맨 앞 삭제

4. 없는 문자 삭제

이 경우에 따라 작성.

- 삽입

Node * Node_Insert(Node * Head, char cData)
{
  Node * stpNew;
  Node * stpFront;
  Node * stpRear;

  stpFront

= Head;
  stpRear = Head;
  stpNew = malloc(sizeof(Node));

  stpNew-

>data = cData;
  stpNew->next = NULL;while(0 != stpRear)  //  삽입 위치 검색
  {
    if(stpNew->data < stpRear->data)  // 삽입 위치 판단
    {
      break;
    }
    stpFront = stpRear;
    stpRear = stpRear->next;
  }if(Head != stpRear)  // 처음인지 그 이후인지 확인.
  {  // 중간, 끝
    stpNew->next = stpRear;
    stpFront->next = stpNew;
  }
  else  // 맨 앞
  {
    stpNew->next = Head;
    Head = stpNew;
  }return Head;
}

- 삭제

Node * Node_Del(Node * Head,

char cData)
{
  Node * stpFront;
  Node * stpRear;

  stpFront

= Head;
  stpRear = Head;while(0 != stpRear)  //  삭제 위치 검색
  {
    if(cData == stpRear->data)  // 삭제 위치 판단
    {
      break;
    }
    stpFront = stpRear;
    stpRear = stpRear->next;
  }if(0 == stpRear)  //  없는 문자일 경우
  {
    return Head;
  }
  else if(Head != stpRear)  // 중간, 끝
  {
    stpFront->next = stpRear->next;
  }
  else    // 처음
  {
    Head = Head->next;
  }

  free(stpRear);

return Head;
}