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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1961|回復: 0
收起左側

基于51單片機電子秤PCB與源代碼

[復制鏈接]
ID:774218 發表于 2022-3-2 20:47 | 顯示全部樓層 |閱讀模式
Altium Designer畫的PCB圖如下:(51hei附件中可下載工程文件)
51hei.png

單片機源程序如下:
  1. /*************************************************
  2. /********************************************************************
  3. ***********主題:基于51單片機電子稱c程序設計       
  4. ***********功能: 可以輸出量程為5kg物體的重量并且結合鍵盤單價的輸入計算
  5. ***********      出價格,還具有去皮、休眠、切換量程等功能,輸出的重量和
  6. ***********      總額采用四舍五入
  7. *********************************************************************/

  8. #include "Main.h"
  9. bit   g_DecimalPointflag = 0, KeycanFlag = 0, RangeFlag = 0, TotalFlag = 0;          //小數點按下標志位,數字按鍵按下標志位,量程切換標志位
  10. sbit  Beep  = P1^3;                                             //蜂鳴器報警
  11. sbit  Led   = P1^4;                                            //報警LED
  12. sbit  RATE   = P2^5;                                        //轉換速率調節
  13. UINT_16 g_HighPrice = 0;                            //輸入單價存儲整數部分變量
  14. UINT_8  g_LowPrice = 0;                                        //輸入單價存儲小數點后部分變量
  15. UINT_8  Count1 = 0, Count2 = 0, DecimalPointCount = 0;                  //Count1限定輸入單價整數部分的次數(限定為5位數,超過自動清零),Count限定為兩位小數,超過自動清零
  16. FLOAT_32 g_Price = 0.0;                             //物品單價(整數與小數之和)
  17. UINT_32 g_TotalPrices = 0;                          //物品總額
  18. FLOAT_32 g_TempPrices = 0.0;                   //總額中間變量(防止總額過大超出液晶屏顯示,超出時警告)
  19. UINT_8 code table1[] = {"歡迎你"};
  20. UINT_8 code table2[] = {"重量G:     g"};
  21. UINT_8 code table3[] = {"單價$:"};
  22. UINT_8 code table4[] = {"總額$:"};
  23. UINT_8 code table5[] = {"Err!"};
  24. UINT_8 code table6[] = {"          "};                         //清屏的某一行
  25. UINT_8 code table7[] = {"重量G:0.000Kg"};
  26. UINT_8 code table8[] = {"0.000"};                            //用空格會引起閃爍感
  27. UINT_8 WeightTable[6];                                         //存儲質量的字符串
  28. UINT_8 TotalPricesTable[11];                         //存儲總額字符串
  29.                                          
  30. void Init(void);                                                   //初始化函數
  31. void Clean_Price(void);                                           //清除函數
  32. void Display_Int2str(UINT_32 DecNum, UINT_8 Str[], UINT_8 DDRAM);                 //輸入十進制顯示字符函數
  33. void Init_Weighttab(UINT_8 *String1, UINT_8 *String2);                                         //初始化字符串數組

  34. void main()                                                                                       
  35. {         
  36.         INT_8 j = 0, k = 0, count = 0;
  37.     UINT_8 Key = 0, Num = 0;                //Key存儲按鍵的鍵值,Num存儲按下的是那個數字
  38.         UINT_32 tmp = 0;                  
  39.         Init();
  40.         while (1)
  41.         {
  42.                 WDT_FeedDog();                           //喂狗
  43.                 if (KeycanFlag == 0)                                        //價格還沒輸入時可以顯示(防止價格輸入一半DDRAM地址改變,造成價格不可連續輸入)
  44.                 {          
  45.                         if (TimeCount >= 50)                            //定時時間超過250ms執行AD采集
  46.                         {
  47.                                 //        Offset = AD_Hx711();                                                                 //8527820-8475960 =51860
  48.                                 //        Display_Int2str(Offset, WeightTable, 0x93);
  49.                                  WeightTemp = AD_Weight(AD_Hx711());                                   //把AD值轉化為以克為單位的質量(含小數)
  50.                                 if (WeightTemp > 4000)                                                            //超出量程4000g報警
  51.                                 {       
  52.                                         for (k = 0; k < 4; k++)
  53.                                         {
  54.                                                 LcdDdram_Display(1,3,table5);                  //輸出錯誤字符串                                  
  55.                                         }
  56.                                         Beep = 0;                          //蜂鳴器鳴叫
  57.                                         Led  = 0;                          //Led亮
  58.                                 }       
  59.                                 else
  60.                                 {                                                                                                             
  61.                                         Beep = 1;                                                                           //重量少于最大量程關閉蜂鳴器
  62.                                         Led  = 1;       
  63.                                         tmp = (UINT_32)(WeightTemp);        //        tmp = (UINT_32)(WeightTemp + 0.5);                   //將質量四舍五入,例如1000.50 》1001
  64.                                         if(RangeFlag == 0)                                                  //量程單位為g
  65.                                         {               
  66.                                                 Init_Weighttab(WeightTable,table6);        //初始化字符數組為空格,防止上次字符位數比這次大,沒有清除
  67.                                                 k = 0;                                                                 //例如上次顯示1234,這次12,殘留34
  68.                                             Weight = tmp;                                                 //中間質量變量賦給質量
  69.                                                 while (tmp != 0)                                                                                
  70.                                                 {
  71.                                                         WeightTable[k++] = 0x30 + tmp % 10;                         //提取十進制最后一位轉換為字符
  72.                                                     tmp /= 10;               
  73.                                                 }       
  74.                                                 if (k == 0)                                        //質量為0時
  75.                                                 {       
  76.                                                         WeightTable[k++] = '0';                  
  77.                                                 }       
  78.                                                 Write_Cmd(0x93);                                                                        
  79.                                                 count = k;
  80.                                                 while (k > 0)                       
  81.                                             {       
  82.                                                         Write_Data(WeightTable[k-1]);          //質量倒序輸出,因為之前是倒序輸入,高位地址為高位,由高位到低位       
  83.                                                         k--;                                                                  
  84.                                                 }        
  85.                                                 for (k = count; k < 5; k++ )                  //把上次殘留的字符清掉
  86.                                                 {
  87.                                                          Write_Data(WeightTable[k]);
  88.                                                 }
  89.                                         }
  90.                                         else
  91.                                         {
  92.                                                 Init_Weighttab(WeightTable,table8);                         //清空字符串數組
  93.                                                 k = 0;
  94.                                                 Weight = tmp / 1000.0;                                    //質量/g 1000 =  /kg
  95.                                                   while (tmp != 0)                                                        
  96.                                                 {
  97.                                                         WeightTable[k++] = 0x30 + tmp % 10;                        
  98.                                                     tmp /= 10;               
  99.                                                         if (k == 3)                                                            //i=3時就是獲得3位小數時插入小數點   
  100.                                                         {                                                       
  101.                                                                 WeightTable[k] = '.';                        
  102.                                                                 k += 1;       
  103.                                                         }
  104.                                                 }
  105.                                                 if (k == 4)                                //剛好3個小數補0 0.123                
  106.                                                 {
  107.                                                         WeightTable[k] = '0';               
  108.                                                         k++;                           //和上面統一,k比實際大1,下面再減回
  109.                                                 }
  110.                                                 if (k < 3)                                                   //當不夠兩位小數時,例如1實際代表的是0.01
  111.                                                 {               
  112.                                                         WeightTable[4] = 0x30;                                //在最高位插入0
  113.                                                         WeightTable[3] = '.';                                //在最次高位插入.
  114.                                                         for (j = k; j < 3; j++)
  115.                                                         {
  116.                                                                 WeightTable[j] = 0x30;                 //如果只有0位時插入一個插入兩個0         0.00
  117.                                                         }                                                                         //如果只有1位時插入一個插入1個0         0.0
  118.                                                         k = 5;                                                        //0.001剛好5個數
  119.                                                 }       
  120.                                                 Write_Cmd(0x93);                                 //重定位液晶DDRAM地址                                                 
  121.                                                 while (k > 0)                              
  122.                                             {       
  123.                                                         Write_Data(WeightTable[k-1]);          //總額結算,倒序輸出,因為之前是倒序輸入,高位地址為高位
  124.                                                         k--;                                                                  
  125.                                                 }
  126.        
  127.                                         }
  128.                                
  129.                                 }                                 
  130.                                 TimeCount = 0;
  131.                                 Write_Cmd(0x8b);                                                         //顯示完體重就定位價格顯示地址
  132.                         }                  
  133.             }       
  134.        
  135.                 if (TimeIRQflag == 1)                 //5ms定時中斷 ,5ms是為了可以利用來去抖延時而不失效率,由掃描態轉入確認態至少5ms
  136.             {
  137.                         TimeIRQflag = 0;               
  138.                         Key = KeyRead();                //鍵盤掃描,獲取鍵值                                                                           按鍵的意義:        1     2     3     量程切換
  139.                         switch (Key)                                                                                                                                                 //                    4          5                6          去皮
  140.                         {                                                                                                                                                                        //                        7          8                9          清除
  141.                                 case KEY1  :         if (TotalFlag== 0) { Write_Data(0x31);  Num = 1; } break;                //                        .     0          開關          結算
  142.                                 case KEY2  :         if (TotalFlag== 0) { Write_Data(0x32);  Num = 2; } break;                       
  143.                                 case KEY3  :         if (TotalFlag== 0) { Write_Data(0x33);  Num = 3; } break;
  144.                                 case KEY4  :                                   
  145.                                 {
  146.                                          RangeFlag = !RangeFlag ;
  147.                                          Clean_Price();
  148.                                          if (RangeFlag == 0)                                   //量程切換模式,0為g為單位,1為Kg為單位
  149.                                          {
  150.                                                  LcdDdram_Display(1,0,table2);            //把字符串Kg 變成 g ,殘留1個g
  151.                                                 Write_Data(' ');                                           //清掉殘留的g
  152.                                          }
  153.                                          else
  154.                                          {
  155.                                                  LcdDdram_Display(1,0,table7);                  //把字符串g 變成 Kg       
  156.                                          }
  157.                                          Write_Cmd(0x8b);
  158.                                 }         
  159.                                 break;               
  160.                                 case KEY5  :         if (TotalFlag== 0) { Write_Data(0x34);  Num = 4;}  break;
  161.                                 case KEY6  :         if (TotalFlag== 0) { Write_Data(0x35);  Num = 5;}  break;
  162.                                 case KEY7  :         if (TotalFlag== 0) { Write_Data(0x36);  Num = 6;}  break;
  163.                                 case KEY8  :         AD_Offset();                                                                                      break;               
  164.                                 case KEY9  :         if (TotalFlag== 0) { Write_Data(0x37);  Num = 7;}  break;
  165.                                 case KEY10 :         if (TotalFlag== 0) { Write_Data(0x38);  Num = 8;}  break;
  166.                                 case KEY11 :         if (TotalFlag== 0) { Write_Data(0x39);  Num = 9;}  break;
  167.                                 case KEY12 :         Clean_Price();                          break;                                                           
  168.                                 case KEY13 :         
  169.                                 {                       
  170.                                                                 if (DecimalPointCount == 0 && KeycanFlag == 0)
  171.                                                                 {       
  172.                                                                          Write_Data(0x30);
  173.                                                                          Write_Data(0x2e);                                  //顯示‘.’
  174.                                                                 }
  175.                                                                 if (DecimalPointCount == 0 && KeycanFlag == 1)
  176.                                                                 {
  177.                                                                          Write_Data(0x2e);
  178.                                                                 }
  179.                                                                 if (DecimalPointCount > 200)
  180.                                                                 {       
  181.                                                                         DecimalPointCount = 0;                       
  182.                                                                 }
  183.                                                                 DecimalPointCount++;
  184.                                                                 g_DecimalPointflag = 1;                 //小數點按下
  185.                                                                 KeycanFlag = 1;
  186.                                 }
  187.                                 break;               
  188.                                 case KEY14 :        if (TotalFlag== 0) { Write_Data(0x30);  Num = 0; }  break;                  
  189.                                 case KEY15 :        PCON_PD();                    break;                                 
  190.                                 case KEY16 :         
  191.                             {               
  192.                                         TotalFlag = 1;                                         //總額顯示之后不能輸入價格
  193.                                         if (Count1 == 1)                          
  194.                                         {
  195.                                                 Count1 = 0;                                  //小數點后面只有1位數的時候*10
  196.                                                 g_LowPrice *= 10;                  //變大10倍,防止出現例如輸入1.2的時候,小數部分為0.02
  197.                                         }                       
  198.                                         g_Price = g_HighPrice + g_LowPrice / 100.0;                        //單價 = 整數 + 小數
  199.                                         g_TempPrices = g_Price * Weight * 100;                                 //總額中間變量 = 價格 * 重量 * 100(保留兩位小數點)
  200.                                         if (g_TempPrices >999999999)                                                 //超出屏幕顯示(10位,1位為小數點)報警
  201.                                         {
  202.                                                 LcdDdram_Display(3,3,table5);                                          //超出量程報錯       
  203.                                                 break;
  204.                                         }                                                                                                           //(int)(a+0.5)為四舍五入
  205.                                         g_TotalPrices = (UINT_32)(g_TempPrices+0.5);                   //把浮點型轉換為整型,2.10*1*100 = 209.99 (優化出錯)。。。       
  206.                                         Display_Int2str(g_TotalPrices, TotalPricesTable, 0x9b);                 //顯示總額
  207.                                 }                                                    
  208.                                 break;       
  209.                                 default  :       break;       
  210.                         }                                                                                                                                                       
  211.                        
  212.                         if (Key == KEY1 || Key == KEY2 || Key == KEY3 || Key == KEY5 || Key == KEY6             //有數字按鍵按下時
  213.                                  || Key == KEY7 || Key == KEY9 || Key == KEY10 || Key == KEY11 || Key == KEY14)
  214.                         {
  215.                             KeycanFlag = 1;
  216.                            if (g_DecimalPointflag != 1)                                 //數字按下時小數點還沒按下輸入的是整數部分
  217.                            {
  218.                                              Count2++;
  219.                                           if (Count2 >= 5)                                        //不可以輸入超過5位數
  220.                                           {
  221.                                                    Clean_Price();                                     //超過自動清零
  222.                                           }
  223.                                           g_HighPrice = g_HighPrice * 10 + Num;                          //連續輸入整數部分時,前一位*10再+后一位  
  224.                            }
  225.                            else                                                                                 //有小數點按下了
  226.                            {
  227.                                              Count1++;
  228.                                           if (Count1 >= 3)                                         //小數部分不可以輸入超過2位數
  229.                                           {
  230.                                                    Clean_Price();                                          //超過自動清零
  231.                                           }
  232.                                              g_LowPrice = g_LowPrice * 10 + Num;       
  233.                                          
  234.                            }

  235.                         }
  236.                                
  237.                 }         
  238.         }                 
  239. }
  240.           
  241. /********************************************************************
  242. 函數名稱: Init()               
  243. 功能簡介: 初始化定時器,液晶初始化
  244. 入口參數: 無
  245. 返回值  :無
  246. *********************************************************************/
  247. void Init(void)
  248. {       
  249.         RATE = 0;                                                            //初始化Hx711轉換速率為10Hz(RATE = 0時AD轉換速率為10Hz,RATE = 1為80Hz)
  250.         Time_Init();                                        //定時器0中斷初始化
  251.         LCD_Init();                                                        //12864液晶初始化
  252.         LcdDdram_Display(0,0,table1);                //第1行顯示數據table1內容        (萬家福超市歡迎你)
  253.         LcdDdram_Display(1,0,table2);                //第2行顯示數據table2內容         (重量G:     g)
  254.         LcdDdram_Display(2,0,table3);            //第3行顯示數據table3內容         (單價$:)
  255.         LcdDdram_Display(3,0,table4);            //第4行顯示數據table4內容         (總額$:)
  256.         AD_Offset();                                            //采集零偏的平均值               
  257. }

  258. /********************************************************************
  259. 函數名稱: void Clean_Price(void)               
  260. 功能簡介: 清除函數,把單價、總額變量等清0
  261. 入口參數: 無
  262. 返回值  :無
  263. *********************************************************************/
  264. void Clean_Price(void)
  265. {
  266.          LcdDdram_Display(2,3,table6);                  //清除單價顯示
  267.          LcdDdram_Display(3,3,table6);                  //清除總額顯示
  268.          g_HighPrice = 0;                                          //清除價格
  269.          g_LowPrice = 0;
  270.          Count1 = 0;
  271.          Count2        = 0;
  272.          KeycanFlag = 0;                                          //清除禁止AD采集標志位
  273.          TotalFlag  = 0;
  274.          DecimalPointCount  = 0;
  275.          g_DecimalPointflag = 0;                          //小數點
  276.          Write_Cmd(0x8b);                                          //DDRAM地址指針調整
  277. }

  278. /********************************************************************
  279. 函數名稱: void Display_Int2str(UINT_32 DecNum, UINT_8 Str[], UINT_8 DDRAM)               
  280. 功能簡介: 把十進制數轉換為字符串輸出,保留兩位小數點
  281.                   此段代碼是把十進制的“總額”倒序轉換為字符串存放在數組TotalPricesTable【】里面,
  282.                   總額TotalPrices的LSB位存放在字符數組的最低位,這樣做的原因有兩點:
  283.               可以確定小數點存放在數組那個位置(由保留小數點位數(i)確定,從最低位數0起到第i位插入小數點)
  284.                   如果設定12864液晶為地址自動減1模式時為小端字節,例如把654321倒序輸出就會變成214365
  285. 入口參數: UINT_32 DecNum, UINT_8 Str[], UINT_8 DDRAM
  286. 返回值  :無
  287. *********************************************************************/
  288. void Display_Int2str(UINT_32 DecNum, UINT_8 Str[], UINT_8 DDRAM)
  289. {
  290.         INT_8 i = 0, j = 0;
  291.         while (DecNum != 0)                                                         //十進制數不為0時               
  292.         {
  293.                 Str[i++] = 0x30 + DecNum % 10;                         //提取十進制最后一位轉換為字符
  294.             DecNum /= 10;               
  295.                 if (i == 2)                                                        //倒序存儲到Str數組里去,例如1234,存放為4321
  296.                 {                                                       
  297.                         Str[i] = '.';                                         //i=2時就是獲得兩位小數時插入小數點
  298.                         i+=1;       
  299.                 }
  300.         }
  301.         if (i == 3)                                                //Str只有兩位數時,在最前面插入‘0’
  302.         {
  303.                 Str[i] = '0';
  304.                 i++;
  305.         }
  306.         Write_Cmd(DDRAM);                                 //重定位液晶DDRAM地址
  307.         if (i < 2)                                                   //當不夠兩位小數時,例如1實際代表的是0.01
  308.         {               
  309.                 Str[3] = 0x30;                                //在最高位插入0
  310.                 Str[2] = '.';                                //在最次高位插入.
  311.                 for (j = i; j < 2; j++)
  312.                 {
  313.                         Str[j] = 0x30;                 //如果只有0位時插入一個插入兩個0         0.00
  314.                 }                                                                         //如果只有1位時插入一個插入1個0         0.0
  315.                 i = 4;                                       //字符數組TotalPricesTable長度
  316.         }                                                                 
  317.         while (i >= 1)                       //i設定大于1不大于0是因為前面的i在不符合循環條件時自動加1,比實際字符數組長度多1位
  318.     {       
  319.                 Write_Data(Str[i-1]);          //總額結算,倒序輸出,因為之前是倒序輸入,高位地址為高位
  320.                 i--;                                                                  
  321.         }        
  322. }

  323. /********************************************************************
  324. 函數名稱: Init_Weighttab()               
  325. 功能簡介: 初始化字符數組
  326. 入口參數: UINT_8 *String1, UINT_8 *String2
  327. 返回值  :無
  328. *********************************************************************/
  329. void Init_Weighttab(UINT_8 *String1, UINT_8 *String2 )
  330. {
  331.         UINT_8 i;
  332.         for (i = 0; i < 5 ;i++)
  333.         {
  334.                  *String1++ = *String2;         
  335.         }
  336. }          
  337.                                                     
