找回密码
 立即注册

QQ登录

只需一步,快速开始

帖子
查看: 3778|回复: 1
打印 上一主题 下一主题
收起左侧

基于单片机的电子称设计报告(word格式文档下载)

[复制链接]
跳转到指定楼层
楼主
ID:370073 发表于 2018-7-12 20:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这是一个基于51单片机电子秤的报告,希望对有需要的人有帮助。

摘要
电子秤是将检测与转换技术、计算机技术、信息处理、数字技术等技术综合一体的现代新型称重仪器。它与我们日常生活紧密结合息息相关。
电子称主要以单片机作为中心控制单元,通过称重传感器进行模数转换单元,在配以键盘、显示电路及强大软件来组成。电子称不但计量准确、快速方便,更重要的自动称重、数字显示,对人们生活的影响越来越大,广受欢迎。
本系统的设计主要从硬件电路设计,软件编程调试,实物焊接调试三部分进行详细阐述。硬件电路主要是基于单片机STC89C52为核心的控制单元实现数据的处理,采用压力传感器对数据进行采集,电子秤专用24位AD转换芯片HX711对传感器采集到的模拟量进行AD转换,转换后的数据送到单片机进行处理显示,数据显示由LCD1602液晶实现,液晶显示效果稳定无闪烁。

1绪论
2 系统硬件方案设计
2.1系统总体设计方案比较与论证
2.2系统元器件选型及器件参数介绍
2.2.1单片机选型
2.2.2传感器选择
2.2.3 显示器选择
2.2.4 AD转换芯片选择
3系统硬件电路设计
3.1系统电源电路设计
3.3单片机控制电路设计
3.4系统显示电路设计
3.5超重报警提示电路设计
3.6按键输入电路设计
4 系统软件设计
4.1系统主程序软件流程图
4.2系统显示部分流程图
4.3系统按键检测部分流程图
5 系统整体调试
5.1硬件电路调试中遇到的问题
5.2系统实物调试效果图
5.3系统设计总结
参考文献
附录
附录1系统整体电路图
附录2系统部分源程序
致 谢

1绪论
    称重技术自古以来就被人们所重视,作为一种计量手段,广泛应用于工农业、科研、交通、内外贸易等各个领域,与人民的生活紧密相连。电子秤是电子衡器中的一种,衡器是国家法定计量器具,是国计民生、国防建设、科学研究、内外贸易不可缺少的计量设备,衡器产品技术水平的高低,将直接影响各行各业的现代化水平和社会经济效益的提高。称重装置不仅是提供重量数据的单体仪表,而且作为工业控制系统和商业管理系统的一个组成部分,推进了工业生产的自动化和管理的现代化,它起到了缩短作业时间、改善操作条件、降低能源和材料的消耗、提高产品质量以及加强企业管理、改善经营管理等多方面的作用。称重装置的应用已遍及到国民经济各领域,取得了显著的经济效益。
电子秤是称重技术中的一种新型仪表,广泛应用于各种场合。电子秤与机械秤比较有体积小、重量轻、结构简单、价格低、实用价值强、维护方便等特点,可在各种环境工作,重量信号可远传,易于实现重量显示数字化,易于与计算机联网,实现生产过程自动化,提高劳动生产率。从世界水平看,衡器技术已经经历了四个阶段,从传统的全部由机械元器件组成的机械称到用电子线路代替部分机械元器件的机电结合秤,再从集成电路式到目前的单片机系统设计的电子计价秤。我国电子衡器从最初的机电结合型发展到现在的全电子型和数字智能型。现今电子衡器制造技术及应用得到了新发展:电子称重技术从静态称重向动态称重发展;计量方法从模拟测量向数字测量发展;测量特点从单参数测量向多参数测量发展。常规的测试仪器仪表和控制装置被更先进的智能仪器所取代,使得传统的电子测量仪器在远离、功能、精度及自动化水平定方面发生了巨大变化,并相应的出现了各种各样的智能仪器控制系统,使得科学实验和应用工程的自动化程度得以显著提高。
电子称重的实现首先是通过压力传感器采集到被测物体的重量并将其转换成电压信号。输出电压信号通常很小,需要通过前端信号处理电路进行准确的线性放大。放大后的模拟电压信号经A/D转换电路转换成数字量被送入到主控电路的单片机中,再经过单片机控制译码显示器,从而显示出被测物体的重量。按照设计的基本要求,系统可分为三大模块,数据采集模块、控制器模块、人机交互液晶显示界面模块。其中数据采集模块由压力传感器、信号的前级处理和A/D转换部分组成。转换后的数字信号送给控制器处理,由控制器完成对该数字量的处理,驱动显示模块完成人机间的信息交换。此部分对软件的设计要求比较高,系统的大部分功能都需要软件来控制。在扩展功能上,本设计增加了一个过载报警提示功能使本电子称的设计更人性化智能化。
2 系统硬件方案设计
2.1系统总体设计方案比较与论证
在设计系统时,针对各个模块实现的功能来设计电子秤的方案有以下几种:
方案一  数码管显示:

