基于STM32单片机电子称重系统设计_最终稿

摘 要

称重技术自古以来便被人们所重视,与我们生活的各个方面息息相关。电子称重技术能够在科学研究、工业生产制造及其他生产和日常生活中得到广泛应用。随着科学技术时代的来临,智能化的仪器已经取代了传统的仪表和控制设备,让我们的传统仪器也有了翻天覆地的发展。给人们的日常生活造成了较大影响,广泛受到老百姓的青睐和热爱。

本系统从硬件电路设计、软件编程调试、实物焊接调试三个部分进行设计。硬件电路主要是以STM32单片机为核心的控制单元实现数据的处理,通过电子称专用24位AD转换芯片HX711对压力式传感器所采集得到的各种模拟量信号进行了模数转换,转换后的数据被发送到单片机上进行信号处理和显示,并使用LCD1602液晶显示屏来对其进行信号处理和显示,达到稳定显示且没有闪烁,采用C语言进行编写,使用keil5 软件作为编译环境,按照原理图进行实物焊接,并下载程序至实物中进行调试,直至完成所设计的目标。

关键词

STM32单片机;电子称重;压力传感器;HX711

  

第1章 绪论

第2章 系统总体方案设计

2.1系统总体方案

2.2系统元器件选型

第3章 系统硬件电路设计

3.1电源电路设计

3.2称重传感器的设计

3.3矩阵按键电路的设计

3.4显示电路的设计

3.5报警电路的设计

3.6原理图绘制

第4章 系统软件设计

4.1系统软件编程环境

4.2系统主函数的设计

4.3按键处理函数设计

4.4称重部分的设计

第5章 系统整体调试

5.1实物焊接

5.2实物检测

5.3实物调试

5.4在调试过程中出现的问题

5.5实物校准

第6章 总结

致谢

参考文献

附录

第1章 绪论

称重技术自古以来便被人们所重视,和人们的生活密切相关。而电子称重作为新时代的一种新型的称重技术,在人们所需要的地方都影响着人们。电子称是电子衡器其中的一种,衡器产品技术水平的进步,不仅意味着现代化水平也在进步,还能提高国家的经济效益。称重装置的普及不仅经济各个方面,还提高了经济效益。

各种公共场合都能广泛的运用到电子称重系统,电子称重有便于携带、通俗易懂、价格便宜、安全、便于维修等特点,实现重量显示数字化,是杆称不能具有的特点。

电子称重功能的实现,首先压力传感器采集到物体的重量,然后转换成电压信号。但是因为输出电压信号一般比较小,需要通过前端信号处理电路把小信号进行线性放大,放大后的模拟电压信号经过模数转换电路把模拟量转换为数字量,并被送入单片机中,经过单片机控制的译码显示器,然后在液晶显示屏中显示出被测物体的重量。

整个电子称重系统可以分为三个部分:数据采集部分、控制器部分、手动输入部分。数据采集部分由压力传感器、信号的前级处理和模数转换部分组成;将转换后的数字信号送入控制器进行处理,并由控对该数字量的处理;手动输入完成单价输入、去皮、删除等功能。

第2章 系统总体方案设计

2.1系统总体方案

本次电子称重系统由主控核心模块、电源模块、数据采集模块、矩阵键盘模块、液晶显示模块、报警模块组成。物体的重量通过承物板传输到称重传感器,通过使用传感器进行数据采集,进行信号放大,通过模数转化,送进单片机进行处理,再加上按键处理,最后通过LCD显示屏进行显示。系统方案如图2-1所示。

图2-1  系统方案

2.2系统元器件选型

2.2.1单片机

系统选用STM32F103C8T6单片机为主控核心。该单片机的引脚分布图如图2-2所示。

图2-2   芯片引脚图

2.2.2显示器

选用LCD1602液晶屏进行显示,LCD1602引脚说明如表2-1所示。

