미안해님 보세요

버닝중 작성일 13.11.27 05:07:00
댓글 1조회 1,355추천 1

아.. 답변이 늦었네요.. 하는건 별로 없는데 나름 바쁘다 보니..ㅎㅎ

 

일단 저는 전체적인 흐름과 짜임, 해결방법만 알려드릴게요.

나머지는 본인이 채우세요ㅎㅎ

 

계산기를 받는데 어떤신호를 받는지는 모르겠습니다.

키패드를 싱크커런트로 쓰는지 소스 커런트로 쓰는지,

무슨 버튼을 눌렀을 때 어떤 신호가 발생되는지에 대해 아는게 전무하니까요..

그 정도야 lcd에 숫자를 띄우긴 하셨다니 상관이 없을 것 같고..

 

138549357283744.jpg
이런 흐름을 가지고 소스를 짜면 무난할 것 같습니다

 

상세 설명 하자면

외부인터럽트를 하나 사용합시다. 간단하게 EXT_INT3를 사용하도록 하죠.

뭐 레지스터를 설정해 주어야 하는데 코드비전에선 클릭 몇번 하면 설정을 해주니 간단합니다.

 

여튼 이안에 입력값이 들어오면 입력값을 숫자와 연산자로 나누어 배열에 저장해 주도록 해요.

data=입력값;을 하고

138549418979746.jpg
이런식으로요..

 

그래서

c=Matric_in(data);

if( (47<c)  && (c<58) ) //47은 0의 아스키 값이고 58은 9의 아스키 값이에요. 그러니까 이 if는 만약 숫자이면!

{

  if(c=='0')  {cal_1[k]=0; dsp[k]='0'; dsp[k+1]='\0';}   //끝에 '\0'(=NULL)을 넣어주는이유는 dsp를 그대로 lcd에

   ....                                                                           출력시키려고 하는거에요. 문자열을 출력하려면 문자열 끝에

  if(c=='9')  {cal_1[k]=9; dsp[k]='9'; dsp[k+1]='\0';}             NULL신호는 필수적으로 넣어줘야해요.

}

else if(만약에 숫자가 아니라 연산기호이면...) //그냥 else를 써도 무방하겠지만 예상치 못한 결과를 미연에 방지해서

{                                                                 돈케어컨디션을 걸어주기 위해서 else if 로 정확히 구분해 줍시다.

     if(c=='<') 면 이전 신호를 지워야 하니까 k--; dsp[k]='\0'; cal_1[k]='\0'; 를 넣어주고

     if(c=='@')만약에 클리어하라고 나오면 lcd를 초기화(lcd_clear(); or lcd_init(16);)하고 변수값들을 전부 초기화 해주세요.

    배열을 초기화 할 땐 memset(배열이름,배열전체에 넣을 값,sizeof(배열이름))을 하시면 배열 전체를 특정값으로 세팅할 수 있어요. 근데 이게 atmega에서도 먹히는 지는 안써봐서 모르겠는데 안되면 for문으로 돌려서 하나하나 초기화 해야죠ㅋㅋ

    

  if(dsp[k-1]이전에 들어간 값이 상수이면)//연산자가 이중으로 적히는 사태를 방지해주는 if문

  {

     if(c=='=')이면 출력을 해야죠. 출력하기 위해서 두가지 플래그를 사용해 봐요.

     {flag=1; lcd_flag=1;}  //이 두개는 제가 임의로 만든 변수에요. 메인에 이 플래그가 셋되면 계산이 동작되도록 설계해요.

     이제 나머지 연산자들을 위에 숫자 넣듯이 넣어주세요.

 }

다음에 인터럽트 신호가 걸리면 배열의 다음 자리에 숫자를 넣어야 하니

k++;을 해줍시다.

}

 

이렇게 외부 인터럽트를 마칩니다.

 

그리고 본함수에 왔습니다. 여담이지만 전 메인에는 함수 위주로만 넣어서 가독성을 높힙니다.

함수에 대한 설명과 값의 흐름과 주석 몇개만 적어놓으면 이 전체적인 흐름을 메인만 봐도 이 프로그램이

뭘하려는 건지 대강은 짐작할 수 있도록이요..

 

여튼 메인에는 두가지만 넣을 겁니다. lcd출력과 (전 lcd출력도 함수로 빼버리는 걸 선호했었죠ㅋㅋ)

계산 함수.

 

main()

{  레지스터 세팅과 lcd를 초기화해 주시구요..

 

if(flag==1) {calculator();} //위에 인터럽트에서 =가 들어오면 세팅시켜 줬던 flag가 1이되자 계산함수를 돌려서 계산을 마무리

                                       합니다.

 

  lcd_gotoxy(0,0); //lcd를 출력할 거에요.

  lcd_puts(dsp);

  delay_ms(10);

if(lcd_flag==1) //플래그의 사용법을 아시겠죠? 이 플래그가 셋되면 두번째 줄에 결과값을 표시할겁니다.

{ lcd_gotoxy(0,1);

  lcd_puts(cal_2);

  delay_ms(10);

}

}

 

 

이제 계산 함수만 짜시면 돼요.

앞에서 신호를 구분하는 매트릭스 처럼 스위치문으로 우순순위표를 하나 짜줍니다.

*=0, /=1 , +=2, -=3, default(숫자)=4 이렇게요. 네 맞습니다. 사칙연산 우선순위를 정해서 사칙연산 순서대로

계산을 하기 위한거에요.

 

이중 반복문과 반복문(while, for)를 활용하여서

cal_2에 있는 것들 중 곱하기와 나누기가 있는지 확인하고 곱하기가 있는 배열의 앞과 뒤를 해당 연산자로 계산하여

앞 배열에 집어 넣고, 전체적으로 두칸 댕겨줍니다.

곱하기와 나누기계산을 전체적으로 끝내고 나면 더하기와 빼기를 해주고 또 두칸씩 땡겨주면

결국 한개의 숫자만 남게 될거에요.

 

그걸 아래 있는 lcd_flag가 셋되면 출력되는 if문에서 출력이 될겁니다.

한가지 분명한건 전 정말 허접해서 제가 한 건 정말정말 악수 일 수 있어요...

본인들이 고민하셔서 답을 내신고 그게 더 마음에 든다면 본인들 걸 쓰시는걸 추천 합니다ㅎ

원래 자기가 고민해서 짠 코딩엔 애착이 가는 법이기도 하구요ㅎㅎㅎ

 

한계점도 분명히 있는 계산기긴 한데..

이것도 삽질 많이 해보셔야 할겁니다. 제가 직접 돌려서 확인해 본건 아니라ㅋㅋㅋ

대충 이렇게 하면 되겠다 싶은 방향성이에요

버닝중의 최근 게시물

자유·수다 인기 게시글