当前位置:文档之家› 电子秤的设计与实现

电子秤的设计与实现

电子秤的设计与实现一.研究的目的和意义随着时代科技的迅猛发展,微电子学和计算机等现代电子技术的成就给传统的电子测量与仪器带来了巨大的冲击和革命性的影响。

常规的测试仪器仪表和控制装置被更先进的智能仪器所取代,使得传统的电子测量仪器在远离、功能、精度及自动化水平定方面发生了巨大变化,并相应的出现了各种各样的智能仪器控制系统,使得科学实验和应用工程的自动化程度得以显著提高。

传统的机械秤有很多缺点,比如精度不高,结构复杂,易老化,成本高等。

随着社会的发展,市场对秤的要求的越来越高,尤其是人体秤、厨房秤等各类便携式小型秤。

电子秤与传统的机械秤相比有许多优越性,它用压力传感器取代机械秤的弹簧大大减小了秤的体积和制造难度,以LCD或LED显示屏取代传统的刻度盘使外形更加美观,由于内部集成了单片机以及软件系统,电子秤还拥有传统机械秤无法比拟的智能性。

他可以完成过载报警,总价计算,数据通信等众多功能。

目前市场上使用的称量工具,或者结构复杂,或者运行不可靠,且成本高,而且整体水平不高,部分小型企业质量差且技术薄弱,设备不全,缺乏产品的开发能力,产品质量在低水平徘徊。

因此,有针对性的开发出一套具有实用价值的电子秤系统,从技术上克服上述诸多缺点,改善电子秤应用中的不足之处,具有现实意义。

二.设计原理1.电子秤的原理就是利用压力传感器采集因压力变化产生的电压信号,经过电压放大电路放大,然后再经过A\D模数转换器转换为数字信号,最后把数字信号送入单片机。

单片机经过相应的处理后,得出当前所称物品的重量及总额,然后再显示出来。

此外,还可通过键盘设定所称物品的价格。

2. 原理仿真设计电路图图1 3.程序框图(1)主程序设计图2 主程序设计(2)子程序A/D 0832的转化图3 A/D 0832的转化(3)显示子程序的设计图4 显示子程的设计(4)按键子程的设计在程序中可以先判断按键编码,然后根据编码将键盘代表的数值送到相应的存储单元,再进行功能选择或数据处理。

