|
#include "main.h"
#include "LCD1602.h"
#include "HX711.h"
#include "EEPROM.H"
//定义变量
unsigned char KEY_NUM = 0; //用来存放按键按下的键值
unsigned long HX711_Buffer = 0; //用来存放HX711读取出来的数据
unsigned long Weight_Maopi = 0; //用来存放毛皮数据
long Weight_Shiwu = 0; //用来存放实物重量
long Max_Value = 0; //用来存放设置最大值
char maxValueTable[4] = {1,0,0,0};
unsigned char state = 0; //用来存放设置状态
unsigned char Blink_Speed = 0;
#define Blink_Speed_Max 6 //该值可以改变设置指针闪烁频率
//校准参数
//因为不同的传感器特性曲线不是很一致,因此,每一个传感器需要矫正这里这个参数才能使测量值很准确。
//当发现测试出来的重量偏大时,增加该数值。
//如果测试出来的重量偏小时,减小改数值。
//该值可以为小数
#define GapValue 780
//传感器最大测量值,单位是g
#define AlarmValue 3000
//****************************************************
//主函数
//****************************************************
void main()
{
Init_LCD1602(); //初始化LCD1602
LCD1602_write_com(0x80); //设置LCD1602指针
LCD1602_write_word("Welcome to use!");
Get_Maopi();
Get_Maopi();
Delay_ms(2000); //延时2s
Get_Maopi();
Get_Maopi(); //称毛皮重量 //多次测量有利于HX711稳定
LCD1602_write_com(0x01); //清屏
//读取EEPROM中保存的报警值
maxValueTable[0] = byte_read(0x2000);
maxValueTable[1] = byte_read(0x2001);
maxValueTable[2] = byte_read(0x2002);
maxValueTable[3] = byte_read(0x2003);
Max_Value = maxValueTable[0]*1000+maxValueTable[1]*100+maxValueTable[2]*10+maxValueTable[3]; //计算超限报警界限值
while(1)
{
Get_Weight();
//显示当前重量
LCD1602_write_com(0x80);
LCD1602_write_word("Weight=");
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);
LCD1602_write_word("Kg");
KEY_NUM = Scan_Key();
if(KEY_NUM == 1) //按键1切换设置状态
{
state++;
if(state == 5)
{
state = 0;
SectorErase(0x2000);
byte_write(0x2000,maxValueTable[0]); //保存EEPROM数据
byte_write(0x2001,maxValueTable[1]);
byte_write(0x2002,maxValueTable[2]); //保存EEPROM数据
byte_write(0x2003,maxValueTable[3]);
Max_Value = maxValueTable[0]*1000+maxValueTable[1]*100+maxValueTable[2]*10+maxValueTable[3]; //计算超限报警界限值
}
}
if(KEY_NUM == 2) //按键加
{
if(state != 0)
{
maxValueTable[state-1]++;
if(maxValueTable[state-1] >= 10)
{
maxValueTable[state-1] = 0;
}
}
}
if(KEY_NUM == 3) //按键减
{
if(state != 0)
{
maxValueTable[state-1]--;
if(maxValueTable[state-1] <= -1)
{
maxValueTable[state-1] = 9;
}
}
}
if(KEY_NUM == 4)
{
Get_Maopi(); //去皮
}
if(state != 0)
{
Blink_Speed ++;
if(Blink_Speed == Blink_Speed_Max)
{
Blink_Speed = 0;
}
}
switch(state)
{
case 0:
LCD1602_write_com(0x80+0x40);
LCD1602_write_word("MAX=");
LCD1602_write_data(maxValueTable[0]+0x30);
LCD1602_write_data('.');
LCD1602_write_data(maxValueTable[1]+0x30);
LCD1602_write_data(maxValueTable[2]+0x30);
LCD1602_write_data(maxValueTable[3]+0x30);
LCD1602_write_word("Kg");
break;
case 1:
LCD1602_write_com(0x80+0x40);
LCD1602_write_word("MAX=");
if(Blink_Speed < Blink_Speed_Max/2)
{
LCD1602_write_data(maxValueTable[0]+0x30);
}
else
{
LCD1602_write_data(' ');
}
LCD1602_write_data('.');
LCD1602_write_data(maxValueTable[1]+0x30);
LCD1602_write_data(maxValueTable[2]+0x30);
LCD1602_write_data(maxValueTable[3]+0x30);
LCD1602_write_word("Kg");
break;
case 2:
LCD1602_write_com(0x80+0x40);
LCD1602_write_word("MAX=");
LCD1602_write_data(maxValueTable[0]+0x30);
LCD1602_write_data('.');
if(Blink_Speed < Blink_Speed_Max/2)
{
LCD1602_write_data(maxValueTable[1]+0x30);
}
else
{
LCD1602_write_data(' ');
}
LCD1602_write_data(maxValueTable[2]+0x30);
LCD1602_write_data(maxValueTable[3]+0x30);
LCD1602_write_word("Kg");
break;
case 3:
LCD1602_write_com(0x80+0x40);
LCD1602_write_word("MAX=");
LCD1602_write_data(maxValueTable[0]+0x30);
LCD1602_write_data('.');
LCD1602_write_data(maxValueTable[1]+0x30);
if(Blink_Speed < Blink_Speed_Max/2)
{
LCD1602_write_data(maxValueTable[2]+0x30);
}
else
{
LCD1602_write_data(' ');
}
LCD1602_write_data(maxValueTable[3]+0x30);
LCD1602_write_word("Kg");
break;
case 4:
LCD1602_write_com(0x80+0x40);
LCD1602_write_word("MAX=");
LCD1602_write_data(maxValueTable[0]+0x30);
LCD1602_write_data('.');
LCD1602_write_data(maxValueTable[1]+0x30);
LCD1602_write_data(maxValueTable[2]+0x30);
if(Blink_Speed < Blink_Speed_Max/2)
{
LCD1602_write_data(maxValueTable[3]+0x30);
}
else
{
LCD1602_write_data(' ');
}
LCD1602_write_word("Kg");
break;
default:
break;
}
//超限报警
if(Weight_Shiwu >= Max_Value || Weight_Shiwu >= AlarmValue) //超过设置最大值或者传感器本身量程最大值报警
{
Buzzer = 0;
}
else
{
Buzzer = 1;
}
}
}
//****************************************************
//称重
//****************************************************
void Get_Weight()
{
Weight_Shiwu = HX711_Read();
Weight_Shiwu = Weight_Shiwu - Weight_Maopi; //获取净重
if(Weight_Shiwu >= 0)
{
Weight_Shiwu = (unsigned long)((float)Weight_Shiwu/GapValue); //计算实物的实际重量
}
else
{
Weight_Shiwu = 0;
}
}
//****************************************************
//获取毛皮重量
//****************************************************
void Get_Maopi()
{
Weight_Maopi = HX711_Read();
}
//****************************************************
//MS延时函数(12M晶振下测试)
//****************************************************
void Delay_ms(unsigned int n)
{
unsigned int i,j;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
//****************************************************
//蜂鸣器程序
//****************************************************
void Buzzer_Di()
{
Buzzer = 0;
Delay_ms(10);
Buzzer = 1;
Delay_ms(10);
}
//****************************************************
//按键扫描程序
//****************************************************
unsigned char Scan_Key()
{
if( KEY1 == 0 ) //按键扫描
{
Delay_ms(10); //延时去抖
if( KEY1 == 0 )
{
Buzzer_Di();
while(KEY1 == 0); //等待松手
return 1;
}
}
if( KEY2 == 0 ) //按键扫描
{
Delay_ms(10); //延时去抖
if( KEY2 == 0 )
{
Buzzer_Di();
while(KEY2 == 0); //等待松手
return 2;
}
}
if( KEY3 == 0 ) //按键扫描
{
Delay_ms(10); //延时去抖
if( KEY3 == 0 )
{
Buzzer_Di();
while(KEY3 == 0); //等待松手
return 3;
}
}
if( KEY4 == 0 ) //按键扫描
{
Delay_ms(10); //延时去抖
if( KEY4 == 0 )
{
Buzzer_Di();
while(KEY4 == 0); //等待松手
return 4;
}
}
return 0;
}
#include "LCD1602.h"
//****************************************************
//MS延时函数(12M晶振下测试)
//****************************************************
void LCD1602_delay_ms(unsigned int n)
{
unsigned int i,j;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
//****************************************************
//写指令
//****************************************************
void LCD1602_write_com(unsigned char com)
{
LCD1602_RS = 0;
LCD1602_delay_ms(1);
LCD1602_EN = 1;
LCD1602_PORT = com;
LCD1602_delay_ms(1);
LCD1602_EN = 0;
}
//****************************************************
//写数据
//****************************************************
void LCD1602_write_data(unsigned char dat)
{
LCD1602_RS = 1;
LCD1602_delay_ms(1);
LCD1602_PORT = dat;
LCD1602_EN = 1;
LCD1602_delay_ms(1);
LCD1602_EN = 0;
}
//****************************************************
//连续写字符
//****************************************************
void LCD1602_write_word(unsigned char *s)
{
while(*s>0)
{
LCD1602_write_data(*s);
s++;
}
}
void Init_LCD1602()
{
LCD1602_EN = 0;
LCD1602_RW = 0; //设置为写状态
LCD1602_write_com(0x38); //显示模式设定
LCD1602_write_com(0x0c); //开关显示、光标有无设置、光标闪烁设置
LCD1602_write_com(0x06); //写一个字符后指针加一
LCD1602_write_com(0x01); //清屏指令
}
#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<24;i++)
{
HX711_SCK=1;
count=count<<1;
HX711_SCK=0;
if(HX711_DOUT)
count++;
}
HX711_SCK=1;
count=count^0x800000;//第25个脉冲下降沿来时,转换数据
Delay__hx711_us();
HX711_SCK=0;
return(count);
}
#include "EEPROM.H"
/* ================ 打开 ISP,IAP 功能 ================= */
void ISP_IAP_enable(void)
{
EA = 0; /* 关中断 */
ISP_CONTR = ISP_CONTR & 0x18; /* 0001,1000 */
ISP_CONTR = ISP_CONTR | WaitTime; /* 写入硬件延时 */
ISP_CONTR = ISP_CONTR | 0x80; /* ISPEN=1 */
}
/* =============== 关闭 ISP,IAP 功能 ================== */
void ISP_IAP_disable(void)
{
ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */
ISP_TRIG = 0x00;
EA = 1; /* 开中断 */
}
/* ================ 公用的触发代码 ==================== */
void ISPgoon(void)
{
ISP_IAP_enable(); /* 打开 ISP,IAP 功能 */
ISP_TRIG = 0x46; /* 触发ISP_IAP命令字节1 */
ISP_TRIG = 0xb9; /* 触发ISP_IAP命令字节2 */
_nop_();
}
/* ==================== 字节读 ======================== */
unsigned char byte_read(unsigned int byte_addr)
{
ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址赋值 */
ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
ISP_CMD = ISP_CMD & 0xf8; /* 清除低3位 */
ISP_CMD = ISP_CMD | RdCommand; /* 写入读命令 */
ISPgoon(); /* 触发执行 */
ISP_IAP_disable(); /* 关闭ISP,IAP功能 */
return (ISP_DATA); /* 返回读到的数据 */
}
/* ================== 扇区擦除 ======================== */
void SectorErase(unsigned int sector_addr)
{
unsigned int iSectorAddr;
iSectorAddr = (sector_addr & 0xfe00); /* 取扇区地址 */
ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);
ISP_ADDRL = 0x00;
ISP_CMD = ISP_CMD & 0xf8; /* 清空低3位 */
ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3 */
ISPgoon(); /* 触发执行 */
ISP_IAP_disable(); /* 关闭ISP,IAP功能 */
}
/* ==================== 字节写 ======================== */
void byte_write(unsigned int byte_addr, unsigned char original_data)
{
ISP_ADDRH = (unsigned char)(byte_addr >> 8); /* 取地址 */
ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
ISP_CMD = ISP_CMD & 0xf8; /* 清低3位 */
ISP_CMD = ISP_CMD | PrgCommand; /* 写命令2 */
ISP_DATA = original_data; /* 写入数据准备 */
ISPgoon(); /* 触发执行 */
ISP_IAP_disable(); /* 关闭IAP功能 */
}
|
|