功能:
1.本系统采用STC89C52作为单片机
2.本系统LCD1602液晶实时显示时间和当前重量
3.四个功能按键其中,按‘设置’键进入时间设置,按’去皮’键实现去皮功能
4.系统设置有重量阈值,超重10kg即声光报警
5.采用DC002作为电源接口可直接输入5V给整个系统供电
6.称重传感器采用的是HX711+圆盘称重支架
原理图:
PCB :
主程序:
#include <reg52.h>
#include <intrins.h>
#include <string.h>
#include "main.h"
#include "LCD1602.h"
#include "HX711.h"
#include "ds1302.h"
sbit KEY_CLEAR = P3^7;
sbit KEY_ADD = P3^6;
sbit KEY_SUB = P3^4;
sbit KEY_SET = P3^5;
sbit BUZZER = P2^0;
unsigned long HX711_Buffer = 0;
unsigned long g_weightMaopi = 0;
unsigned long g_weightMaopiBuf = 0;
long g_weightShiwu = 0;
long g_quPi = 0;
//键盘处理变量
unsigned char g_keyCode;
unsigned char g_keyPressNum = 0;
unsigned char g_setLocation = 0;
unsigned char disTime[16] = " / / : ";
bit g_setTimeFlag = 0;
bit refreshFlag = 0;
//校准参数
//因为不同的传感器特性曲线不是很一致,因此,每一个传感器需要矫正这里这个参数才能使测量值很准确。
//当发现测试出来的重量偏大时,增加该数值。
//如果测试出来的重量偏小时,减小该数值。
//该值可以为小数
#define GAP_VALUE 2150 //10kg
// #define GAP_VALUE 4250 //5kg
#define MAX_WEIGHT 10000 //单位g,不同秤盘支架需要更改
// 函数声明
void DelayMs(unsigned int n);
void Get_Maopi();
void Get_Weight();
void DisplayWeight();
void KeyPress();
void Init_Timer0();
void DispTime();
void SetTime();
//主函数
void main()
{
Init_LCD1602(); //初始化LCD1602
Init_Timer0();
DS1302_Init();
//初始化完成
// Get_Maopi();
LCD1602_WriteCom(0x80); //指针设置
LCD1602_WriteWord(" Welcome To Use "); //
LCD1602_WriteCom(0x80 + 0x40); //指针设置
LCD1602_WriteWord("Wlectronic Scale");
// DelayMs(2000);
Get_Maopi();
DS1302_Read_Time();
DispTime();
LCD1602_WriteCom(0x80 + 0x40); //指针设置
LCD1602_WriteWord("Weight: 0.000kg");
// Get_Maopi(); //称毛皮重量
while (1)
{
if (refreshFlag)
{
refreshFlag = 0;
if (g_setTimeFlag == 1)
{
SetTime();
}
else
{
DS1302_Read_Time();
DispTime();
TR0 = 0;
Get_Weight();
TR0 = 1;
}
}
KeyPress();
}
}
//称重
void Get_Weight()
{
g_weightShiwu = HX711_Read();
g_weightShiwu = g_weightShiwu - g_weightMaopi; //获取净重
g_weightShiwu = ((float)(g_weightShiwu * 10) / GAP_VALUE) - g_quPi; //计算实物的实际重量
if (g_weightShiwu <= 0)
{
g_weightShiwu = 0;
BUZZER = 1;
LCD1602_WriteCom(0x80 + 0x40);
LCD1602_WriteWord("Weight: 0.000kg");
}
else if (g_weightShiwu > MAX_WEIGHT) //超重报警
{
BUZZER = !BUZZER;
LCD1602_WriteCom(0x80 + 0x40 + 8);
LCD1602_WriteWord("Error!!!");
}
else
{
BUZZER = 1;
DisplayWeight();
}
}
//获取毛皮重量
void Get_Maopi()
{
unsigned char clear;
mm:
g_weightMaopiBuf = HX711_Read();
for (clear = 0; clear < 10; clear++)
{
BUZZER = 1;
DelayMs(100);
}
g_weightMaopi = HX711_Read();
if (g_weightMaopi / GAP_VALUE != g_weightMaopiBuf / GAP_VALUE)
{
goto mm;
}
BUZZER = 0;
DelayMs(500);
BUZZER = 1;
}
//MS延时函数(11.0592M晶振下测试)
void DelayMs(unsigned int n)
{
unsigned int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < 121; j++)
;
}
void DispTime()
{
disTime[1] = '0' + timeBufDec[1] / 10;
disTime[2] = '0' + timeBufDec[1] % 10;
disTime[4] = '0' + timeBufDec[2] / 10;
disTime[5] = '0' + timeBufDec[2] % 10;
disTime[7] = '0' + timeBufDec[3] / 10;
disTime[8] = '0' + timeBufDec[3] % 10;
disTime[10] = '0' + timeBufDec[4] / 10;
disTime[11] = '0' + timeBufDec[4] % 10;
disTime[13] = '0' + timeBufDec[5] / 10;
disTime[14] = '0' + timeBufDec[5] % 10;
LCD1602_WriteCom(0x80); //指针设置
LCD1602_WriteWord(disTime);
}
void SetTime()
{
LCD1602_WriteCom(0x0F);
switch (g_setLocation)
{
case 1: LCD1602_WriteCom(0x80 + 2); break;
case 2: LCD1602_WriteCom(0x80 + 5); break;
case 3: LCD1602_WriteCom(0x80 + 8); break;
case 4: LCD1602_WriteCom(0x80 + 11); break;
case 5: LCD1602_WriteCom(0x80 + 14); break;
case 6: LCD1602_WriteCom(0x0C); DelayMs(5); DS1302_Write_Time(); g_setLocation = 0; g_setTimeFlag = 0; break;
default: ;
}
}
//显示重量,单位kg,两位整数,三位小数
void DisplayWeight()
{
LCD1602_WriteCom(0x80 + 0x40);
LCD1602_WriteWord("Weight: ");
if (g_weightShiwu / 10000 == 0)
{
LCD1602_WriteData(' ');
}
else
{
LCD1602_WriteData(g_weightShiwu / 10000 + '0');
}
LCD1602_WriteData(g_weightShiwu % 10000 / 1000 + '0');
LCD1602_WriteData('.');
LCD1602_WriteData(g_weightShiwu % 1000 / 100 + '0');
LCD1602_WriteData(g_weightShiwu % 100 / 10 + '0');
LCD1602_WriteData(g_weightShiwu % 10 + '0');
LCD1602_WriteData('k');
LCD1602_WriteData('g');
}
void KeyPress()
{
if (KEY_SET == 0) //设置键
{
DelayMs(5);
if (KEY_SET == 0)
{
if (g_setTimeFlag == 0)
{
g_setTimeFlag = 1;
g_setLocation = 1;
}
else if (g_setTimeFlag == 1)
{
g_setLocation++;
}
}
while (!KEY_SET);
}
if (!KEY_CLEAR) //去皮键
{
DelayMs(5);
if (!KEY_CLEAR)
{
// Get_Maopi();
if (g_setTimeFlag == 1)
{
g_setLocation = 6;
}
else
{
if (g_quPi == 0)
{
g_quPi = g_weightShiwu;
}
else
{
g_quPi = 0;
}
}
}
while (!KEY_CLEAR);
}
if (!KEY_ADD) //加
{
DelayMs(180);
if (!KEY_ADD)
{
if (g_setTimeFlag)
{
switch (g_setLocation)
{
case 1:
{
timeBufDec[1]++;
if (timeBufDec[1] > 99)
{
timeBufDec[1] = 0;
}
break;
}
case 2:
{
timeBufDec[2]++;
if (timeBufDec[2] > 12)
{
timeBufDec[2] = 1;
}
break;
}
case 3:
{
timeBufDec[3]++;
if (timeBufDec[3] > YDay(timeBufDec[1], timeBufDec[2]))
{
timeBufDec[3] = 1;
}
break;
}
case 4:
{
timeBufDec[4]++;
if (timeBufDec[4] > 23)
{
timeBufDec[4] = 0;
}
break;
}
case 5:
{
timeBufDec[5]++;
if (timeBufDec[5] > 59)
{
timeBufDec[5] = 0;
}
break;
}
}
}
DispTime();
}
// while (!KEY_ADD);
}
if (!KEY_SUB) //减
{
DelayMs(180);
if (!KEY_SUB)
{
if (g_setTimeFlag)
{
switch (g_setLocation)
{
case 1:
{
if (timeBufDec[1] == 0)
{
timeBufDec[1] = 100;
}
timeBufDec[1]--;
break;
}
case 2:
{
timeBufDec[2]--;
if (timeBufDec[2] < 1)
{
timeBufDec[2] = 12;
}
break;
}
case 3:
{
timeBufDec[3]--;
if (timeBufDec[3] < 1)
{
timeBufDec[3] = YDay(timeBufDec[1], timeBufDec[2]);
}
break;
}
case 4:
{
if (timeBufDec[4] == 0)
{
timeBufDec[4] = 24;
}
timeBufDec[4]--;
break;
}
case 5:
{
if (timeBufDec[5] == 0)
{
timeBufDec[5] = 60;
}
timeBufDec[5]--;
break;
}
}
}
DispTime();
}
// while (!KEY_SUB);
}
}
//定时器0初始化
void Init_Timer0()
{
ET0 = 1; //允许定时器0中断
TMOD &= 0xF0;
TMOD |= 0x01; //定时器工作方式选择
TL0 = 0xb0;
TH0 = 0x3c; //定时器赋予初值
TR0 = 1; //启动定时器
EA = 1;
}
//定时器0中断
void Timer0_ISR(void) interrupt 1
{
static unsigned char cnt1;
TL0 = 0xb0;
TH0 = 0x3c; //定时器赋予初值
cnt1++;
if (cnt1 >= 4)
{
refreshFlag = 1;
cnt1 = 0;
}
}