键盘扫描子程序的流程图如下:图5 按键子程序的设计3.程序清单#include<regx51.h>#include<intrins.h>#include <absacc.h>#include <math.h>#define uchar unsigned char#define uint unsigned int#define BUSY 0x80 //常量定义#define DATAPORT P0sbit bADcs=P1^3; //片选位sbit bADcl=P1^6; //时钟位sbit bADda=P1^7; //数据位sbit LCM_RS=P1^0;sbit LCM_RW=P1^1;sbit LCM_EN=P1^2;uint x1,y1,z1=0,w1,temp1;uchar ad_data,k,n,m,e,num,s; //采样值存储uchar z;uchar data1;char press_data; //标度变换存储单元unsigned char ad_alarm; unsigned char press_ge=0; //显示值百位unsigned char press_shifen=0; //显示值十位unsigned char press_baifen=0; //显示值个位unsigned char press_qianfen=0; //显示值十分位uchar code str0[]={"Weight: . Kg "};uchar code str2[]={"Price: "};uchar code str3[]={"Total: "};uchar code table2[]={0x37,0x38,0x39,0xfd,0x34,0x35,0x36,0x78,0x31,0x32,0x33,0x2d,0x3d,0x 30,0x2e,0x2b}; //键盘码void intu();void jianpan();void delay(uint);void lcd_wait(void);void delay_LCM(uint); //LCD延时子程序void initLCM( void); //LCD初始化子程序void lcd_wait(void); //LCD检测忙子程序void WriteCommandLCM(uchar WCLCM,uchar BusyC); //写指令到ICM子函数void WriteDataLCM(uchar WDLCM); //写数据到LCM子函数void DisplayOneChar(uchar X,uchar Y,uchar DData); //显示指定坐标的一个字符子函数void DisplayListChar(uchar X,uchar Y,uchar code *DData); //显示指定坐标的一串字符子函数void weishu(uint m);void weishu1(uint m);void display(void);void ad0832();void alarm(void);void data_pro(void);void ad0832(void){ uchar i;bADcs = 0;//当ADC0832未工作时其CS输入端应为高电平,此时芯片禁用,开始工作CS为低电平bADcl=0; //第一个时钟下降沿前da为1,第二个与第三时钟下降沿前的数据为通道选择bADda=1; //选置起始位bADcl=1;bADcl=0; // 1downbADda=1; //通道选择第1位bADcl=1;bADcl=0; // 2 downbADda=0; //通道选择第2位,通道选择为1,0选通道0bADcl=1;bADcl=0; // 3 downbADda=1;bADcl=1;bADcl=0; // 4 downfor(i=8;i>0;i--){ad_data<<=1; //从第7位开始,要左移data1=data1<<1bADcl=0;bADcl=1;if(bADda==1) ad_data|=0x01; //如果输出1,data1最后一位补1}bADcs=1; //转换完后CS置1}/**********main funcation************/void main(void){delay(50); //系统延时500ms启动ad_data=0; //采样值存储单元初始化为0initLCM( );intu();WriteCommandLCM(0x01,1); //清显示屏DisplayListChar(0,0,str0);DisplayListChar(0,1,str2);while(1){ad0832(); //采样值存储单元初始化为0data_pro();display();jianpan();if(k==1){if(s<=3){DisplayOneChar((s+7),1,table2[num-1]);if(s==1)data1=n;elsedata1=data1*10+n;}}if(k=='='){z1=data1*temp1;WriteCommandLCM(0x01,1);DisplayListChar(0,1,str3);s=0;weishu1(z1);k=0;}if(k==' '){WriteCommandLCM(0x80+0x40,1);WriteCommandLCM(0x01,1);z1=0;s=0; //防止清零时指针后移动}}/*********延时K*1ms,12.000mhz**********/void delay(uint k){uint i,j;for(i=0;i<k;i++)for(j=0;j<10;j++);}/**********写指令到ICM子函数************/void WriteCommandLCM(uchar WCLCM,uchar BusyC) {if(BusyC)lcd_wait();DATAPORT=WCLCM;LCM_RS=0; // 选中指令寄存器LCM_RW=0;LCM_RW=0; // 写模式LCM_EN=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();LCM_EN=0;/**********写数据到LCM子函数************/void WriteDataLCM(uchar WDLCM){lcd_wait( ); //检测忙信号DATAPORT=WDLCM;LCM_RS=1; // 选中数据寄存器LCM_RW=0; // 写模式LCM_EN=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();LCM_EN=0;}/***********lcm内部等待函数*************/void lcd_wait(void){DATAPORT=0xff; //读LCD前若单片机输出低电平,而读出LCD为高电平,则冲突,Proteus仿真会有显示逻辑黄色LCM_EN=1;LCM_RS=0;LCM_RW=0;LCM_RW=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();while(DATAPORT&BUSY){ LCM_EN=0;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();LCM_EN=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}LCM_EN=0;}/**********LCM初始化子函数***********/void initLCM( ){LCM_EN=0;DATAPORT=0;delay(10);WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号delay(5);WriteCommandLCM(0x38,0);delay(5);WriteCommandLCM(0x38,0);delay(5);WriteCommandLCM(0x38,1); //8bit数据传送,2行显示,5*7字型,检测忙信号WriteCommandLCM(0x08,1); //关闭显示,检测忙信号WriteCommandLCM(0x01,1); //清屏,检测忙信号WriteCommandLCM(0x06,1); //显示光标右移设置,检测忙信号WriteCommandLCM(0x0c,1); //显示屏打开,光标不显示,不闪烁,检测忙信号}void intu(){k=0;x1=0;y1=0;z1=0;}/****显示指定坐标的一个字符子函数****/void DisplayOneChar(uchar X,uchar Y,uchar DData){Y&=0x01;X&=0x0f;if(Y)X|=0x40; //若y为1(显示第二行),地址码+0X40 X|=0x80; //指令码为地址码+0X80WriteCommandLCM(X,1);WriteDataLCM(DData);}/*******显示指定坐标的一串字符子函数*****/void DisplayListChar(uchar X,uchar Y,uchar code *DData) {uchar ListLength=0;Y&=0x01;X&=0x0f;while(X<10){DisplayOneChar(X,Y,DData[ListLength]);ListLength++;X++;}}/*****************系统显示子函数*****************/ void display(void){WriteCommandLCM(0x0c,1); //显示屏打开,光标不显示,不闪烁,检测忙信号DisplayListChar(0,0,str0);//DisplayListChar(0,1,str2);DisplayOneChar(8,0,press_ge+0x30);DisplayOneChar(10,0,press_shifen+0x30);DisplayOneChar(11,0,press_baifen+0x30);DisplayOneChar(12,0,press_qianfen+0x30);delay(1000); //稳定显示}void data_pro(void){unsigned int;float press;if(0<ad_data<256){int vary=ad_data;press=(0.019531*vary);temp1=(int)(press*1000); //放大1000倍,便于后面的计算press_ge=temp1/1000; //取压力值百位press_shifen=(temp1%1000)/100; //取压力值十位press_baifen=((temp1%1000)%100)/10; //取压力值个位press_qianfen=((temp1%1000)%100)%10; //取压力值十分位} }void weishu1(uint m){uchar wei5,wei4,wei3,wei2,wei1,wei0;wei5=m/100000;wei4=m%100000/10000;wei3=m%10000/1000;wei2=m%1000/100;wei1=m%100/10;wei0=m%10;DisplayOneChar(7,1,0x30+wei4);DisplayOneChar(8,1,0x30+wei3);DisplayOneChar(9,1,'.');DisplayOneChar(10,1,0x30+wei2);//DisplayOneChar(10,1,'.');DisplayOneChar(11,1,0x30+wei1);DisplayOneChar(12,1,0x30+wei0);}/***** 键盘扫描程序*****/void jianpan(){ uchar temp;P2=0xfe;temp=P2;temp=temp&0xf0;if(temp!=0xf0){delay(5);temp=P2;temp=temp&0xf0;while(temp!=0xf0){temp=P2;switch(temp){case 0xee:num=1;n=7;k=1,s++;break;case 0xde:num=2;n=8;k=1,s++;break;case 0xbe:num=3;n=9;k=1,s++;break;case 0x7e:num=4;k='/',s++;break;}while(temp!=0xf0){temp=P2;temp=temp&0xf0;}//DisplayOneChar((s+6),1,table2[num-1]); }}P2=0xfd;temp=P2;temp=temp&0xf0;if(temp!=0xf0){delay(1);temp=P2;temp=temp&0xf0;while(temp!=0xf0){temp=P2;switch(temp){case 0xed:num=5;n=4;k=1;s++;break;case 0xdd:num=6;n=5;k=1;s++;break;case 0xbd:num=7;n=6;k=1;s++;break;case 0x7d:num=8;k='*';s++;break;}while(temp!=0xf0){temp=P2;temp=temp&0xf0;}//DisplayOneChar(k+6,1,table2[num-1]);}}P2=0xfb;temp=P2;temp=temp&0xf0;if(temp!=0xf0){delay(1);temp=P2;temp=temp&0xf0;while(temp!=0xf0){temp=P2;switch(temp){case 0xeb:num=9;n=1;k=1;s++;break;case 0xdb:num=10;n=2;k=1;s++;break;case 0xbb:num=11;n=3;k=1;s++;break;case 0x7b:num=12;k='-';s++;break;}while(temp!=0xf0){temp=P2;temp=temp&0xf0;}// DisplayOneChar(k+6,1,table2[num-1]);}}P2=0xf7;temp=P2;temp=temp&0xf0;if(temp!=0xf0){delay(1);temp=P2;temp=temp&0xf0;while(temp!=0xf0){temp=P2;switch(temp){case 0xe7:num=13;k=' ';break;case 0xd7:num=14;n=0;k=1;s++;;break;case 0xb7:num=15;k='=';s++;break;case 0x77:num=16;k='+';s++;;break;}while(temp!=0xf0){temp=P2;temp=temp&0xf0;}//DisplayOneChar(k+6,1,table2[num-1]);}}}三.元件清单C51单片机1个LCD1602显示1个A/D0832芯片1个UA741放大器1个按键13个电解电容30PF 1个15PF电容2个10k电阻1个1k电阻5个1k滑动变阻1个4.7k滑动变阻1个四.调试过程遇到的问题及解决方法在调试过程中,一开始单片机程序烧不进去,发现是单片机坏了,找老师重新换了一块,重量部分显示,但发现没有放大,在进行检查电路发现,放大器的3和4引脚短路,器件本身是坏的,重新换了一个,有了放大,在调试按键部分的过程中,按键显示不正常,经过重新修正程序和换了单片机,按键和总价显示正常。

相关主题