找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7753|回复: 6
打印 上一主题 下一主题
收起左侧

51单片机hx711简易电子秤源程序

  [复制链接]
跳转到指定楼层
楼主
此程序适用单片机类型STC89C52RC


单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #include<string.h>
  4. #include<lcd12864.h>
  5. #include<hx711.h>
  6. #include<eeprom52.h>
  7. #include<keyboard.h>

  8. #define MAX   10000
  9. #define uint unsigned int
  10. #define uchar unsigned char
  11. #define ulong unsigned long

  12. #define delayNOP();{_nop_();_nop_();_nop_();_nop_();};

  13. //定义量程系数
  14. //#define RATIO     2356/1000
  15. uint RATIO;  

  16. //定义标识
  17. volatile bit FlagTest = 0;                //定时测试标志,每0.5秒置位,测完清0
  18. volatile bit FlagKeyPress = 0;  //有键按下标志,处理完毕清0
  19. volatile bit FlagSetPrice = 0;  //价格设置状态标志,设置好为1?
  20. volatile bit ClearWeighFlag = 0; //传感器调零标志位,清除0漂?
  21. volatile bit wtk = 0; //称重/时间模式

  22. //管脚定义
  23. sbit beep = P3^3;
  24. sbit alert = P3^4;

  25. //显示用变量
  26. int Counter;
  27. uchar idata str1[6] = "000000";
  28. int i, iTemp;

  29. //称重用变量
  30. ulong idata FullScale; //满量程AD值/1000
  31. ulong AdVal;     //AD采样值
  32. ulong weight;    //重量值,单位g
  33. ulong idata price;     //单价,长整型值,单位为分   
  34. ulong idata money;     //总价,长整型值,单位为分
  35. ulong idata pricebc;   //单价,长整型值,单位为分  

  36. //键盘处理变量
  37. uchar keycode;
  38. uchar DotPos;                                   //小数点标志及位置
  39. uchar wttime;//

  40. //函数声明
  41. void int2str(int, char *);
  42. void Data_Init();
  43. void Timer0_Init();
  44. void Timer0_ISR () ;
  45. void INT1_Init();
  46. void KeyPress(uchar);
  47. void To_Zero();
  48. void Display_Price();  //单价写入屏函数
  49. void Display_Weight(); //重量写入屏函数
  50. void Display_Money();  //总价写入屏函数


  51. //整型转字符串的函数,转换范围0--65536
  52. void int2str(int x, char* str)
  53. {
  54.         int i=1;
  55.         int tmp=10;
  56.         while(x/tmp!=0)
  57.         {
  58.                         i++;
  59.                         tmp*=10;
  60.         }
  61.         tmp=x;
  62.         str[i]='\0';
  63.         while(i>1)
  64.         {
  65.                         str[--i]='0'+(tmp%10);
  66.                         tmp/=10;
  67.         }
  68.         str[0]=tmp+'0';
  69. }

  70. //重新找回零点,每次测量前调用
  71. void To_Zero()
  72. {
  73.            FullScale=ReadCount();
  74.            price=0;
  75. }


  76. /******************把数据保存到单片机内部eeprom中******************/
  77. void write_eeprom()
  78. {
  79.         uchar x1,x2;
  80.         x1=RATIO/256;
  81.   x2=RATIO%256;
  82.         SectorErase(0x2000);
  83.         byte_write(0x2000, x1);
  84.         byte_write(0x2001, x2);
  85.         byte_write(0x2058, a_a);       
  86. }

  87. /******************把数据从单片机内部eeprom中读出来*****************/
  88. void read_eeprom()
  89. {
  90.         uchar x1,x2;
  91.   x2 = byte_read(0x2001);
  92.         x1 = byte_read(0x2000);
  93.         a_a= byte_read(0x2058);
  94.         RATIO = x1*256+x2;
  95. }

  96. /**************开机自检eeprom初始化*****************/
  97. void init_eeprom()
  98. {
  99.         read_eeprom();                //先读
  100.         if(a_a != 1)                //新的单片机初始单片机内问eeprom
  101.         {
  102.                 RATIO = 3500;
  103.                 a_a = 1;
  104.                 write_eeprom();           //保存数据
  105.         }       
  106. }

  107. //显示单价,单位为元,四位整数,两位小数
  108. void Display_Price()
  109. {
  110.            uint i,j;
  111.         uchar A1,A2,A3,A4;
  112.         uchar B1,B2;
  113.            i = price/100;    //得到整数部分
  114.            j = price - i*100;//得到小数部分
  115.            int2str(i,str1);
  116.         A1=i/1000+48;
  117.         A2=i%1000/100+48;
  118.         A3=i%1000%100/10+48;
  119.         A4=i%1000%100%10+48;
  120.         B1=j/10+48;
  121.         B2=j%10+48;
  122.            //显示整数部分
  123.            if (i>=1000)
  124.            {
  125.               Lcd_Pos(2,3);
  126.                 Lcd_Wdat(A1);
  127.                    Lcd_Wdat(A2);
  128.                 Lcd_Wdat(A3);
  129.                 Lcd_Wdat(A4);
  130.            }
  131.            else if (i>=100)
  132.            {
  133.               Lcd_Pos(2,3);
  134.                 Lcd_Wdat(' ');
  135.                    Lcd_Wdat(A2);
  136.                 Lcd_Wdat(A3);
  137.                 Lcd_Wdat(A4);
  138.            }
  139.            else if (i>=10)
  140.            {
  141.               Lcd_Pos(2,3);
  142.                 Lcd_Wdat(' ');
  143.                 Lcd_Wdat(' ');
  144.                 Lcd_Wdat(A3);
  145.                 Lcd_Wdat(A4);
  146.            }
  147.    else
  148.    {
  149.         Lcd_Pos(2,3);
  150.                 Lcd_Wdat(' ');
  151.                 Lcd_Wdat(' ');
  152.                 Lcd_Wdat(' ');
  153.                 Lcd_Wdat(A4);
  154.    }
  155.    //显示小数点, 小数点部分
  156.    int2str(j,str1);
  157.    if(j<10)
  158.    {
  159.         Lcd_Pos(2,5);
  160.                 Lcd_Wdat('.');
  161.                 Lcd_Wdat('0');
  162.                 Lcd_Wdat(B2);
  163.                 Lcd_Wdat(' ');          
  164.    }
  165.    else
  166.    {
  167.         Lcd_Pos(2,5);
  168.                 Lcd_Wdat('.');
  169.                 Lcd_Wdat(B1);
  170.                 Lcd_Wdat(B2);
  171.                 Lcd_Wdat(' ');
  172.    }
  173. }
  174. //显示重量,单位kg,两位整数,三位小数
  175. void Display_Weight()
  176. {
  177.            uint i,j;
  178.            uchar A1,A2;
  179.            uchar B1,B2,B3;
  180.            //weight单位是g                                          
  181.            i = weight/1000;    //得到整数部分
  182.            j = weight - i*1000;//得到小数部分
  183.            A1=i/10+48;
  184.            A2=i%10+48;
  185.            B1=j/100+48;
  186.            B2=j%100/10+48;
  187.            B3=j%100%10+48;
  188.     int2str(i,str1);
  189.            if (i>=10)
  190.            {
  191.              
  192.            }
  193.            else
  194.            {
  195.                Lcd_Pos(1,4);
  196.                 Lcd_Wdat(' ');
  197.                 Lcd_Wdat(A2);
  198.            }  
  199.            int2str(j,str1);
  200.            if (j<10)
  201.            {
  202.               Lcd_Pos(1,5);
  203.                 Lcd_Wdat('.');
  204.                 Lcd_Wdat('0');
  205.                 Lcd_Wdat('0');
  206.                 Lcd_Wdat(B3);
  207.            }
  208.            else if (j<100)
  209.            {
  210.               Lcd_Pos(1,5);
  211.                 Lcd_Wdat('.');
  212.                 Lcd_Wdat('0');
  213.                 Lcd_Wdat(B2);
  214.                 Lcd_Wdat(B3);
  215.            }
  216.            else
  217.            {
  218.               Lcd_Pos(1,5);
  219.                 Lcd_Wdat('.');
  220.                 Lcd_Wdat(B1);
  221.                 Lcd_Wdat(B2);
  222.                 Lcd_Wdat(B3);
  223.            }
  224. }
  225. //显示总价,单位为元,四位整数,两位小数
  226. void Display_Money()
  227. {
  228.            uint i,j;
  229.            uchar A1,A2,A3,A4;
  230.            uchar B1,B2;
  231.            if (money>999999)         //超出显示量程
  232.            {
  233.               Lcd_Pos(3,3);
  234.                 Lcd_Wdat('-');
  235.                 Lcd_Wdat('-');
  236.                    Lcd_Wdat('-');
  237.                 Lcd_Wdat('-');
  238.                 Lcd_Wdat('-');
  239.                 Lcd_Wdat('-');
  240.                 Lcd_Wdat('-');
  241.               return;      
  242.            }
  243.            i = money/100;    //得到整数部分
  244.            j = money - i*100;//得到小数部分
  245.            A1=i/1000+48;
  246.            A2=i%1000/100+48;
  247.            A3=i%1000%100/10+48;
  248.            A4=i%1000%100%10+48;
  249.            B1=j/10+48;
  250.            B2=j%10+48;
  251.            int2str(i,str1);
  252.            //显示整数部分
  253.         if (i>=1000)
  254.            {
  255.               Lcd_Pos(3,3);
  256.                 Lcd_Wdat(A1);
  257.                    Lcd_Wdat(A2);
  258.                 Lcd_Wdat(A3);
  259.                 Lcd_Wdat(A4);
  260.            }
  261.            else if (i>=100)
  262.            {
  263.               Lcd_Pos(3,3);
  264.                 Lcd_Wdat(' ');
  265.                    Lcd_Wdat(A2);
  266.                 Lcd_Wdat(A3);
  267.                 Lcd_Wdat(A4);
  268.            }
  269.            else if (i>=10)
  270.            {
  271.               Lcd_Pos(3,3);
  272.                 Lcd_Wdat(' ');
  273.                 Lcd_Wdat(' ');
  274.                 Lcd_Wdat(A3);
  275.                 Lcd_Wdat(A4);
  276.            }
  277.            else
  278.            {
  279.              Lcd_Pos(3,3);
  280.                 Lcd_Wdat(' ');
  281.                 Lcd_Wdat(' ');
  282.                 Lcd_Wdat(' ');
  283.                 Lcd_Wdat(A4);
  284.            }
  285.            //显示小数点, 小数点部分
  286.            int2str(j,str1);
  287.            if(j<10)
  288.            {
  289.         Lcd_Pos(3,5);
  290.                 Lcd_Wdat('.');
  291.                 Lcd_Wdat('0');
  292.                 Lcd_Wdat(B2);          
  293.            }
  294.            else
  295.            {
  296.         Lcd_Pos(3,5);
  297.                 Lcd_Wdat('.');
  298.                 Lcd_Wdat(B1);
  299.                 Lcd_Wdat(B2);
  300.            }
  301. }
  302. //数据初始化
  303. void Data_Init()
  304. {
  305.            price = 0;
  306.            DotPos = 0;
  307.            beep = 1;
  308.            alert = 1;
  309. }

  310. //定时器0初始化
  311. void Timer0_Init()
  312. {
  313.         ET0 = 1;        //允许定时器0中断
  314.         TMOD = 1;       //定时器工作方式选择
  315.         TL0 = 0x06;     
  316.         TH0 = 0xf8;     //定时器赋予初值
  317.         TR0 = 1;        //启动定时器
  318. }
  319. //定时器0中断
  320. void Timer0_ISR (void) interrupt 1 using 0
  321. {
  322.         TL0 = 0x06;
  323.         TH0 = 0xf8;     //定时器赋予初值

  324.         //每0.5秒钟刷新重量
  325.     Counter ++;
  326.     if (Counter >= 200)
  327.     {
  328.                FlagTest = 1;
  329.                    Counter = 0;
  330.     }
  331. }
  332. //按键响应程序,参数是键值
  333. //返回键值:
  334. //         1          2       3      10(清0)
  335. //         4          5       6      11(删除单价)
  336. //         7          8       9      12(去皮)
  337. //         14(未定义) 0      15(.)   13(未定义)

  338. void KeyPress(uchar keycode)
  339. {
  340.         switch (keycode)
  341.            {
  342.               case 0:
  343.               case 1:
  344.               case 2:
  345.               case 3:
  346.               case 4:
  347.               case 5:
  348.               case 6:
  349.               case 7:
  350.               case 8:
  351.               case 9:
  352.             //目前在设置整数位,要注意price是整型,存储单位为分
  353.                    if (DotPos == 0)
  354.                 {  
  355.                     //最多只能设置到千位
  356.                         if (price<100000)
  357.                         {
  358.                               price=price*10+keycode*100;
  359.                         }
  360.                 }
  361.                  //目前在设置小数位
  362.                 else if (DotPos==1)  //小数点后第一位
  363.                 {
  364.                     price=price+keycode*10;
  365.                         DotPos++;
  366.                 }
  367.                 else if (DotPos==2)
  368.                 {
  369.                     price=price+keycode;
  370.                         DotPos++;
  371.                 }
  372.                         Display_Price();
  373.             break;
  374.                
  375.                
  376.       case 10:   //清零键
  377.                                 Delay(15);//延时
  378.                         pricebc=price;
  379.             To_Zero();
  380.                         price=pricebc;
  381.                          Display_Price();
  382.                          DotPos = 0;
  383.                         beep=~beep;
  384.                          break;
  385.                        
  386.                        
  387.                   case 11:        //清楚单价
  388.                                 Delay(15);//延时
  389.                                 price=0;
  390.                     DotPos = 0;
  391.                                 Display_Price();
  392.                  break;
  393.                        
  394.                   case 12:                //去皮
  395.                                 Delay(15);//延时
  396.                         ClearWeighFlag = 1;        //置零传感器标志 置1
  397.                         break;
  398.                        
  399.                        
  400.       case 13:   //微调
  401.                                 Delay(15);//延时
  402.                                 if(wtk==0)
  403.                                 RATIO--;//微调系数
  404.                         else
  405.                                 RATIO=RATIO-20;//微调系数
  406.                         write_eeprom();//存入eerom内,掉电不丢失系数数据
  407.                   break;
  408.                        
  409.                        
  410.                         case 14:   //微调减
  411.                                 Delay(15);//延时
  412.                         if(wtk==0)
  413.                                 RATIO++;//微调系数
  414.                         else
  415.                                 RATIO=RATIO+20;//微调系数
  416.                         write_eeprom();//存入eerom内,掉电不丢失系数数据
  417.                   break;
  418.                        
  419.                   case 15:   //小数点按下
  420.                                 Delay(15);//延时
  421.                          if (DotPos == 0)  
  422.                          {   
  423.                                 DotPos = 1;      //小数点后第一位
  424.                          }
  425.                      break;
  426.                    }
  427.            Delay(10);
  428. }



  429. void main()
  430. {
  431.    Lcd_Init();
  432.    EA = 0;
  433.    Data_Init();
  434.    Timer0_Init();
  435.    
  436.          EA = 1;//初始化完成,开中断
  437.          beep=1;
  438.         init_eeprom();

  439.          Lcd_Clear();    //clear all dots
  440.          Lcd_Display1();
  441.          Delay(700);
  442.          To_Zero();
  443.          Lcd_Clear();
  444.          Lcd_Display2();
  445.          Display_Price();   
  446.            while(1)
  447.            {
  448.               //每0.5秒称重一次
  449.                   if (FlagTest==1)
  450.                   {
  451.                      //称重,得到重量值weight,单位为g
  452.                          AdVal=ReadCount();
  453.                          weight=FullScale-AdVal;
  454.                          if (weight>0x8000000) weight=0;
  455.                                 weight=weight*10/RATIO;//物体实际重量=总量量程对于的是多少。
  456.                          //weight=10000*weight/FullScale;
  457.                          //weight=weight*RATIO;
  458.                          //如果超量程,则报警
  459.                          if (weight >= MAX)
  460.                          {
  461.                     beep = 0;
  462.                                 alert = 0;
  463.                                 Lcd_Pos(1,4);
  464.                                 Lcd_Wdat('-');
  465.                                 Lcd_Wdat('-');
  466.                                    Lcd_Wdat('-');
  467.                                 Lcd_Wdat('-');
  468.                                 Lcd_Wdat('-');
  469.                                 Lcd_Wdat('-');

  470.                                    Lcd_Pos(3,3);
  471.                                 Lcd_Wdat('-');
  472.                                 Lcd_Wdat('-');
  473.                                    Lcd_Wdat('-');
  474.                                 Lcd_Wdat('-');
  475.                                 Lcd_Wdat('-');
  476.                                 Lcd_Wdat('-');
  477.                                 Lcd_Wdat('-');
  478.                          }
  479.                          //如果不超量程
  480.                          else
  481.                          {
  482.                     beep = 1;
  483.                                 alert = 1;
  484.               Display_Weight();                 
  485.                     money = weight*price/1000;  //money单位为分                 
  486.                     Display_Money();//显示总金额
  487.                           if(money>999999)
  488.                                         money=999999;
  489. ……………………

  490. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
1-程序-10kg.rar (67.55 KB, 下载次数: 144)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:371269 发表于 2018-8-11 12:38 | 只看该作者
博主那个清除0飘是什么意思啊
回复

使用道具 举报

板凳
ID:396503 发表于 2018-9-11 20:12 | 只看该作者
点赞,感觉收益很大
回复

使用道具 举报

地板
ID:369904 发表于 2019-8-3 11:24 | 只看该作者
下载一个看看能不能用上
回复

使用道具 举报

5#
ID:48140 发表于 2019-9-30 09:17 来自手机 | 只看该作者
下载一个看看,这个还搞不懂。
回复

使用道具 举报

6#
ID:446775 发表于 2020-5-9 22:37 | 只看该作者
请教一下,您这个校正的原理是什么呢?程序里 有吗?
回复

使用道具 举报

7#
ID:638921 发表于 2020-6-27 11:09 | 只看该作者
大佬,需要用到些什么东西,怎么连接,可以教一下吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表