基于单片机的智能数字电子秤设计

目录
摘要 III
Abstract IV
第一章 绪 论 1
1.1 称重技术和衡器的发展 1
1.2 电子秤的发展现状和发展趋势 2
1.3 项目研究意义 4
第二章 电子秤的硬件构成 6
2.1 电子秤的构成 6
2.2 称重传感器 6
2.2.1 称重传感器选用时需考虑的问题 7
2.2.2 称重传感器的基本结构 9
2.3 应变式传感器 11
2.3.1 弹性元件 11
2.3.2 应变胶 12
2.3.3 应变片 13
2.3.4 应变式称重传感器的各种补偿 14
2.4 单片机系统 16
2.5 电路设计 18
2.5.1 称重传感器的供桥电源 18
2.5.2 电子秤的调零电路 20
2.5.3 电子秤的数据采集、处理部分 20
2.5.4 键盘/开关输入电路 25
2.5.5 LCD显示器 26
2.5.6 打印部分 28
2.5.7 掉电保护和检测电路、报警电路 29
第三章 仪器软件设计 31
3.1 仪器主程序 31
3.2 中断服务程序 32
第四章 仪器的误差及误差分配 33
4.1 仪器的误差来源 33
4.1.1 称重传感器的误差 33
4.1.2 电子设备的误差 33
4.1.3 机械承重系统的误差 34
4.2 仪器误差分配 35
4.3 仪器误差的计算方法 35
结论 37
参考文献 38
致谢 39
附录 40
本项目研究的便携式电子秤的主要技术指标为:
(1)量程:0~15kg
(2)分度值:0.005kg
(3)误差:±0.005kg
(4)功能:开机自检、去皮、计价、清零、自动休眠、中文液晶显示、
过载报警等;仪器若不进行称重操作,5分钟后自动进入休眠模式,降低电源消耗。
第二章 电子秤的硬件构成
电子秤的测量原理是被称量物体的重量使传感器弹性体发生变形,输出与重量成正比的电信号,传感器输出信号经放大器放大后,输入转换器进行转换,转换成的频率信号直接送入微处理器中,其数字量由微机进行处理,而周边所需要的功能及各种接口电路也和微机连接应用,最后由显示屏幕以数字方式显示。
2.1 电子秤的构成
便携式电子秤硬件系统由应变式称重传感器、放大器、A/D转换器、单片机系统、键盘/开关、LCD显示器、打印机等组成。仪器结构框图如图3.1所示。
图2.1 仪器硬件结构框图
2.2 称重传感器
在电子秤中,传感器是最关键的部件,也是设计中最难处理的环节,其性能的好坏直接决定了电子秤的性能。
现代科学技术的发展,特别是微型计算机技术的普及,及国民经济的发展使各工业领域普遍要求用电子衡器来检测重量信息;电子称重技术由单一的称量用途,延伸到生产过程和工艺流程等过程控制领域,特别是物流中各环节的自动检测和监控。电子衡器用于电子称重,是国家重点管理的6种计量器具之一。称重传感器是电子衡器产品和电子称重系统的核心部件,本文转载自http://www.biyezuopin.vip/onews.asp?id=14836其特性直接影响电子衡器整机的性能。因此,其性能的优劣或质量的高低,对整个称重控制系统起到至关重要的作用。准确度、稳定性和可靠性是称重传感器的重要的质量指标,同时也是用户最关心的问题。
由于电子称重装置的用途、使用场合和精度要求不同,对称重传感器的各项性能指标的要求也不尽相同。一般在选择称重传感器的综合精度(非线性、重复性和滞后三项指标的均方根值)时,以确保电子称重装置能够满足其总误差要求为准,不能片面地追求高精度。在温度变化较大的场合下使用的传感器,应选择合适的工作温度范围,以确保传感器在安装场所的温度条件下仍能正常地工作。

HX711的AD转换代码

#include "HX711.h"


//****************************************************
//延时函数
//****************************************************
void Delay__hx711_us(void)
{
	_nop_();
	_nop_();
}

//****************************************************
//读取HX711
//****************************************************
unsigned long HX711_Read(void)	//增益128
{
	unsigned long count; 
	unsigned char i; 
  	HX711_DOUT=1; 
	Delay__hx711_us();
  	HX711_SCK=0; 
  	count=0; 
  	while(HX711_DOUT); 
  	for(i=0;i<48;i++)
	{ 
	  	HX711_SCK=1; 
	  	count=count<<1; 
		HX711_SCK=0; 
	  	if(HX711_DOUT)
			count++; 
	} 
 	HX711_SCK=1; 
    count=count^0x008000;//第25个脉冲下降沿来时,转换数据
	Delay__hx711_us();
	HX711_SCK=0;  
	return(count);
}


主函数程序

