电子秤的仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #define PLEN 7
- #define WLEN 4
- #define MLEN 4
- #define SUMLEN 10
- #define BEEP() P1^=(1<<0);//蜂鸣器
- #define Key_NO (P2&0x0F)
- #define delay4us() {_nop_(); _nop_(); _nop_(); _nop_();}
- #define Key_Pressed (P2&(1<<4)) //DA(P1^4)为高电平时表示有键按下
- //#define Key_NO (P2&0x0F) /、//解码器输出线连接在P1低四位
- sbit RS=P1^1; //寄存器选择引脚,搞电平选择数据寄存器,低电平选择指令寄存器
- sbit RW=P1^2; //读写操作使能引脚,高电平使能读操作,低电平使能写操作
- sbit E=P1^3; //总使能引脚
- sbit FMQ=P1^0; //蜂鸣器
- sbit CS=P3^5;
- sbit CLK=P3^6;
- sbit DIO=P3^7;
- volatile int AD_Result,Pre_Result=0,Pressure_Value=0,Pressure_Value1=0,AD_Result1=0;
- code char KEY_CHAR_TABLE[]="0123456789.BCDEF"; //键盘字符表
- //----------------------AD转换程序--------------//
- uchar GET_CHx_AD_Value(uchar ch)
- {
- uchar i,dat1=0,dat2=0;
- CS=0;CLK=0;
- DIO=1;
- _nop_(); _nop_();
- CLK=1;
- _nop_(); _nop_();
- CLK=0;DIO=1;
- //_nop_(); _nop_();
- _nop_(); _nop_();
- CLK=1; _nop_(); _nop_();
- CLK=0;DIO=ch;
- _nop_(); _nop_();
- CLK=1;
- _nop_(); _nop_();
- CLK=0;DIO=1;
- _nop_(); _nop_();
- for(i=0;i<8;i++)
- {
- CLK=1; _nop_(); _nop_();
- CLK=0; _nop_(); _nop_();
- dat1=(dat1<<1)|DIO;
- }
- for(i=0;i<8;i++)
- {
- dat2=dat2|((uchar)DIO<<i);
- CLK=1; _nop_(); _nop_();
- CLK=0; _nop_(); _nop_();
- }
- CS=1;
- return (dat1==dat2)?dat1:0x00;
- }
- //--------------------延时子函数--------//
- void delay(uchar x)
- {
- uchar t;while(x--) for(t=0;t<120;t++) ;
- }
- /*//-----------------------单键扫描子函数-------------//
- unsigned char JP()
- {
- unsigned char x=0x00;
- bit i=0;
- x=P2; //扫描Y坐标
- FMQ=0; //响起蜂鸣器
- delay(125); //延时去抖动
- P2=0x0f;
- delay(2);
- x+=P2; //扫描X坐标
- switch(x)
- {
- case 0xee:x=0x30;break; //按下0
- case 0xed:x=0x31;break; //按下1
- case 0xeb:x=0x34;break; //按下4
- case 0xe7:x=0x37;break; //按下7
- case 0xde:x=0x46;break; //按下F
- case 0xdd:x=0x32;break; //按下2
- case 0xdb:x=0x35;break; //按下5
- case 0xd7:x=0x38;break; //按下8
- case 0xbe:x=0x45;break; //按下E
- case 0xbd:x=0x33;break; //按下3
- case 0xbb:x=0x36;break; //按下6
- case 0xb7:x=0x39;break; //按下9
- case 0x7e:x=0x44;break; //按下D
- case 0x7d:x=0x43;break; //按下C
- case 0x7b:x=0x42;break; //按下B
- case 0x77:x=0x41;break; //按下A
- default:x=0xff;break;
- }
- //FMQ=1; //关闭蜂鸣器
- while(i==0) //等待按键松开
- {
- P2=0xf0;
- delay(150);
- if(P2==0xf0)
- {
- i=1;
- }
- else{i=0;}
- }
- return x; //返回x(ASCII码)
- }*/
- //------------------测忙-----------------//
- bit Read_LCD_Busy_Flag()
- {
- uchar result;
- P0=0xFF;
- RS=0;RW=1;
- E=1;delay4us(); result=P0; E=0;
- return(result & 0x80)?1:0;
- }
- //------------------写指令-------------------------//
- void write_com(uchar com)
- {
- while(Read_LCD_Busy_Flag());
- RS=0;RW=0;
- E=0;_nop_(); _nop_(); P0=com;
- delay4us();E=1;delay4us();E=0;
- }
- //------------------写数据-------------------------//
- void write_dat(uchar dat)
- {
- while(Read_LCD_Busy_Flag());
- RS=1;RW=0;
- E=0;P0=dat;delay4us();
- E=1;delay4us();E=0;
- }
- //----------------------显示-----------------------------//
- void LCD_Show_String(uchar r,uchar c,char *s )
- {
- uchar i=0;
- uchar code DDRAM[]={0x80,0xC0};
- write_com(DDRAM[r]|c);
- while(s[i]&&i<16) write_dat(s[i++]);
- }
- //---------------1602初始化-----------------//
- void initinal()
- {
- write_com(0x38);delay(1);
- write_com(0x0C);delay(1);
- write_com(0x06);delay(1);
- write_com(0x01);delay(1);
- }
- //LCD显示输出缓冲(单价,重量,总价)
- char disp_buffer_P[PLEN];
- char disp_buffer_W[WLEN];
- char disp_buffer_SUM[SUMLEN];
- uchar NumberPtr=0; //价格输入缓冲的索引
- ////----------蜂鸣器输出------------//
- void Sounder()
- {
- uchar i,j;
- for(i=0;i<200;i++)
- {
- BEEP();
- j=70;
- while(--j);
- }
- }
- //------------处理运算并显示余额 -----------//
- void Compute_and_show_sum()
- {
- float p,w;
- if(strlen(disp_buffer_P)==0)p=0;else
- p=strtod(disp_buffer_P,'\0'); //价格未输入时,将p设为0,否则转换为float类型
- w=strtod(disp_buffer_W,'\0'); //将重量字符串转换成float类型
- sprintf(disp_buffer_SUM,"%.2f",p*w); //计算金额并生成字符串
- LCD_Show_String(1,7,(char *)" " ); //清除金额,然后显示最新金额
- LCD_Show_String(1,7,disp_buffer_SUM );
- }
- //处理键盘操作
- void KeyBoard_Handle()
- {
- char KeyChar;
- static uchar havedot=0; //是否已经输入的价格p的小数点
- static uchar dtnum=PLEN; //在没有输入小数点时可继续输入的字符的个数(dtnum初始值为7)
- if(Key_Pressed)
- {
- Sounder(); //按键提示音
- KeyChar=KEY_CHAR_TABLE[Key_NO]; //获取按键字符
- //如果输入的是数字字符或小数点并且此前没有输入过小数点
- if(isdigit(KeyChar)||(KeyChar=='.'&&!havedot))
- {
- if(strlen(disp_buffer_P)==3&&(KeyChar!='.'&&!havedot)) //限制整数部分最高为三位数,及整数部分最大为999
- return;
- //将输入的字符存入缓冲
- if(NumberPtr<dtnum)
- {
- // 如果输入的第一个字符是‘0’或者‘.’,就相当于直接输入了‘0.’
- if(NumberPtr==0&&(KeyChar=='0'||KeyChar=='.'))
- {
- disp_buffer_P[NumberPtr++]='0';
- KeyChar=='.';
- disp_buffer_P[NumberPtr++]='.';
- }
- else
- {
- disp_buffer_P[NumberPtr++]=KeyChar;
- }
- disp_buffer_P[NumberPtr]='\0'; //加字符串结束标志
- LCD_Show_String(0,3,disp_buffer_P ); //刷新显示总价
- }
- //输入字符为‘.’,且此前未输入过小数点,开始限定可输入的小数位数
- if(KeyChar=='.'&&!havedot)
- {
- dtnum=NumberPtr+2;havedot=1;
- }
- }
- if(KeyChar=='B') //清零操作
- {
- NumberPtr=0;
- havedot=0;
- dtnum=PLEN-2;
- disp_buffer_P[0]='\0';
- disp_buffer_SUM[0]='\0';
- LCD_Show_String(0,3,(char *)" " ); //清除单价
- LCD_Show_String(1,7,(char *)" " ); //清除总价
- }
- if(KeyChar=='C') //删除操作(可用于单价输入错误时)
- {
- write_com(0x80+NumberPtr+2); //确定删除对象
- write_dat(' '); //显示空格即为删除
- disp_buffer_P[--NumberPtr]=0; //删除后数据清零
- write_com(0x80+NumberPtr); //为下次输入数据时写好位置,必须是在最后一个后面
-
- }
-
- if (Key_Pressed) Compute_and_show_sum();
- while(Key_Pressed); //等待按键释放
- }
- }
- //--------------------主函数-------------//
- void main()
- {
- initinal();
- LCD_Show_String(0,0,(char*)"P: W:");
- LCD_Show_String(1,0,(char*)"SUM($):");
- while(1)
- {
- AD_Result=GET_CHx_AD_Value(0) ;
-
-
- Pressure_Value=(int)((AD_Result*5.0*2/511.0/5.1-0.04)/0.00369-3.45);
- KeyBoard_Handle();
- //M_Value=(int)(Pressure_Value*0.0101972);
- if(Pressure_Value>=230) //超重报警
- { write_com(0x01);
- LCD_Show_String(0,0,"ERROR!");
- Sounder();
- }
- sprintf(disp_buffer_W,"%-3d",Pressure_Value);
- LCD_Show_String(0,13,disp_buffer_W);
- //KeyBoard_Handle();
- //压力变化就计算金额
- if(Pre_Result!=AD_Result)
- {
- Compute_and_show_sum();
- Pre_Result=AD_Result;
- Sounder();
- }
- delay(50);
- }
- }
复制代码
所有资料51hei提供下载:
最终版.zip
(102.99 KB, 下载次数: 111)
|