山东省电子设计大赛电子称.docx
《山东省电子设计大赛电子称.docx》由会员分享,可在线阅读,更多相关《山东省电子设计大赛电子称.docx(31页珍藏版)》请在冰豆网上搜索。
山东省电子设计大赛电子称
山东省电子设计大赛
(2014年)
实用电子秤(C)
编号:
C甲1009
参赛学校:
指导教师:
设计者:
2004年9月13号
摘要
本系统采用单片机AT89S52为控制核心,实现电子秤的基本控制功能。
系统的硬件部分包括最小系统板,数据采集、人机交互界面三大部分。
最小系统部分主要是扩展了外部数据存储器,数据采集部分由压力传感器、信号的前级处理和A/D转换部分组成。
人机界面部分为键盘输入,128
64点阵式液晶显示,可以直观的显示中文,使用方便。
软件部分应用单片机C语言实现了本设计的全部控制功能,包括基本的称重功能,和发挥部分的显示购物清单的功能,可以设置日期和重新设定10种商品的单价,具有超重报警功能,由于系统资源丰富,还可以方便的扩展其应用
第一部分:
方案论证与比较
一、控制器部分
本系统基于51系列单片机来实现,因为系统需要大量的控制液晶显示和键盘。
不宜采用大规模可编程逻辑器件:
CPLD、FPGA来实现。
(因为大规模可编程逻辑器件一般是使用状态机方式来实现,即所解决的问题都是规则的有限状态转换问题。
本系统状态较多,难度较大。
)另外系统没有其它高标准的要求,我们最终选择了AT89S52通用的比较普通单片机来实现系统设计。
内部带有8KB的程序存储器,在外面扩展了32K数据存储器,以满足系统要求。
二、数据采集部分
(1)、传感器
题目要求称重范围9.999Kg,重量误差不大于
Kg,考虑到秤台自重、振动和冲击分量,还要避免超重损坏传感器,所以传感器量程必须大于额定称重—
。
我们选择的是L-PSIII型传感器,量程20Kg,精度为
,满量程时误差
0.002Kg。
可以满足本系统的精度要求。
其原理如下图所示:
称重传感器主要由弹性体、电阻应变片电缆线等组成,内部线路采用惠更斯电桥,当弹性体承受载荷产生变形时,输出信号电压可由下式给出:
(2)、前级放大器部分
压力传感器输出的电压信号为毫伏级,所以对运算放大器要求很高。
我们考虑可以采用以下几种方案可以采用:
方案一、利用普通低温漂运算放大器构成多级放大器。
普通低温漂运算放大器构成多级放大器会引入大量噪声。
由于A/D转换器需要很高的精度,所以几毫伏的干扰信号就会直接影响最后的测量精度。
所以,此中方案不宜采用。
方案二、由高精度低漂移运算放大器构成差动放大器。
差动放大器具有高输入阻抗,增益高的特点,可以利用普通运放(如OP07)做成一个差动放大器。
电阻R1、R2电容C1、C2、C3、C4用于滤除前级的噪声,C1、C2为普通小电容,可以滤除高频干扰,C3、C4为大的电解电容,主要用于滤除低频噪声。
优点:
输入级加入射随放大器,增大了输入阻抗,中间级为差动放大电路,滑动变阻器R6可以调节输出零点,最后一级可以用于微调放大倍数,使输出满足满量程要求。
输出级为反向放大器,所以输出电阻不是很大,比较符合应用要求。
缺点:
此电路要求R3、R4相等,误差将会影响输出精度,难度较大。
实际测量,每一级运放都会引入较大噪声。
对精度影响较大。
方案三:
采用专用仪表放大器,如:
INA126,INA121等。
此类芯片内部采用差动输入,共模抑制比高,差模输入阻抗大,增益高,精度也非常好,且外部接口简单。
以INA126为例,接口如下图所示:
放大器增益
,通过改变
的大小来改变放大器的增益。
基于以上分析,我们决定采用制作方便而且精度很好的专用仪表放大器INA126。
(3)、A/D转换器
由上面对传感器量程和精度的分析可知:
A/D转换器误差应在
以下
12位A/D精度:
10Kg/4096=2.44g
14位A/D精度:
10Kg/16384=0.61g
考虑到其他部分所带来的干扰,12位A/D无法满足系统精度要求。
所以我们需要选择14位或者精度更高的A/D。
方案一、逐次逼近型A/D转换器,如:
ADS7805、ADS7804等。
逐次逼近型A/D转换,一般具有采样/保持功能。
采样频率高,功耗比较低,是理想的高速、高精度、省电型A/D转换器件。
高精度逐次逼近型A/D转换器一般都带有内部基准源和内部时钟,基于89C52构成的系统设计时仅需要外接几个电阻、电容。
但考虑到所转换的信号为一慢变信号,逐次逼近型A/D转换器的快速的优点不能很好的发挥,且根据系统的要求,14位AD足以满足精度要求,太高的精度就反而浪费了系统资源。
所以此方案并不是理想的选择。
方案二、双积分型A/D转换器:
如:
ICL7135、ICL7109等。
双积分型A/D转换器精度高,但速度较慢(如:
ICL7135),具有精确的差分输入,输入阻抗高(大于
),可自动调零,超量程信号,全部输出于TTL电平兼容。
双积分型A/D转换器具有很强的抗干扰能力。
对正负对称的工频干扰信号积分为零,所以对50HZ的工频干扰抑制能力较强,对高于工频干扰(例如噪声电压)已有良好的滤波作用。
只要干扰电压的平均值为零,对输出就不产生影响。
尤其对本系统,缓慢变化的压力信号,很容易受到工频信号的影响。
故而采用双积分型A/D转换器可大大降低对滤波电路的要求。
作为电子秤,系统对AD的转换速度要求并不高,精度上14位的AD足以满足要求。
另外双积分型A/D转换器较强的抗干扰能力,和精确的差分输入,低廉的价格。
综合的分析其优点和缺点,我们最终选择了ICL7135。
三、人机交互界面
(1)、键盘输入
键盘输入是人机交互界面中最重要的组成部分,它是系统接受用户指令的直接途径。
我们采用了专用的键盘显示芯片ZLG7289。
Intel8279是一种比较成熟的可编程键盘/显示芯片,可以满足小系统的要求。
ZLG7289是周立功单片机公司设计的串行输入输出可编程键盘/显示芯片有强大的键盘显示功能,支持64键控制。
可以比较方便的扩展系统。
另外ZLG7289内部有译码电路,大大简化了程序。
我们选择功能更好的ZLG7289作为键盘扫描显示芯片
(2)、显示输出
虽然ZLG7289具有控制数码管显示的功能,但考虑到本题目要求中文显示,数码管无法满足,只能考虑用带有中文字库的液晶显示器。
由于可以分页显示,无需太大屏幕,我们选择了点阵式128×64型LCD—OCM4X8C。
第二部分:
具体实现方案
一、硬件组成:
(一)、硬件结构框图如下:
(二)、各部分硬件电路实现
(1)、基于AT89S52的主控电路图
主控电路以89C52为核心扩展32KRAM;单片机使用6M晶振,P0口外接上拉电阻,增大了带负载能力;A12~A15接74LS138译码器,输出作外部片选信号。
扩展了几个接口用于其它部分于单片机的通信
(2)前端信号处理
INA126构成的放大器及滤波电路:
通过调节
的阻值来改变放大倍数。
微弱信号Vi1和Vi2被分别放大后从INA126的第6脚输出。
A/D转换器ICL7135的输入电压变化范围是-2V~+2V,传感器的输出电压信号在0~20mv左右,因此放大器的放大倍数在200~300左右,可将
接成
的滑动变阻器。
由于ICL7135对高频干扰不敏感,所以滤波电路主要针对工频及其低次谐波引入的干扰。
因为压力信号变化十分缓慢,所以滤波电路可以把频率做得很低。
(3)A/D转换器
基于ICL7135的A/D转换器实现电路:
基准源选用芯片MC14032.5V分压得到:
由于ICL7135内部没有振荡器,所以需要外接。
但A/D转换器精度与时钟频率的漂移无关。
正向积分时间T1和反向积分时间T2按相同比例增加并不影响测量的结果。
ICL7135的时钟频率典型值为200kHz最高允许为1200kHz,时钟频率越高,转换速度越快。
每输出一位BCD码的时间为200个时钟周期,选通脉冲位于数据脉冲的中部,如果时钟频率太高,则数据的接受程序还没有接受完毕,数据就已经消失了。
考虑到此系统频率要求不是太高,且单片机的工作频率也不是很高,因此我们取时钟频率的典型值:
200kHz。
由于频率比较低,对时钟漂移要求不高,我们采用阻容方式实现了基本的振荡电路。
如下:
振荡频率约为160kHz。
此外ICL7135外部还需要外接积分电阻、积分电容,但A/D转换器精度与外接的积分电阻、积分电容的精度无关,故可以降低对元件质量的要求。
不过积分电容和积分电容的介质损耗会影响到A/D转换器的精度,所以应采用介质损耗较小的聚丙乙烯电容
ICL7135还需要外接基准电源,这是因为芯片内部的基准源一般容易受到温度的影响,而基准电源的变化会直接影响转换精度。
所以当精度要求较高时,应采用外接基准源。
一般接其典型值1V。
(4)、人机交互界面
(a)、键盘接口图:
键盘控制芯片ZLG7289控制键盘的扫描,当监测到有键按下后ZLG7289的9脚便产生一个低电平通知单片机,单片机可以采用查询或者中断方式将数据通过P1.5以串行方式读入。
因为查询方式会浪费大量的时间,所以本系统采用的是中断方式。
(b)、LCD显示接口电路
.
LCD复位信号通过反相器接到单片机的RESET上,上电或手动复位时将随单片机同时复位。
由于复位后并行口输出高电平,LCD处于选中状态,此时LCD将输出内部状态字,将会影响数据总线上的数据传输。
所以外接一个反相器。
二、软件组成:
(一)、流程图
主程序流程如图所示:
中断服务程序流程图如下:
(2)、软件说明
由于涉及到大量数据的运算,程序不宜采用汇编语言,C语言大大缩短了开发时间,且程序可读性非常好。
程序中对AD采入的数据进行了数字滤波,进一步减小AD读入数据的误差。
7289键盘控制采用中断方式,加快了程序的执行效率。
详细的操作过程见使用说明。
第三部分:
测试及结果分析
一、测试结果及误差分析:
砝码重量(g)
实际显示重量1(g)
实际显示重量2(g)
实际显示重量3(g)
100
99
99
98
150
148
147
149
200
195
197
198
250
244
246
244
300
295
296
294
350
342
344
343
400
393
395
396
450
443
443
444
500
493
494
495
550
552
551
553
600
590
593
594
650
641
641
642
700
689
692
693
750
740
740
741
800
790
791
790
850
839
840
842
900
887
888
888
950
938
938
938
1000
986
987
987
注:
由于传感器和其他器件本身并非理想线性,程序中对实测数据进行了线性补偿。
误差分析:
经校准,非线性补偿后,误差已基本达到要求。
所用测量仪器:
总重1Kg的砝码,万用表,示波器
第四部分:
使用操作说明
本系统采用32键键盘来实现,分为数字键:
0-9,商品1-商品10,6个控制键。
本系统开机显示公司名称,后提示输入收银员编号和当前日期。
正确输入后,进入称重显示。
数字键和小数点键:
用于输入单价;
累加键:
相当于确认,可以将当然信息保存至购物清单;并且将金额累加,得到所购买商品的总金额。
去皮键:
用于去除皮重;
清单价:
用于输入的单价错误的时候,重新输入;
购物清单键:
当需要显示当前顾客的总的购物清单时,可以连续按下购物清单键,分页显示所购买的商品信息,并且若以达到最后一页,则显示总计金额,收银员编号,和公司名称,当然日期。
运行中如果顾客购买已存入的10种商品,只需按下相应的商品键,既可以将商品的名称和单价以中文的形式显示,同样累加键保存此商品的信息,包括其重量,金额和当前累计金额。
另外,已存入的10种商品的单价均可重新设置,直接输入其单价即可,方便实用。
如果所称重物超过了系统最大量程10Kg,则蜂明器发出报警声音。
第五部分:
附录
电子秤的信号采集、处理、显示的程序.
#include
#include
//ad控制线
#definead_244XBYTE[0xbfff];
sbitad_stb=P3^3;
sbitad_start=P1^1;
//lcd控制线
sbitlcd_di=P1^7;
sbitlcd_rw=P1^2;
sbitlcd_e=P1^0;
//7289控制线
sbitcs7289=P1^3;
sbitclk7289=P1^4;
sbitdio7289=P1^5;
//sbitkey7289=P1^6;//7289查询方式
sbitkey7289=P3^2;//7289中断方式
sbitbaoj=P3^5;
//7289子程序
voidini_7289(void);
voidsend7289(short);
shortreceive(void);
voidkeyin(void);
//lcd子程序
voidini_lcd(void);
voidlcdd_send(short);
voidlcdi_send(short);
voidchk_busy(void);
//ad子程序
voidad(void);
voidbaojing(void);
voidd_change(long);
//初始化,编号,日期
voidini();
voiderror1(void);
voidnop1()
{}
voidchange(s)
intdealy;//全局变量
shortsh=0;//商品号
shortdot=0;//小数点标志
bitlist=0;
shortqb=0;
charxdatashuju[7]="";
shortxdatabcd[5];
charxdatas1[16]="单价:
元";
charxdatas2[16]="重量:
Kg";
charxdatas3[16]="金额:
元";
charxdatas4[16]="累计:
元";
charcodemessage0[]="信息学院山东大学";
charcodemessage1[]="输入收银员代号:
";
charcodemessage2[]="输入日期:
";
charcodemessage3[16]="--山东大学--";
charcodemessage5[16]="垃圾公司欢迎您!
!
";
charxdatabianhao[16]="收银员:
";
charxdatariqi[16]="--";
longintxdatazongjia=0,jine=0,jine1=0;
intxdatashizhong=0,pizhong=0,zhongliang=0;
longintxdataqingdan[20][4];
charcodeshangpin[11][4]={{"单价"},{"苹果"},{"梨"},{"花生"},{"大米"},
{"桃子"},{"塑料"},{"瓜子"},{"桔子"},{"香蕉"},{"玉米"}};
longintxdatadanjia[11]=
{0,2000,3635,5502,6660,3320,5502,660,3210,6600,5600};
charxdatajiage[6]={0x0,0x0,0x0,0xfe,0x0,0x0};//0.00
shortxdataxiuzheng[]={0,2,5,6,7,8,9,12,13};
chars[16];
{s[6]=shuju[0];
s[7]=shuju[1];
s[8]=shuju[2];
s[9]=shuju[3];
s[10]=shuju[4];
s[11]=shuju[5];
s[12]=shuju[6];
}
//****************************************************************
voidmain()
{shorti,j;
longintx,z;
inty;
intxdataduilie[3]={0};
P1=0xff;
ini_lcd();//初始化LCD
lcdi_send(0x8a);
while(message0[i])lcdd_send(message0[i++]);
ini_7289();//初始化7289
pizhong=ad1();
lcdi_send(0x1);//总清屏
ini();//初始页面,收银员编号,日期
lcdi_send(0x1);//总清屏
EA=1;EX0=1;//中断
//EX1=1;
//ad_start=1;
while
(1)
{if(list){lcdi_send(0x80);//显示单位名称
for(i=0;i<16;i++)lcdd_send(message3[i]);
x=qingdan[0][0];//商品名单价
for(i=0;i<4;i++)s1[i]=shangpin[x][i];
x=qingdan[0][1];
d_change(x);change(s1);
lcdi_send(0x90);
for(i=0;i<16;i++)lcdd_send(s1[i]);
x=qingdan[0][2];//显示重量
d_change(x);change(s2);
s2[10]=s2[9];s2[9]='.';
if(s2[8]==32)s2[8]=0x30;
lcdi_send(0x88);
for(i=0;i<16;i++)lcdd_send(s2[i]);
x=qingdan[0][3];
d_change(x);change(s3);
lcdi_send(0x98);
for(i=0;i<16;i++)lcdd_send(s3[i]);//以上为第一页
EA=0;EX0=0;//关键盘中断
for(j=1;j{while(key7289);
x=qingdan[j][2];
d_change(x);change(s2);//显示数据
s2[10]=s2[9];
s2[9]='.';if(s2[8]==32)s2[8]=0x30;
lcdi_send(0x90);
for(i=0;i<16;i++)lcdd_send(s2[i]);
x=qingdan[j][1];
d_change(x);change(s1);
x=qingdan[j][0];
for(i=0;i<4;i++)s1[i]=shangpin[x][i];
lcdi_send(0x80);
for(i=0;i<16;i++)lcdd_send(s1[i]);
x=qingdan[j][3];
d_change(x);change(s3);
lcdi_send(0x88);
for(i=0;i<16;i++)lcdd_send(s3[i]);
lcdi_send(0x98);
for(i=0;i<16;i++)lcdd_send(0x20);
lcdi_send(0x98);
while(key7289==0);
}
while(key7289);
d_change(zongjia);change(s4);
lcdi_send(0x80);
for(i=0;i<16;i++)lcdd_send(s4[i]);
lcdi_send(0x90);
for(i=0;i<16;i++)lcdd_send(bianhao[i]);
lcdi_send(0x88);
for(i=0;i<16;i++)lcdd_send(message5[i]);
lcdi_send(0x98);
for(i=0;i<16;i++)lcdd_send(riqi[i]);
list=0;
while(key7289==0);
while(key7289==1);
while(key7289==0);
EA=1;EX0=1;
}
else{y=0;
/*duilie[2]=duilie[1];//数字滤波
duilie[1]=duilie[0];
y=ad1();
duilie[0]=y>>1;
x=duilie[0];
x=x<<1;
x=x+duilie[1]+duilie[2];*/
zhongliang=ad1();
shizhong=zhongliang-pizhong;//数据转换
x=danjia[sh];
jine1=shizhong*x;
jine=jine1/1000;
d_change(shizhong);change(s2);//显示数据
s2[10]=s2[9];s2[9]='.';
if(s2[8]==32)s2[8]=0x30;
lcdi_send(0x90);
for(i=0;i<16;i++)lcdd_send(s2[i]);
d_change(danjia[sh]);change(s1);
for(i=0;i<4;i++)s1[i]=shangpin[sh][i];
lcdi_send(0x80);
for(i=0;i<16;i++)lcdd_send(s1[i]);
d_change(jine);change(s3);
lcdi_send(0x88);
for(i=0;i<16;i++)lcdd_send(s3[i]);
d_change(zongjia);change(s4);
lcdi_send(0x98);
for(i=0;i<16;i++)lcdd_send(s4[i]);
lcdi_send(0x98);
//while
(1);
}
}
}
voidkeyin(void)interrupt0using0//中断0服务程序
{charX,i;
longinty;
send7289(0x15);//接收数据
X=receive();
cs7289=1;
X=X&0x1f;
switch(X)
{case0xf:
{zongjia=zongjia+jine;
qingdan[qb][0]=sh;
qingdan[qb][1]=danjia[sh];
qingdan[qb][2]=shizhong;
qingdan[qb][3]=jine;
qb++;sh=0;dot=0;
danjia[0]=0;
for(i=0;i<6;i++)jiage[i]=0;
}
break;//累加
case0xe:
pizhong=zhongliang;break;//去皮
case0xd:
{danjia[s