摘要
电子秤是一种集检测和转换技术、计算机技术、信息处理、数字技术等技术于一体的现代新型称重仪器。它与我们的日常生活密切相关。 电子称重主要以单片机为中心控制单元,通过称重传感器进行模数转换单元,由键盘、显示电路和强大软件组成。电子称重不仅测量准确、快速、方便,而且自动称重和数字显示对人们的生活也越来越受欢迎。 本系统的设计主要从硬件电路设计、软件编程调试和物理焊接调试三个部分进行详细阐述。硬件电路主要基于单片机STC89C52是数据处理的核心控制单元,采用压力传感器采集数据,电子秤专用24位AD转换芯片HX711模拟传感器采集的模拟量AD转换后的数据发送到单片机进行处理显示,数据显示由LCD1602液晶显示效果稳定,无闪烁。
绪论
称重技术自古以来就受到人们的重视。称重技术作为一种测量手段,广泛应用于工农业、科研、交通、内外贸易等领域,与人们的生活息息相关。电子秤是电子衡器之一,是国计民生、国防建设、科研、内外贸易不可缺少的测量设备。衡器产品的技术水平将直接影响各行各业的现代化水平和社会经济效益的提高。称重装置不仅是提供重量数据的单一仪器,也是工业控制系统和商业管理系统的一部分,促进了工业生产的自动化和管理的现代化。它在缩短运行时间、改善运行条件、减少能源和材料消耗、提高产品质量、加强企业管理、改善运行管理等方面发挥了重要作用。称重装置的应用已遍及国民经济的各个领域,取得了显著的经济效益。 电子秤是称重技术中的一种新型仪器,广泛应用于各种场合。电子秤和机械秤具有体积小、重量轻、结构简单、价格低、实用价值强、维护方便等特点。它们可以在各种环境中工作,重量信号可以传输,容易实现重量显示的数字化,容易与计算机连接,实现生产过程的自动化,提高劳动生产率。从世界水平来看,称重技术已经经历了四个阶段,从所有传统的机械部件,到用电子线路取代部分机械部件的机电结合秤,再从集成电路到当前单片机系统设计的电子计价秤。我国电子称重从最初的机电结合型发展到现在的全电子数字智能型。如今,电子称重技术的制造技术和应用得到了新的发展:电子称重技术从静态称重发展到动态称重;测量方法从模拟测量发展到数字测量;测量特性从单参数测量发展到多参数测量。传统的测试仪器和控制技术得到了更先进的智能和应用。 电子称重的实现首先是通过压力传感器收集被测物体的重量,并将其转换为电压信号。输出电压信号通常很小,需要通过前端信号处理电路准确线性放大。放大后的模拟电压信号通过A/D将转换电路转换为数字量,送入主控电路的单片机,然后通过单片机控制译码显示器显示被测物体的重量。根据设计的基本要求,系统可分为数据采集模块、控制器模块和人机交互液晶显示界面模块三个模块。数据采集模块由压力传感器和信号进行预处理A/D转换部分组成。转换后的数字信号由控制器处理,驱动显示模块完成人机驱动显示模块完成人机之间的信息交换。这部分对软件的设计有很高的要求,系统的大部分功能都需要软件来控制。在扩展功能方面,该设计增加了过载报警提示功能,使该电子名称的设计更加人性化和智能化。
系统硬件设计方案
系统总体设计方案比较比较比较
在设计系统时,针对各个模块实现的功能来设计电子秤的方案有以下几种: 方案1 数码管显示:
该方案使用数字管显示物体的重量,简单可行,可以使用具有模数转换功能的内部单片机。由此设计的电子秤系统硬件部分简单,接口电路易于实现,编程时程序量大大降低,电路结构中只有简单的输出输入关系。缺点是硬件部分简单。虽然电子称重的基本称重功能可以实现,但外部数据的输入和各种控制参数不能根据实际情况灵活设置。由于数字管只能显示简单的数字和英文字符,不能显示汉字和其他复杂的字符,也不能满足显示购物清单的要求。由于采用了具有模数转换功能的单片机,系统电路太简单,系统硬件的扩展必须受到限制,电子秤的功能太简单,无法达到设计标准。 方案二 在前一个方案的基础上扩展,增加一个键盘输入装置,增加单片机内部的外部数据设置,实现电子称重定价功能。 结构简图如图2所示:
此方案设计的电子秤,可以实现称物计价功能,但是局限于数码管的功能,在显示时只能显示单价、购物总额以及简单的货物代码等。在显示重量时,如果数码管没有足够的位数,那么称量物体重量的精度必受到限制,所以此方案需要较多的数码管接入电路中。这样在处理输入输出接口时需要另行扩展足够多的I/O数码管使用接口比较麻烦。 方案三 前端信号处理时,采取放大、信号转换等措施增加信号采集强度,但会增加相应的设计成本;显示采用字符图形显示功能LCD显示器。该方案不仅增强了人机交换的能力,而且满足了设计要求当需要增加扩展功能时,可以通过切换液晶显示界面来实现购物清单、称重物体信息等相关内容。
鉴于上述三种方案的优缺点,本系统在设计时充分考虑到系统的实用性及成本的可行性的前提下,设计完成了最终的电子称方案,最终的硬件设计方案图如图4所示,
介绍系统元器件选型及器件参数
传感器选择
压电传感器是一种典型的有源传感器,也称为自发电传感器。其工作原理是在某些材料受力后在相应的特定表面产生电荷的压电效应。 压电传感器体积小、重量轻、结构简单、工作可靠,适用于动态力学测量,不适用于低频测量,更不用说静态测量了。目前,它主要用于测量加速度和动态力或压力。压电设备的弱点:内阻高,功率小。功率小,输出能量弱,电缆分布电容和噪声干扰影响输出特性,对外部电路要求高。 电阻应变传感器是一种结构性传感器,利用电阻应变效应将各种力学量转换为电信号。电阻应变片电阻应变传感器的核心元件的工作原理是基于材料的电阻应变效应。电阻应变片可单独用作传感器,也可用作敏感元件和弹性元件的力学传感器。 导体电阻随机械变形而变化的现象称为电阻应变效应。电阻应变片将机械应变信号转换为△R/R之后,由于应变量和相应的电阻变化一般很小,难以直接准确测量,处理不方便。因此,应变片应采用转换电路△R/R电压或电流电压或电流变化。电桥通常用于转换电路。 直流电桥的特点是信号不受各部件和电线分布电感和电容器的影响,抗干扰性强。但由于机械应变输出信号小,需要高增益、高稳定性的放大器放大。 图5为一直流电源的平衡电阻电桥,连接直流电源E: 当电桥输出端连接无限大负载电阻时,可视输出端为开路,直流电桥称为电压桥,即只有电压输出。
显示器选择
方案1 数码管显示 数码管是一种半导体发光器件,其基本单元为发光二极管。数码管按段数分为七段数码管和八段数码管。八段数码管比七段数码管多一个发光二极管单元(多一个小数点显示);根据能显示多少个8,可分为1位、2位、4位等数码管;根据发光二极管单元的连接方式,分为共阳极数码管和共阴极数码管。共阳数码管是指将所有发光二极管的阳极连接在一起形成公共阳极(COM)数码管。共阳数码管应用于公共极端COM接到 5V,当一个字段的发光二极管阴极为低电时,相应的字段将被点亮。当一个字段的阴极为高电时,相应的字段不亮。共阴数字管是指将所有发光二极管的阴极连接在一起形成公共阴极(COM)数码管。共阴数码管应用于公共极端COM接到地线GND当某一字段发光二极管的阳极为高电时,相应相应的字段就会被点亮。当一个字段的阳极是低电平时,相应的字段就不亮了。 数字管显示信息有限。当显示信息较多时,需要多个数字管级联,导致硬件连接复杂,成本增加;数字管不能很好地显示大多数字符,动态扫描不容易闪烁。
方案二 LCD液晶字符显示 采用点阵字符型 LCD 液晶显示,液晶显示模块具有体积小、功耗低、显示内容丰富等特点,现在字符液晶显示模块是单片机应用设计中最常用的信息显示设备,但使用LCD液晶显示会增加设计成本。 LCD1602可显示2行 16 字符, 8 位数据总线 D0-D7,和 RS、R/W、 EN 工作电压为 5V,还有字符对比度调节和背光[4]。
LCD1602 液晶模块2 液晶模块中的字符(CGROM) 160 存储了不同 的点阵字符图形,如表 1 所示。这些字符包括:阿拉伯数字、英文字母大小写、 常用符号、日文假名等。每个字符都有一个固定的代码,其读写操作、 屏幕和光标操作通过指令编程实现。 最后,考虑到各种因素,选择了 LCD1602 显示器作为系统的显示界面。
AD转换芯片
HX711是专为高精度电子秤设计的24位A/D转换器芯片。与其他类型的芯片相比,该芯片集成了稳压电源和片内时间钟振荡器等其它同类型芯片所需要的外围电路,具有集成度高、响应速度快、抗干扰性强等优点。降低了电子秤的整机成本,提高了整机的性能和可靠性。该芯片与后端MCU 芯片的接口和编程非常简单,所有控制信号由管脚驱动,无需对芯片内部的寄存器编程。输入选择开关可任意选取通道A 或通道B,与其内部的低噪声可编程放大器相连。通道A 的可编程增益为128 或64,对应的满额度差分输入信号幅值分别为±20mV或±40mV。通道B 则为固定的64 增益,用于系统参数检测。芯片内提供的稳压电源可以直接向外部传感器和芯片内的A/D 转换器提供电源,系统板上无需另外的模拟电源。芯片内的时钟振荡器不需要任何外接器件。上电自动复位功能简化了开机的初始化过程。芯片管脚图如图7所示。
系统硬件电路
系统硬件电路设计
由于该系统中 51 单片机及 AD 转换芯片及液晶显示器所需供电电压均为 5V 电压,所以要保证系统稳定可靠的工作,需要设计一个可以稳定提供 5V 电压的供电系统。本设计采用USB供电方式,USB 接口供电方便程序调试,电源输接口加上LED 电源指示灯,用来判定电源是否正常工作。该系统电源电路设计如图 11 所示。
单片机控制电路设计
系统主控电路由STC89C52单片机及晶振电路和复位电路组成,该电路作为整个系统功能实现的核心单元,其连接方式如图14所示。 晶振全称为晶体振荡器,其作用在于产生原始的时钟频率,这个频率经过频率发生器的放大或缩小后就成了电脑中各种不同的总线频率。晶振一般叫做晶体谐振器,是一种机电器件,是用电损耗很小的石英晶体经精密切割磨削并镀上电极焊上引线做成。这种晶体有一个很重要的特性,如果给它通电,它就会产生机械振荡,反之,如果给它机械力,它又会产生电,这种特性叫机电效应。他们有一个很重要的特点,其振荡频率与他们的形状,材料,切割方向等密切相关。由于石英晶体化学性能非常稳定,热膨胀系数非常小,其振荡频率也非常稳定,由于控制几何尺寸可以做到很精密,因此,其谐振频率也很准确。根据石英晶体的机电效应,我们可以把它等效为一个电磁振荡回路,即谐振回路。他们的机电效应是机-电-机-电…的不断转换,由电感和电容组成的谐振回路是电场-磁场的不断转换。在电路中的应用实际上是把它当作一个高Q值的电磁谐振回路。由于石英晶体的损耗非常小,即Q值非常高,做振荡器用时,可以产生非常稳定的振荡,作滤波器用,可以获得非常稳定和陡削的带通或带阻曲线[10]。 复位电路是用来让单片机返回到初始状态的辅助电路,其作用是当单片机程序跑飞或系统出现死机状态时可以让系统从新恢复工作。本系统复位电路的设计为上电复位复位方式。按键复位就没有太大必要使用看,所以没有设计按键复位。
系统显示电路设计
显示部分采用LCD1602液晶显示模块,液晶板上排列着若干 5×7或 5×10点阵的字符显示位,每个显示位可显示1个字符,从规格上分为每行 8、16、20、24、32、40位,有一行、两行及四行三类。其与单片机的连接电路如图15所示 1脚和2脚为液晶1602地和电源引脚,3脚为背光调节引脚,通过10K电位器接地,背光可通过电位器来调节亮度;4脚、5脚、6脚为液晶片选控制引脚,分别连接到单片机的P2.5、P2.6、P2,7端口,7~14脚为数据接口,与单片机的P0口相连实现数据的传输,15、16、脚为液晶的背光控制脚,分别接到电源和地[9]。
超重报警电路设计
报警指示电路用来在称重测量超出最高值时报警提示,以免重量太高的情况下损坏传感器。报警指示电路由PNP三极管9S8550驱动蜂鸣器来实现,单片机IO口控制三极管的基极,当单片机的IO口输出为低电平时,三极管导通,蜂鸣器的正极与电源接通,蜂鸣器通电发出报警声,当单片机IO口输出高电平时,三极管截止,蜂鸣器停止报警。报警指示电路如图16所示。
按键输入电路设计
按键输入电路用来在电子称测量过程中输入单价值,按键输入电路采用4*4矩阵键盘实现,矩阵键盘电路如图17所示。 此电子秤是开机检测托盘重量,并将托盘重量清零(即电子秤每次开机后检测托盘重量,并程序中自动将托盘重量保存在一个变量中,称量过程中每次都将获得的重量减去托盘重量,而得到所要称量物体的真正的重量), 计算功能:在正确输入了单价之后,按下计算按键,将会计算出金额,并在液晶显示器上显示出重量、单价、总价。
系统软件
主程序
显示部分
按键检测
系统整体调试
硬件电路调试中遇到的问题
1、电子电路的设计中对各种影响因素的考虑不够完全,比如在对过电压情况的处理中未作防范措施。 2、系统设计不够优化,有待改善。比如系统的超量程信号直接由单片机送入报警电路,没有设计保护电路再入单片机处理后送入报警电路。 3、没有扩展更多电路,如温度显示功能,通讯接口电路与上位机(PC机)进行通讯,上位机显示功能从而将大量的商品数据存于上位机,然后通过串口或并口通讯与电子称相连,达到远距离控制的目的。 4、对各种实用芯片价格了解不够,选择上任有欠缺,如所选的称重传感器价格较贵。 这些都为我今后的学习和工作留下了积极的影响。
系统实物调试效果图
代码
#include "main.h"#include "LCD1602.h"#include "HX711.h"unsigned long HX711_Buffer = 0;unsigned long Weight_Maopi = 0,Weight_Shiwu = 0;char Price_Count = 0;unsigned char KEY_NUM = 0;unsigned char Price_Buffer[3] = {
0x00,0x00,0x00};unsigned long Money = 0;bit Flag_OK = 0;//****************************************************//主函数//****************************************************void main(){
char k = 10 ; Init_LCD1602(); //初始化LCD1602 LCD1602_write_com(0x80); //指针设置 LCD1602_write_word(" Hello Welcome"); //开机画面第一行 Delay_ms(800); //延时1s LCD1602_write_com(0x80+0x40); //指针设置 LCD1602_write_word(" "); Get_Maopi(); //称毛皮重量 Delay_ms(1000); //延时1s Init_LCD1602(); //初始化LCD1602 消除之前的显示内容loop:Price_Count = 0; Price_Buffer[0] = 0; Price_Buffer[1] = 0; Price_Buffer[2] = 0; Flag_OK = 0; LCD1602_write_com(0x80); //指针设置 LCD1602_write_word(" W: Kg"); LCD1602_write_com(0x80+0x40); //指针 LCD1602_write_word("P: . Z: "); LCD1602_write_com(0x80+0x40+6); //指针 LCD1602_write_data(0x5c); LCD1602_write_com(0x80+0x40+15); //指针 LCD1602_write_data(0x5c); Get_Maopi(); //称毛皮重量 while(1) {
if( Flag_OK == 0) {
if( k == 0) Get_Weight(); //称重 k--; if( k < 0) {
k = 10; } //显示当前重量 LCD1602_write_com(0x86); LCD1602_write_data(Weight_Shiwu/1000 + 0x30); LCD1602_write_data('.'); LCD1602_write_data(Weight_Shiwu%1000/100 + 0x30); LCD1602_write_data(Weight_Shiwu%100/10 + 0x30); LCD1602_write_data(Weight_Shiwu%10 + 0x30); } KEY_NUM = KEY_Scan(); if( KEY_NUM != 0x55) //当返回的不是初值时候,确认按键按下。 {
if(KEY_NUM == 16) //数字A键,去皮功能 {
Get_Maopi(); //去皮 } if(KEY_NUM == 15) //数字B键清除键,二次测量 {
goto loop; } if(KEY_NUM == 12) //数字C输入单价错误时返回上一步 {
Price_Count--; if( Price_Count < 0) {
Price_Count = 0; } Price_Buffer[Price_Count] = 0; //清除上一个输入的数据 switch(Price_Count) {
case 0: LCD1602_write_com(0x80+0x40+2); LCD1602_write_data(' '); break; case 1: LCD1602_write_com(0x80+0x40+3); LCD1602_write_data(' '); break; case 2: LCD1602_write_com(0x80+0x40+5); LCD1602_write_data(' '); break; default : break; } } if(KEY_NUM == 13) //数字D键,计算总价 {
Money = Price_Buffer[0] * 100 + Price_Buffer[1] * 10 + Price_Buffer[2]; Money = Money * Weight_Shiwu / 1000; LCD1602_write_com(0x80+0x40+10); LCD1602_write_data(Money/1000 + 0x30); LCD1602_write_data(Money%1000/100 + 0x30); LCD1602_write_data(Money%100/10 + 0x30); LCD1602_write_data('.'); LCD1602_write_data(Money%10 + 0x30); Flag_OK = 1; } if(KEY_NUM >= 0 && KEY_NUM <= 9) //显示输入的价格值 {
Price_Buffer[Price_Count] = KEY_NUM; switch(Price_Count) {
LCD1602_write_com(0x80+0x40); //指针 LCD1602_write_word("P: . Z: "); case 0: LCD1602_write_com(0x80+0x40+2); LCD1602_write_data(Price_Buffer[0] + 0x30); break; case 1: LCD1602_write_com(0x80+0x40+3); LCD1602_write_data(Price_Buffer[1] + 0x30); break; case 2: LCD1602_write_com(0x80+0x40+5); LCD1602_write_data(Price_Buffer[2] + 0x30); break; default : break; } Price_Count++; if( Price_Count >= 3) {
Price_Count = 3; } } } }}//****************************************************//矩阵键盘扫描//****************************************************unsigned char KEY_Scan(){
unsigned char temp = 0; unsigned char com = 0x55 , com1 = 0 , com2 = 0; P3=0xf0; if(P3!=0xf0) {
com1=P3; P3=0x0f; com2=P3; } P3=0xf0; while(P3!=0xf0); temp=com1|com2; if(temp==0xee)com=1;//数字1 if(temp==0xed)com=4;//数字4 if(temp==0xeb)com=7;//数字7 if(temp==0xe7)com=11;//备用键*号键 if(temp==0xd7)com=0;//数字0 if(temp==0xb7)com=14;//备用键*号键 if(temp==0xde)com=2; //数字2 if(temp==0xdd)com=5; //数字5 if(temp==0xdb)com=8;//数字8 if(temp==0xbe)com=3;//数字3 if(temp==0xbd)com=6; //数字6 if(temp==0xbb)com=9;//数字9 if(temp==0x7e)com=16;//数字A键,去皮功能 if(temp==0x7d)com=15;//数字B键清除键,二次测量 if(temp==0x7b)com=12;//数字C输入单价错误时返回上一步 if(temp==0x77)com=13;//数字D键,计算总价 return(com);}//****************************************************//称重//****************************************************void Get_Weight(){
HX711_Buffer = HX711_Read(); HX711_Buffer = HX711_Buffer/100; if(HX711_Buffer > Weight_Maopi) {
Weight_Shiwu = HX711_Buffer; Weight_Shiwu = Weight_Shiwu - Weight_Maopi; //获取实物的AD采样数值。 Weight_Shiwu = (unsigned int)((float)Weight_Shiwu/4.40+0.05); //计算实物的实际重量 //因为不同的传感器特性曲线不一样,因此,每一个传感器需要矫正这里的4.30这个除数。 //当发现测试出来的重量偏大时,增加该数值。 //如果测试出来的重量偏小时,减小改数值。 //该数值一般在4.0-5.0之间。因传感器不同而定。 //+0.05是为了四舍五入百分位 Buzzer = 1; //关闭警报 }// else if(HX711_Buffer < Weight_Maopi - 30)// {
// Buzzer = 0; //负重量报警// }// else if(HX711_Buffer > Weight_Maopi + 24970) //大于5Kg的最大量程,报警 // {
// Buzzer = 0;// } if(Weight_Shiwu > 5000 || HX711_Buffer < Weight_Maopi - 30) {
Buzzer = 0; } else {
Buzzer = 1; } }//****************************************************//获取毛皮重量//****************************************************void Get_Maopi(){
HX711_Buffer = HX711_Read(); Weight_Maopi = HX711_Buffer/100; } //****************************************************//MS延时函数(12M晶振下测试)//****************************************************void Delay_ms(unsigned int n){
unsigned int i,j; for(i=0;i<n;i++) for(j=0;j<123;j++);}