久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 3632|回復(fù): 2
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)計(jì)算器程序狀態(tài)圖與Proteus仿真

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機(jī)源程序如下:
  1. #include "led_seg.h"
  2. #include "key.h"
  3. #include "mymath.h"

  4. typedef enum
  5. {
  6.         OPERATOR_EMPTY,
  7.         OPERATOR_PLUS,
  8.         OPERATOR_MINUS,
  9.         OPERATOR_MULTIPLY,
  10.         OPERATOR_DIVIDE,
  11.         OPERATOR_EQUAL
  12. } OPERATOR;


  13. typedef enum
  14. {
  15.         STATE_INIT,
  16.         STATE_INPUT_FIRST_NUM,
  17.         STATE_INPUT_SECOND_NUM,
  18.         STATE_CALC_SIGN,
  19.         STATE_EQUAL
  20. } STATE;

  21. u8 timer = 0;
  22. double show_number = 0;

  23. // 用來(lái)標(biāo)記小數(shù)點(diǎn)是否按下
  24. bit is_dot_press = 0;
  25. // 用來(lái)記錄小數(shù)點(diǎn)按下后鍵盤(pán)按下的數(shù)的數(shù)量
  26. u8 after_dot_press_number = 0;


  27. // (float) 等價(jià)于 (double) 6位有效數(shù)字
  28. void Timer0Init(void);
  29. void Timer0Interrupt(void);
  30. void update_show_number(u8);
  31. void update_calc_sign(OPERATOR);

  32. double first_number = 0;
  33. double second_number = 0;



  34. OPERATOR myoperator = OPERATOR_EMPTY;
  35. STATE state = STATE_INIT;
  36. void main()
  37. {
  38.         Timer0Init();
  39.         while(1)
  40.         {
  41.                
  42.                 keyscan();
  43.                
  44.                 if(NO_KEY_PRESS != key_state)
  45.                 {
  46.                         switch(key_state)
  47.                         {
  48.                                 // 1
  49.                                 case 0:
  50.                                         update_show_number(1);
  51.                                         break;
  52.                                 // 2
  53.                                 case 1:
  54.                                         update_show_number(2);
  55.                                         break;
  56.                                 // 3
  57.                                 case 2:
  58.                                         update_show_number(3);
  59.                                         break;
  60.                                 // +
  61.                                 case 3:
  62.                                         update_calc_sign(OPERATOR_PLUS);
  63.                                         break;
  64.                                 // 4
  65.                                 case 4:
  66.                                         update_show_number(4);
  67.                                         break;
  68.                                 // 5
  69.                                 case 5:
  70.                                         update_show_number(5);
  71.                                         break;
  72.                                 // 6
  73.                                 case 6:
  74.                                         update_show_number(6);
  75.                                         break;
  76.                                 // -
  77.                                 case 7:
  78.                                         update_calc_sign(OPERATOR_MINUS);
  79.                                         break;
  80.                                 // 7
  81.                                 case 8:
  82.                                         update_show_number(7);
  83.                                         break;
  84.                                 // 8
  85.                                 case 9:
  86.                                         update_show_number(8);
  87.                                         break;
  88.                                 // 9
  89.                                 case 10:
  90.                                         update_show_number(9);
  91.                                         break;
  92.                                 // ×
  93.                                 case 11:
  94.                                         update_calc_sign(OPERATOR_MULTIPLY);
  95.                                         break;
  96.                                 // .
  97.                                 case 12:
  98.                                         is_dot_press = 1;
  99.                                         break;
  100.                                 // 0
  101.                                 case 13:
  102.                                         update_show_number(0);
  103.                                         break;
  104.                                 // =
  105.                                 case 14:
  106.                                                 switch(state)
  107.                                                 {
  108.                                                         case STATE_INIT:
  109.                                                         case STATE_EQUAL:
  110.                                                         case STATE_INPUT_FIRST_NUM:
  111.                                                                 first_number = show_number;
  112.                                                                 state = STATE_EQUAL;
  113.                                                                 myoperator = OPERATOR_EMPTY;                                
  114.                                                                 break;
  115.                                                         case STATE_INPUT_SECOND_NUM:
  116.                                                                 second_number = show_number;
  117.                                                                 switch(myoperator)
  118.                                                                 {
  119.                                                                         case OPERATOR_PLUS:
  120.                                                                                 show_number = first_number + second_number;
  121.                                                                                 break;
  122.                                                                         case OPERATOR_MINUS:
  123.                                                                                 show_number = first_number - second_number;
  124.                                                                                 break;
  125.                                                                         case OPERATOR_MULTIPLY:
  126.                                                                                 show_number = first_number * second_number;
  127.                                                                                 break;
  128.                                                                         case OPERATOR_DIVIDE:
  129.                                                                                 
  130.                                                                                 if(0.000000 != second_number)
  131.                                                                                 {
  132.                                                                                         show_number = first_number / second_number;
  133.                                                                                 }
  134.                                                                                 else
  135.                                                                                 {
  136.                                                                                         // warning
  137.                                                                                         show_number = 0;

  138.                                                                                 }
  139.                                                                                        
  140.                                                                                 break;
  141.                                                                         default:
  142.                                                                                 break;
  143.                                                                 }
  144.                                                                 is_dot_press = 0;
  145.                                                                 after_dot_press_number = 0;
  146.                                                                 first_number = 0;
  147.                                                                 second_number = 0;
  148.                                                                 state = STATE_EQUAL;
  149.                                                                 myoperator = OPERATOR_EMPTY;
  150.                                                                 break;
  151.                                                         case STATE_CALC_SIGN:
  152.                                                                 break;
  153.                                                         default:
  154.                                                                 break;
  155.                                                 }
  156.                                         break;
  157.                                 // ÷
  158.                                 case 15:
  159.                                         update_calc_sign(OPERATOR_DIVIDE);
  160.                                         break;
  161.                                 //意外情況的處理
  162.                                 default:
  163.                                         break;
  164.                         }
  165.                         key_state = NO_KEY_PRESS;
  166.                 }
  167.         }
  168. }


  169. void Timer0Init(void)                //100微秒@12.000MHz
  170. {
  171.         TMOD &= 0xF0;                //設(shè)置定時(shí)器模式
  172.         TMOD |= 0x02;                //設(shè)置定時(shí)器模式
  173.         TL0 = 0x9C;                //設(shè)置定時(shí)初值
  174.         TH0 = 0x9C;                //設(shè)置定時(shí)重載值
  175.         TF0 = 0;                //清除TF0標(biāo)志
  176.         TR0 = 1;                //定時(shí)器0開(kāi)始計(jì)時(shí)
  177.         ET0 = 1;
  178.         EA = 1;
  179. }

  180. void Timer0Interrupt(void) interrupt 1
  181. {
  182.         timer++;
  183.         if(10 == timer)
  184.         {
  185.                 LedShowByNum(show_number);
  186.                 timer = 0;
  187.         }
  188.         keyrescan();
  189. }


  190. void update_show_number(u8 number)
  191. {

  192.         switch(state)
  193.         {
  194.                 case STATE_INIT:
  195.                 case STATE_EQUAL:
  196.                         show_number = 0;
  197.                         first_number = 0;
  198.                         second_number = 0;
  199.                         myoperator = OPERATOR_EMPTY;
  200.                         state = STATE_INPUT_FIRST_NUM;
  201.                         break;
  202.                 case STATE_INPUT_FIRST_NUM:
  203.                         break;
  204.                 case STATE_INPUT_SECOND_NUM:
  205.                         break;
  206.                 case STATE_CALC_SIGN:
  207.                         second_number = show_number = 0;
  208.                         state = STATE_INPUT_SECOND_NUM;
  209.                         break;
  210.                 default:
  211.                         break;
  212.         }
  213.         if(is_dot_press)
  214.         {
  215.                 after_dot_press_number++;
  216.                 show_number += number / ((double)mypow(10,after_dot_press_number));
  217.         }
  218.         else
  219.         {
  220.                 show_number *= 10;
  221.                 show_number += number;
  222.         }
  223.         switch(state)
  224.         {
  225.                 case STATE_INPUT_FIRST_NUM:
  226.                         first_number = show_number;
  227.                         break;
  228.                 case STATE_INPUT_SECOND_NUM:
  229.                         second_number = show_number;
  230.                         break;
  231.                 default:
  232.                         break;
  233.         }
  234.         
  235. }

  236. void update_calc_sign(OPERATOR opr)
  237. {
  238.         switch(state)
  239.         {
  240.                 case STATE_INIT:
  241.                         first_number = 0;
  242.                         myoperator = opr;
  243.                         state = STATE_CALC_SIGN;
  244.                         break;
  245.                 case STATE_EQUAL:
  246.                 case STATE_INPUT_FIRST_NUM:
  247.                         first_number = show_number;
  248.                         state = STATE_CALC_SIGN;
  249.                         myoperator = opr;
  250.                         break;
  251.                 case STATE_INPUT_SECOND_NUM:
  252.                         second_number = show_number;
  253.                         is_dot_press = 0;
  254.                         after_dot_press_number = 0;
  255.                         switch(myoperator)
  256.                         {
  257.                                 case OPERATOR_PLUS:
  258.                                         show_number = first_number + second_number;
  259.                                         break;
  260.                                 case OPERATOR_MINUS:
  261.                                         show_number = first_number - second_number;
  262.                                         break;
  263.                                 case OPERATOR_MULTIPLY:
  264.                                         show_number = first_number * second_number;
  265.                                         break;
  266.                                 case OPERATOR_DIVIDE:
  267.                                         if(0.000000 != second_number)
  268.                                         {
  269.                                                 show_number = first_number / second_number;
  270.                                         }
  271.                                         else
  272.                                         {
  273.                                                 is_dot_press = 0;
  274.                                                 after_dot_press_number = 0;
  275.                                                 // warning
  276.                                                 show_number = 0;
  277.                                                 first_number = 0;
  278.                                                 second_number = 0;
  279.                                                 myoperator = OPERATOR_EMPTY;
  280.                                                 state = STATE_INIT;
  281.                                                 return;
  282.                                         }
  283.                                                 
  284.                                         break;
  285.                                 default:
  286.                                         break;
  287.                         }
  288.                         first_number = show_number;
  289.                         state = STATE_CALC_SIGN;
  290.                         myoperator = opr;
  291.                         break;
  292.                 case STATE_CALC_SIGN:
  293.                         break;
  294.         }
  295. }
