calc.c
来自「一款收款机C源代码!因为是几年前的代码了」· C语言 代码 · 共 709 行 · 第 1/2 页
C
709 行
#include "ecrsys.h"
#include "disp.h"
#include "data.h"
#include "sysdata.h"
#include "ftype.h"
#include "Calc.h"
#include "Mathes.h"
#include "string.h"
#include "keydef.h"
/*********************************************************/
void Clr_Status(void);
void Calc_GetIn(void);
void Calc_Disp(byte Cnt);
void Calc_Update(void);
void Calc_Result_Disp(void);
void Calc_Result_Adjust(DoubleLong *ll);
long bak_lnum; /* The backup number of the input data */
long bak_lnum1; /* The backup number of the display data */
byte bak_dots; /* The backup number of the input dots */
byte bak_dots1; /* The backup number of the display dots */
byte Calc_Mode; /* The mode of calculation */
DoubleLong bak_result; /* The backup of result for the operations PRI */
byte bak_mode; /* The backup of mode for the operations PRI */
const word Calc_Digit_Table[];
/*********************************************************/
/******************************************************************************
A simple calculator function.
Only used in the simply calculation, the the positive data result
is from 0.000000005000...(displayed to the LCD is 0.00000001, if sumaller
, display 0) to 999999999.4999...(displayed to the LCD is 999999999),
and the negative data result is from -999999999.4999...(displayed to
the LCD is -999999999) to 0.000000005000...(displayed to the LCD
is -0.00000001). The method of deal the mantissa is the round.
The operation key:(Used the logical position, so when use free function
key changed the position, but this position will not changed along with it)
OP: The keyboard logical code:
0: 32
1: 25
2: 26
3: 27
4: 18
5: 19
6: 20
7: 11
8: 12
9: 13
00: 33
.: 34
+: 14
-: 21
*: 28
/: 35
-/+: 9 // the negative value and positive value exchange
=: 37/38
CL: 6 // CLEAR, clear the all status and data.
CE: 7 // Clear the just input data, but the status still remain
BS: 8 // Backspace
ST: 31 // SUBTTL, exit this mode
FD: 1 // FEED, feed the paper
MODE: 2 // MODE, working mode key
Note: Enter this mode : 1+SUBTTL
Exit this mode : 0+SUBTTL
In this program, it store the calculate result in the DoubleLong
structure. The max value of integer part is 999999999, and remain
max 10 decimal digits.
If the result is too long such as 99999999.3555555555, The data
displayed to the LCD is 99999999.4, if you want to get the more decimal
digits, can use the step:'-' + '='(first press SUB key, and later press
EQUAL key) can see the remain part of decimal digits. Continue the last
example, when press '-'&'=', the display to the LCD is -0.04444444.
If the result is 99999999.6333333333, the data dispalyed to the LCD is
99999999.6, when press '-'&'=', the LCD will display 0.03333333.
******************************************************************************/
void Calc(void)
{
Clr_Period(); /* Clear the period display from the sale mode influence */
Clr_Status(); /* Initialize the calculator's status */
Calc_Flag = 1; /* Set the calc flag, indicate in the calculator mode */
while(TRUE)
{
Calc_GetIn(); /* Get the data input */
GetMainMode();
if(MainMode != CurrMode) /* The control lock is changed */
{
Calc_Flag = 0;
Clr_Dsp_Data();
RightDisp(0,sysflag->sysdots);
return;
}
/*----------------------------------------------------------------------*/
if(numcnt == 0) /* No digit input */
{
if((InCmd == CALC_EQU) || (InCmd == CALC_EQU1))
{
if((lastincmd == CALC_EQU) || (lastincmd == CALC_EQU1))
{
lnum = bak_lnum; /* Get the last input data, or the last display data */
dec_cnt = bak_dots;
}
else if(lastincmd != CALC_XCH) /* When the last press key is '-','+','*','/',
backup the last display data to the lnum */
{
bak_lnum = bak_lnum1;
bak_dots = bak_dots1;
lnum = bak_lnum;
dec_cnt = bak_dots;
}
}
else if(InCmd != CALC_XCH)
{
bak_lnum = bak_lnum1; /* Press other key, get the last display data */
bak_dots = bak_dots1;
}
}
else /* Some digits input */
{
if((InCmd == CALC_EQU) || (InCmd == CALC_EQU1))
{
bak_lnum = lnum; /* Backup the input data, can used when no digit input */
bak_dots = dec_cnt;
}
/*----------------------------------------------------------------------*/
/* The above is for the abnormal case deal. */
if((lastincmd == CALC_EQU)|| (lastincmd == CALC_EQU1)) /* When the last press key is EQUAL, and this time input
has some digits, can clear the last calculate result,
indicate a new calculation */
{
DL_Clr(&Calc_Result);
Calc_Mode = CALCM_NULL;
}
}
switch(InCmd)
{
case CALC_XCH:
Calc_Mode = CALCM_XCH;
Calc_Update();
break;
case CALC_EQU:
case CALC_EQU1:
case CALC_PLUS:
case CALC_MINUS:
if((numcnt) || (InCmd == CALC_EQU) || (InCmd == CALC_EQU1)) /* The '=' can also continue do the operation */
{
Calc_Update();
if(bak_mode != CALCM_NULL) /* In the operations PRI mode */
{
bak_lnum = bak_lnum1; /* Such as: 2+ 3* 5=, must backup the data 15(3*5),
and this time displayed to the LCD is 17, when
press '=' again, will display to the LCD 32 */
bak_dots = bak_dots1;
Calc_Mode = CALCM_PRI;
Calc_Update();
Calc_Mode = bak_mode; /* Used for the key '=' */
bak_mode = CALCM_NULL;
}
}
else
{
// if(bak_mode != CALCM_NULL) /* The last press is '*' or the '/', replace it with '+' or '-' */
// {
// Calc_Mode = CALCM_PRI;
// Calc_Update();
// bak_mode = CALCM_NULL; /* Clear the mode */
// }
}
if(InCmd == CALC_PLUS)
Calc_Mode = CALCM_ADD;
else if(InCmd == CALC_MINUS)
Calc_Mode = CALCM_SUB;
break;
case CALC_MUL:
case CALC_DIV:
if(numcnt)
{
if((Calc_Mode == CALCM_ADD) || (Calc_Mode == CALCM_SUB)) /* If the last key is '-' or '+', backup the result */
{
DL_Eva(&bak_result, &Calc_Result);
bak_mode = Calc_Mode;
DL_Clr(&Calc_Result);
Calc_Mode = CALCM_NULL;
}
Calc_Update();
}
if(InCmd == CALC_MUL)
Calc_Mode = CALCM_MUL;
else
Calc_Mode = CALCM_DIV;
break;
case CALC_ST: /* Return the calculation mode */
Calc_Flag = 0;
Clr_Dsp_Data();
RightDisp(0,sysflag->sysdots);
return;
}
}
}
/* Clear the all status */
void Clr_Status(void)
{
numcnt = 0;
dec_flag = 0;
dec_cnt = 0;
Calc_Sign = 0;
bak_lnum = 0;
bak_dots = 0;
bak_lnum1 = 0; /* A new calculation, clear the backup data of last display */
bak_dots1 = 0;
Calc_Mode = CALCM_NULL;
bak_mode = CALCM_NULL;
InCmd = KD_NULL;
lastincmd = KD_NULL2;
DL_Clr(&Calc_Result);
// DL_Clr(&bak_result);
Clr_Dsp_Data();
RightDisp(0,0);
Insert_Period(9); /* Display the dots */
}
/* Get the tenkey input */
void Calc_GetIn(void)
{
byte Mode;
byte TenKey;
numcnt = 0;
dec_flag = 0;
dec_cnt = 0;
Calc_Sign = POSITIVE;
mode_disp_flag = 0;
while(TRUE)
{
// if(In_Buff[0] == 0)
GetKey();
GetMainMode(); /* The control lock changed, return */
if(MainMode != CurrMode)
return;
switch(Logi_Code)
{
case CALC_MODE:
if(sysflag->soft_lock_flag != 1)
{
errorType(ERR_MODE);
Clr_Status();
break;
}
if(numcnt == 0)
{
Disp_Mode(); /* Dispaly the current mode */
mode_disp_flag = 1;
break;
}
if(numcnt != 1)
{
errorType(ERR_MODE);
Clr_Status();
break;
}
if(In_Buff[0] == 0)
Mode = X_OFF;
else if(In_Buff[0] == 1)
Mode = REGISTER;
else if(In_Buff[0] == 2)
Mode = XREPORT;
else if(In_Buff[0] == 3)
Mode = ZREPORT;
else if(In_Buff[0] == 4)
Mode = PROGRAM;
else
{
errorType(ERR_MODE);
Clr_Status();
break;
}
if(Mode != CurrMode)
{
if((CurrMode == REGISTER) || (CurrMode == TRAINING)) /* Sale check */
{
if(NewTrans) /* The transaction not end, error */
{
errorType(ERR_SALE_NO_END);
Clr_Status();
break;
}
}
else if(CurrMode == PROGRAM) /* Program check */
{
if(progflag)
{
errorType(ERR_PROGRAM_NO_END);
Clr_Status();
break;
}
}
currmodeInt = Mode;
return;
}
Clr_Status();
break;
case CALC_0:
if(numcnt == 0)
{
In_Buff[numcnt ++] = 0;
Clr_Dsp_Data();
RightDisp(0,0);
Insert_Period(9);
}
else if((In_Buff[0] == 0) && (dec_flag == 0))
;
else
{
if(numcnt != 9)
{
In_Buff[numcnt ++] = 0;
if(dec_flag)
dec_cnt ++;
Calc_Disp(numcnt);
}
}
break;
case CALC_D0:
if(numcnt == 0)
{
In_Buff[numcnt ++] = 0;
Clr_Dsp_Data();
RightDisp(0,0);
Insert_Period(9);
}
else if((In_Buff[0] == 0) && (dec_flag == 0))
;
else
{
if(numcnt != 9)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?