1 数码管显示方案

此方案利用数码管显示物体重量,简单可行,可以采用内部带有模数转换功能的单片机。由此设计出的电子秤系统,硬件部分简单,接口电路易于实现,并且在编程时大大减少程序量,在电路结构上只有简单的输出输入关系。缺点是:硬件部分简单,虽然可以实现电子称基本的称重功能,但是不能实现外部数据的输入,无法根据实际情况灵活地设定各种控制参数。由于数码管只能实现简单的数字和英文字符的显示,不能显示汉字以及其他的复杂字符,不能达到显示购物清单的要求。又因为采用了具有模数转换功能的单片机,系统电路过于简单,系统硬件的扩展必受到限制,电子秤的功能过于单一,达不到设计的标准。
方案二  在前一种方案的基础上进行扩展,增加一键盘输入装置,增加外界对单片机内部的数据设定,使电子称实现称重计价的功能。
结构简图如图2所示:

2带有键盘输入的结构简图


此方案设计的电子秤,可以实现称物计价功能,但是局限于数码管的功能,在显示时只能显示单价、购物总额以及简单的货物代码等。在显示重量时,如果数码管没有足够的位数,那么称量物体重量的精度必受到限制,所以此方案需要较多的数码管接入电路中。这样在处理输入输出接口时需要另行扩展足够多的I/O接口供数码管使用,比较麻烦。
方案三 前端信号处理时,选用放大、信号转换等措施来增加信号采集强度但会增加相应的设计成本;显示方面采用具有字符图文显示功能的LCD显示器。这种方案不仅加强了人机交换的能力,而且满足设计要求,可以显示购物清单、所称量的物体信息等相关内容,当需要增加扩展功能时可以通过切换液晶显示界面的方式来实现。
结构简图如下图3所示:

3带有键盘输入及液晶显示的结构简图


鉴于上述三种方案的优缺点,本系统在设计时充分考虑到系统的实用性及成本的可行性的前提下,设计完成了最终的电子称方案,最终的硬件设计方案图如图4所示,




3系统设计硬件框图

2.2系统元器件选型及器件参数介绍2.2.1单片机选型

单片机的选择在整个系统设计中至关重要,要满足大内存、高速率、通用性、价格便宜等要求,鉴于以上考虑本课题选择ST89C52作为整个系统的主控芯片。

ST89C52是一个低功耗,高性能CMOS 8位单片机,片内含8k Bytes ISP(In-system programmable)的可反复擦写10000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及80C51引脚结构[1],芯片内集成了通用8位中央处理器和ISP Flash存储单元,功能强大的微型计算机的ST89C52可为许多嵌入式控制应用系统提供高性价比的解决方案。ST89C52芯片具有以下特性[2]:

①指令集和芯片引脚与Intel公司的8051兼容;

②8KB片内在系统可编程Flash程序存储器;

③时钟频率为0~33MHz;

④128字节片内随机读写存储器(RAM);

⑤32个可编程输入/输出引脚;

⑥2个16位定时/计数器;

⑦6个中断源,2级优先级;

⑧全双工串行通信接口;

⑨监视定时器;

⑩2个数据指针。

ST89C52单片机的40个引脚中有2个专用于主电源引脚,2个外接晶振的引脚,4个控制或与其它电源复用的引脚,以及32条输入输出I/O引脚。