表2-1 LCD1602字符液晶引脚定义

编号

符号

引脚说明

编号

符号

引脚说明

1

VSS

电源地

9

D2

Data I/O

2

VDD

电源正极

10

D3

Data I/O

3

VL

液晶显示偏压信号

11

D4

Data I/O

4

RS

数据/命令选择器(H/L)

12

D5

Data I/O

4

R/W

读/写选择器(H/L)

13

D6

Data I/O

6

E

使能信号

14

D7

Data I/O

7

D0

Data I/O

15

BLA

背光源正极

8

D1

Data I/O

16

BLK

背光源负极

LCD1602 液晶模块内部存储了 160 个不同的点阵字符图形,包括:阿拉伯数字、英文字母的大小写、常用的符号和日文假名等,它们的代码和标准的ASCII的字符代码相同。实现读写、屏幕和光标的操作需要使用指令编程来完成。

2.2.3 AD转换芯片

此次选用的传感器为HX711,它内部具有24位的具有A/D转换功能的芯片,除此之外,HX71 1还具有许多的优点,例如,测量精度比较高,响应速度非常快,是做电子称重系统的首选之一,其工作电压的范围在2V~5V之间,非常适合和此次的STM32F103芯片相结合。HX711芯片引脚图如图2-3所示

图2-3 HX711芯片引脚图

第3章 系统硬件电路设计

3.1电源电路设计

由于系统中的元件都需要一个稳定的电压,设计一个能够提供稳定电压的电路是必不可少的,虽然STM32F103C8T6自带有USB供电端,但设计的电路能够提供稳定的电压,提高系统的稳定性。电路设计如图3-1所示。

图3-1电源接口电路

供电的部分是由插座和开关构成,外部的电源可以通过电线插入插座,打开开关就能给系统供电。

3.2称重传感器的设计

DT端口与单片机PB8端口进行连接,SCK端口与单片机PB9端口进行连接。通过传感器的DT端口把数据传输到单片机中,单片机采集到数据后,向SCK端口传输高电平信号,传感器停止采集数据。

图3-2 称重模块图

3.3矩阵按键电路的设计

本次按键电路的设计是用来输入单价的,当按键按下时,单片机先将第一行设置为低电平,其他行设置为高电平,当有按键按下时,电平就会发生变化,产生高低电平差,单片机就能根据电平差判断是哪一个按键被按下。选用矩阵键盘的好处是省下引脚,节省空间,避免浪费。由于人按按键的时间会大于扫描按键的时间,所以设计程序时需要进行按键消抖。具体的电路如图3-3所示。

图3-3 矩阵按键电路

按键的功能分别为:

S1-S3、S5-S7、S9-S11、S14按键:数字1-3、4-6、7-9、0

S4按键:删除功能,能够删除一位单价

S8按键:去皮功能,将称盘上的物品清零

S12按键:清零功能,将单价置零

3.4显示电路的设计

使用LCD1602液晶显示屏进行显示,连接图如3-4所示。

 

图3-4 LCD1602连接图

3.5报警电路的设计

蜂鸣器选用有源蜂鸣器,这类蜂鸣器工作的时候需要的电流太大,所以需要使用三极管来进行电流的放大。在蜂鸣器两侧串联一个发光二极管,再添加一个电阻来分压保护发光二极管。基极连接单片机的PB7端口,发射基连接高电平,集电极连接蜂鸣器的高电平端口。当基极端为低电平,三级管导通,集电极为高电平,蜂鸣器发出声响,二极管变亮。当基极端为高电平,三级管截止,集电极为低电平,蜂鸣器无响应,二极管熄灭。报警电路如图3-5所示。

图3-5 报警指示电路

3.6原理图绘制

