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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1733|回復(fù): 10
收起左側(cè)

為什么我這個單片機計算器程序200*200往上的數(shù) 結(jié)果不對

[復(fù)制鏈接]
ID:1025149 發(fā)表于 2022-6-13 13:29 | 顯示全部樓層 |閱讀模式
  1. #include <reg51.h>
  2. #include <stdio.h>
  3. #include <intrins.h>
  4. #define u8  unsigned char
  5. #define u16  unsigned char
  6. sbit LCDEN=P3^4;
  7. sbit RS=P3^5;
  8. sbit RW=P3^6;
  9. sbit BF=P0^7;
  10. u8 code keyval[]="789/456*123-c0=+"; //按鍵對應(yīng)的符號
  11. u8 data1[10];
  12. u8 k=0;
  13. char  m[10]={0};
  14. double sum=0;
  15. void delay(u16 x)          //延時x毫秒
  16. {
  17. u16 i,j;
  18. for(i=0;i<x;i++)
  19.         for(j=0;j<115;j++)
  20.                 ;
  21. }

  22. u8 keypad4_4()//按鍵掃描函數(shù):要去抖,若有按鍵按下,返回對應(yīng)的按鍵值(0-15),沒有按鍵按下返回16
  23. {
  24. u8 i,row,temp;
  25. u8 key=16;//按鍵號,初值設(shè)置為16,目的是:沒有按鍵按下時返回16;
  26.           //若不設(shè)初值(默認值為0),沒有按鍵按下時,將返回0,會誤認為0被按下  
  27. row=0xef; //從第一列開始      
  28. for(i=0;i<4;i++)
  29. {
  30.         P1=0xff;  
  31.         P1=row;        //第i列信號,對應(yīng)列為低,其他全為高
  32.         row=_crol_(row,1);           //生成下一列信號
  33.         temp=P1; //讀入掃描信號
  34.         temp=temp&0x0f; //屏蔽高4位列信號,只保留低4位行信號
  35.         if(temp!=0x0f)//有按鍵被按下,因為第i列某行有按鍵按下,則低4位中有一位為低  
  36.          {  
  37.                 delay(20);  //延時去抖
  38.                 temp=P1;  
  39.                 temp=temp&0x0f;  
  40.                 if(temp!=0x0f)   //再次確認有按鍵被按下
  41.                   {  
  42.                 switch(temp)  //根據(jù)低4位行信號,判斷哪個按鍵被按下
  43.             {  
  44.                     case 0x0e:key=0+i;break; //第i列第1行按鍵被按下
  45.                 case 0x0d:key=4+i;break; //第i列第2行按鍵被按下  
  46.                 case 0x0b:key=8+i;break; //第i列第3行按鍵被按下
  47.                                 case 0x07:key=12+i;      //第i列第4行按鍵被按下
  48.             }
  49.                         
  50.                         do
  51.                         {
  52.                                 temp=P1;              //再次掃描按鍵
  53.                                   temp=temp&0x0f;  
  54.                           }while(temp!=0x0f); //等待按鍵釋放   
  55.                   }  
  56.      }
  57. }  
  58. return(key);//掃面結(jié)束,返回按鍵值
  59. }

  60. unsigned char DectectBusyBit(void)//狀態(tài)判斷函數(shù)(忙/閑?)
  61. {   
  62.         bit result;
  63.         P0 = 0xff;        //讀狀態(tài)前先置高電平,防止誤判
  64.         RS = 0;
  65.         delay(5);
  66.     RW = 1;
  67.         LCDEN = 1;
  68.         delay(5);
  69.         result=BF; //若LCM忙,則反復(fù)測試,在此處原地踏步;當LCM閑時,才往下繼續(xù)
  70.         LCDEN = 0;
  71.         return result;                     
  72. }

  73. void WrComLCD(unsigned char ComVal)//寫命令函數(shù)
  74. {
  75.         while(DectectBusyBit()==1);         //先檢測LCM是否空閑
  76.         RS = 0;
  77.         delay(1);
  78.     RW = 0;
  79.         LCDEN = 1;
  80.         P0 = ComVal;
  81.         delay(1);
  82.         LCDEN = 0;        
  83. }

  84. void WrDatLCD(unsigned char DatVal)//寫數(shù)據(jù)函數(shù)
  85. {
  86. while(DectectBusyBit()==1);
  87.         RS = 1;
  88.         delay(1);
  89.     RW = 0;
  90.         LCDEN = 1;
  91.         P0 = DatVal;
  92.         delay(1);
  93.         LCDEN = 0;        
  94. }

  95. void LCD_Init(void)//1602初始化函數(shù)
  96. {
  97.         WrComLCD(0x38);     // 功能設(shè)定:16*2行、5*7點陣、8位數(shù)據(jù)接口
  98.         WrComLCD(0x38);
  99.         WrComLCD(0x38);   
  100. //多次重復(fù)設(shè)定功能指令,因為LCD啟動后并不知道使用的是4位數(shù)據(jù)接口還是8位的,所以開始時總是默認為4位
  101.         WrComLCD(0x01);    // 清屏
  102.         WrComLCD(0x06);    // 光標自增、屏幕不動  
  103.         delay(1);              // 延時,等待上面的指令生效,下面再顯示,防止出現(xiàn)亂碼
  104.         WrComLCD(0x0c);    // 開顯示
  105. }
  106.                                                          
  107. void compute(){
  108.         u8 i,j=0,k,n=0;
  109.         char data3[10]={0};
  110.         int sum1,data2[10]={0};
  111.         sum=0;
  112.                
  113.         for(i=0;data1[i]!='\0';i++){
  114.                   if(data1[i]!='+' && data1[i]!='-' && data1[i]!='*' && data1[i]!='/'){
  115.                           data2[j] =data2[j]*10+(data1[i]-'0');
  116.                   }
  117.                   else{
  118.                           data3[n++] = data1[i];
  119.                           j++;
  120.                   }
  121.         }
  122.         for(i=0;i<n;i++){
  123.                 if(i==0){
  124.                         if(data3[0]=='+')  sum = data2[0] + data2[1];
  125.                         if(data3[0]=='-')  sum = data2[0] - data2[1];
  126.                         if(data3[0]=='*')  sum = data2[0] * data2[1];
  127.                         if(data3[0]=='/')  sum = data2[0] / (double)data2[1];
  128.                 }
  129.                 if(i==1){
  130.                         if(data3[1]=='+')  sum = sum+data2[2];
  131.                         if(data3[1]=='-')  sum = sum-data2[2];
  132.                         if(data3[1]=='*')  sum = sum*data2[2];
  133.                         if(data3[1]=='/')  sum = sum/((float)data2[2]);
  134.                 }
  135.                 if(i==2){
  136.                         if(data3[2]=='+')  sum = sum+data2[3];
  137.                         if(data3[2]=='-')  sum = sum-data2[3];
  138.                         if(data3[2]=='*')  sum = sum*data2[3];
  139.                         if(data3[2]=='/')  sum = sum/((float)data2[3]);
  140.                 }

  141.         
  142.         }

  143.         //判斷是小數(shù)輸出還是整數(shù)輸出
  144.         sum1 = sum;
  145.         if(sum1==sum){
  146.                 sprintf(m,"%d",sum1);
  147.         }
  148.         else{
  149.                 sprintf(m,"%f",sum);
  150.         }
  151.         //把結(jié)果輸出出來
  152.         for(k=0;m[k]!='\0';k++){
  153.                  WrDatLCD(m[k]);
  154.         }
  155. }  



  156. void main()
  157. {
  158.         u8 y;        
  159.         LCD_Init();
  160.         delay(5);   //延時,等待初始化完成
  161.         WrDatLCD('0');

  162.         WrComLCD(0x80);           //設(shè)置顯示地址第一行第一位:0X00(0x80+0x00)
  163.         while(1){
  164.                 y= keypad4_4();
  165.                 if(y==12)  { k=0;WrComLCD(0x01);WrDatLCD('0'); WrComLCD(0x80);}   //清屏
  166.                
  167.                 if(y==14)  {
  168.                         WrComLCD(0xC0); WrDatLCD(keyval[y]); WrDatLCD(' '); data1[k]='\0';compute();//調(diào)用出結(jié)果函數(shù)

  169.                 }                  

  170.                 if(y<16 && y!=12 && y!=14)
  171.                 {
  172.                         WrDatLCD(keyval[y]);
  173.                         data1[k++]= keyval[y];
  174.                 }
  175.         }
  176.                
  177. }