ST89C52单片机引脚图如图4所示:



图4 ST89C52单片机引脚图
2.2.2传感器选择   
压电传感器是一种典型的有源传感器,又称自发电式传感器。其工作原理是基于某些材料受力后在其相应的特定表面产生电荷的压电效应。
压电传感器体积小、重量轻、结构简单、工作可靠,适用于动态力学量的测量,不适合测频率太低的被测量,更不能测静态量。目前多用于加速度和动态力或压力的测量。压电器件的弱点:高内阻、小功率。功率小,输出的能量微弱,电缆的分布电容及噪声干扰影响输出特性,这对外接电路要求很高。
电阻应变式传感器是一种利用电阻应变效应,将各种力学量转换为电信号的结构型传感器。电阻应变片式电阻应变式传感器的核心元件,其工作原理是基于材料的电阻应变效应,电阻应变片即可单独作为传感器使用,又能作为敏感元件结合弹性元件构成力学量传感器。
导体的电阻随着机械变形而发生变化的现象叫做电阻应变效应。电阻应变片把机械应变信号转换为△R/R后,由于应变量及相应电阻变化一般都很微小,难以直接精确测量,且不便处理。因此,要采用转换电路把应变片的△R/R变化转换成电压或电流变化。其转换电路常用测量电桥。
直流电桥的特点是信号不会受各元件和导线的分布电感及电容的影响,抗干扰能力强,但因机械应变的输出信号小,要求用高增益和高稳定性的放大器放大。
图5为一直流供电的平衡电阻电桥,接直流电源E:










   


图5 传感器内部连接图
当电桥输出端接无穷大负载电阻时,可视输出端为开路,此时直流电桥称为电压桥,即只有电压输出。
当忽略电源的内阻时,由分压原理有:

=                                   (2.1)

当满足条件R1R3=R2R4时,即
(2.2)

=0,即电桥平衡。式(2.2)称平衡条件。
应变片测量电桥在测量前使电桥平衡,从而使测量时电桥输出电压只与应变片感受的应变所引起的电阻变化有关。
若差动工作,即R1=R-△R,R2=R+△R,R3=R-△R,R4=R+△R,按式(2.1),则电桥输出为


                                       (2.3)

应变片式传感器有如下特点:
(1)应用和测量范围广,应变片可制成各种机械量传感器。
(2)分辨力和灵敏度高,精度较高。
(3)结构轻小,对试件影响小, 对复杂环境适应性强,可在高温、高压、强磁场等特殊环境中使用,频率响应好。
(4)商品化,使用方便,便于实现远距离、自动化测量[5]。
通过对压力传感器与电阻应变式传感器比较分析,最终选择了第二种方案。题目要求称重范围0~5Kg,满量程量误差不大于0.005Kg,考虑到秤台自重、振动和冲击分量,还要避免超重损坏传感器,所以传感器量程必须大于额定称重5Kg。我们选择的是电阻应变片压力传感器,量程为5Kg,精度为0.01% ,满足本系统的精度要求。
2.2.3 显示器选择

方案一 数码管显示

数码管是一种半导体发光器件,其基本单元是发光二极管。数码管按段数分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元(多一个小数点显示);按能显示多少个“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]。

具体引脚说明如表图6所示。

图6 LCD1602字符液晶引脚定义

LCD1602 液晶模块内部的字符发生存储器(CGROM)已经存储了 160 个不同 的点阵字符图形,如表 1 所示,这些字符有:阿拉伯数字、英文字母的大小写、 常用的符号、和日文假名等,每一个字符都有一个固定的代码,它的读写操作、 屏幕和光标的操作都是通过指令编程来实现的。

最后综合了多方面因素的考虑采用了方案二,选择 LCD1602 显示器作为系统的显示界面。

2.2.4 AD转换芯片选择

