小巧电子秤课程设计.docx
《小巧电子秤课程设计.docx》由会员分享,可在线阅读,更多相关《小巧电子秤课程设计.docx(29页珍藏版)》请在冰点文库上搜索。
![小巧电子秤课程设计.docx](https://file1.bingdoc.com/fileroot1/2023-5/1/b94f9e78-f9d0-4151-bf43-40b20510c2cc/b94f9e78-f9d0-4151-bf43-40b20510c2cc1.gif)
小巧电子秤课程设计
烟台南山学院
单片机课程设计
题目小巧智能电子称
姓名:
所在学院:
烟台南山学院
所学专业:
自动化
班级:
学号:
指导教师:
完成时间:
2012-9-6
摘要
电子秤是利用物体的重力作用来确定物体质量(重量)的测量仪器,也可用来确定与质量相关的其它量大小、参数或特性。
本文所设计的电子秤由三大部分组成:
承重、传力复位系统;称重传感器;测量显示和数据输出的载荷测量装置。
本系统的设计思路是:
利用电阻应变式传感器采集当前物重压力,利用全桥四壁电桥电路测量转换压力信号,利用专用仪表INA126放大器放大传感器输出的微弱模拟信号,利用A/D转换器ADC0808把模拟信号转变成数字信号,进行模数转换,然后把数字信号输送到单片机中,单片机根据测量转换电路输出电压和标准重量的线性关系所建立的数学模型计算相应的重量传送到显示电路中去,由显示LED电路根据输入单价,准确计算出物品的金额,同时把重量、金额显示到LED上,它可以分析压力过量程,并发出超重(过载)提示。
1绪论
1.1电子秤的概述
电子秤的发展过程与其它事物一样,也经历了由简单到复杂,由粗糙到精密、由机械到机电结合再到全电子化、由单一功能到多功能的过程。
特别是近30年以来,工艺流程中的现场称重、配料定量称重、以及产品质量的监测等工作,都离不开能输出电信号的电子衡器。
这是由于电子衡器不仅能给出质量或重量信号,而且也能作为总系统中的一个单元承担着控制和检验功能,从而推进工业生产和贸易交往的自动化和合理化。
近年来,电子秤已愈来愈多地参与到数据处理和过程控制中。
现代称重技术和数据系统已经成为工艺技术、储运技术、预包装技术、收货业务及商业销售领域中不可缺少的组成部分。
随着称重传感器各项性能的不断突破,为电子秤的发展奠定了其础,国外如美国、西欧等一些国家在20世纪60年代就出现了0.1%称量准确度的电子秤,并在70年代中期约对75%的机械秤进行了机电结合式的电子化改造。
称重装置不仪是提供重量数据的单体仪表,而且作为工业控制系统和商业管理系统的一个组成部分,推进了工业生产的自动化和管理的现代化,它起到了缩短作业时间、改善操作条件、降低能源和材料的消耗、提高产品质量以及加强企业管理、改善经营管理等多方面的作用。
称重装置的应用已遍及到围民经济各领域,取得了显著的经济效益。
因此,称重技术的研究和衡器工业的发展各国都非常重视。
50年代中期电子技术的渗入推动了衡器制造业的发展。
60年代初期出现机电结合式电了衡器以来,经过40多年的不断改进与完善,我国电子衡器从最初的机电结合型发展到现在的全电子型和数字智能型。
现今电子衡器制造技术及应用得到了新发展。
电子称重技术从静态称重向动态称重发展:
计量方法从模拟测量向数字测量发展;测量特点从单参数测量向多参数测量发展,特别是对快速称重和动态称重的研究与应用。
通过分析近年来电子衡器产品的发展情况及国内外市场的需求,电子衡器总的发展趋势是小型化、模块化、集成化、智能化;其技术性能趋向是速率高、准确度高、稳定性高、可靠性高;其功能趋向是称重计量的控制信息和非控制信息并重的“智能化”功能;其应用性能趋向于综合性和组合性。
电子秤是电了衡器中的一种,衡器是国家法定计量器具,是围计民生、国防建设、科学研究、内外贸易不可缺少的计量设备,衡器产品技术水平的高低,将直接影响各行各业的现代化水平和社会经济效益的提高。
1.2设计目的
单片机以其功能强,体积小,功耗低,易开发等很多优势被广泛应用。
但单片机不是万能的,也存在不适合的场合,我们要充分利用单片机的内部资源和选择合适的单片机来完成我们的设计。
本数字电子秤的设计过程中需要用到A/D转换、键盘、液晶显示、复位电路和蜂鸣器报警驱动电路的知识,同时在软件的设计过程中需要用到键盘扫描、液晶显示驱动、模数转换程序及汉字库的的设计,可以很好的将数电、模电、单片机知识进行综合应用。
在综合应用中进一步熟悉单片机设计的开发各个流程,最终达到"巩固基础、注重设计、培养技能、追求创新、走向实用"的目的。
2方案论证及选择
2.1输入模块
接口电路方案一:
采用独立式按键作为输入模块,其特点:
直接用I/O口构成单个按键电路,配置灵活、软件结构简单,但是当键数较多时,占用I/O口较多;
方案二:
采用矩阵式键盘作为输入电路,其特点:
电路和软件稍复杂,但相比之下,当键数越多时越节约I/O口。
本设计使用键盘输入价格值,若采用独立按键,对数值进行递增递减需频繁按键,为软件设计增加负担,且操作界面不友好。
若采用矩阵式按键,可以方便地输入一个价格值,节约了宝贵的I/O口资源。
通过对比,故采用方案二作为系统输入模块。
2.2显示模块
方案一:
用LCD显示,液晶显示屏具有低耗电量,无辐射危险,以及影像不闪烁等优势,可视面积大,画面效果好,分辨率高,抗干扰能力强等特点。
方案二:
采用LED数码管并行动态显示,电路简单,同样的功率驱动下,显示亮度不及静态显示,且占用I/O口较多。
综上所述,我们采用方案一使用了1602型号的的LCD进行显示,能显示出更多的重量值以及显示更大的总额从而扩大了称量范围。
图1基于单片机的实用电子秤组成框图
3系统硬件及功能
3.1单片机控制电路功能及介绍
本设计中单片机控制电路是由AT89C51组成,它是一个低功耗,高性能CMOS8位单片机,片内含4kBytesISP(In-systemprogrammable)的可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISPFlash存储单元,功能强大的微型计算机的AT89C51可为许多嵌入式控制应用系统提供高性价比的解决方案。
AT89C51具有如下特点:
40个引脚,4kBytesFlash片内程序存储器,128bytes的随机存取数据存储器(RAM),32个外部双向输入/输出(I/O)口,5个中断优先级2层中断嵌套中断,2个16位可编程定时计数器,2个全双工串行通信口,看门狗(WDT)电路,片内时钟振荡器。
图2AT89C51单片机引脚图
此外,AT89C51设计和配置了振荡频率可为0Hz并可通过软件设置省电模式。
空闲模式下,CPU暂停工作,而RAM定时计数器,串行口,外中断系统可继续工作,掉电模式冻结振荡器而保存RAM的数据,停止芯片其它功能直至外中断激活或硬件复位。
同时该芯片还具有PDIP、TQFP和PLCC等三种封装形式,以适应不同产品的需求。
3.2A/D转换
8位A/D精度:
10Kg/1204=2.44g
考虑到其他部分所带来的干扰,12位A/D无法满足系统精度要求。
所以我们需要选择14位或者精度更高的A/D。
方案一、逐次逼近型A/D转换器,如:
ADS7805、ADS7804等。
逐次逼近型A/D转换,一般具有采样/保持功能。
采样频率高,功耗比较低,是理想的高速、高精度、省电型A/D转换器件。
高精度逐次逼近型A/D转换器一般都带有内部基准源和内部时钟,基于89C52构成的系统设计时仅需要外接几个电阻、电容。
但考虑到所转换的信号为一慢变信号,逐次逼近型A/D转换器的快速的优点不能很好的发挥,且根据系统的要求,14位AD足以满足精度要求,太高的精度就反而浪费了系统资源。
所以此方案并不是理想的选择。
方案二、双积分型A/D转换器:
如:
ICL7135、ICL7109ADC0808等。
双积分型A/D转换器精度高,但速度较慢(如:
ICL7135),具有精确的差分输入,输入阻抗高,可自动调零,超量程信号,全部输出于TTL电平兼容。
双积分型A/D转换器具有很强的抗干扰能力。
对正负对称的工频干扰信号积分为零,所以对50HZ的工频干扰抑制能力较强,对高于工频干扰(例如噪声电压)已有良好的滤波作用。
只要干扰电压的平均值为零,对输出就不产生影响。
尤其对本系统,缓慢变化的压力信号,很容易受到工频信号的影响。
故而采用双积分型A/D转换器可大大降低对滤波电路的要求。
图3ADC0808引脚图
作为电子秤,系统对AD的转换速度要求并不高,精度上8位的AD足以满足要求。
另外双积分型A/D转换器较强的抗干扰能力,和精确的差分输入,低廉的价格。
综合的分析其优点和缺点,我们最终选择了ADC0808。
3.33×4键盘
3×4键盘采用扫描技术进行识别,处值是七个端口都是高电平,对各行进行扫描时,先令第一列全是低电平,若第一列为低电平就表示一行一列为选中即有键按下,若第二行为低电平即二行一列为选中即有键按下,以此类推就可以对所有的见进行编码了。
图4键盘
3.4LCD显示
1602型号的的LCD是能够显示16列2行的液晶显示器,功率小显示面积大。
图5LCD1602
1602采用标准的16脚接口,其中:
第1脚:
VSS为地电源。
第2脚:
VDD接5V正电源。
第3脚:
VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
第4脚:
RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:
R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
第6脚:
E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:
D0~D7为8位双向数据线。
第15脚:
背光源正极。
第16脚:
背光源负极。
表1
控制命令表:
1
清显示
0
0
0
0
0
0
0
0
0
1
2
光标返回
0
0
0
0
0
0
0
0
1
*
3
置输入模式
0
0
0
0
0
0
0
1
I/D
S
4
显示开/关控制
0
0
0
0
0
0
1
D
C
B
5
光标或字符移位
0
0
0
0
0
1
S/C
R/L
*
*
6
置功能
0
0
0
0
1
DL
N
F
*
*
7
置字符发生存贮器地址
0
0
0
1
字符发生存贮器地址
8
置数据存贮器地址
0
0
1
显示数据存贮器地址
9
读忙标志或地址
0
1
BF
计数器地址
10
写数到CGRAM或DDRAM)
1
0
要写的数据内容
11
从CGRAM或DDRAM读数
1
1
读出的数据内容
4软件系统设计
4.1数据采集子程序
数据处理子程序是整个程序的核心。
主要用来调整输入值系数,使输出满足量程要求。
另外完成A/D的采样结果从十六进制数向十进制数形式转化。
在硬件调试过程中重量与电压的关系如表2所示:
表2称重与转换电压的关系
重量
0.02
0.04
0.06
0.08
0.10
电压
0.145
0.300
0.445
0.593
0.742
重量
0.12
0.14
0.16
0.18
0.20
电压
0.890
1.040
1.189
1.337
1.486
重量
0.22
0.0.24
0.26
0.28
0.30
电压
1.635
1.784
1.932
2.081
2.230
重量
0.32
0.34
0.36
0.38
0.40
电压
2.378
2.527
2.676
2.826
2.973
重量
0.42
0.44
0.46
0.48
0.50
电压
3.121
3.270
3.419
3.568
3.717
利用MATLAB软件编程,得拟合函数为:
式中
——物体所受的重量;
——传感器输出的压力值
(其中
=7.3458
=-0.0012)
数据处理过程是对A/D转换结果的数字量的处理,即
式中
——数据的模拟量;
——数据的数字量
再对
和
进行十进制与十六进制的转换
=(
)
所以在编程中实际的运算过程为
据最小二乘法得到拟合图形如下图6所示
图6称重与电压的拟曲线
具体程序流程图如图7所示
图7数据采集程序流程图
4.2显示子程序
显示程序是用来实时显示所测质量值,该部分程序是将显缓单元数据进行实时显示,其流程图如图8所示。
图8显示子程序流程图
4.3系统主程序
图9主程序框图
5仿真结果
5.1当输入不超出位时
图10
5.2当输入超出位时
图11
6总结与体会
这次课程设计是对前面所学知识非常系统全面的一次检验。
通过这次课程设计与仿真,让我更明确的了解了一些芯片的用途功能,也熟练了对它们的运用。
在这个设计的过程中,我需要不断地思考,不断地请教,不断地寻找资料以借鉴,不断的用对知识的深入掌握去解决设计中存在的一些问题和调试时出现的一些故障。
虽然说这样的设计很难很烦很累人,但是确实是充实的,是让人感到有意义的。
这次课程设计,不但让我了解了一个数字电子秤,更让我收获了专业知识以外的东西,那就是学会了坚信、坚持,同时也磨砺了我的意志和耐心。
真的,作为一个本来对这个专业不是很感兴趣的学生,让我收获了一份从来没有过的成就感。
虽然到现在我对这个设计的部分原理还是不能用很专业的语言讲述出来,但是当我最初做成功这个设计的时候,我有一种说不出的激动,我写下一句话:
“人很怪,上天给予每个人的都是公平的,没有谁没能力去做事,只是在于那个人愿不愿意去做,敢不敢去做,能不能坚持去做!
”是的,这就是我这次课程设计之后最大的收获!
虽然对这个专业依旧不是很感兴趣,但是我还是想通过这份设计报告来建议老师,希望以后能多搞一些像这样很实际的实践课程,我们作为学生,的确需要好的成绩,但更需要用这种对知识非常全面统一的检验来考察自己,证明自己,坚持自己。
7参考文献
1.《手把手教你学单片机》周兴华著北京航空航天出版社2005.4
2.《单片机原理及接口技术》余锡存曹国华著西安电子科技出版社1999.11
3.李朝青.单片机原理及接口技术(简明修订版).杭州:
北京航空航天大学出版社,1998
4. 李广弟.单片机基础[M].北京:
北京航空航天大学出版社,1994
5. 阎石.数字电子技术基础(第三版).北京:
高等教育出版社,1989
6. 廖常初.现场总线概述[J].电工技术,1999.
附录:
源程序
#include
#include"chushi.h"
#include"jianpan.h"
voidmain()
{voidjianpan();
voiddelay2();
OE=0;//定时1开
TMOD=0x02;
TH1=(65536-400)/256;
TL1=(65536-400)%256;
TR1=1;
ET1=1;
EA=1;
ST=1;
ST=0;
Lcd_Init();
while
(1)
{
if(ctrl==0)
{set=!
set;while(ctrl==0);geat=1;t=0;num5=0;}
if(set==1)
{
jianpan();
}
if(EOC==1&&set==0)
{
OE=1;
num1=P3;
delay2();
OE=0;
delay2();
ST=1;
ST=0;
num1=num1*9999/255;
count[0]=num1%10000/1000;
count[1]=num1%1000/100;
count[2]=num1%100/10;
count[3]=num1%10;
max=num1*up;
count[7]=max%10000000/1000000;
count[8]=max%1000000/100000;
count[9]=max%100000/10000;
count[10]=max%10000/1000;
count[11]=max%1000/100;
count[12]=max%100/10;
count[13]=max%10;
DisplayOneChar(0,1,'j');
DisplayOneChar(1,1,'g');
DisplayOneChar(2,1,':
');
DisplayString(6,1,"max:
");
DisplayOneChar(9,1,count[7]+0x30);
DisplayOneChar(10,1,count[8]+0x30);
DisplayOneChar(11,1,count[9]+0x30);
DisplayOneChar(12,1,count[10]+0x30);
DisplayOneChar(13,1,count[11]+0x30);
DisplayOneChar(14,1,count[12]+0x30);
DisplayOneChar(15,1,count[13]+0x30);
DisplayString(0,0,"dj:
");
DisplayOneChar(3,0,count[0]+0x30);
DisplayOneChar(4,0,count[1]+0x30);
DisplayOneChar(5,0,count[2]+0x30);
DisplayOneChar(6,0,count[3]+0x30);
}
}
}
voiddelay2()
{unsignedchari,j,k;
for(k=2;k>0;k--)
for(i=2;i>0;i--)
for(j=248;j>0;j--);
}
voidLcd_Init(void);
voidLcd_WriteCmd(unsignedcharTempData,unsignedcharBuysC);
voidLcd_WriteData(unsignedcharTempData);
voidLcd_ReadStatus(void);
//unsignedcharLcd_ReadData(void);
voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData);
voidDisplayString(unsignedcharX,unsignedcharY,unsignedchar*DData);
voidDelay(unsignedintdelaytime);
voidLcd_WriteData(unsignedcharTempData)
{
Lcd_ReadStatus();
Lcd_Data=TempData;
Lcd_RS=1;
Lcd_RW=0;
Lcd_E=0;
Lcd_E=0;
Lcd_E=1;
}
//写指令
voidLcd_WriteCmd(unsignedcharTempData,unsignedcharBuysC)
{
if(BuysC)Lcd_ReadStatus();
Lcd_Data=TempData;
Lcd_RS=0;
Lcd_RW=0;
Lcd_E=0;
Lcd_E=0;
Lcd_E=1;
}
//读数据
/*unsignedcharLcd_ReadData(void)
{
Lcd_RS=1;
Lcd_RW=1;
Lcd_E=0;
Lcd_E=0;
Lcd_E=0;
Lcd_E=0;
Lcd_E=1;
return(Lcd_Data);
}*/
voidLcd_ReadStatus(void)
{
Delay(500);
}
voidLcd_Init(void)//LCM初始化
{
Lcd_Data=0;
Lcd_WriteCmd(0x38,0);//三次显示模式设置,不检测忙信号
Delay(6000);
Lcd_WriteCmd(0x38,0);
Delay(6000);
Lcd_WriteCmd(0x38,0);
Delay(6000);
Lcd_WriteCmd(0x38,1);//显示模式设置,开始要求每次检测忙信号
Lcd_WriteCmd(0x08,1);//关闭显示
Lcd_WriteCmd(0x01,1);//显示清屏
Lcd_WriteCmd(0x06,1);//显示光标移动设置
Lcd_WriteCmd(0x0C,1);//显示开及光标设置
}
//按指定位置显示一个字符
voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData)
{
Y&=0x1;
X&=0xF;//限制X不能大于15,Y不能大于1
if(Y)X|=0x40;//当要显示第二行时地址码+0x40;
X|=0x80;//算出指令码
Lcd_WriteCmd(X,0);//这里不检测忙信号,发送地址码
Lcd_WriteData(DData);
}
//按指定位置显示一串字符
voidDisplayString(unsignedcharX,unsignedcharY,unsignedchar*DData)
{
unsignedcharListLength;
ListLength=0;
Y&=0x1;
X&=0xF;//限制X不能大于15,Y不能大于1
while(DData[ListLength]!
='\0')//若到达字串尾则退出
{
if(X<=0xF)//X坐标应小于0xF
{
DisplayOneChar(X,Y,DData[ListLength]);//显示单个字符
ListLength++;
X++;
}
}
}
voidDelay(unsignedintdelaytime)
{
while(delaytime--);
}
voidt1(void)interrupt3using0
{
clock1=!
clock1;
TH1=(65536-4000)/256;
TL1=(65536-4000)%256;
}
intcount[20],up=0,down=0;
unsignedchartab1[10]={0x0