復(fù)制代碼
_F5P(N2PMQ7BPK5%@_Z9A]4.png
回復(fù)

使用道具 舉報

ID:426861 發(fā)表于 2022-6-13 14:37 | 顯示全部樓層
先搞清楚數(shù)據(jù)類型,尤其是經(jīng)過運輸后的數(shù)據(jù)是否存在溢出情況
回復(fù)

使用道具 舉報

ID:161164 發(fā)表于 2022-6-13 15:00 | 顯示全部樓層
sum1是int -32768~32767
sum是double 0~4294967295
如果sum = 200 * 200 = 40000
sum1 = sum
sum1會變?yōu)?-25536
于是sum1 != sum
sprintf(m,"%f",sum);
但sum不是float
于是輸出0.000000
回復(fù)

使用道具 舉報

ID:94031 發(fā)表于 2022-6-13 15:08 | 顯示全部樓層
因為你運算結(jié)果 sum1數(shù)據(jù)類型是 int 能表示最大整數(shù)是32767,200*200=40000超過32767,所以處理錯誤。
回復(fù)

使用道具 舉報

ID:844772 發(fā)表于 2022-6-13 15:26 | 顯示全部樓層
程序?qū)懙猛玫模揖尤话l(fā)現(xiàn)40000以上有問題很厲害了。因該是  int sum1; 的問題,有符號的int,范圍是正負32767吧,所以40000以上就算不了了。
回復(fù)

