|
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png (22.31 KB, 下載次數(shù): 92)
下載附件
2020-12-4 16:45 上傳
狀態(tài)圖.jpg (97.45 KB, 下載次數(shù): 72)
下載附件
2020-12-4 16:45 上傳
單片機(jī)源程序如下:
- #include "led_seg.h"
- #include "key.h"
- #include "mymath.h"
- typedef enum
- {
- OPERATOR_EMPTY,
- OPERATOR_PLUS,
- OPERATOR_MINUS,
- OPERATOR_MULTIPLY,
- OPERATOR_DIVIDE,
- OPERATOR_EQUAL
- } OPERATOR;
- typedef enum
- {
- STATE_INIT,
- STATE_INPUT_FIRST_NUM,
- STATE_INPUT_SECOND_NUM,
- STATE_CALC_SIGN,
- STATE_EQUAL
- } STATE;
- u8 timer = 0;
- double show_number = 0;
- // 用來(lái)標(biāo)記小數(shù)點(diǎn)是否按下
- bit is_dot_press = 0;
- // 用來(lái)記錄小數(shù)點(diǎn)按下后鍵盤(pán)按下的數(shù)的數(shù)量
- u8 after_dot_press_number = 0;
- // (float) 等價(jià)于 (double) 6位有效數(shù)字
- void Timer0Init(void);
- void Timer0Interrupt(void);
- void update_show_number(u8);
- void update_calc_sign(OPERATOR);
- double first_number = 0;
- double second_number = 0;
- OPERATOR myoperator = OPERATOR_EMPTY;
- STATE state = STATE_INIT;
- void main()
- {
- Timer0Init();
- while(1)
- {
-
- keyscan();
-
- if(NO_KEY_PRESS != key_state)
- {
- switch(key_state)
- {
- // 1
- case 0:
- update_show_number(1);
- break;
- // 2
- case 1:
- update_show_number(2);
- break;
- // 3
- case 2:
- update_show_number(3);
- break;
- // +
- case 3:
- update_calc_sign(OPERATOR_PLUS);
- break;
- // 4
- case 4:
- update_show_number(4);
- break;
- // 5
- case 5:
- update_show_number(5);
- break;
- // 6
- case 6:
- update_show_number(6);
- break;
- // -
- case 7:
- update_calc_sign(OPERATOR_MINUS);
- break;
- // 7
- case 8:
- update_show_number(7);
- break;
- // 8
- case 9:
- update_show_number(8);
- break;
- // 9
- case 10:
- update_show_number(9);
- break;
- // ×
- case 11:
- update_calc_sign(OPERATOR_MULTIPLY);
- break;
- // .
- case 12:
- is_dot_press = 1;
- break;
- // 0
- case 13:
- update_show_number(0);
- break;
- // =
- case 14:
- switch(state)
- {
- case STATE_INIT:
- case STATE_EQUAL:
- case STATE_INPUT_FIRST_NUM:
- first_number = show_number;
- state = STATE_EQUAL;
- myoperator = OPERATOR_EMPTY;
- break;
- case STATE_INPUT_SECOND_NUM:
- second_number = show_number;
- switch(myoperator)
- {
- case OPERATOR_PLUS:
- show_number = first_number + second_number;
- break;
- case OPERATOR_MINUS:
- show_number = first_number - second_number;
- break;
- case OPERATOR_MULTIPLY:
- show_number = first_number * second_number;
- break;
- case OPERATOR_DIVIDE:
-
- if(0.000000 != second_number)
- {
- show_number = first_number / second_number;
- }
- else
- {
- // warning
- show_number = 0;
- }
-
- break;
- default:
- break;
- }
- is_dot_press = 0;
- after_dot_press_number = 0;
- first_number = 0;
- second_number = 0;
- state = STATE_EQUAL;
- myoperator = OPERATOR_EMPTY;
- break;
- case STATE_CALC_SIGN:
- break;
- default:
- break;
- }
- break;
- // ÷
- case 15:
- update_calc_sign(OPERATOR_DIVIDE);
- break;
- //意外情況的處理
- default:
- break;
- }
- key_state = NO_KEY_PRESS;
- }
- }
- }
- void Timer0Init(void) //100微秒@12.000MHz
- {
- TMOD &= 0xF0; //設(shè)置定時(shí)器模式
- TMOD |= 0x02; //設(shè)置定時(shí)器模式
- TL0 = 0x9C; //設(shè)置定時(shí)初值
- TH0 = 0x9C; //設(shè)置定時(shí)重載值
- TF0 = 0; //清除TF0標(biāo)志
- TR0 = 1; //定時(shí)器0開(kāi)始計(jì)時(shí)
- ET0 = 1;
- EA = 1;
- }
- void Timer0Interrupt(void) interrupt 1
- {
- timer++;
- if(10 == timer)
- {
- LedShowByNum(show_number);
- timer = 0;
- }
- keyrescan();
- }
- void update_show_number(u8 number)
- {
- switch(state)
- {
- case STATE_INIT:
- case STATE_EQUAL:
- show_number = 0;
- first_number = 0;
- second_number = 0;
- myoperator = OPERATOR_EMPTY;
- state = STATE_INPUT_FIRST_NUM;
- break;
- case STATE_INPUT_FIRST_NUM:
- break;
- case STATE_INPUT_SECOND_NUM:
- break;
- case STATE_CALC_SIGN:
- second_number = show_number = 0;
- state = STATE_INPUT_SECOND_NUM;
- break;
- default:
- break;
- }
- if(is_dot_press)
- {
- after_dot_press_number++;
- show_number += number / ((double)mypow(10,after_dot_press_number));
- }
- else
- {
- show_number *= 10;
- show_number += number;
- }
- switch(state)
- {
- case STATE_INPUT_FIRST_NUM:
- first_number = show_number;
- break;
- case STATE_INPUT_SECOND_NUM:
- second_number = show_number;
- break;
- default:
- break;
- }
-
- }
- void update_calc_sign(OPERATOR opr)
- {
- switch(state)
- {
- case STATE_INIT:
- first_number = 0;
- myoperator = opr;
- state = STATE_CALC_SIGN;
- break;
- case STATE_EQUAL:
- case STATE_INPUT_FIRST_NUM:
- first_number = show_number;
- state = STATE_CALC_SIGN;
- myoperator = opr;
- break;
- case STATE_INPUT_SECOND_NUM:
- second_number = show_number;
- is_dot_press = 0;
- after_dot_press_number = 0;
- switch(myoperator)
- {
- case OPERATOR_PLUS:
- show_number = first_number + second_number;
- break;
- case OPERATOR_MINUS:
- show_number = first_number - second_number;
- break;
- case OPERATOR_MULTIPLY:
- show_number = first_number * second_number;
- break;
- case OPERATOR_DIVIDE:
- if(0.000000 != second_number)
- {
- show_number = first_number / second_number;
- }
- else
- {
- is_dot_press = 0;
- after_dot_press_number = 0;
- // warning
- show_number = 0;
- first_number = 0;
- second_number = 0;
- myoperator = OPERATOR_EMPTY;
- state = STATE_INIT;
- return;
- }
-
- break;
- default:
- break;
- }
- first_number = show_number;
- state = STATE_CALC_SIGN;
- myoperator = opr;
- break;
- case STATE_CALC_SIGN:
- break;
- }
- }
復(fù)制代碼 全部資料51hei下載地址(仿真+程序):
09-實(shí)現(xiàn)一個(gè)簡(jiǎn)便的計(jì)算器.7z
(116.72 KB, 下載次數(shù): 47)
2020-12-4 15:23 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|