復(fù)制代碼
全部資料51hei下載地址(仿真+程序):
09-實(shí)現(xiàn)一個(gè)簡(jiǎn)便的計(jì)算器.7z (116.72 KB, 下載次數(shù): 47)

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:1048675 發(fā)表于 2023-4-9 16:29 | 只看該作者
第一次輸入數(shù)不能帶小數(shù),否則運(yùn)算符后的第二次輸入數(shù)出錯(cuò)。比如7.1+2=9.2 。但是顯示為7.1+0.02=7.12 。不知什么原因?樓主能不能查一下,更正后我再來(lái)下載一下。
回復(fù)

使用道具 舉報(bào)

板凳
ID:1048675 發(fā)表于 2023-4-13 15:57 | 只看該作者
已解決了第一次輸入不能是小數(shù)的問(wèn)題。但是出現(xiàn)了第二個(gè)問(wèn)題,就是不能及時(shí)顯示小數(shù)點(diǎn)及小數(shù)點(diǎn)后面的零,只有小數(shù)點(diǎn)后面是除零外的數(shù)才能及時(shí)顯示。一直沒(méi)有找到原因,樓主幫一下,謝謝!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 伦理午夜电影免费观看 | 成人在线视频网址 | 91麻豆精品一区二区三区 | 欧美一区二区三区在线播放 | 国产日韩91 | 成人欧美日韩一区二区三区 | 羞羞视频在线观看 | 91久久精品一区二区三区 | 午夜视频在线免费观看 | 一区二区三区高清 | 国产精品成人一区二区三区 | 亚洲精品99| 日本不卡免费新一二三区 | 欧美日韩精品久久久免费观看 | 成人影院在线 | 91啪亚洲精品 | 91麻豆精品国产91久久久久久 | 久久9久 | 黄色在线免费看 | 一区二区三区小视频 | 欧美精品一区二区三区在线 | 欧美视频第三页 | 日本粉嫩一区二区三区视频 | 一区二区欧美在线 | 成人三级在线播放 | 欧美区日韩区 | 日韩久久精品 | 日韩无 | 欧美日韩国产精品一区 | 国产精品一区在线观看 | 观看av| 国产精品久久久久久久久久妞妞 | a级黄色片在线观看 | 欧洲亚洲精品久久久久 | 九九在线视频 | 国产成人一区二区三区 | 日韩视频免费 | 久久国产美女视频 | 欧美性成人 | 久久中文字幕视频 | 国产精品美女一区二区 |