基于51单片机智能电子秤方案原理图程序设计

硬件设计

(文末附资料)
在这里插入图片描述
单片机最小系统
对51系列单片机来说,最小系统一般应该包括:单片机、晶振电路、复位电路。下面给出一个51单片机的最小系统电路图。
复位电路:
一、复位电路的用途:单片机复位电路就好比电脑的重启部分,当电脑在使用中出现死机,按下重启按钮电脑内部的程序从头开始执行。单片机也一样,当单片机系统在运行中,受到环境干扰出现程序跑飞的时候,按下复位按钮内部的程序自动从头开始执行。单片机复位电路如下图:
二、复位电路的工作原理在书本上有介绍,51单片机要复位只需要在第9引脚接个高电平持续2US就可以实现,那这个过程是如何实现的呢?在单片机系统中,系统上电启动的时候复位一次,当按键按下的时候系统再次复位,如果释放后再按下,系统还会复位。所以可以通过按键的断开和闭合在运行的系统中控制其复位。

晶振电路:晶振是晶体振荡器的简称 在电气上它可以等效成一个电容和一个电阻并联再串联一个电容的二端网络 电工学上这个网络有两个谐振点 以频率的高低分其中较低的频率是串联谐振 较高的频率是并联谐振 由于晶体自身的特性致使这两个频率的距离相当的接近 在这个极窄的频率范围内 晶振等效为一个电感 所以只要晶振的两端并联上合适的电容它就会组成并联谐振电路 这个并联谐振电路加到一个负反馈电路中就可以构成正弦波振荡电路 由于晶振等效为电感的频率范围很窄 所以即使其他元件的参数变化很大 这个振荡器的频率也不会有很大的变化

P0口的上拉电阻:
P0口作为I/O口输出的时候时 输出低电平为0 输出高电平为高组态(并非5V,相当于
悬空状态)。也就是说P0 口不能真正的输出高电平,给所接的负载提供电流,因此必须接上拉电阻(一电阻连接到VCC),由电源通过这个上拉电阻给负载提供电流。 由于P0口内部没有上拉电阻,是开漏的,不管它的驱动能力多大,相当于它是没有电源的,需要外部的电路提供,绝大多数情况下P0口是必需加上拉电阻的。
1.一般51单片机的P0口在作为地址/数据复用时不接上拉电阻。
2.作为一般的I/O口时用时,由于内部没有上拉电阻,故要接上上拉电阻!!
3.当p0口用来驱动PNP管子的时候,就不需要上拉电阻,因为此时的低电平有效; 4.当P0口用来驱动NPN管子的时候,就需要上拉电阻的,因为此时只有当P0为1时候,才能够使后级端导通。

31脚EA/Vpp接电源:
STC89C51/52或其他51系列兼容单片机特别注意:对于31脚(EA/Vpp),当接高电平时,单片机在复位后从内部ROM的0000H开始执行,当接低电平时,复位后直接从外部ROM的0000H开始执行,这一点是初学者容易忽略的。

程序设计

include <reg52.h>
#include <intrins.h>
#include <string.h>
#include "main.h"
#include "LCD1602.h"
#include "HX711.h"
#include "eeprom52.h"

#define uchar unsigned char
#define uint  unsigned int

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 keycode;
unsigned char key_press_num=0;
uint GapValue,GapValue1;

//定义标识
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;

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

/******************把数据保存到单片机内部eeprom中******************/
void write_eeprom()
{
	SectorErase(0x1000);
	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();	   //保存数据
	}	
}

//显示重量,单位kg,两位整数,三位小数
void Display_Weight()
{
	LCD1602_write_com(0x80+0x40+8);
	if(Weight_Shiwu/10000==0)
	LCD1602_write_data(' ');
	else
	LCD1602_write_data(Weight_Shiwu/10000 + 0x30);
	LCD1602_write_data(Weight_Shiwu%10000/1000 + 0x30);
	LCD1602_write_data('.');
	LCD1602_write_data(Weight_Shiwu%1000/100 + 0x30);
	LCD1602_write_data(Weight_Shiwu%100/10 + 0x30);
	LCD1602_write_data(Weight_Shiwu%10 + 0x30);
}

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