HX711是一款专为高精度电子秤而设计的24位A/D转换器芯片。与同类型其它芯片相比,该芯片集成了包括稳压电源、片内时钟振荡器等其它同类型芯片所需要的外围电路,具有集成度高、响应速度快、抗干扰性强等优点。降低了电子秤的整机成本,提高了整机的性能和可靠性。该芯片与后端MCU 芯片的接口和编程非常简单,所有控制信号由管脚驱动,无需对芯片内部的寄存器编程。输入选择开关可任意选取通道A 或通道B,与其内部的低噪声可编程放大器相连。通道A 的可编程增益为128 或64,对应的满额度差分输入信号幅值分别为±20mV或±40mV。通道B 则为固定的64 增益,用于系统参数检测。芯片内提供的稳压电源可以直接向外部传感器和芯片内的A/D 转换器提供电源,系统板上无需另外的模拟电源。芯片内的时钟振荡器不需要任何外接器件。上电自动复位功能简化了开机的初始化过程。芯片管脚图如图7所示。

图7 HX711管脚定义

HX711典型应用电路如图8所示。

图8 HX711典型应用电路

3系统硬件电路设计3.1系统电源电路设计

由于该系统中 51 单片机及 AD 转换芯片及液晶显示器所需供电电压均为 5V 电压,所以要保证系统稳定可靠的工作,需要设计一个可以稳定提供 5V 电压的供电系统。本设计采用USB供电方式,USB 接口供电方便程序调试,电源输接口加上LED 电源指示灯,用来判定电源是否正常工作。该系统电源电路设计如图 11 所示。

3.3单片机控制电路设计

系统主控电路由STC89C52单片机及晶振电路和复位电路组成,该电路作为整个系统功能实现的核心单元,其连接方式如图14所示。

图14单片机主控电路

晶振全称为晶体振荡器,其作用在于产生原始的时钟频率,这个频率经过频率发生器的放大或缩小后就成了电脑中各种不同的总线频率。晶振一般叫做晶体谐振器,是一种机电器件,是用电损耗很小的石英晶体经精密切割磨削并镀上电极焊上引线做成。这种晶体有一个很重要的特性,如果给它通电,它就会产生机械振荡,反之,如果给它机械力,它又会产生电,这种特性叫机电效应。他们有一个很重要的特点,其振荡频率与他们的形状,材料,切割方向等密切相关。由于石英晶体化学性能非常稳定,热膨胀系数非常小,其振荡频率也非常稳定,由于控制几何尺寸可以做到很精密,因此,其谐振频率也很准确。根据石英晶体的机电效应,我们可以把它等效为一个电磁振荡回路,即谐振回路。他们的机电效应是机-电-机-电..的不断转换,由电感和电容组成的谐振回路是电场-磁场的不断转换。在电路中的应用实际上是把它当作一个高Q值的电磁谐振回路。由于石英晶体的损耗非常小,即Q值非常高,做振荡器用时,可以产生非常稳定的振荡,作滤波器用,可以获得非常稳定和陡削的带通或带阻曲线[10]。

复位电路是用来让单片机返回到初始状态的辅助电路,其作用是当单片机程序跑飞或系统出现死机状态时可以让系统从新恢复工作。本系统复位电路的设计为上电复位复位方式。按键复位就没有太大必要使用看,所以没有设计按键复位。

3.4系统显示电路设计

显示部分采用LCD1602液晶显示模块,液晶板上排列着若干 5×7或 5×10点阵的字符显示位,每个显示位可显示1个字符,从规格上分为每行 8、16、20、24、32、40位,有一行、两行及四行三类。其与单片机的连接电路如图15所示

图15系统状态显示电路图

     1脚和2脚为液晶1602地和电源引脚,3脚为背光调节引脚,通过10K电位器接地,背光可通过电位器来调节亮度;4脚、5脚、6脚为液晶片选控制引脚,分别连接到单片机的P2.5、P2.6、P2,7端口,7~14脚为数据接口,与单片机的P0口相连实现数据的传输,15、16、脚为液晶的背光控制脚,分别接到电源和地[9]。


3.5超重报警提示电路设计

报警指示电路用来在称重测量超出最高值时报警提示,以免重量太高的情况下损坏传感器。报警指示电路由PNP三极管9S8550驱动蜂鸣器来实现,单片机IO口控制三极管的基极,当单片机的IO口输出为低电平时,三极管导通,蜂鸣器的正极与电源接通,蜂鸣器通电发出报警声,当单片机IO口输出高电平时,三极管截止,蜂鸣器停止报警。报警指示电路如图16所示。

