//***********3KG电子称测试程序**HX711电路板*****************
//******2013 6 8 05:38 L601 自动称重测试草稿 需硬件测试
/********-------------------------**********/
/*******|设定 00000 |***********************/
/*******|实际 00000 |***********************/
/*******|产量 0000 |***********************/
/*******|***********************************/
/********-------------------------**********/
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar code disdt[10]={0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9};
uint val,val1; /*设定重量 实际重量*/
uint a,l,m,n,k,s; /****个十百代码缓冲**/
sbit Buzzer=P1^1;
sbit OUT1=P1^0;
sbit OUT2=P1^1;
sbit OUT3=P1^3;
unsigned long HX711_Buffer = 0;
unsigned int Weight_Maopi = 0,WeiDATA =0;
uint t0,t1,t2,t3,t4;
uchar TBIT; //光标地址计数器
sbit HX711_DOUT=P3^3;
sbit HX711_SCK=P3^4;
sbit RS=P3^5;
sbit RW=P3^6;
sbit E=P3^7;
sbit SDA=P1^7; /****EEPROM数据****/
sbit SCL=P1^6; /****EEPROM脉冲****/
sbit WEIGHTSET=P3^2; //重量加
sbit WEIGHTBIT=P1^4; //重量减
sbit WEIGHTCLR=P0^7; //归零
sbit TOTALCLR=P3^1; //产量清零
sbit MUTALAIR=P0^4; //手动输出
sbit Filling=P0^5; //灌装P1^0;
#define Lcd_Bus P2
bdata char com_data;
sbit mos_bit=com_data^7; /****高位****/
sbit low_bit=com_data^0; /****低位****/
/**************************************/
void start()
{
SDA=1;nop();nop();nop();nop();
SCL=1;nop();nop();nop();nop();
SDA=0;nop();nop();nop();nop();
SCL=0;nop();nop();nop();nop();
}
/***************************************/
void stop()
{
SDA=0;nop();nop();nop();nop();
SCL=1;nop();nop();nop();nop();
SDA=1;nop();nop();nop();nop();
}
/***************************************/
void ack()
{
SCL=1;nop();nop();nop();nop();
SCL=0;nop();nop();nop();nop();
}
/***************************************/
void shift8(char a)
{
data uchar i;
com_data=a;
for(i=0;i<8;i++)
{
SDA=mos_bit;
SCL=1;nop();nop();nop();nop();nop();nop();
SCL=0;nop();nop();nop();nop();nop();nop();
com_data=com_data*2;
}
}
/***************************************/
void delay_iic(int v)
{
int i;
for(i=1;i<v;i++){;}
}
/***************************************/
uchar rd_24c01(char a)
{
data uint i,command;
SDA=1;nop();nop();nop();nop();
SCL=0;nop();nop();nop();nop();
start();
command=160;
shift8(command); /*****写入160*****/
ack();
shift8(a);
ack();
start();
command=161;
shift8(command); /*****写入161*****/
ack();
SDA=1;nop();nop();nop();nop();
for(i=0;i<8;i++)
{
com_data=com_data*2;
SCL=1;nop();nop();nop();nop();nop();nop();
low_bit=SDA;
SCL=0;nop();nop();nop();nop();nop();nop();
}
stop();
return(com_data);
}
/***************************************/
void wr_24c01(char a,char b)
{
data uint command;
nop();nop();nop();nop();nop();
SDA=1;nop();nop();nop();nop();
SCL=0;nop();nop();nop();nop();
start();
command=160;
shift8(command); /*****写入160*****/
ack();
shift8(a); /*****写入 a *****/
ack();
shift8(b); /*****写入 b *****/
ack();
stop();
nop();nop();nop();nop();nop();
}
/*********写入EEPROM 运行总时*****************************/
void writea(void)
{
wr_24c01(1,a);delay_iic(200); /*写入万位*/
wr_24c01(2,l);delay_iic(200); /*写入千位*/
wr_24c01(3,m);delay_iic(200); /*写入百位*/
wr_24c01(4,n);delay_iic(200); /*写入十位*/
wr_24c01(5,s);delay_iic(200); /*写入个位*/
}
/**************************************/
void red24 (void)
{
a=rd_24c01(1);delay_iic(25); /*数据万位*/
l=rd_24c01(2);delay_iic(25); /*数据千位*/
m=rd_24c01(3);delay_iic(25); /*数据百位*/
n=rd_24c01(4);delay_iic(25); /*数据十位*/
s=rd_24c01(5);delay_iic(25); /*数据个位*/
val1=a*10000+l*1000+m*100+n*10+s;/*x置初值合并A数据 百位乘百 十位乘十*/
}
/*------------------检查忙位--------------------------*/
void chk_busy()
{
RS=0;
RW=1;
E=1;
Lcd_Bus=0xff;
while((Lcd_Bus&0x80)==0x80);
E=0;
}
/*------------------延时子程序------------------------*/
void delay(unsigned int t)
{
uint i,j;
for(i=0;i<t;i++)
for(j=0;j<20;j++);
}
/*------------------写命令到LCD-----------------------*/
void write_com(uchar cmdcode)
{
chk_busy();
RS=0;
RW=0;
E=1;
Lcd_Bus=cmdcode;
delay(5); /*在数据写入的时候加入适当的延时*/
E=0;
delay(5);
}
/*-------------------写数据到LCD----------------------*/
void write_data(unsigned char Dispdata)
{
chk_busy();
RS=1;
RW=0;
E=1;
Lcd_Bus=Dispdata;
delay(5); /*在数据写入的时候加入适当的延时 */
E=0;
delay(5);
}
/*------------------显示文字--------------------------*/
void displaywriting()
{
write_com(0x80);
write_data(0xC9);
write_data(0xE8);
write_com(0x81);
write_data(0xB6);
write_data(0xA8); //设定
write_com(0x82);
write_data(0xA3);
write_data(0xBA); /*---:----*/
write_com(0x90);
write_data(0xCA);
write_data(0xB5);
write_com(0x91);
write_data(0xBC);
write_data(0xCA); //实际
write_com(0x92);
write_data(0xA3);
write_data(0xBA); /*---:----*/
write_com(0x88);
write_data(0xB2);
write_data(0xFA);
write_com(0x89);
write_data(0xC1);
write_data(0xBF); //产量
write_com(0x8A);
write_data(0xA3);
write_data(0xBA); /*---:----*/
}
/*------------------显示灌装---------------------------------*/
void disfilling()
{
write_com(0x98);
write_data(0xB9);
write_data(0xE0);
write_com(0x99);
write_data(0xD7);
write_data(0xB0); //灌装
}
/*------------------清除灌装---------------------------------*/
void clrfilling()
{
write_com(0x98);
write_data(0xB6);
write_data(0xA0);
write_com(0x99);
write_data(0xB6);
write_data(0xA0); //清除显示灌装
}
/*------------------显示设定重量数据--------------------------*/
void displaya()
{
write_com(0x83);
write_data(0xA3);
write_data(disdt[a]);
write_com(0x84);
write_data(0xA3);
write_data(disdt[l]);
write_com(0x85);
write_data(0xA3);
write_data(disdt[m]);
write_com(0x86);
write_data(0xA3);
write_data(disdt[n]);
write_com(0x87);
write_data(0xA3);
write_data(disdt[s]);
}
/*------------------显示实际重量数据--------------------------*/
void displayb()
{
write_com(0x93);
write_data(0xA3);
write_data(disdt[t0]);
write_com(0x94);
write_data(0xA3);
write_data(disdt[t1]);
write_com(0x95);
write_data(0xA3);
write_data(disdt[t2]);
write_com(0x96);
write_data(0xA3);
write_data(disdt[t3]);
write_com(0x97);
write_data(0xA3);
write_data(disdt[t4]);
}
/*------------------初始化LCD屏-----------------------*/
void lcdreset()
{
delay(300);
RW=0;
delay(10); /*选择基本指令集 */
write_com(0x30); /*选择8bit数据流 */
delay(50);
write_com(0x0F); /*开显示(无游标、不反白) */
delay(50);
write_com(0x01); /*清除显示,并且设定地址指针为00H */
delay(50);
write_com(0x04); /*游标的移动方向及指定显示的移位*/
delay(50);
}
/*******************************************/
void Delay__hx711_us(void)
{
nop();
nop();
}
/*******************************************/
void Delay_ms(unsigned int n)
{
unsigned int i,j;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
/*******************************************/
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;
Delay__hx711_us();
HX711_SCK=0;
return(count);
}
/*******************************************/
void Get_Weight()
{
HX711_Buffer=HX711_Read();
HX711_Buffer=HX711_Buffer/100;
if(HX711_Buffer > Weight_Maopi)
{
WeiDATA=HX711_Buffer;
WeiDATA=WeiDATA- Weight_Maopi; //获取实物的AD采样数值。
WeiDATA=(unsigned int)((float)WeiDATA/13.2+0.05); //计算实物的实际重量
if(WeiDATA>20000 )
{
Buzzer=0; //打开警报
}
else
{
Buzzer=1; //关闭警报
}
}
else if(HX711_Buffer < Weight_Maopi - 30)
{
Buzzer=0; //负重量报警
}
}
/*******************************************/
void Get_Maopi()
{
unsigned char i=0;
unsigned int Temp_Weight=0;
Weight_Maopi=0;
for( i=0;i<10;i++)
{
HX711_Buffer=HX711_Read();
Temp_Weight=HX711_Buffer/100;
if(Temp_Weight>Weight_Maopi)
{
Weight_Maopi=Temp_Weight;
}
}
}
/**************设定重量处理*****************************/
void dispose1()
{
a=val1/10000; /*除以10000*/
l=(val1-a*10000)/1000; /*除以1000*/
m=(val1-a*10000-l*1000)/100; /*减t1x1000再除以100*/
n=(val1-a*10000-l*1000-m*100)/10; /*减t1x1000再减t2X100*/
s=val1-a*10000-l*1000-m*100-n*10; /*分离千 百 十 个三位*/
}
/***************实际重量处理****************************/
void dispose2()
{
t0=WeiDATA/10000;
t1=WeiDATA%10000/1000 ;
t2=WeiDATA%1000/100 ;
t3=WeiDATA%100/10;
t4=WeiDATA%10;
}
/*--------------显示万位--------------------------*/
void TenThousands()
{
write_com(0x83); /*地址*/
write_data(0xA3); /*半个字符*/
write_data(disdt[a]); /*万位*/
}
/*--------------显示千位---------------------------*/
void Thousands()
{
write_com(0x84); /*地址*/
write_data(0xA3); /*半个字符*/
write_data(disdt[l]); /*千位*/
}
/*--------------显示百位---------------------------*/
void hundreds()
{
write_com(0x85); /*地址*/
write_data(0xA3); /*半个字符*/
write_data(disdt[m]); /*百位*/
}
/*--------------显示十位---------------------------*/
void decade()
{
write_com(0x86); /*地址*/
write_data(0xA3); /*半个字符*/
write_data(disdt[n]); /*十位*/
}
/*--------------显示个位---------------------------*/
void single()
{
write_com(0x87); /*地址*/
write_data(0xA3); /*半个字符*/
write_data(disdt[s]); /*个位*/
}
/*---------------显示位选光标-------------------*/
void displaybit()
{
switch(TBIT)
{
case 1: /*光标个位显示*/
{
single(); /*个位数据显示*/
//decade(); /*十位数据显示光标自动后移一位*/
break; /*子程序返回*/
}
case 2: /*光标十位显示*/
{
decade(); /*十位数据显示*/
//hundreds(); /*百位数据显示光标自动后移一位*/
break; /*子程序返回*/
}
case 3: /*光标百位显示*/
{
hundreds(); /*百位数据显示*/
//Thousands(); /*千位数据显示光标自动后移一位*/
break; /*子程序返回*/
}
case 4: /*光标千位显示*/
{
Thousands(); /*千位数据显示*/
//TenThousands(); /*万位数据显示光标自动后移一位*/
break; /*子程序返回*/
}
case 5: /*光标千位显示*/
{
TenThousands(); /*万位数据显示*/
//write_com(0x82);
//write_data(0xA3);
//write_data(0xBA); /*---:显示光标自动后移一位----*/
break; /*子程序返回*/
}
}
}
/*----------设定重量按位加-------------------------*/
void setda1on() /*写数据B子函数*/
{ /*子函数开始*/
dispose1(); /*设定重量处理分离各位*/
switch (TBIT)
{
case 1: /*光标个位显示*/
{
s++;
if(s>=10)
{s=0;}
single();
//decade();
break;
}
case 2: /*光标十位显示*/
{
n++;
if(n>=10)
{n=0;}
decade();
//hundreds();
break;
}
case 3: /*光标百位显示*/
{
m++;
if(m>=10)
{m=0;}
hundreds();
//Thousands();
break;
}
case 4: /*光标千位显示*/
{
l++;
if(l>=10)
{l=0;}
Thousands();
//TenThousands();
break;
}
case 5: /*光标千位显示*/
{
a++;
if(a>=4)
{a=0;}
TenThousands(); /*万位显示*/
break;
}
}
val1=a*10000+l*1000+m*100+n*10+s;
writea(); /*百 十 个三位写入EEPROM*/
}
/*******************************************/
void main()
{
lcdreset();
Delay_ms(1000); //延时1s,等待传感器稳定
displaywriting(); //显示文字
Get_Maopi(); //称毛皮重量
TBIT=0;
Get_Weight(); //称重
dispose2(); //数据处理取实际重量个十百千万位值
displayb(); //显示实际重量数据
red24 (); //读EEPROM数据 取设定值数据
dispose1(); //数据处理取设定重量个十百千万位值
displaya(); //显示设定重量数据
while(1)
{
if(!WEIGHTSET) /*设置重量按键*/
{ /*循环*/
for(;k<=25;) /*小于等于25循环*/
{
if(!WEIGHTSET) /*检测重量按键为低电平?*/
{ /*循环检测 */
OUT3=0;
k++;
delay(10);
}
else if(~WEIGHTSET) /*检测重量按键为高电平?*/
k=0;break; /*寄存器复位*/
} /*循环*/
k=0;OUT3=1; /*寄存器复位*/
nop();nop(); /*空操作*/
setda1on(); /*调用位码加子程序并显示*/
delay(600);
} /*结束*/
else if(!WEIGHTBIT) /**重量位选按键**/
{ /*循环*/
for(;k<=25;) /*小于等于5循环*/
{
if(!WEIGHTBIT) /*检测重量位选为低电平?*/
{ /*循环检测 */
OUT3=0;
k++;
delay(10);
}
else if(~WEIGHTBIT) /*检测重量位选高电平?*/
k=0;break; /*寄存器复位*/
} /*循环*/
k=0;OUT3=1; /*寄存器复位*/
TBIT++; /*空操作*/
if(TBIT>=6)
{TBIT=0;}
displaybit(); /*位选光标显示*/
delay(2500);
}
if(!Filling) /*检测灌装开关为低电平?**/
{ /*自动开始*/
for(;k<=10;) /*寄存器复位*/
{
if(!Filling) /*检测灌装开关为低电平?*/
{ /*自动运行*/
k++;
delay(10);
}
else if(~!Filling) /*检测灌装开关为高电平?*/
k=0;break; /*寄存器复位返回循环*/
}
k=0; /*寄存器复位*/
disfilling();
OUT1=0; OUT2=0; /*灌装输出*/
while(WeiDATA<val1)
{
Get_Weight(); //称重
dispose2(); //数据处理取实际重量个十百千万位值
displayb(); //显示实际重量数据
}
clrfilling();
}
OUT1=1;OUT2=1; /*灌装关*/
//产量加一
}
Get_Weight(); //称重
dispose2(); //数据处理取实际重量个十百千万位值
displayb(); //显示实际重量数据
OUT3=0;
Delay_ms(200); //延时
OUT3=1;
Delay_ms(200); //延时
}