使用DXP软件绘制原理图。首先需要创建一个文件夹,来保存所制作的原理图,然后在DXP中创建新的PCB项目,再创建原理图,并且保存到先前创建的文件夹中;根据原件清单(附录二),使用软件中自带的元件库,找出对应的软件并使用,如果元件库里没有自己需要用的元件,需要在网上搜索它的引脚图,自己进行创建元件。完成元件放置后,进行导线连接,尽量做到导线不进行交叉。如图3-6所示。方便以后焊接使用。

 

图3-6系统整体电路图

创建元件库的操作:在“文件→创建→库→原理图库”创建一个原理图命名为“jingxinge.SchLib”,然后找到并点击,进入原理图库的设计,然后点击追加,并元件命名为STM32F103C8T6。

首先放置一个矩形,根据对STM32F103C8T6的搜索,知道引脚数量,来放置矩形的大小,再添加引脚,并对每个引脚命名和定义引脚属性。元件图如图3-7所示。

图3-7 STM32F103C8T6元件

第4章 系统软件设计

4.1系统软件编程环境

软件开发环境有Visual C++开发调试系统和Keil uVision开发调试系统,通过对比选择了Keil开发环境。Keil可以兼容C语言和汇编语言,使用此开发环境可以对软件的编写事半功倍。语言选择考虑汇编语言和C语言,C语言与汇编语言相比有简单紧凑、高执行率、较强的移植性等优点,所以选择C语言进行编程。

4.2系统主函数的设计

主函数int main(void)是程序的入口函数,一个完整的程序必需包含这个函数。进入main()主函数时,我们需要对按键引脚、蜂鸣器引脚、HX711引脚、1602液晶显示屏引脚初始化。然后打开蜂鸣器,延时后,关闭蜂鸣器,通过传感器得到的信号,传输到单片机的PB8端口,进入while循环,执行按键程序,如果有按键按下时蜂鸣器发出声响,延时后,蜂鸣器关闭,经过延时后,单片机获得被测物体的重量,如果重量的数值超过设定的数值,则会报警;若没有超出,则会显示物品的重量,计算总价,显示总价。

具体流程图如图4-1所示。

 

图4-1  系统主程序流程图

4.3按键处理函数设计

先设置一个符号key_can=20,然后将行全部设置为低电平,如果有按键按下时,先将第一行设置为低电平,其余行设置为高电平,若有按键按下,进行按键的消抖,确定有按键按下时,如果时第一个按键按下,则设定得到按键值为1;第二个按键按下时,设定得到的按键值为2;第三个按键按下时,设定按键值为3;第四个按键按下时,设定按键值为15。若没有检测到按键按下时,则将第二行设置为低电平,其余行设置为高电平,若有按键按下时,按键进行消抖,确定有按键按下时,如果第一个按键按下,设定得到的按键值为4;第二个按键按下时,设定得到的按键值为5;第三个按键按下时,设定得到的按键值为6;第四个按键按下时,设定得到的按键值为14。若还是没有检查测到是哪个按键按下,则就要将第三行设置为低电平,其它行设置为高电平,若有按键按下时,按键消抖,若第一个按键按下,则得到的按键值为7;第二个按键按下时,设定得到的值为8;第三个按键按下时,设定得到的值为9;第四个按键按下时,得到设定的按键值为13。如果仍然没有检测到按键按下时,将第四行设置为低电平,前三行设置为高电平,若有按键按下,按键消抖,第一个按键按下,得到预先设定的按键值10;第二个按键按下时,得到按键值0;第三个按键按下时,设定按键值11;第四个按键按下,得到按键值12。若检测到的按键值为0~9,则会在显示屏上显示对应的数字;若检测到按键值为15,进行判断,如果单价的值不为零,则单价的数值就会向右移一位,意义是删除一位单价;若检测按键值为14,则会将称盘得到的数据置零;如果检测到了13这个按键值,则价格会清零。到此,键盘扫描完成,输出所按下的按键得到相应的功能。

设计流程图如图4-2所示。

图4-2 按键检测部分流程图

4.4称重部分的设计

