找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机电子秤 仿真+程序

[复制链接]
跳转到指定楼层
楼主
ID:677847 发表于 2021-3-9 01:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序
  1. #include<reg51.h>
  2. #include<intrins.h>
  3. #include <absacc.h>
  4. #include <math.h>

  5. #define uchar unsigned char
  6. #define uint   unsigned int
  7. #define BUSY  0x80                               //常量定义
  8. #define DATAPORT P0

  9. sbit ADCS =P3^5;
  10. sbit ADDI =P3^7;  
  11. sbit ADDO =P3^7;  
  12. sbit ADCLK =P3^6;  

  13. sbit LCM_RS=P2^0;
  14. sbit LCM_RW=P2^1;
  15. sbit LCM_EN=P2^2;
  16. uint x1,y1,z1=0,w1,temp1;
  17. uchar ad_data,k,n,m,e,num,s;                              //采样值存储
  18. sbit beep =P3^0;                        
  19.                   
  20. char press_data;                                  //标度变换存储单元
  21. unsigned char ad_alarm;                           //报警值存储单元
  22. unsigned char press_ge=0;                        //显示值百位
  23. unsigned char press_shifen=0;                        //显示值十位
  24. unsigned char press_baifen=0;                         //显示值个位
  25. unsigned char press_qianfen=0;                        //显示值十分位

  26. uchar code str0[]={"Weight:  .   Kg "};
  27. uchar code str2[]={"Price:          "};
  28. uchar code str3[]={"Total:             "};
  29. uchar code table2[]={0x37,0x38,0x39,0xfd,0x34,0x35,0x36,0x78,0x31,0x32,0x33,0x2d,0x3d,0x30,0x2e,0x2b}; //键盘码

  30. void delay(uint);
  31. void lcd_wait(void);
  32. void delay_LCM(uint);                                                                                                     //LCD延时子程序
  33. void initLCM( void);                                                                                                       //LCD初始化子程序
  34. void lcd_wait(void);                                                                                                      //LCD检测忙子程序
  35. void WriteCommandLCM(uchar WCLCM,uchar BusyC);                              //写指令到ICM子函数
  36. void WriteDataLCM(uchar WDLCM);                                             //写数据到LCM子函数
  37. void DisplayOneChar(uchar X,uchar Y,uchar DData);                           //显示指定坐标的一个字符子函数
  38. void DisplayListChar(uchar X,uchar Y,uchar code *DData);                                         //显示指定坐标的一串字符子函数
  39. void weishu(uint m);  
  40. void weishu1(uint m);           
  41. void display(void);
  42. uchar Adc0832(unsigned char channel);                                                                                                                       
  43. void alarm(void);
  44. void data_pro(void);
  45. /**********main funcation************/

  46. void main(void)
  47. {
  48.     delay(500);                      //系统延时500ms启动
  49.         //ad_data=0;                       //采样值存储单元初始化为0
  50.            initLCM( );
  51.         
  52.            WriteCommandLCM(0x01,1);                    //清显示屏
  53.     DisplayListChar(0,0,str0);
  54.            DisplayListChar(0,1,str2);
  55.         while(1)
  56.     {
  57.            ad_data =Adc0832(0);           //采样值存储单元初始化为0
  58.            alarm();
  59.            data_pro();
  60.            display();
  61.         if(k==1)
  62.      {
  63.       DisplayOneChar((s+7),1,table2[num-1]);
  64.           x1=m;
  65.           y1=n;
  66.           y1=y1*10+x1;
  67.      }

  68.     if(k=='*')
  69.    {
  70.      data_pro();
  71.          WriteCommandLCM(0x01,1);
  72.          weishu(z1);
  73.          k=0;
  74.     }
  75.     if(k=='=')
  76.         {         
  77.             z1=z1*temp1;
  78.             WriteCommandLCM(0x01,1);
  79.         DisplayListChar(0,1,str3);
  80.                 s=0;
  81.             weishu1(765);
  82.             k=0;
  83.         }
  84.         if(k==' ')
  85.         {
  86.            WriteCommandLCM(0x80+0x40,1);
  87.            WriteCommandLCM(0x01,1);
  88.            z1=0;
  89.            s=0;     //防止清零时指针后移动
  90.         }
  91.   }
  92. }


  93. /*********延时K*1ms,12.000mhz**********/

  94. void delay(uint k)
  95. {
  96.    uint i,j;
  97.    for(i=0;i<k;i++)
  98.     for(j=0;j<100;j++);
  99. }   
  100. /**********写指令到ICM子函数************/

  101. void WriteCommandLCM(uchar WCLCM,uchar BusyC)
  102. {
  103.     if(BusyC)
  104.         lcd_wait();
  105.         DATAPORT=WCLCM;
  106.     LCM_RS=0;                   // 选中指令寄存器
  107.     LCM_RW=0;     
  108.         LCM_RW=0;                    // 写模式       
  109.     LCM_EN=1;   
  110.         _nop_();   
  111.         _nop_();
  112.    _nop_();
  113.    _nop_();
  114.    _nop_();
  115.    _nop_();
  116.    _nop_();
  117.     LCM_EN=0;
  118.    
  119. }

  120. /**********写数据到LCM子函数************/

  121. void WriteDataLCM(uchar WDLCM)
  122. {
  123.     lcd_wait( );             //检测忙信号   
  124.         DATAPORT=WDLCM;
  125.     LCM_RS=1;                // 选中数据寄存器
  126.     LCM_RW=0;                    // 写模式
  127.     LCM_EN=1;
  128.     _nop_();
  129.            _nop_();
  130.            _nop_();
  131.            _nop_();
  132.            _nop_();
  133.            _nop_();
  134.            _nop_();
  135.         _nop_();
  136.     LCM_EN=0;
  137. }
  138. /***********lcm内部等待函数*************/

  139. void lcd_wait(void)
  140. {
  141.     DATAPORT=0xff;             //读LCD前若单片机输出低电平,而读出LCD为高电平,则冲突,Proteus仿真会有显示逻辑黄色
  142.         LCM_EN=1;
  143.     LCM_RS=0;     
  144.         LCM_RW=0;
  145.     LCM_RW=1;   
  146.     _nop_();
  147.     _nop_();
  148.     _nop_();
  149.     _nop_();
  150.     _nop_();
  151.     _nop_();
  152.         _nop_();
  153.     while(DATAPORT&BUSY)  
  154.         {  LCM_EN=0;
  155.            _nop_();
  156.     _nop_();
  157.     _nop_();
  158.     _nop_();
  159.     _nop_();
  160.     _nop_();
  161.     _nop_();
  162.     _nop_();
  163.            LCM_EN=1;
  164.     _nop_();
  165.     _nop_();
  166.     _nop_();
  167.     _nop_();
  168.     _nop_();
  169.         _nop_();
  170.         _nop_();
  171.            }         
  172.            LCM_EN=0;       
  173.        
  174. }

  175. /**********LCM初始化子函数***********/

  176. void initLCM( )
  177. {  
  178.     LCM_EN=0;
  179.         DATAPORT=0;       
  180.         delay(15);
  181.         WriteCommandLCM(0x38,0);    //三次显示模式设置,不检测忙信号
  182.     delay(5);
  183.     WriteCommandLCM(0x38,0);
  184.     delay(5);
  185.     WriteCommandLCM(0x38,0);
  186.     delay(5);

  187.     WriteCommandLCM(0x38,1);    //8bit数据传送,2行显示,5*7字型,检测忙信号
  188.     WriteCommandLCM(0x08,1);    //关闭显示,检测忙信号
  189.     WriteCommandLCM(0x01,1);    //清屏,检测忙信号
  190.     WriteCommandLCM(0x06,1);    //显示光标右移设置,检测忙信号
  191.     WriteCommandLCM(0x0c,1);    //显示屏打开,光标不显示,不闪烁,检测忙信号
  192.     TMOD=0x11;
  193.         EA=1;
  194.     ET1=1;
  195.         TR1=1;
  196.         k=0;
  197.         x1=0;
  198.         y1=0;
  199.         z1=0;
  200. }

  201. /****显示指定坐标的一个字符子函数****/

  202. void DisplayOneChar(uchar X,uchar Y,uchar DData)

  203. {
  204.     Y&=0x01;
  205.     X&=0x0f;
  206.     if(Y)
  207.         X|=0x40;               //若y为1(显示第二行),地址码+0X40
  208.     X|=0x80;                    //指令码为地址码+0X80
  209.     WriteCommandLCM(X,1);
  210.     WriteDataLCM(DData);
  211. }

  212. /*******显示指定坐标的一串字符子函数*****/

  213. void DisplayListChar(uchar X,uchar Y,uchar code *DData)
  214. {
  215.     uchar ListLength=0;
  216.     Y&=0x01;
  217.     X&=0x0f;
  218.     while(X<16)
  219.     {
  220.         DisplayOneChar(X,Y,DData[ListLength]);
  221.         ListLength++;
  222.         X++;
  223.     }
  224. }

  225. /*****************系统显示子函数*****************/

  226. void display(void)
  227. {
  228.            WriteCommandLCM(0x0c,1);                                    //显示屏打开,光标不显示,不闪烁,检测忙信号       
  229.         DisplayListChar(0,0,str0);       
  230.         //DisplayListChar(0,1,str2);       


  231.         DisplayOneChar(8,0,press_ge+0x30);
  232.         DisplayOneChar(10,0,press_shifen+0x30);
  233.         DisplayOneChar(11,0,press_baifen+0x30);
  234.     DisplayOneChar(12,0,press_qianfen+0x30);
  235.         delay(1000);                               //稳定显示
  236. }
  237. /************
  238. 读ADC0832函数
  239. ************/

  240. //采集并返回
  241. uchar Adc0832(unsigned char channel)     //AD转换,返回结果
  242. {
  243.      uchar i=0;
  244.     uchar j;
  245.     uint dat=0;
  246.     uchar ndat=0;

  247.     if(channel==0)channel=2;
  248.     if(channel==1)channel=3;
  249.     ADDI=1;
  250.     _nop_();
  251.     _nop_();
  252.     ADCS=0;//拉低CS端
  253.     _nop_();
  254.     _nop_();
  255.     ADCLK=1;//拉高CLK端
  256.     _nop_();
  257.     _nop_();
  258.     ADCLK=0;//拉低CLK端,形成下降沿1
  259.     _nop_();
  260.     _nop_();
  261.     ADCLK=1;//拉高CLK端
  262.     ADDI=channel&0x1;
  263.     _nop_();
  264.     _nop_();
  265.     ADCLK=0;//拉低CLK端,形成下降沿2
  266.     _nop_();
  267.     _nop_();
  268.     ADCLK=1;//拉高CLK端
  269.     ADDI=(channel>>1)&0x1;
  270.     _nop_();
  271.     _nop_();
  272.     ADCLK=0;//拉低CLK端,形成下降沿3
  273.     ADDI=1;//控制命令结束
  274.     _nop_();
  275.     _nop_();
  276.     dat=0;
  277.     for(i=0;i<8;i++)
  278.     {
  279.         dat|=ADDO;//收数据
  280.         ADCLK=1;
  281.         _nop_();
  282.         _nop_();
  283.         ADCLK=0;//形成一次时钟脉冲
  284.         _nop_();
  285.         _nop_();
  286.         dat<<=1;
  287.         if(i==7)dat|=ADDO;
  288.     }  
  289.     for(i=0;i<8;i++)
  290.     {
  291.         j=0;
  292.         j=j|ADDO;//收数据
  293.         ADCLK=1;
  294.         _nop_();
  295.         _nop_();
  296.         ADCLK=0;//形成一次时钟脉冲
  297.         _nop_();
  298.         _nop_();
  299.         j=j<<7;
  300.         ndat=ndat|j;
  301.         if(i<7)ndat>>=1;
  302.     }
  303.     ADCS=1;//拉低CS端
  304.     ADCLK=0;//拉低CLK端
  305.     ADDO=1;//拉高数据端,回到初始状态
  306.     dat<<=8;
  307.     dat|=ndat;
  308.     return(dat);            //return ad k         
  309. }


  310. void data_pro(void)
  311. {
  312.       unsigned int;
  313.       float  press;                             

  314.           if(0<ad_data<256)                                      
  315.                  {                            
  316.                     int vary=ad_data;                                                                       
  317.                         press=(0.019531*vary);                       
  318.                                                                                                                   
  319.                         temp1=(int)(press*1000);                        //放大1000倍,便于后面的计算
  320.                                                                                               
  321.                                                                                                            
  322.                         press_ge=temp1/1000;                                     //取压力值百位
  323.                         press_shifen=(temp1%1000)/100;                            //取压力值十位
  324.                         press_baifen=((temp1%1000)%100)/10;                    //取压力值个位
  325.                         press_qianfen=((temp1%1000)%100)%10;                        //取压力值十分位

  326.                       }            
  327.                          
  328. }
  329. /*****************报警子函数*******************/

  330. void alarm(void)
  331. {
  332.          if(ad_data>=256)                        

  333.            beep=0;          //则启动报警
  334.         
  335.           else
  336.                beep=1;                   
  337. }
  338. void weishu(uint m)
  339. {  
  340.    uchar wei4,wei3,wei2,wei1,wei0;
  341.    wei4=m/10000;
  342.    wei3=m%10000/1000;
  343.    wei2=m%1000/100;
  344.    wei1=m%100/10;
  345.    wei0=m%10;
  346.    DisplayOneChar(7,1,0x30+wei4);
  347.    DisplayOneChar(8,1,0x30+wei3);       
  348.    DisplayOneChar(10,1,0x30+wei2);
  349.            //DisplayOneChar(10,1,'.');
  350.    DisplayOneChar(11,1,0x30+wei1);
  351.    DisplayOneChar(12,1,0x30+wei0);

  352. }
  353. void weishu1(uint m)
  354. {  
  355.    uchar wei5,wei4,wei3,wei2,wei1,wei0;
  356.    wei5=m/100000;
  357.    wei4=m%100000/10000;
  358.    wei3=m%10000/1000;
  359.    wei2=m%1000/100;
  360.    wei1=m%100/10;
  361.    wei0=m%10;
  362.    DisplayOneChar(7,1,0x30+wei4);
  363.    DisplayOneChar(8,1,0x30+wei3);
  364.    DisplayOneChar(9,1,'.');       
  365.    DisplayOneChar(10,1,0x30+wei2);
  366.    //DisplayOneChar(10,1,'.');
  367.    DisplayOneChar(11,1,0x30+wei1);
  368.    DisplayOneChar(12,1,0x30+wei0);

  369. }
  370. void temer1() interrupt 3
  371. { uchar temp;
  372.   EX1=0;
  373.   P1=0xfe;
  374.   temp=P1;
  375.   temp=temp&0xf0;
  376.   if(temp!=0xf0)
  377.   {
  378.     delay(5);
  379.         temp=P1;
  380.     temp=temp&0xf0;
  381.         while(temp!=0xf0)
  382.         {
  383.           temp=P1;
  384.           switch(temp)
  385.           {
  386.             case 0xee:num=1;n=7;k=1,s++;break;
  387.             case 0xde:num=2;n=8;k=1,s++;break;
  388.             case 0xbe:num=3;n=9;k=1,s++;break;
  389.             case 0x7e:num=4;k='/',s++;break;
  390.           }
  391.           while(temp!=0xf0)
  392.           {
  393.                    temp=P1;
  394.         temp=temp&0xf0;
  395.           }
  396.         //DisplayOneChar((s+6),1,table2[num-1]);
  397.         }
  398.   }
  399.   P1=0xfd;
  400.   temp=P1;
  401.   temp=temp&0xf0;
  402.   if(temp!=0xf0)
  403.   {
  404.     delay(5);
  405.         temp=P1;
  406.     temp=temp&0xf0;
  407.         while(temp!=0xf0)
  408.         {
  409.           temp=P1;
  410.           switch(temp)
  411.           {
  412.             case 0xed:num=5;n=4;k=1;s++;break;
  413.             case 0xdd:num=6;n=5;k=1;s++;break;
  414.             case 0xbd:num=7;n=6;k=1;s++;break;
  415.             case 0x7d:num=8;k='*';s++;break;
  416.           }
  417.           while(temp!=0xf0)
  418.           {
  419.                    temp=P1;
  420.         temp=temp&0xf0;
  421.           }
  422.         //DisplayOneChar(k+6,1,table2[num-1]);
  423.         }
  424.   }
  425.   P1=0xfb;
  426.   temp=P1;
  427.   temp=temp&0xf0;
  428.   if(temp!=0xf0)
  429.   {
  430.     delay(5);
  431.         temp=P1;
  432.     temp=temp&0xf0;
  433.         while(temp!=0xf0)
  434.         {
  435.           temp=P1;
  436.           switch(temp)
  437.           {
  438.             case 0xeb:num=9;n=1;k=1;s++;break;
  439.             case 0xdb:num=10;n=2;k=1;s++;break;
  440.             case 0xbb:num=11;n=3;k=1;s++;break;
  441.             case 0x7b:num=12;k='-';s++;break;
  442.           }
  443.           while(temp!=0xf0)
  444.           {
  445.                    temp=P1;
  446.         temp=temp&0xf0;
  447.           }
  448. //        DisplayOneChar(k+6,1,table2[num-1]);

  449.         }
  450.   }
  451.   P1=0xf7;
  452.   temp=P1;
  453.   temp=temp&0xf0;
  454.   if(temp!=0xf0)
  455.   {
  456.     delay(5);
  457.         temp=P1;
  458.     temp=temp&0xf0;
  459.         while(temp!=0xf0)
  460.         {
  461.           temp=P1;
  462.           switch(temp)
  463.           {
  464.             case 0xe7:num=13;k=' ';break;
  465.             case 0xd7:num=14;n=0;k=1;s++;;break;
  466.             case 0xb7:num=15;k='=';s++;break;
  467.             case 0x77:num=16;k='+';s++;;break;
  468.           }
  469.           while(temp!=0xf0)
  470.           {
  471.                    temp=P1;
  472.         temp=temp&0xf0;
  473.           }
  474.         //DisplayOneChar(k+6,1,table2[num-1]);
  475.          }
  476.    
  477.   }
  478.   EX1=1;
  479. }

复制代码





LCD+ADC0832 电子秤.zip

186.81 KB, 下载次数: 39, 下载积分: 黑币 -5

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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