復制代碼

Keil代碼PCB 2個文件下載:
電子秤.7z (664.39 KB, 下載次數: 29)

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲第一区国产精品 | 亚洲精品久久久9婷婷中文字幕 | 免费在线观看成人 | 国产欧美精品一区二区色综合朱莉 | 精品久草 | 国产乱码精品一品二品 | 蜜桃视频成人 | 亚洲视频免费在线播放 | 欧美三级在线 | 成人小视频在线观看 | 日韩三级免费观看 | 久久久久国产精品一区 | 精品一区二区三区中文字幕 | 国产精品成人一区 | 亚洲69p | 欧美自拍一区 | 亚洲不卡在线观看 | 亚洲一区二区三区免费视频 | 日本视频免费 | 在线精品一区二区 | 免费看的av| www.99re| 国产盗摄视频 | 国产欧美在线观看 | 欧美精品久久久 | 日韩欧美日韩在线 | 欧美日韩精品一区二区三区四区 | 成人免费看片又大又黄 | 成人性视频免费网站 | 免费一二区 | 国产一区二区精品自拍 | 草草草久久久 | 欧美不卡一区二区 | 久久国产精品首页 | 欧美性一区二区三区 | 久久99精品久久久久久狂牛 | 天天拍天天插 | 欧美一区2区三区4区公司 | 黄色毛片在线观看 | 国产成人影院 | 欧美日韩在线一区二区三区 |