//定时器0中断
void Timer0_ISR (void) interrupt 1 using 0
{
	uchar Counter;
	TL0 = 0xb0;
	TH0 = 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)   //去皮键
	{
		Delay_ms(5);
		if(ROW1==0)
		{
//			Get_Maopi();
			if(qupi==0)
			qupi=Weight_Shiwu;
			else
			qupi=0;
			Buzzer=0;
			Delay_ms(50);
			Buzzer=1;	
			while(ROW1==0);
		}
	}
	if(ROW2==0)	   //加
	{
		Delay_ms(5);
		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;
						Delay_ms(10);
						Buzzer=1;
						Delay_ms(10);
						Get_Weight();
					}
				}
				Delay_ms(10);
			}
			if(key_press_num!=0)
			{
				key_press_num=0;
				if(GapValue<10000)
				GapValue++;
				Buzzer=0;
				Delay_ms(50);
				Buzzer=1;
			}
			write_eeprom();		
		}
	}
	if(ROW3==0)  //减
	{
		Delay_ms(5);
		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;
						Delay_ms(10);
						Buzzer=1;
						Delay_ms(10);
						Get_Weight();
					}
				}
				Delay_ms(10);
			}
			if(key_press_num!=0)
			{
				key_press_num=0;
				if(GapValue>1)
				GapValue--;
				Buzzer=0;
				Delay_ms(50);
				Buzzer=1;
			}
			write_eeprom();			   //保存数?
		}
	}
}
//****************************************************
//主函数
//****************************************************
void main()
{
	init_eeprom();  //开始初始化保存的数据
	Init_LCD1602();									//初始化LCD1602
   EA = 0;
   Timer0_Init();
   //初中始化完成,开断
   EA = 1;
	
//	Get_Maopi();
	LCD1602_write_com(0x80);						//指针设置
   LCD1602_write_word(" Welcome To Use ");	//  
   LCD1602_write_com(0x80+0x40);						//指针设置
   LCD1602_write_word("Wlectronic Scale");
//   Delay_ms(2000);
   Get_Maopi();
   LCD1602_write_com(0x80);						//指针设置
   LCD1602_write_word("The Weight:     ");
   LCD1602_write_com(0x80+0x40);				//指针设置
   LCD1602_write_word("         0.000kg");
//	Get_Maopi();				//称毛皮重量

	while(1)
	{
//每0.5秒称重一次
		if (FlagTest==1)
		{
			Get_Weight();
			FlagTest = 0;
		}	 
		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 >= 11000)		//超重报警
	{
		Buzzer = !Buzzer;	
		LED=!LED;
		LCD1602_write_com(0x80+0x40+8);
	   LCD1602_write_word("--.---");
	}
	else
	{
		if(Weight_Shiwu==0)
		LED=0;
		else if(Weight_Shiwu>0)
		LED=1; 
		Buzzer = 1;
		Display_Weight();
	}
}

//****************************************************
//获取毛皮重量
//****************************************************
void Get_Maopi()
{
	unsigned char clear;
mm:	Weight_Maopi_0 = HX711_Read();
	for(clear=0;clear<10;clear++)
	{
		Buzzer=1;
		LED=0;
		Delay_ms(100);
		LED=1;
		Delay_ms(100);	
	}
	Weight_Maopi = HX711_Read();
	if(Weight_Maopi/GapValue!=Weight_Maopi_0/GapValue)
	goto mm;
	Buzzer=0;
	Delay_ms(500);
	Buzzer=1;
} 

//****************************************************
//MS延时函数(12M晶振下测试)
//****************************************************
void Delay_ms(unsigned int n)
{
	unsigned int  i,j;
	for(i=0;i<n;i++)
		for(j=0;j<121;j++);
}

原文:http://www.jh-tec.cn/archives/5757

  • 13
    点赞
  • 152
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于51单片机电子秤设计AD图的过程如下: 1. 确定需求:根据电子秤的功能需求,确定所需测量范围、精度和显示方式等参数。 2. 选择传感器:根据需求选择合适的传感器,常见的有称重传感器、应变传感器等。传感器的选取要考虑到所需测量范围、精度和稳定性。 3. 电路设计:根据传感器的工作原理和信号特点,设计电路来对传感器信号进行放大、滤波和数字化处理。常见的电路包括放大电路、滤波电路、模数转换电路等。 4. 选择51单片机:根据需求选择适合的51单片机,根据硬件资源来确定所需的I/O口数量、存储容量和时钟频率等。 5. 连接电路:将传感器和51单片机连接起来,传感器的信号输入到51单片机的引脚上。此外,还需要连接显示器、按键等外部设备。 6. 程序编写:根据需求编写控制程序,实现称重的计算、单位转换、数据处理和显示等功能。编程语言可以采用C语言或汇编语言。 7. 调试测试:完成程序编写后,进行调试测试,检查各个功能是否正常工作。在测试过程中可能需要进行校准,以确保测量结果的准确性。 8. 完善系统:根据实际需求对系统进行进一步完善,比如增加数据存储,添加通信接口等。 9. 绘制AD图:根据上述设计过程,使用绘图软件绘制AD图。AD图应包括各个模块的连接关系、引脚定义和电源连接等信息。 总体来说,基于51单片机电子秤设计AD图需要考虑到传感器的选择、电路设计、51单片机的选择与连接、程序编写、调试测试和系统的完善等多个方面。绘制AD图可以帮助我们更清晰地展示整个系统的设计思路和结构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值