图16报警指示电路

3.6按键输入电路设计

按键输入电路用来在电子称测量过程中输入单价值,按键输入电路采用4*4矩阵键盘实现,矩阵键盘电路如图17所示。

图17按键输入电路

电子称按键功能分配如下表所示:

            

此电子秤是开机检测托盘重量,并将托盘重量清零(即电子秤每次开机后检测托盘重量,并程序中自动将托盘重量保存在一个变量中,称量过程中每次都将获得的重量减去托盘重量,而得到所要称量物体的真正的重量),

计算功能:在正确输入了单价之后,按下计算按键,将会计算出金额,并在液晶显示器上显示出重量、单价、总价。

4 系统软件设计

本电子称设计采用C语言编程,编译环境为keil UV3。

keil c51 是美国Keil Software 公司出品的51 系列兼容单片机C 语言软件开发系统,和汇编相比,C 在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。

Keil c51 软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows 界面。另外重要的一点,只要看一下编译后生成的汇编代码,就能体会到keil c51 生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体现高级语言的优势。

Keil C51 可以完成编辑、编译、连接、调试、仿真等整个开发流程。开发人员可用IDE 本身或其它编辑器编辑C 或汇编源文件,然后分别有C51 及A51 编辑器编译连接生成单片机可执行的二进制文件(.HEX),然后通过单片机的烧写软件将HEX 文件烧入单片机内。软件主要三个方面:一是初始化系统;二是按键检测;三是数据采集、数据处理并进行显示。这三个方面的操作分别在主程序中来进行。程序采用模块化的结构,这样程序结构清楚,易编程和易读性好,也便于调试和修改。

4.1系统主程序软件流程图
系统软件部分主程序流程图如图20所示。
图20 系统主程序流程图
4.2系统显示部分流程图
显示子程序主要是来判断是否需要显示,以及如何去显示,也是十分重要的程序之一。设计流程图如图21所示。

图21 系统显示部分流程图
4.3系统按键检测部分流程图
键盘电路设计成4X4矩阵式,在程序中可以先判断按键编码,然后根据编码将键盘代表的数值送到相应的存储单元,再进行功能选择或数据处理。设计流程图如图22所示。
图22 按键检测部分流程图
5 系统整体调试
5.1硬件电路调试中遇到的问题
1、电子电路的设计中对各种影响因素的考虑不够完全,比如在对过电压情况的处理中未作防范措施。
2、系统设计不够优化,有待改善。比如系统的超量程信号直接由单片机送入报警电路,没有设计保护电路再入单片机处理后送入报警电路。
3、没有扩展更多电路,如温度显示功能,通讯接口电路与上位机(PC机)进行通讯,上位机显示功能从而将大量的商品数据存于上位机,然后通过串口或并口通讯与电子称相连,达到远距离控制的目的。
4、对各种实用芯片价格了解不够,选择上任有欠缺,如所选的称重传感器价格较贵。
这些都为我今后的学习和工作留下了积极的影响。
5.2系统实物调试效果图

经过不懈的努力和导师的细心指导,实物最终得以调试成功,最终完成的实物效果图如图23所示。

   


     
图23 效果图

5.3系统设计总结

在此毕业设计过程中,巩固了我在大学4年内学过的知识,尤其是单片机和C语言编程方面的知识,同时通过这次毕设提高了单片机编程的能力,尤其是获得的软件调试经验,同时了解到了其它相关领域的知识,对今后的工作学习有着极大的帮助。

由于时间太仓促,经验不足,理论方面也相应的存在不足,加上条件有限,仍存在着一些设计方面的问题,个人技能也有待提高。理论知识还要巩固加强。但是宝贵的实践经验还是对自己的提高有着极大的帮助。


附录
附录1系统整体电路图