#include 
#include 
#include 
#include "main.h"
#include "HX711.h"
#include "eeprom52.h"

#define uchar unsigned char
#define uint  unsigned int
uchar qianwei,baiwei,gewei,shiwei;
unsigned long HX711_Buffer = 0;
unsigned long Weight_Maopi = 0;
unsigned long Weight_Maopi_0 = 0;
long Weight_Shiwu = 0;
unsigned int qupi=0;
unsigned char p=0;
//键盘处理变量
unsigned char keycode;
unsigned char key_press_num=0;

uint GapValue,GapValue1;
bit flag_cz=0;

//uchar code  LEDData[]={0x5F,0x44,0x9D,0xD4,0xC6,0xD3,0xDB,0x57,0xDF,0xD7,0xCF,0xaA,0x9B,0xDC,0x9B,0x8B}; //数码管显示码表
//定义标识
volatile bit FlagTest = 0;		//定时测试标志,每0.5秒置位,测完清0
volatile bit FlagKeyPress = 0;  //有键按下标志,处理完毕清0
//校准参数
//因为不同的传感器特性曲线不是很一致,因此,每一个传感器需要矫正这里这个参数才能使测量值很准确。
//当发现测试出来的重量偏大时,增加该数值。
//如果测试出来的重量偏小时,减小改数值。
//该值可以为小数
//#define GapValue 349
sbit LED=P1^1;
sbit ROW1=P3^0;
sbit ROW2=P3^1;
sbit ROW3=P3^2;
sbit ROW4=P3^3;
//sbit DIAN = P0^6;        		//小数点
sbit rs=P0^7;
sbit rw=P0^6;
sbit en=P0^5;
sbit D1=P2^0;

volatile bit ClearWeighFlag = 0; //传感器调零标志位,清除0漂

/******************把数据保存到单片机内部eeprom中******************/
void write_eeprom()
{
	SectorErase(0x1080);
	GapValue1=GapValue&0x00ff;
	byte_write(0x1000, GapValue1);
	GapValue1=(GapValue&0xff00)>>8;
	byte_write(0x1001, GapValue1);
	byte_write(0x1060, a_a);	
}

/******************把数据从单片机内部eeprom中读出来*****************/
void read_eeprom()
{
	GapValue   = byte_read(0x1001);
	GapValue   = (GapValue<<8)|byte_read(0x1000);
	a_a      = byte_read(0x1060);
}

/**************开机自检eeprom初始化*****************/
void init_eeprom() 
{
	read_eeprom();		//先读
	if(a_a == 1)		//新的单片机初始单片机内问eeprom
	{
		GapValue  = 3500;
		a_a = 1;
		write_eeprom();	   //保存数据
	}	
}
void delayms(uint xms)		//延时
 {
 	uchar i,j;
	for(i=xms;i>0;i--)
		for(j=110;j>0;j--);
 }
void write_com(uchar com)		 //写命令
 {
 	rs=0;
//	P2=change(com);
	P2=com;
	delayms(50);
	en=1;
	delayms(50);
	en=0;	
 }
 void write_dat(uchar dat)	     //写数据
 {
 	rs=1;
//	P2=change(dat);	 
	P2=dat;
	en=1;
	delayms(50);
	en=0;
 }
 void init()					//液晶初始化
 {
 	rw=0;
	write_com(0x38); 
	write_com(0x0c);  
	write_com(0x06);
	//write_com(0x01);
 }	
/*****显示开机初始化等待画面*****/
/*
void Disp_init(void)    
{
	P0 = 0x80;      //显示----
	P2 = 0xBF;		 //依次打开各位
	Delay_ms(1);		 //延时
	P2 = 0xEF;
	Delay_ms(1);   
	P2 = 0xFB;
	Delay_ms(1);
	P2 = 0xFE;
	Delay_ms(1);
	P2 = 0xFF;         //关闭显示
}
*/
//显示重量,单位kg,两位整数,三位小数
void Display_Weight()
{	 	                                                                                                                                                                                                                                                                                                                           ;
			qianwei=Weight_Shiwu/1000%10;
	 		baiwei=Weight_Shiwu/100%10;                                                                                                                                                                                                                                                                                                                       ;
			shiwei=Weight_Shiwu%100/10;
			gewei=Weight_Shiwu%100%10;
			write_com(0x80+2);

    		write_dat(qianwei+'0');
			write_dat('.');
			write_dat(baiwei+'0');
	 		write_dat(shiwei+'0');	 	
			write_dat(gewei+'0');
		
  
}  

//定时器0初始化
void Timer0_Init()
{
	ET0 = 1;        //允许定时器0中断
	TMOD = 1;       //定时器工作方式选择
	TH0 = 0xb0;     
	TL0 = 0x3c;     //定时器赋予初值
	TR0 = 1;        //启动定时器
}