将HX711_SCK端口进行配置,设置为推挽输出模式,设置和单片机PB9口配置;将HX711_DOUT端口进行配置,设置为上拉输入模式,和单片机的PB8口配置。

数据采集时,先定义一个数组count,次数i,将DOUT口设置为高电平,延时后,将SCK口置为低电平(该口高电平断电),当脉冲次数小于24时,数据便会一直采集,若脉冲次数大于24时,则SCK高电平,输出保存在数组count中的数据。

获取重量时,得到的重量数值便是count中保存的数值,想要得到去皮后的重量,需要按下“去皮”按键,系统会判断这次的重量是否大于先前储存的重量,如果大于,则会用现在测得的重量减去保存的重量,获得净重量,最后将净重量进行放大,并有LCD进行显示;如果小于,则显示0。

设计流程图如图4-3所示。

图4-3称重部分流程图

第5章 系统整体调试

5.1实物焊接

先对每一个元件进行检查,查看检验型号、数值、耐压和极性是不是合格,如果不合格,需要及时进行更换;把元件的引线刮干净,漏出金属光泽,最后在合适的位置放置元件。在洞洞板的正面放置元件,并从背面进行焊接。焊接时先焊接大元件,然后再把电容电阻等小元件穿插在焊点孔中,尽量排列的整齐好看。采用安装一个元件焊接一个元件的方法进行焊接。用适当的力将烙铁头压在加热的部位。烙铁与洞洞板的夹角在50度左右。焊锡融化适量时,马上从左上45°的方向移开焊锡。距离短的可以用焊锡直接焊接,距离远的可以使用导线进行飞线连接。

将LCD屏的4引脚、5引脚、6引脚分别与STM32F103C8T6单片机的PB10、PB1、PB0焊接;LCD屏的7引脚~14引脚与单片机的PA7-PA0一一对应焊接;在LCD的1引脚和3引脚之间串联一个2K的电阻;LCD屏1引脚、3引脚、16引脚接地,2引脚、15引脚接电源。矩阵键盘排列好后第1列与PB12连接、第2列与PB13连接、第3列与PB14连接、第4列与PB15连接、第1行与PA8连接、第2行与PA11连接、第3行与PA12连接、第4行与PA15连接。

PNP型三极管的发射极e与电源焊接、基极b与单片机的PB7端口焊接、集电极c与蜂鸣器一端焊接;蜂鸣器的两端,分别与集电极c焊接和地焊接;发光二极管和2K电阻串联焊接后,再与蜂鸣器并联焊接。HX711的5引脚与地焊接,3引脚与电源焊接,12引脚与单片机PB8焊接,11引脚与单片机PB9焊接。所有电源焊接,所有地焊接。根据绘制的原理图焊接,如图5-1所示。

图5-1焊接图

5.2实物检测

把万用表调到二极管蜂鸣档的档位,黑红表笔短接会发出“哔”的声音,并且红灯亮起。检查电源和地焊接后有没有短路,再检查所有的电源,所有的地都检查一遍,确保万无一失。测量矩阵键盘每一行每一列分别与对应的I/O口是不是焊接在一起,检测没有连接短路。检测1602显示屏和STM32F103C8T6是否成功焊接。电源和地的电压差进过测量的数值为5.035V。如图5-2所示。

图5-2 电压检测图

5.3实物调试

1.按下电源开关,系统开始工作,液晶屏第一行显示“W:0.000kg”

液晶屏第二行显示“P;00.00¥ Z:00.00”如图5-3所示。

 

图5-3 LCD屏显示

2.在矩阵键盘上进行按键测试,当按下“0~9”十个按键时,显示屏单价一栏会显示所按下的数字,当按下第五个数字时,便会覆盖前面的四个数字。按删除键时,能够删除一位单价;按下去皮键,可以让重量一栏的数值清零;清零键可以清除单价;矩阵键盘如图5-4所示。