致 谢
该电子秤控制系统的设计及论文的撰写是在我的导师老师的精心指导和悉心关怀下完成的,从论文的选题、研究、撰写到定稿,都得到了?老师细心指导。他宽厚待人,对学生关怀备至,在工作上精益求精,对学生严格要求,鼓励学生学以致用,敢于实践,勇于创新,在实践中发现问题、解决问题。?老师具有丰富的科研经验与理论水平,其开明的学术思想、求实的科研作风和对科学研究及发展趋势的深刻认识给我以极大的影响、启迪和熏陶,令我受益匪浅。该设计及论文的圆满完成是和?老师的细心关怀分不开的。
在系统的设计和论文的研究工作中无不倾注着各位老师的心血和辛勤的汗水,各位老师严谨的治学态度、渊博的知识、生动而满富激情的授课方式,让我四年里学到了扎实的理论知识。从各位尊敬的老师身上,我不仅学到了扎实的专业知识和丰富的实践技能,也学到了很多做人的道理。在此,向给予我指导和帮助的各位老师致以最衷心的感谢和深深的敬意!
在这四年多的学习和研究工作中,也得到了学院的师兄弟们的关心和热心帮助,在此向他们表示由衷的感谢!
最后,衷心感谢在百忙中评阅论文和参加答辩的各位专家、教授和同学!