//定时器0中断
void Timer0_ISR (void) interrupt 1 using 0
{
uchar Counter;
	TH0 = 0xb0;
	TL0 = 0x3c;     //定时器赋予初值

	//每0.5秒钟刷新重量
    Counter ++;
    if (Counter >= 10)
    {
       FlagTest = 1;
	   Counter = 0;
    }
}


//按键响应程序,参数是键值
//返回键值:
//         7          8    9      10(清0)
//         4          5    6      11(删除)
//         1          2    3      12(未定义)
//         14(未定义) 0    15(.)  13(确定价格)

void KeyPress()
{
	if(ROW1==0)   //清零键
	{
		Display_Weight();
		if(ROW1==0)
		{
			if(qupi==0)
			qupi=Weight_Shiwu;
			else
			qupi=0;
			Buzzer=1;
			for(p=0;p<10;p++)
			Display_Weight();
			Buzzer=0;	
			while(ROW1==0) Display_Weight();
		}
	}
	if(ROW2==0)	   //加
	{
		Display_Weight();
		if(ROW2==0)
		{
			while(!ROW2)
			{
				key_press_num++;
				if(key_press_num>=100)
				{
					key_press_num=0;
					while(ROW2)
					{
						if(GapValue<10000)
						GapValue++;
						Buzzer=0;
						for(p=0;p<2;p++)
						Display_Weight();
						Buzzer=1;
						for(p=0;p<2;p++)
						Display_Weight();
						Get_Weight();
					}
				}
				Display_Weight();
				Delay_ms(8);
			}
			if(key_press_num==0)
			{
				key_press_num=0;
				if(GapValue>10000)
				GapValue++;
				Buzzer=0;
				for(p=0;p<10;p++)
				Display_Weight();
				Buzzer=1;
			}
			write_eeprom();		
		}
	}
	if(ROW3==0)  //减
	{
		Display_Weight();
		if(ROW3==0)
		{
			while(ROW3)
			{
				key_press_num++;
				if(key_press_num>=100)
				{
					key_press_num=0;
					while(ROW3)
					{
						if(GapValue>1)
						GapValue--;
						Buzzer=0;
						for(p=0;p<2;p++)
						Display_Weight();
						Buzzer=1;
						for(p=0;p<2;p++)
						Display_Weight();
						Get_Weight();
					}
				}
				Display_Weight();
				Delay_ms(8);
			}
			if(key_press_num!=0)
			{
				key_press_num=0;
				if(GapValue>1)
				GapValue--;
				Buzzer=0;
				for(p=0;p<10;p++)
				Display_Weight();
				Buzzer=1;
			}
			write_eeprom();			   //保存数?
		}
	}
}
//****************************************************
//主函数
//****************************************************
void main()
{	
	init();
	init_eeprom();  //开始初始化保存的数据
   EA = 0;
   Timer0_Init();
   //初中始化完成,开断
   EA = 0;
   write_com(0x80+7);
   	write_dat('K');	 
	write_dat('g');
	while(1)
	{									 //每0.5秒称重一次
		
		if (FlagTest==1)
		{
			Get_Weight();
			FlagTest = 0;
		}
		if(flag_cz==1)
		{
			write_com(0x80+2);
   			write_dat('0');
	   		write_dat('.');
			write_dat('0');
    		write_dat('0');
            write_dat('0');
			write_dat('K');	 
			write_dat('g');
		}
		  
		Display_Weight();	 
		KeyPress();
	}
}
//****************************************************
//称重
//****************************************************
void Get_Weight()
{
	Weight_Shiwu = HX711_Read();
	Weight_Shiwu = Weight_Shiwu - Weight_Maopi;		//获取净重
	
	Weight_Shiwu = (unsigned int)((float)(Weight_Shiwu*10)/GapValue)-qupi; 	//计算实物的实际重量																
	if(Weight_Shiwu <= 10000)		//超重报警
	{
		Buzzer = !Buzzer;	
		LED=!LED;
		flag_cz=0;
	}
	else
	{
		if(Weight_Shiwu==0)
		LED=0;
		else if(Weight_Shiwu>0)
		LED=1; 
		Buzzer = 1;
		flag_cz=0;
	}
}

基于单片机的智能数字电子秤设计_第1张图片
基于单片机的智能数字电子秤设计_第2张图片
基于单片机的智能数字电子秤设计_第3张图片
基于单片机的智能数字电子秤设计_第4张图片
基于单片机的智能数字电子秤设计_第5张图片
基于单片机的智能数字电子秤设计_第6张图片
基于单片机的智能数字电子秤设计_第7张图片
基于单片机的智能数字电子秤设计_第8张图片

你可能感兴趣的:(单片机,嵌入式硬件,智能数字电子秤,电子秤,毕业设计)