图5-4 矩阵键盘

3.在托盘上放置一个物品(测试时使用的充电宝),物品的重量通过传感器采集到的数据,经过转换,被送入到系统中进行数据处理,并利用矩阵键盘输入88.00(单价),最后在LCD显示屏上显示物品重量:0.278KG;单价:88.00¥;总价:24.46¥。测试图如图5-5所示。

图5-5 测试图

5.4在调试过程中出现的问题

没有扩展更多电路,如温度显示、时间显示等功能;在进行校准时,播放音乐或者较大的声响,都会干扰称重数据的准确性,这样会产生误差;测试1g砝码时,检测不到1g砝码的重量;有时会出现称出来的重量与物品本身的重量差距很大。

出现的这些问题都给我留下了深刻的印象,让我在以后的学习和工作之中,让我能够更快的发现它们,并且能够及时的对这些问题进行防范和解决。

5.5实物校准

在承物盘上放置依次放置5g、10g、20g、50g砝码,在LCD显示屏会依次显示的5g、10g、20g、50g数值,如图5-6所示。

图5-6 校准图

第6章 总结

通过这次毕业设计,让我对单片机有了新的认识,熟悉了单片机的系统设计,提高了自己在C语言编程方面的知识。

为了这次设计的完成,我从去年就开始准备,首先构思怎么能把这次设计做好,首先确定使用STM32F103C8T6单片机,然后要绘制原理图,进行程序的编写,最后购买元件进行焊接、调试,直至达到预期的效果。

在设计原理图时,我选用DXP 2004这个软件,在绘制原理图期间,发现元件库之中没有发现自己需要的元件,就需要我自己根据网上的介绍,自己制作所需要的元件,而且添加对应的封装。这让我更加了解了DXP 2004软件的操作。 

然后在代码的编写过程中,使用Keil μVision5这个软件。根据自己所绘制的原理图,编写代码,如:定时器的初始化,端口的初始化,显示屏的初始化等多个方面。这让我对编程更加的了解。最后进行焊接实物,实物进行仿真,校准,直至完成。

经过五个月的学习和研究,完成了硬件电路设计、软件编程调试以及实物的焊接和整体调试,最后能够达到预期所设想的目标。完成这次设计后,我明白了,学习的过程是永无止境的,并不是一朝一夕就能够完成的,需要通过不断地学习新的知识和回忆之前学过的内容,才能的完成本次的毕业设计。

附录

附录1:系统整体电路图

    

附录2:实物图

附录3:元件清单

元件名称

元件型号

元件标号

数量

蜂鸣器

蜂鸣器

B1

1

发光二极管

发光二极管

D1

1

液晶显示器

LCD1602

LCD1

1

DC3.5

电源输入

P1

1

HX711AD模块

Header 4

P2

1

三极管

9012

Q1

1

电阻

2K

R1, R2

2

按键

SW-PB

S1-S16

16

电源开关

电源开关

SW1

1

单片机

STM32

U1

1

附录4:系统部分源程序

#include "stm32f10x.h" //STM32头文件

#include "sys.h"

#include "delay.h"

#include "key.h"

#include "lcd1602.h"





#define beep  PBout(7) //蜂鸣器的定义

  

#define rs  PBout(10)   //寄存器选择信号 H:数据寄存器   L:指令寄存器

#define rw  PBout(1)   //寄存器选择信号 H:数据寄存器   L:指令寄存器

#define e   PBout(0)     //片选信号   下降沿触发



#define HX711_SCK PBout(9)// PB9

#define HX711_DOUT PBin(8)// PB8



extern u8 key_can; //按键用的变量



u16 flag_300ms=1;     //200ms标志位



u32 HX711_Buffer;

u32 Weight_Maopi;



u32 price,z_price;   //单价 总价

u8 flag_p;

u32 weight;

   

float GapValue=2221;





void beep_Init()  //蜂鸣器引脚初始化配置