单片机源码:


  1. <font color="rgb(0, 0, 0)">#include "main.h"
  2. #include "LCD1602.h"
  3. #include "HX711.h"

  4. unsigned long HX711_Buffer = 0;
  5. unsigned long Weight_Maopi = 0,Weight_Shiwu = 0;
  6. char Price_Count = 0;
  7. unsigned char KEY_NUM = 0;
  8. unsigned char Price_Buffer[3] = {0x00,0x00,0x00};
  9. unsigned long Money = 0;
  10. bit Flag_OK = 0;

  11. //****************************************************
  12. //主函数
  13. //****************************************************
  14. void main()
  15. {
  16.               char k = 10 ;
  17.               Init_LCD1602();                                                                                                                              //初始化LCD1602

  18.               LCD1602_write_com(0x80);                                                                                    //指针设置
  19.               LCD1602_write_word(" Hello Welcome");                                          //开机画面第一行
  20.               Delay_ms(800);                            //延时1s
  21.               LCD1602_write_com(0x80+0x40);                                                        //指针设置
  22.               LCD1602_write_word("        ");

  23.               Get_Maopi();                                                        //称毛皮重量
  24.               Delay_ms(1000);                            //延时1s
  25.   Init_LCD1602();                                                                                                                              //初始化LCD1602 消除之前的显示内容

  26. loop:Price_Count = 0;
  27.               Price_Buffer[0] = 0;
  28.               Price_Buffer[1] = 0;
  29.               Price_Buffer[2] = 0;
  30.               Flag_OK = 0;

  31.               LCD1602_write_com(0x80);                                                                                    //指针设置
  32.               LCD1602_write_word("    W:     Kg");
  33.             
  34.               LCD1602_write_com(0x80+0x40);                                                        //指针
  35.               LCD1602_write_word("P:  .   Z:     ");

  36.   LCD1602_write_com(0x80+0x40+6);                                                        //指针
  37.               LCD1602_write_data(0x5c);

  38.               LCD1602_write_com(0x80+0x40+15);                                                        //指针
  39.               LCD1602_write_data(0x5c);

  40.             
  41.               Get_Maopi();                                                        //称毛皮重量

  42.               while(1)
  43.               {
  44.                             if( Flag_OK == 0)
  45.                             {
  46.                                           if( k == 0)
  47.                                                         Get_Weight();                                          //称重
  48.                                           k--;
  49.                                           if( k < 0)
  50.                                           {
  51.                                                         k = 10;
  52.                                           }
  53.             
  54.                                           //显示当前重量
  55.                                           LCD1602_write_com(0x86);
  56.                                           LCD1602_write_data(Weight_Shiwu/1000 + 0x30);
  57.                                           LCD1602_write_data('.');
  58.                                           LCD1602_write_data(Weight_Shiwu%1000/100 + 0x30);
  59.                                           LCD1602_write_data(Weight_Shiwu%100/10 + 0x30);
  60.                                           LCD1602_write_data(Weight_Shiwu%10 + 0x30);
  61.                             }

  62.                             KEY_NUM = KEY_Scan();

  63.                             if( KEY_NUM != 0x55)                                          //当返回的不是初值时候,确认按键按下。
  64.                             {
  65.                                           if(KEY_NUM == 16)                                          //数字A键,去皮功能
  66.                                           {
  67.                                                         Get_Maopi();                                          //去皮            
  68.                                           }

  69.                                           if(KEY_NUM == 15)                                          //数字B键清除键,二次测量
  70.                                           {
  71.                                                         goto loop;            
  72.                                           }

  73.                                           if(KEY_NUM == 12)                                          //数字C输入单价错误时返回上一步
  74.                                           {
  75.                                                         Price_Count--;
  76.                                                         if( Price_Count < 0)
  77.                                                         {
  78.                                                                       Price_Count = 0;
  79.                                                         }
  80.                                                       
  81.                                                         Price_Buffer[Price_Count] = 0;                                             //清除上一个输入的数据

  82.                                                         switch(Price_Count)
  83.                                                         {
  84.                                                                       case 0:
  85.                                                                                                   LCD1602_write_com(0x80+0x40+2);
  86.                                                                                                   LCD1602_write_data(' ');
  87.                                                                                                   break;
  88.                                                                       case 1:
  89.                                                                                                   LCD1602_write_com(0x80+0x40+3);
  90.                                                                                                   LCD1602_write_data(' ');
  91.                                                                                                   break;
  92.                                                                       case 2:
  93.                                                                                                   LCD1602_write_com(0x80+0x40+5);
  94.                                                                                                   LCD1602_write_data(' ');
  95.                                                                                                   break;
  96.                                                                       default : break;
  97.                                                         }            
  98.                                           }

  99.                                           if(KEY_NUM == 13)                                          //数字D键,计算总价
  100.                                           {
  101.                                                         Money = Price_Buffer[0] * 100 + Price_Buffer[1] * 10 + Price_Buffer[2];            
  102.                                                         Money = Money * Weight_Shiwu / 1000;
  103.                                                         LCD1602_write_com(0x80+0x40+10);
  104.                                                         LCD1602_write_data(Money/1000 + 0x30);                                         
  105.                                                         LCD1602_write_data(Money%1000/100 + 0x30);
  106.                                                         LCD1602_write_data(Money%100/10 + 0x30);
  107.                                                         LCD1602_write_data('.');
  108.                                                         LCD1602_write_data(Money%10 + 0x30);
  109.                                                       
  110.                                                         Flag_OK = 1;                                                                     
  111.                                           }

  112.                                           if(KEY_NUM >= 0 && KEY_NUM <= 9)                                                                        //显示输入的价格值
  113.                                           {
  114.                                                         Price_Buffer[Price_Count] = KEY_NUM;
  115.                   
  116.                                                       
  117.                                                         switch(Price_Count)
  118.                                                         {
  119.                                                                       LCD1602_write_com(0x80+0x40);                                                        //指针
  120.                        LCD1602_write_word("P:  .   Z:     ");
  121.                                                                      
  122.                                                                       case 0:
  123.                                                                                                   LCD1602_write_com(0x80+0x40+2);
  124.                                                                                                   LCD1602_write_data(Price_Buffer[0] + 0x30);
  125.                                                                                                   break;
  126.                                                                       case 1:
  127.                                                                                                   LCD1602_write_com(0x80+0x40+3);
  128.                                                                                                   LCD1602_write_data(Price_Buffer[1] + 0x30);
  129.                                                                                                   break;
  130.                                                                       case 2:
  131.                                                                                                   LCD1602_write_com(0x80+0x40+5);
  132.                                                                                                   LCD1602_write_data(Price_Buffer[2] + 0x30);
  133.                                                                                                   break;
  134.                                                                       default : break;
  135.                                                         }
  136.             
  137.                                                         Price_Count++;
  138.             
  139.                                                         if( Price_Count >= 3)
  140.                                                         {
  141.                                                                       Price_Count = 3;
  142.                                                         }
  143.                                           }

  144.                             }

  145.               }
  146. }

  147. //****************************************************
  148. //矩阵键盘扫描
  149. //****************************************************
  150. unsigned char KEY_Scan()
  151. {
  152.               unsigned char temp = 0;
  153.               unsigned char com = 0x55 , com1 = 0 , com2 = 0;
  154.               P3=0xf0;
  155.               if(P3!=0xf0)
  156.               {
  157.                             com1=P3;
  158.                             P3=0x0f;
  159.                             com2=P3;      
  160.               }
  161.               P3=0xf0;
  162.     while(P3!=0xf0);               
  163.               temp=com1|com2;
  164.               if(temp==0xee)com=1;//数字1
  165.               if(temp==0xed)com=4;//数字4
  166.               if(temp==0xeb)com=7;//数字7
  167.               if(temp==0xe7)com=11;//备用键*号键
  168.               if(temp==0xd7)com=0;//数字0
  169.               if(temp==0xb7)com=14;//备用键*号键
  170.             

  171.               if(temp==0xde)com=2; //数字2
  172.               if(temp==0xdd)com=5; //数字5
  173.               if(temp==0xdb)com=8;//数字8

  174.               if(temp==0xbe)com=3;//数字3
  175.               if(temp==0xbd)com=6; //数字6
  176.               if(temp==0xbb)com=9;//数字9

  177.               if(temp==0x7e)com=16;//数字A键,去皮功能            
  178.               if(temp==0x7d)com=15;//数字B键清除键,二次测量
  179.               if(temp==0x7b)com=12;//数字C输入单价错误时返回上一步
  180.               if(temp==0x77)com=13;//数字D键,计算总价            
  181.               return(com);
  182. }

  183. //****************************************************
  184. //称重
  185. //****************************************************
  186. void Get_Weight()
  187. {
  188.               HX711_Buffer = HX711_Read();
  189.               HX711_Buffer = HX711_Buffer/100;
  190.               if(HX711_Buffer > Weight_Maopi)                                         
  191.               {
  192.                             Weight_Shiwu = HX711_Buffer;
  193.                             Weight_Shiwu = Weight_Shiwu - Weight_Maopi;                                                        //获取实物的AD采样数值。
  194.             
  195.                             Weight_Shiwu = (unsigned int)((float)Weight_Shiwu/4.40+0.05);               //计算实物的实际重量
  196.                                                                                                                                                                                                                                                             //因为不同的传感器特性曲线不一样,因此,每一个传感器需要矫正这里的4.30这个除数。
  197.                                                                                                                                                                                                                                                             //当发现测试出来的重量偏大时,增加该数值。
  198.                                                                                                                                                                                                                                                             //如果测试出来的重量偏小时,减小改数值。
  199.                                                                                                                                                                                                                                                             //该数值一般在4.0-5.0之间。因传感器不同而定。
  200.                                                                                                                                                                                                                                                             //+0.05是为了四舍五入百分位
  201.                             Buzzer = 1;                                                        //关闭警报
  202.               }
  203. //              else if(HX711_Buffer < Weight_Maopi - 30)
  204. //              {
  205. //                            Buzzer = 0;                                                        //负重量报警
  206. //              }
  207. //              else if(HX711_Buffer > Weight_Maopi + 24970)                            //大于5Kg的最大量程,报警            
  208. //              {
  209. //                            Buzzer = 0;
  210. //              }

  211.               if(Weight_Shiwu > 5000 || HX711_Buffer < Weight_Maopi - 30)
  212.               {
  213.                             Buzzer = 0;            
  214.               }
  215.               else
  216.               {
  217.                             Buzzer = 1;
  218.               }

  219.             
  220. }

  221. //****************************************************
  222. //获取毛皮重量
  223. //****************************************************
  224. void Get_Maopi()
  225. {
  226.               HX711_Buffer = HX711_Read();
  227.               Weight_Maopi = HX711_Buffer/100;                           
  228. }

  229. //****************************************************
  230. //MS延时函数(12M晶振下测试)
  231. //****************************************************
  232. void Delay_ms(unsigned int n)
  233. {
  234.               unsigned int  i,j;
  235.               for(i=0;i<n;i++)
  236.                             for(j=0;j<123;j++);
  237. }</font>
复制代码



完整的Word格式文档51黑下载地址:

基于单片机的电子称设计.doc (2.4 MB, 下载次数: 27)



评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

举报

沙发
ID:370073 发表于 2018-7-12 21:07 | 只看该作者
好资料
回复

举报

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

本版积分规则

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

Powered by 单片机教程网

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