使用道具 舉報

ID:1034355 發(fā)表于 2022-6-13 15:36 來自觸屏版 | 顯示全部樓層
沒清零
回復(fù)

使用道具 舉報

ID:824490 發(fā)表于 2022-6-13 16:18 | 顯示全部樓層
"#define u8  unsigned char "ok,
"#define u16  unsigned char" ?????????
回復(fù)

使用道具 舉報

ID:1025149 發(fā)表于 2022-6-13 19:32 | 顯示全部樓層
lkc8210 發(fā)表于 2022-6-13 15:00
sum1是int -32768~32767
sum是double 0~4294967295
如果sum = 200 * 200 = 40000

那我該怎么改呢
回復(fù)

使用道具 舉報

ID:1025149 發(fā)表于 2022-6-13 19:33 | 顯示全部樓層
glinfei 發(fā)表于 2022-6-13 15:26
程序?qū)懙猛玫模揖尤话l(fā)現(xiàn)40000以上有問題很厲害了。因該是  int sum1; 的問題,有符號的int,范圍是正 ...

改成 float 會程序錯誤

我用的keil
回復(fù)

使用道具 舉報

ID:844772 發(fā)表于 2022-6-14 09:00 | 顯示全部樓層
蔣蔣丫丫 發(fā)表于 2022-6-13 19:33
改成 float 會程序錯誤

我用的keil

你要看看到底要計算多少位數(shù),還有是否可以使用科學計數(shù)法,要是太多位數(shù),用long 的也不夠,就只能拆開計算了。
回復(fù)

使用道具 舉報

ID:1034715 發(fā)表于 2022-6-14 20:13 | 顯示全部樓層
sum1 改成int64 試試
還有double浮點數(shù)和比較整數(shù)比較時 可以參考這篇文章 搜索 Checking if float is an integer - Stack Overflow

if (fabsf(roundf(z) - z) <= 0.00001f) {
    printf("integer\n");
} else {
    printf("fraction\n");
}

評分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 欧美一级黄带 | 久久久久久国产 | 国产欧美精品在线观看 | 国产三区四区 | 日韩a视频 | 一区二区av在线 | 国产精品视频 | 久草福利 | 一区二区三区成人 | 国产精品成人国产乱一区 | 九九热这里 | 国产欧美久久一区二区三区 | 日本色高清 | 中文字幕二区三区 | 久久久免费少妇高潮毛片 | 狠狠的干| 91在线看片 | www.9191| 欧美日韩一区二区视频在线观看 | 怡红院成人在线视频 | 国产黄视频在线播放 | 免费在线一区二区 | 国产美女特级嫩嫩嫩bbb片 | 免费看91 | 久久九九色 | 亚洲一区在线免费观看 | 网页av | 国产成人综合在线 | 嫩草视频网站 | 久久精品 | 狠狠爱免费视频 | 久久久久成人精品 | 色久电影| 国产激情91久久精品导航 | 色伊人网 | 久久久精彩视频 | 久久久精彩视频 | 欧美精品久久久 | 日本精品一区二区 | 精品国产一区二区三区在线观看 | 久久久性|