실전의 고급 계산기
10060 단어 블루 브리지 컵의 단편기블루 브리지의 단편기 설계
1602액정 기반의 성형가감승제계산기는 연속조작을 고려하지 않고 피제수 등을 고려하지 않았다.
내 Github에 코드 다운로드 가능
메일만 꺼냅니다.c 주요한 실현 방향은 다음과 같다.
/*
*******************************************************************************
* :main.c
* :
* :CLAY
* :v1.0.0
* :
* :
*
*******************************************************************************
*/
#include "config.h"
#include "lcd1602.h"
#include "keyboard.h"
long num1=0, num2=0, result=0;
u8 step=0, oprt=0;
u8 T0RH, T0RL;
void ConfigTimer0(u16 ms);
void main()
{
EA = 1;
ConfigTimer0(1);
InitLcd1602();
LcdShowStr(15, 1, "0");
while(1)
{
KeyDriver();
}
}
u8 LongToStr(u8 *str, long dat)
{
u8 i=0;
u8 len=0;
u8 buf[12];
if(dat < 0)
{
dat = -dat;
len++;
*str++ = '-';
}
do{
buf[i++] = dat % 10;
dat /= 10;
}while(dat > 0);
len += i;
while(i-- > 0)
{
*str++ = buf[i] + '0';
}
*str = '\0';
return len;
}
void Reset()
{
step = 0;
num1 = 0;
num2 = 0;
result = 0;
LcdFullClear();
}
void NumKeyAction(u8 num)
{
u8 buf[16];
u8 len;
if(step > 1)
{
Reset();
}
if(step == 0)
{
num1 = num1 * 10 + num;
len = LongToStr(buf, num1);
LcdShowStr(16-len, 1, buf);
}
else
{
num2 = num2 * 10 + num;
len = LongToStr(buf, num2);
LcdShowStr(16-len, 1, buf);
}
}
void ShowOprt(u8 y, u8 type)
{
switch(type)
{
case 0: LcdShowStr(0, y, "+"); break;
case 1: LcdShowStr(0, y, "-"); break;
case 2: LcdShowStr(0, y, "*"); break;
case 3: LcdShowStr(0, y, "/"); break;
default: break;
}
oprt = type;
}
void OprtKeyAction(u8 type)
{
u8 len;
u8 buf[12];
if(step == 0)
{
step = 1;
ShowOprt(1, type);
len = LongToStr(buf, num1);
LcdShowStr(16-len, 0, buf);
LcdShowStr(15, 1, "0");
LcdAreaClear(1, 1, 14);
}
}
void GetResult()
{
u8 len;
u8 buf[12];
if(step == 1) // !
{
switch(oprt)
{
case 0: result = num1 + num2; break;
case 1: result = num1 - num2; break;
case 2: result = num1 * num2; break;
case 3: result = num1 / num2; break;
default: break;
}
step = 2;
ShowOprt(0, oprt);
LcdShowStr(0, 1, "=");
len = LongToStr(buf, result);
LcdAreaClear(1, 1, 15-len);
LcdShowStr(16-len, 1, buf);
}
}
void KeyAction(u8 keycode)
{
if((keycode >= '0') && (keycode <= '9'))
{
NumKeyAction(keycode - '0');
}
else if(keycode == 0x26)
{
OprtKeyAction(0);
}
else if(keycode == 0x28)
{
OprtKeyAction(1);
}
else if(keycode == 0x25)
{
OprtKeyAction(2);
}
else if(keycode == 0x27)
{
OprtKeyAction(3);
}
else if(keycode == 0x1B)
{
Reset();
LcdShowStr(15, 1, "0");
}
else if(keycode == 0x0D)
{
GetResult();
}
}
void ConfigTimer0(u16 ms)
{
u32 tmp;
tmp = 11059200 / 12;
tmp = (tmp * ms) / 1000;
tmp = 65536 - tmp;
T0RH = (u8)(tmp >> 8);
T0RL = (u8)tmp;
TMOD &= 0xF0;
TMOD |= 0x01;
TH0 = T0RH;
TL0 = T0RL;
ET0 = 1;
TR0 = 1;
}
void InterruptTimer0() interrupt 1
{
TH0 = T0RH;
TL0 = T0RL;
KeyScan();
}
KeyAction
에서 인용한 몇 가지 함수, NumKeyAction
, OprtKeyAction
, Reset
와 GetResult
를 각각 실현하면 된다.총체적으로 보면 그렇다. 바로 실현된 세부 사항이 주의하지 않으면 잘못된다. 반드시 신중하고 신중해야 한다.또한 나는 두 개의 모든 변수
step
와 oprt
를 정의하여 현재의 입력 상태(첫 번째 수인지 두 번째 수인지)와 진행할 연산 유형을 표시했다.(이곳은 한 번의 연산이기 때문에 전체 국면을 직접 정의하여 상대적으로 편리하다.)step
의 변화는 기호의 가감승제 또는 호변을 입력하는 것이다!한 번의 연산으로 일단 등호를 누르면 step = 2
에 대응하는 조작은Reset
이다.또 한 번의 연산 방치 연속 연산 오류는 OprtKeyAction
에서 처리step == 1
한 경우만 있고 다른 것은 상관하지 않습니다.코드가 주의해야 할 것도 이렇게 많은데, 이런 모듈화 사상은 또 당신의 마음속에 더욱 깊이 파고들지 않습니까?