找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5809|回复: 2
收起左侧

单片机电子秤的仿真设计

[复制链接]
ID:311821 发表于 2018-4-19 17:14 | 显示全部楼层 |阅读模式
电子秤的仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png

0.jpg

单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #include <string.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <ctype.h>
  9. #define PLEN  7
  10. #define WLEN  4
  11. #define MLEN  4
  12. #define SUMLEN 10
  13. #define BEEP() P1^=(1<<0);//蜂鸣器
  14. #define Key_NO (P2&0x0F)

  15. #define delay4us() {_nop_();        _nop_(); _nop_();        _nop_();}
  16. #define Key_Pressed (P2&(1<<4))                //DA(P1^4)为高电平时表示有键按下
  17. //#define Key_NO (P2&0x0F)                /、//解码器输出线连接在P1低四位
  18. sbit RS=P1^1;     //寄存器选择引脚,搞电平选择数据寄存器,低电平选择指令寄存器
  19. sbit RW=P1^2;    //读写操作使能引脚,高电平使能读操作,低电平使能写操作
  20. sbit E=P1^3;     //总使能引脚
  21. sbit FMQ=P1^0;           //蜂鸣器
  22. sbit CS=P3^5;
  23. sbit CLK=P3^6;
  24. sbit DIO=P3^7;

  25. volatile int AD_Result,Pre_Result=0,Pressure_Value=0,Pressure_Value1=0,AD_Result1=0;
  26. code char KEY_CHAR_TABLE[]="0123456789.BCDEF";         //键盘字符表



  27. //----------------------AD转换程序--------------//
  28. uchar GET_CHx_AD_Value(uchar ch)
  29. {
  30.         uchar i,dat1=0,dat2=0;
  31.         CS=0;CLK=0;
  32.         DIO=1;
  33.         _nop_();        _nop_();
  34.         CLK=1;
  35.         _nop_();        _nop_();

  36.         CLK=0;DIO=1;
  37.         //_nop_();        _nop_();
  38.         _nop_();        _nop_();
  39.         CLK=1;        _nop_();        _nop_();

  40.         CLK=0;DIO=ch;
  41.         _nop_();        _nop_();
  42.         CLK=1;
  43.         _nop_();        _nop_();

  44.         CLK=0;DIO=1;
  45.         _nop_();        _nop_();

  46.         for(i=0;i<8;i++)
  47.         {
  48.                 CLK=1;                  _nop_();        _nop_();
  49.                 CLK=0;                _nop_();        _nop_();
  50.                 dat1=(dat1<<1)|DIO;
  51.         }
  52.         for(i=0;i<8;i++)
  53.         {
  54.                 dat2=dat2|((uchar)DIO<<i);
  55.                 CLK=1;                  _nop_();        _nop_();
  56.                 CLK=0;                _nop_();        _nop_();
  57.         }
  58.         CS=1;
  59.         return (dat1==dat2)?dat1:0x00;
  60. }







  61. //--------------------延时子函数--------//
  62. void delay(uchar x)
  63. {
  64.         uchar t;while(x--) for(t=0;t<120;t++) ;
  65. }

  66. /*//-----------------------单键扫描子函数-------------//

  67. unsigned char JP()
  68. {
  69.         unsigned char x=0x00;
  70.     bit i=0;
  71.     x=P2;   //扫描Y坐标
  72.     FMQ=0;    //响起蜂鸣器
  73.     delay(125);  //延时去抖动
  74.     P2=0x0f;
  75.     delay(2);
  76.     x+=P2;    //扫描X坐标
  77.     switch(x)
  78.     {
  79.                    case 0xee:x=0x30;break;    //按下0
  80.                    case 0xed:x=0x31;break;    //按下1
  81.                   case 0xeb:x=0x34;break;    //按下4
  82.                    case 0xe7:x=0x37;break;    //按下7
  83.                    case 0xde:x=0x46;break;    //按下F
  84.                    case 0xdd:x=0x32;break;    //按下2
  85.                    case 0xdb:x=0x35;break;    //按下5
  86.                    case 0xd7:x=0x38;break;    //按下8
  87.                    case 0xbe:x=0x45;break;    //按下E
  88.                    case 0xbd:x=0x33;break;    //按下3
  89.                    case 0xbb:x=0x36;break;    //按下6
  90.                    case 0xb7:x=0x39;break;    //按下9
  91.                    case 0x7e:x=0x44;break;    //按下D
  92.                    case 0x7d:x=0x43;break;    //按下C
  93.                    case 0x7b:x=0x42;break;    //按下B
  94.                    case 0x77:x=0x41;break;    //按下A
  95.                    default:x=0xff;break;
  96.    }
  97.    //FMQ=1;       //关闭蜂鸣器
  98.    while(i==0)    //等待按键松开
  99.    {
  100.             P2=0xf0;
  101.             delay(150);
  102.             if(P2==0xf0)
  103.             {
  104.                      i=1;
  105.             }
  106.             else{i=0;}
  107.    }
  108.   return x;    //返回x(ASCII码)
  109. }*/


  110. //------------------测忙-----------------//
  111. bit Read_LCD_Busy_Flag()
  112. {
  113.    uchar result;
  114.    P0=0xFF;
  115.    RS=0;RW=1;
  116.    E=1;delay4us(); result=P0; E=0;
  117.    return(result & 0x80)?1:0;
  118. }

  119. //------------------写指令-------------------------//
  120. void write_com(uchar com)
  121. {
  122.         while(Read_LCD_Busy_Flag());
  123.         RS=0;RW=0;
  124.         E=0;_nop_();        _nop_(); P0=com;
  125.         delay4us();E=1;delay4us();E=0;

  126. }
  127. //------------------写数据-------------------------//
  128. void write_dat(uchar dat)
  129. {
  130.         while(Read_LCD_Busy_Flag());
  131.         RS=1;RW=0;
  132.         E=0;P0=dat;delay4us();
  133.         E=1;delay4us();E=0;
  134. }
  135. //----------------------显示-----------------------------//
  136. void LCD_Show_String(uchar r,uchar c,char *s )
  137. {
  138.         uchar i=0;
  139.         uchar code DDRAM[]={0x80,0xC0};
  140.         write_com(DDRAM[r]|c);
  141.         while(s[i]&&i<16) write_dat(s[i++]);
  142. }
  143. //---------------1602初始化-----------------//
  144. void initinal()
  145. {
  146.         write_com(0x38);delay(1);
  147.         write_com(0x0C);delay(1);
  148.         write_com(0x06);delay(1);
  149.         write_com(0x01);delay(1);
  150. }


  151. //LCD显示输出缓冲(单价,重量,总价)
  152. char disp_buffer_P[PLEN];
  153. char disp_buffer_W[WLEN];
  154. char disp_buffer_SUM[SUMLEN];
  155. uchar NumberPtr=0;                                //价格输入缓冲的索引

  156. ////----------蜂鸣器输出------------//
  157. void Sounder()
  158. {
  159.         uchar i,j;
  160.         for(i=0;i<200;i++)
  161.         {
  162.                 BEEP();
  163.                 j=70;
  164.                 while(--j);
  165.         }


  166. }
  167. //------------处理运算并显示余额 -----------//
  168. void Compute_and_show_sum()
  169. {
  170.         float p,w;
  171.         if(strlen(disp_buffer_P)==0)p=0;else
  172.         p=strtod(disp_buffer_P,'\0');                           //价格未输入时,将p设为0,否则转换为float类型
  173.         w=strtod(disp_buffer_W,'\0');                           //将重量字符串转换成float类型
  174.         sprintf(disp_buffer_SUM,"%.2f",p*w);           //计算金额并生成字符串
  175.         LCD_Show_String(1,7,(char *)"       " );   //清除金额,然后显示最新金额
  176.         LCD_Show_String(1,7,disp_buffer_SUM );

  177. }


  178. //处理键盘操作
  179. void KeyBoard_Handle()
  180. {
  181.         char KeyChar;
  182.         static uchar havedot=0;                         //是否已经输入的价格p的小数点
  183.         static uchar dtnum=PLEN;                 //在没有输入小数点时可继续输入的字符的个数(dtnum初始值为7)
  184.         if(Key_Pressed)                                   
  185.         {                                                               
  186.                 Sounder();                                        //按键提示音
  187.                 KeyChar=KEY_CHAR_TABLE[Key_NO];                           //获取按键字符
  188. //如果输入的是数字字符或小数点并且此前没有输入过小数点               
  189.                 if(isdigit(KeyChar)||(KeyChar=='.'&&!havedot))
  190.                 {
  191.                         if(strlen(disp_buffer_P)==3&&(KeyChar!='.'&&!havedot))        //限制整数部分最高为三位数,及整数部分最大为999
  192.                            return;

  193.                   //将输入的字符存入缓冲
  194.                         if(NumberPtr<dtnum)
  195.                         {
  196.                                 // 如果输入的第一个字符是‘0’或者‘.’,就相当于直接输入了‘0.’
  197.                                 if(NumberPtr==0&&(KeyChar=='0'||KeyChar=='.'))
  198.                                 {
  199.                                         disp_buffer_P[NumberPtr++]='0';
  200.                                         KeyChar=='.';
  201.                                         disp_buffer_P[NumberPtr++]='.';       
  202.                                 }
  203.                                 else
  204.                                 {
  205.                                         disp_buffer_P[NumberPtr++]=KeyChar;       
  206.                                 }
  207.                                 disp_buffer_P[NumberPtr]='\0';         //加字符串结束标志
  208.                                 LCD_Show_String(0,3,disp_buffer_P );           //刷新显示总价

  209.                         }

  210.                         //输入字符为‘.’,且此前未输入过小数点,开始限定可输入的小数位数
  211.                         if(KeyChar=='.'&&!havedot)
  212.                         {
  213.                                 dtnum=NumberPtr+2;havedot=1;
  214.                         }
  215.                 }
  216.             if(KeyChar=='B')                         //清零操作
  217.                 {
  218.                         NumberPtr=0;
  219.                         havedot=0;
  220.                         dtnum=PLEN-2;
  221.                         disp_buffer_P[0]='\0';
  222.                         disp_buffer_SUM[0]='\0';
  223.                         LCD_Show_String(0,3,(char *)"      " );                 //清除单价
  224.                         LCD_Show_String(1,7,(char *)"         " );                           //清除总价

  225.                 }
  226.                 if(KeyChar=='C')                        //删除操作(可用于单价输入错误时)
  227.                 {

  228.                         write_com(0x80+NumberPtr+2);        //确定删除对象
  229.                         write_dat(' ');                                         //显示空格即为删除
  230.                         disp_buffer_P[--NumberPtr]=0;                 //删除后数据清零
  231.                         write_com(0x80+NumberPtr);                         //为下次输入数据时写好位置,必须是在最后一个后面

  232.                 }
  233.        

  234.                 if (Key_Pressed) Compute_and_show_sum();
  235.                 while(Key_Pressed);                                                   //等待按键释放

  236.         }
  237. }







  238. //--------------------主函数-------------//


  239. void main()
  240. {
  241.         initinal();
  242.         LCD_Show_String(0,0,(char*)"P:        W:");
  243.         LCD_Show_String(1,0,(char*)"SUM($):");
  244.         while(1)
  245.         {
  246.                 AD_Result=GET_CHx_AD_Value(0) ;
  247.        
  248.                        
  249.                 Pressure_Value=(int)((AD_Result*5.0*2/511.0/5.1-0.04)/0.00369-3.45);
  250.                 KeyBoard_Handle();
  251.                 //M_Value=(int)(Pressure_Value*0.0101972);


  252.                 if(Pressure_Value>=230)                                                   //超重报警
  253.                         {        write_com(0x01);
  254.                                 LCD_Show_String(0,0,"ERROR!");
  255.                                 Sounder();

  256.                     }


  257.                 sprintf(disp_buffer_W,"%-3d",Pressure_Value);
  258.                 LCD_Show_String(0,13,disp_buffer_W);

  259.                 //KeyBoard_Handle();
  260.                 //压力变化就计算金额
  261.                 if(Pre_Result!=AD_Result)
  262.                 {
  263.                         Compute_and_show_sum();
  264.                         Pre_Result=AD_Result;
  265.                         Sounder();
  266.                 }
  267.                 delay(50);
  268.         }
  269. }



复制代码

所有资料51hei提供下载:
最终版.zip (102.99 KB, 下载次数: 111)
回复

使用道具 举报

ID:719367 发表于 2020-4-18 20:18 | 显示全部楼层
运行不了
回复

使用道具 举报

ID:332724 发表于 2020-4-21 17:29 | 显示全部楼层
运行不了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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