资源描述
2023江苏省大学生电子设计竞赛
参赛试题(含题号):D 简易电子秤
摘要
本设计以MSP430单片机为控制核心,设计并实现了一个以电阻应变片为称重传感器的简易电子秤,具有“称重”、“计价”、“去皮”等功能。具体来说,采用自制的电阻应变片称重传感器将砝码重量变化转换为电压信号的变化,并用精密仪用放大器放大信号以及A/D转化,最终将信号送往单片机解决,得到物体重量,同时,该设计还实现了通过按键对电子秤设立单价并计价与“去皮”功能。
关键词:电阻应变片 称重传感器 仪用放大器 简易电子秤
1.方案设计与论证
本设计运用到五个模块,分别是主控芯片模块、HX711AD转换、LCD液晶显示模块、独立按键、称重传感器模块以及蓝牙数据传输(测试专用)。系统方案框图如图1所示。
图1 系统方案框图
1.1主控芯片模块
方案一:采用51单片机,但是51单片机的IO口个数较少,同时解决性能较低,无法满足本设计的工作规定。故我们不采用此方案。
方案二:采用MSP430单片机,该芯片由TI公司生产,它是一种16位超低功耗,具有精简指令集(RISC)的混合信号解决器,将多个不同功能的模拟电路、数字电路模块和微解决器集成在一个芯片上,具有丰富的寻址方式,简洁的 27 条内核指令以及大量的模拟指令;大量的寄存器以及片内数据存储器都可参与多种运算;尚有高效的查表解决指令。该芯片有解决能力强、运算速度快、超低功耗、片内资源丰富、开发环境方便高效的优点。故我们采用此方案。
1.2 A/D转换+仪用放大器模块
方案一:采用MSP430解决器自带的A/D接入口,但是A/D的位数较低,无法适应我们的转换精度。故我们不采用此方案。
方案二:采用ADC0809转换芯片,该芯片是8位逐次逼近式A/D模数转换器,A/D的位数也较低,无法适应我们的转换精度。故我们不采用此方案。
方案三:采用HX711芯片,它是一款专为高精度电子秤而设计的24位A/D转换器芯片,与同类型其它芯片相比,该芯片集成了涉及稳压电源、片内时钟振荡器等其它同类型芯片所需要的外围电路,具有集成度高、响应速度快、抗干扰性强等优点。该芯片的特点是两路可选择差分输入;有片内低噪声可编程放大器,选择增益为128;片内稳压电路可直接向外部传感器和芯片内A/D转换器提供电源;片内时钟振荡器无需任何外接器件,必要时也可使用外接晶振或时钟;上电自动复位电路;数字控制和串口通讯简朴,所有控制由管脚输入,芯片内寄存器无需编程。综合以上所述优点,故我们选择此方案。
1.3 液晶显示模块
液晶显示采用LCD1602液晶屏,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块,它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用。显示的内容为16X2即可以显示两行,每行16个字符液晶模块(显示字符和数字)
1.4独立键盘模块
在计价功能上要用到数字键盘,所以我们自己焊制了4X4独立键盘,可以有16个IO口,IO口较多,比较稳定,可靠性高,各个按键之间不会互相干扰。
1.5 称重传感器模块
我们在材料力学的基础上对悬臂梁进行受力分析来拟定悬臂梁的尺寸,联系工厂进行加工。将4片电阻应变片以全桥电路的形式贴于悬臂梁上,通过测试,自制成功称重传感器。
图2 自制称重传感器实物图
2理论分析与计算
2.1全桥电路分析
图3是直流电桥的基本结构。以电阻R1、R2、R3、R4组成电桥的四个桥臂,在电桥的对角点A、B端接入直流电源Ue作为电桥的激励电源,从另一对角点C、D两端输出电压Uo。使用时,电桥四个桥臂中的一个或多个是阻值随被测量变化的电阻传感器元件,如电阻应变片。电桥的输出电压Uo可通过下式拟定
(1)
图3 直流电桥
图4为全桥接法。工作中四个桥臂阻值都随被测量而变化,即,,,,当,时,电桥输出
(2)
图4 全桥接法
可以看出,电桥的输出电压与激励电压成正比,只是比例系数不同。现定义电桥的灵敏度为
(3)
全桥的灵敏度为,全桥接法可以获得最大的灵敏度。在这里,电阻应变片的阻值即=350。
2.2悬臂梁尺寸分析与计算
题目的规定检测出的砝码变化精度是0.5g,即砝码变化0.5g,相应的通过A/D转换器输出的数字量变化为1,由全桥电路分析可知
(4)
同时
(5)
其中为灵敏度,为正应变。
综合上述两式,得出
(6)
由于采用的是HX711A/D转换器,里面自带128增益,所以
(7)
从A/D转换的分辨率角度考虑可得
(8)
式中=1。由于已知,所以可计算得出,又由于灵敏度=2.08,
最后求出的最小值为2.2×10-10。
由材料力学可知
(9)
式中,为弹性模量,=69KN/mm2
在即横截面上离中性轴最远的各点处,弯曲正应力最大,其值为
(10)
式中为弯矩,为惯性矩。
我们设计了一串数据,最后选出了一组符合题目最小精度规定的数据,再将计算得到的数据代入材料力学的相关公式中进行强度校核,经校核,这组数据满足力学强度规定,保证了悬臂梁的稳定性和可靠性。
图5 悬臂梁尺寸设计图
悬臂梁尺寸设计仿真图见附录图Ⅰ
3电路与程序设计
本设计中的主控芯片用的是MSP430149,由TI公司生产,它是一种16位超低功耗,具有精简指令集(RISC)的混合信号解决器,在设计中起着至关重要的作用,图6是它的电路原理图。
A/D转换器采用的是HX711芯片,是一款专为高精度电子秤而设计的24位A/D转换器芯片,图7是它的电路原理图。
液晶显示采用LCD1602液晶屏,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块,图8是它的电路原理图。
图6 MSP430电路图
图7 HX711电路图
图8 LCD1602电路图
在软件代码实现方面,我们采用基于IAR SYSTEMS的C编译器嵌入式开发软件,支持众多知名半导体公司的微解决器。整体程序按照如下的流程进行:
图9 程序设计流程框图
关键程序代码详见附录程序源码。
4测试方法与测试结果
原始数据通过HX711的A/D转换变为一串十进制数据,通过蓝牙模块,将测得的数据传入电脑,并用Matlab对接受到的数据进行拟合,发现原始数据和重量呈线性关系,拟合出的函数代入程序中进行测试,再根据实际测量情况软件补偿,最终可以达成抱负的称重效果。
测试结果如下:
表1 实验测试结果
砝码质量/g
测量结果/g
相对误差%
5
5.0
0
10
9.9
1%
20
19.9
0.5%
30
30.1
0.33%
50
49.9
0.2%
80
80.2
0.25%
150
150.2
0.13%
200
199.7
0.15%
350
350.4
0.11%
500
500.5
0.1%
5设计总结
本设计以TI公司MSP430F149为核心控制单元,采用自制的电阻应变片称重传感器采集砝码重量变化,并转换为电压信号的变化,用精密仪用放大器放大信号以及A/D转化,最终将信号送往单片机进行解决,得到物体重量,考虑到自制的称重传感器系统的非线性,系统通过单片机对测量结果进行分段比例因子补偿,测试结果显示系统已经很好地实现了线性测量以及优于1%的称重精度。同时,该设计还实现了通过按键对电子秤设立单价,可计算物品金额并实钞票额累加与“去皮”功能,去皮范围不超过100g。在圆满完毕题目规定的同时,本系统还实现了称重超过量程5g时报警的功能,为系统设立了安全保障。
最后,感谢大赛组委会以及为比赛提供众多帮助的TI公司。
附录
图Ⅰ 悬臂梁尺寸设计软件仿真图
图Ⅱ 队员贴电阻应变片
图Ⅲ 指导老师、小组成员合影
图Ⅳ 作品实物图片
程序源码
1.AD转换程序
unsigned long ReadCount(void)
{
unsigned long Count;
unsigned char i;
ADSK_0; //使能AD(PD_SCK 置低)
Count=0;
while(P3IN&0x20); //AD转换未结束则等待,否则开始读取
delay_us(1);
for (i=0;i<24;i++)
{
ADSK_1; //PD_SCK 置高(发送脉冲)
delay_us(10);
Count=Count<<1; //下降沿来时变量Count左移一位,右侧补零
ADSK_0; //PD_SCK 置低
if(P3IN&0x20) Count++;
delay_us(10);
}
ADSK_1;
Count=Count^0x800000; //第25个脉冲下降沿来时,转换数据
delay_us(10);
ADSK_0;
delay_us(10);
return(Count);
}
2.按键检测函数
#include "key.h"
#include "clock.h"
#include "Uart.h"
int num=0;
int GetKey()
{
if((P1IN & BIT0)==0)
{
delay_ms(30); //延时消抖
if((P1IN & BIT0)==0)
{
while((P1IN & BIT0)==0); //等待松开
delay_ms(30);
if((P1IN & BIT0)!=0) //松手检测
{
num=1;
}
}
}
else if((P1IN & BIT1)==0)
{
delay_ms(30); //延时消抖
if((P1IN & BIT1)==0)
{
while((P1IN & BIT1)==0); //等待松开
delay_ms(30);
if((P1IN & BIT1)!=0) //松手检测
{
num=2;
}
}
}
else if((P1IN & BIT2)==0)
{
delay_ms(30); //延时消抖
if((P1IN & BIT2)==0)
{
while((P1IN & BIT2)==0); //等待松开
delay_ms(30);
if((P1IN & BIT2)!=0) //松手检测
{
num=3;
}
}
}
{
while((P2IN & BIT3)==0); //等待松开
delay_ms(30);
if((P2IN & BIT3)!=0) //松手检测
{
num=12;
}
}
}
else if((P2IN & BIT4)==0)
{
delay_ms(30); //延时消抖
if((P2IN & BIT4)==0)
{
while((P2IN & BIT4)==0); //等待松开
delay_ms(30);
if((P2IN & BIT4)!=0) //松手检测
{
num=13;
}
}
}
else if((P2IN & BIT5)==0)
{
delay_ms(30); //延时消抖
if((P2IN & BIT5)==0)
{
while((P2IN & BIT5)==0); //等待松开
delay_ms(30);
if((P2IN & BIT5)!=0) //松手检测
{
num=14;
}
}
}
3.主函数
#include <msp430x14x.h>
#include"Uart.h"
#include"HX711.h"
#include "clock.h"
#include "timer.h"
#include "led.h"
#include "1602.h"
#include "key.h"
#include <stdio.h>
#define threshold 9390000 //有人无人阀值 此处需要根据实际修改,阀值=读取40公斤值的AD值-零点AD值
float temp=0;
//unsigned char PeopleFlag;
//unsigned char buf[20];
int key=20;
float sum=0,price=0,weight=0,error=0,vesweight=0,realweight=0,SUM=0,AVG=0;;
uint qupiflag=0,dotflag=0;
void start_check()
{
uchar i=0;
float SUM=0;
for(i=0;i<50;i++)
{
temp=ReadCount();
weight=temp*4877/10000000-4613;
SUM+=weight;
}
error=SUM/50;
}
void Function1()
{
uchar i=0;
SUM=0;
for(i=0;i<5;i++)
{
temp=ReadCount();
weight=temp*4877/10000000-4613-error;
SUM+=weight;
//SendData(10*weight);
}
AVG=SUM/5;
if(AVG>=200 && AVG<300) AVG=AVG-0.5;
if(AVG>=300 && AVG<400) AVG=AVG-0.8;
if(AVG>=400 && AVG<=500) AVG=AVG-1;
if(AVG>500) AVG=AVG-1.2;
if(qupiflag!=0&&vesweight<=100)
{
realweight=AVG-vesweight;
lcd_result((int)(10*realweight));
}
else
{
lcd_result((int)(10*AVG));
}
}
void Function2()
{
//weight=100;
key=GetKey();
if(key==13) //清除键
{
lcd_sum(0);
sum=0;
}
if (key==14)
{
qupiflag=~qupiflag;
vesweight=AVG;
}
if(key==15)
{
error=error-0.1;
}
if(key==16)
{
error=error+0.1;
}
if(key==12) //单价输入完毕
{
sum+=price*AVG;
// SendData((long int)sum);
lcd_sum((long int)(10*sum));
price=0;
}
if(key>=0 && key<12)
{
if(key==11) //小数点
{
//key=GetKey();
dotflag=1;
}
else
{
if(dotflag==1)
{
price=price+(float)key/10;
dotflag=0;
}
else
{
price=price*10+key;
}
}
}
//SendData((long int)price);
key=20;
//delay_ms(100);
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗
Clock_Init(); //时钟初始化,使用外部8M晶振,MCLK SMCLK
Port_Init(); //HX711端口初始化
UART1_Init(); //串口1初始化9600波特率
lcd_init(); //1602液晶初始化
//TimerInit();//定期器初始化 1S中断一次
start_check();
P6OUT&=~BIT7;
delay_ms(50);
P6OUT|=BIT7;
delay_ms(50); //蜂鸣器响一声表达完毕启动
while(1)
{
Function1();
Function2();
}
}
展开阅读全文