{



GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);   //开时钟

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;  //定义控制脚

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;   //50M速度

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;  //推挽输出

GPIO_Init(GPIOB,&GPIO_InitStructure);

}



void HX711_Init(void)  //HX711引脚初始化配置

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //使能PF端口时钟



//HX711_SCK

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  // 端口配置

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  //IO口速度为50MHz

GPIO_Init(GPIOB, &GPIO_InitStructure);  //根据设定参数初始化GPIOB



//HX711_DOUT

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//输入上拉

    GPIO_Init(GPIOB, &GPIO_InitStructure);  



GPIO_SetBits(GPIOB,GPIO_Pin_9); //初始化设置为0

}







//****************************************************

//读取HX711

//****************************************************

u32 HX711_Read(void) //增益128

{

unsigned long count;

unsigned char i;

   HX711_DOUT=1;

delay_us(1);

   HX711_SCK=0;

    while(HX711_DOUT);

    for(i=0;i<24;i++)

{

   HX711_SCK=1;

   count=count<<1;

delay_us(1);

HX711_SCK=0;

   if(HX711_DOUT)

count++;

delay_us(1);

}

  HX711_SCK=1;

    count=count^0x80000;//第25个脉冲下降沿来时,转换数据

delay_us(1);

HX711_SCK=0;  

return(count);

}



//****************************************************

// 获取皮重,秤盘重量

//****************************************************

void get_pizhong(void)

{

Weight_Maopi = HX711_Read();

}



//****************************************************

//称重

//****************************************************

void Get_Weight()   //获取被测物体重量

{

HX711_Buffer = HX711_Read();

if(HX711_Buffer > Weight_Maopi)

{

weight = HX711_Buffer;

weight = weight - Weight_Maopi; //获取净重

if(weight > 0)

{

weight = (s32)((float)weight/GapValue+0.05); //计算实物的实际重量

}

else

{

weight = 0;

}

}

}



/************按键控制函数*************/

void key_with()

{

if(key_can <= 9)   //数字键

{

if(flag_p >= 4)

{

flag_p = 0;

}

if(flag_p == 0)

price = key_can;

else

{

price = price * 10 + key_can;    

}    

write_sfm4_price(2,2,price); //显示单价

flag_p ++;

  }

if(key_can == 15)   //删除键

{   

if(price != 0 )

{

flag_p --;

price /= 10;                 //删除

write_sfm4_price(2,2,price);//显示单价

}

}

if(key_can == 14)   //去皮

{

get_pizhong();   //获取皮重,秤盘重量

}

if(key_can == 13)   //价格清零

{

flag_p = 0;

price = 0;

write_sfm4_price(2,2,price);//显示单价

}

}







int main (void){//主程序

RCC_Configuration(); //时钟设置

  KEY_Init();//按键引脚初始化配置

  beep_Init();   //蜂鸣器引脚初始化配置

HX711_Init();  //HX711引脚初始化配置

  lcd1602_Init();  //1602液晶引脚初始化配置

 init_1602(); //   液晶显示初始化

  beep = 0;  

delay_ms(300);

beep = 1;  

get_pizhong();   //获取皮重,秤盘重量

while(1)

{

key();  //按键程序

  if(key_can < 20)

{

  key_with();  

  beep = 0;  //蜂鸣器叫一声

delay_ms(100);

beep = 1;

}

flag_300ms++;

if(flag_300ms >= 300)

{

flag_300ms = 0;  

Get_Weight();   //获取被测物体重量

  if(weight >= 10000)  //超重报警

beep = ~beep;

else

beep = 1;

  write_1602_yl(1,4,weight);       //显示重量

z_price = weight * price / 1000;   //总价等于重量*单价

write_sfm4_price(2,11,z_price); //显示总价

}

delay_ms(1);

}

}

猜你喜欢

转载自blog.csdn.net/qq_58404700/article/details/131382654