- /*--------------------------------------
- Calculator progarm V1.1
- MCU STC12C5A16S2 XAL 12MHz
- Build by Gavin Hu, 2021.4.13
- Key arrangement:
- C 7 8 9 /
- 4 5 6 *
- 1 2 3 -
- 0 . + =
- --------------------------------------*/
- #include <STC_NEW_8051.H>
- #include "typedef.h"
- #define LED7SEG_CA true
- #define LED7SEG_LSB_LEFT true
- #define DISP_OFF_CODE 26
- #define DISP_MINUS_CODE 25
- #define DISP_DIG_CODE 0X80
- #define KEY_PORT P1
- #define NO_KEY_PRESS 255
- #define MAX_NUMBER 99999992.0
- #define MIN_NUMBER -9999992.0
- void delay_ms(unsigned int dt);
- void Led7segDisplay(const uint8_t c_a_u8DispRam[]);
- uint8_t u8KeyScan(void);
- bool bAddNumber(uint8_t a_u8String[], uint8_t u8Number);
- bool bString2Float(float32_t* p_f32Data, const uint8_t c_a_u8String[]);
- bool bFloat2String(uint8_t a_u8String[], float32_t f32Value);
- bool bCalculate(float32_t* p_f32Data, float32_t f32Data, uint8_t u8Operater);
- sbit BUZZ=P1^7;
- static bit l_bInputNewNumber=true;
- /*--------------------------------------
- main function
- --------------------------------------*/
- void main(void)
- {
- code uint8_t c_a_u8KeyTable[]={7,8,9,'/',4,5,6,'*',1,2,3,'-',0,'.','+','='};
- idata uint8_t a_u8DispRam[]={DISP_OFF_CODE,DISP_OFF_CODE,DISP_OFF_CODE,DISP_OFF_CODE,DISP_OFF_CODE,DISP_OFF_CODE,DISP_OFF_CODE,0};
- uint8_t u8KeyRecord, u8Key, u8Operater;
- float32_t f32DataOld, f32DataNew;
- bit bDataReady=false;
- #if LED7SEG_CA
- P2M0=0xFF;
- #else
- P0M0=0xFF;
- #endif
- u8KeyRecord = NO_KEY_PRESS;
- while(1)
- {
- u8Key = u8KeyScan();
- if ((u8KeyRecord != u8Key) && (u8Key != NO_KEY_PRESS))
- {
- switch (u8Key)
- {
- case 0:
- case 1:
- case 2:
- case 4:
- case 5:
- case 6:
- case 8:
- case 9:
- case 10:
- case 12:
- case 13:
- bAddNumber(a_u8DispRam, c_a_u8KeyTable[u8Key]);
- break;
- case 3:
- case 7:
- case 11:
- case 14:
- if (bDataReady)
- {
- if (!l_bInputNewNumber)
- {
- bString2Float(&f32DataNew, a_u8DispRam);
- bCalculate(&f32DataOld, f32DataNew, u8Operater);
- bFloat2String(a_u8DispRam, f32DataOld);
- }
- }
- else
- {
- bString2Float(&f32DataOld, a_u8DispRam);
- bDataReady = true;
- }
- u8Operater = c_a_u8KeyTable[u8Key];
- l_bInputNewNumber = true;
- break;
- case 15:
- if (bDataReady)
- {
- if (!l_bInputNewNumber)
- {
- bString2Float(&f32DataNew, a_u8DispRam);
- }
- bCalculate(&f32DataOld, f32DataNew, u8Operater);
- bFloat2String(a_u8DispRam, f32DataOld);
- }
- l_bInputNewNumber = true;
- break;
- }
- }
- u8KeyRecord = u8Key;
- Led7segDisplay(a_u8DispRam);
- }
- }
- /*--------------------------------------
- Calculate data
- Parameter: data pointer, data, operater
- Return: true=secced
- --------------------------------------*/
- bool bCalculate(float32_t* p_f32Data, float32_t f32Data, uint8_t u8Operater)
- {
- switch (u8Operater)
- {
- case '+':
- *p_f32Data += f32Data;
- break;
- case '-':
- *p_f32Data -= f32Data;
- break;
- case '*':
- *p_f32Data *= f32Data;
- break;
- case '/':
- *p_f32Data /= f32Data;
- break;
- }
- if ((*p_f32Data > MAX_NUMBER)||(*p_f32Data < MIN_NUMBER))
- {
- return false;
- }
- else
- {
- return true;
- }
- }
- /*--------------------------------------
- Add number to string
- Parameter: string,number
- Return: true=secced
- --------------------------------------*/
- bool bAddNumber(uint8_t a_u8String[], uint8_t u8Number)
- {
- static bit s_bDecFlag;
- uint8_t i;
- bit bRetFlag=false;
- if (l_bInputNewNumber)
- {
- s_bDecFlag = false;
- for (i=0;i<7;i++)
- {
- a_u8String[i] = DISP_OFF_CODE;
- }
- a_u8String[7] = 0;
- l_bInputNewNumber = false;
- }
- if (DISP_OFF_CODE == a_u8String[0])
- {
- if ('.'==u8Number)
- {
- if (!s_bDecFlag)
- {
- s_bDecFlag = true;
- a_u8String[7] |= DISP_DIG_CODE;
- bRetFlag = true;
- }
- }
- else
- {
- if ((0==a_u8String[7])&&(DISP_OFF_CODE==a_u8String[6]))
- {
- a_u8String[7]=u8Number;
- }
- else
- {
- for (i=0;i<7;i++)
- {
- a_u8String[i] = a_u8String[i+1];
- }
- a_u8String[7] = u8Number;
- }
- bRetFlag = true;
- }
- }
- return bRetFlag;
- }
- /*--------------------------------------
- Convert string to float function
- Parameter: return data point, string
- Return: true=secuceed
- --------------------------------------*/
- bool bString2Float(float32_t* p_f32Data, const uint8_t c_a_u8String[])
- {
- bit bNegativeSign=false;
- uint8_t i=0;
- float32_t f32Coefficient=0.1;
- while (DISP_OFF_CODE == c_a_u8String[i])
- {
- i++;
- }
- if (DISP_MINUS_CODE == c_a_u8String[i])
- {
- bNegativeSign = true;
- i++;
- }
- *p_f32Data = 0.0;
- for (;i<8;i++)
- {
- *p_f32Data *= 10.0;
- *p_f32Data += (c_a_u8String[i] & 0x7F);
- if ((c_a_u8String[i] & DISP_DIG_CODE) != 0)
- {
- i++;
- break;
- }
- }
- for (;i<8;i++)
- {
- *p_f32Data += (c_a_u8String[i] * f32Coefficient);
- f32Coefficient *= 0.1;
- }
- if (bNegativeSign)
- {
- *p_f32Data = 0.0 - *p_f32Data;
- }
- if ((*p_f32Data > MAX_NUMBER)||(*p_f32Data < MIN_NUMBER))
- {
- return false;
- }
- else
- {
- return true;
- }
- }
- /*--------------------------------------
- Convert float to string function
- Parameter: return string,float data
- Return: true=secced
- --------------------------------------*/
- bool bFloat2String(uint8_t a_u8String[], float32_t f32Value)
- {
- bit bNegativeSign=false;
- uint8_t i;
- float32_t f32Coefficient = 10000000.0;
- if ((f32Value < MAX_NUMBER) && (f32Value > MIN_NUMBER))
- {
- if (f32Value < 0.0)
- {
- bNegativeSign = true;
- f32Value = 0.0 - f32Value;
- }
- for (i=0;i<7;i++)
- {
- if ((f32Value / f32Coefficient) < 1.0)
- {
- f32Coefficient /= 10.0;
- }
- else
- {
- break;
- }
- }
- for (i=0;i<8;i++)
- {
- a_u8String[i] = (uint8_t)(f32Value / f32Coefficient);
- f32Value -= f32Coefficient * a_u8String[i];
- if (1 == (uint8_t)f32Coefficient)
- {
- a_u8String[i] |= DISP_DIG_CODE;
- }
- f32Coefficient /= 10.0;
- }
- if (bNegativeSign)
- {
- for (i=7;i!=0;i--)
- {
- a_u8String[i] = a_u8String[i-1];
- }
- a_u8String[0] = DISP_MINUS_CODE;
- }
- while (0 == a_u8String[7])
- {
- for (i=7;i!=0;i--)
- {
- a_u8String[i] = a_u8String[i-1];
- }
- a_u8String[0] = DISP_OFF_CODE;
- }
- return true;
- }
- else
- {
- return false;
- }
- }
- /*--------------------------------------
- Delay function
- STC 1T MCU @ 12MHz
- Parameter: unsigned int dt
- Delay time=dt(ms)
- --------------------------------------*/
- void delay_ms(uint16_t u16Time)
- {
- register uint8_t i,j;
- for (; u16Time; u16Time--)
- {
- for (i=12;i!=0;i--)
- {
- for (j=248;j!=0;j--)
- {
- }
- }
- }
- }
- /*--------------------------------------
- 8 LED digital tubes display function
- Parameter: sting pointer to display
- --------------------------------------*/
- void Led7segDisplay(const uint8_t c_a_u8DispRam[])
- {
- static uint8_t s_u8Index=0;
- #if LED7SEG_CA
- code uint8_t c_a_u8Led7segCode[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xC2,0x89,0xF1,0xC7,0xAB,0x8C,0xAF,0x87,0xC1,0xBF,0xFF};
- P2=0;
- P0=c_a_u8Led7segCode[c_a_u8DispRam[s_u8Index] & 0x7F] & ~(c_a_u8DispRam[s_u8Index]&0x80);
- #if LED7SEG_LSB_LEFT
- P2=1<<s_u8Index;
- #else
- P2=0x80>>s_u8Index;
- #endif
- #else
- code uint8_t c_a_u8Led7segCode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x3D,0x76,0x0E,0x38,0x54,0x73,0x50,0x78,0x3E,0x40,0x00};
- P2=0xFF;
- P0=c_a_u8Led7segCode[c_a_u8DispRam[s_u8Index] & 0x7F] | (c_a_u8DispRam[s_u8Index]&0x80);
- #if LED7SEG_LSB_LEFT
- P2=~(1<<s_u8Index);
- #else
- P2=~(0x80>>s_u8Index);
- #endif
- #endif
- delay_ms(1);
- s_u8Index++;
- if (s_u8Index>=8)
- {
- s_u8Index=0;
- }
- }
- /*--------------------------------------
- Key scan function
- Return key number,255 no key press
- --------------------------------------*/
- uint8_t u8KeyScan(void)
- {
- uint8_t u8Key=255;
- uint8_t u8Value=0xEF,i;
- for (i=0;i<4;i++)
- {
- KEY_PORT=u8Value;
- switch (KEY_PORT & 0x0F)
- {
- case 0x0E: u8Key=i*4;
- break;
- case 0x0D: u8Key=i*4+1;
- break;
- case 0x0B: u8Key=i*4+2;
- break;
- case 0x07: u8Key=i*4+3;
- break;
- }
- u8Value=u8Value<<1|1;
- }
- return u8Key;
- }
复制代码 |