此程序适用单片机类型STC89C52RC
单片机源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- #include<string.h>
- #include<lcd12864.h>
- #include<hx711.h>
- #include<eeprom52.h>
- #include<keyboard.h>
- #define MAX 10000
- #define uint unsigned int
- #define uchar unsigned char
- #define ulong unsigned long
- #define delayNOP();{_nop_();_nop_();_nop_();_nop_();};
- //定义量程系数
- //#define RATIO 2356/1000
- uint RATIO;
- //定义标识
- volatile bit FlagTest = 0; //定时测试标志,每0.5秒置位,测完清0
- volatile bit FlagKeyPress = 0; //有键按下标志,处理完毕清0
- volatile bit FlagSetPrice = 0; //价格设置状态标志,设置好为1?
- volatile bit ClearWeighFlag = 0; //传感器调零标志位,清除0漂?
- volatile bit wtk = 0; //称重/时间模式
- //管脚定义
- sbit beep = P3^3;
- sbit alert = P3^4;
- //显示用变量
- int Counter;
- uchar idata str1[6] = "000000";
- int i, iTemp;
- //称重用变量
- ulong idata FullScale; //满量程AD值/1000
- ulong AdVal; //AD采样值
- ulong weight; //重量值,单位g
- ulong idata price; //单价,长整型值,单位为分
- ulong idata money; //总价,长整型值,单位为分
- ulong idata pricebc; //单价,长整型值,单位为分
- //键盘处理变量
- uchar keycode;
- uchar DotPos; //小数点标志及位置
- uchar wttime;//
- //函数声明
- void int2str(int, char *);
- void Data_Init();
- void Timer0_Init();
- void Timer0_ISR () ;
- void INT1_Init();
- void KeyPress(uchar);
- void To_Zero();
- void Display_Price(); //单价写入屏函数
- void Display_Weight(); //重量写入屏函数
- void Display_Money(); //总价写入屏函数
- //整型转字符串的函数,转换范围0--65536
- void int2str(int x, char* str)
- {
- int i=1;
- int tmp=10;
- while(x/tmp!=0)
- {
- i++;
- tmp*=10;
- }
- tmp=x;
- str[i]='\0';
- while(i>1)
- {
- str[--i]='0'+(tmp%10);
- tmp/=10;
- }
- str[0]=tmp+'0';
- }
- //重新找回零点,每次测量前调用
- void To_Zero()
- {
- FullScale=ReadCount();
- price=0;
- }
- /******************把数据保存到单片机内部eeprom中******************/
- void write_eeprom()
- {
- uchar x1,x2;
- x1=RATIO/256;
- x2=RATIO%256;
- SectorErase(0x2000);
- byte_write(0x2000, x1);
- byte_write(0x2001, x2);
- byte_write(0x2058, a_a);
- }
- /******************把数据从单片机内部eeprom中读出来*****************/
- void read_eeprom()
- {
- uchar x1,x2;
- x2 = byte_read(0x2001);
- x1 = byte_read(0x2000);
- a_a= byte_read(0x2058);
- RATIO = x1*256+x2;
- }
- /**************开机自检eeprom初始化*****************/
- void init_eeprom()
- {
- read_eeprom(); //先读
- if(a_a != 1) //新的单片机初始单片机内问eeprom
- {
- RATIO = 3500;
- a_a = 1;
- write_eeprom(); //保存数据
- }
- }
- //显示单价,单位为元,四位整数,两位小数
- void Display_Price()
- {
- uint i,j;
- uchar A1,A2,A3,A4;
- uchar B1,B2;
- i = price/100; //得到整数部分
- j = price - i*100;//得到小数部分
- int2str(i,str1);
- A1=i/1000+48;
- A2=i%1000/100+48;
- A3=i%1000%100/10+48;
- A4=i%1000%100%10+48;
- B1=j/10+48;
- B2=j%10+48;
- //显示整数部分
- if (i>=1000)
- {
- Lcd_Pos(2,3);
- Lcd_Wdat(A1);
- Lcd_Wdat(A2);
- Lcd_Wdat(A3);
- Lcd_Wdat(A4);
- }
- else if (i>=100)
- {
- Lcd_Pos(2,3);
- Lcd_Wdat(' ');
- Lcd_Wdat(A2);
- Lcd_Wdat(A3);
- Lcd_Wdat(A4);
- }
- else if (i>=10)
- {
- Lcd_Pos(2,3);
- Lcd_Wdat(' ');
- Lcd_Wdat(' ');
- Lcd_Wdat(A3);
- Lcd_Wdat(A4);
- }
- else
- {
- Lcd_Pos(2,3);
- Lcd_Wdat(' ');
- Lcd_Wdat(' ');
- Lcd_Wdat(' ');
- Lcd_Wdat(A4);
- }
- //显示小数点, 小数点部分
- int2str(j,str1);
- if(j<10)
- {
- Lcd_Pos(2,5);
- Lcd_Wdat('.');
- Lcd_Wdat('0');
- Lcd_Wdat(B2);
- Lcd_Wdat(' ');
- }
- else
- {
- Lcd_Pos(2,5);
- Lcd_Wdat('.');
- Lcd_Wdat(B1);
- Lcd_Wdat(B2);
- Lcd_Wdat(' ');
- }
- }
- //显示重量,单位kg,两位整数,三位小数
- void Display_Weight()
- {
- uint i,j;
- uchar A1,A2;
- uchar B1,B2,B3;
- //weight单位是g
- i = weight/1000; //得到整数部分
- j = weight - i*1000;//得到小数部分
- A1=i/10+48;
- A2=i%10+48;
- B1=j/100+48;
- B2=j%100/10+48;
- B3=j%100%10+48;
- int2str(i,str1);
- if (i>=10)
- {
-
- }
- else
- {
- Lcd_Pos(1,4);
- Lcd_Wdat(' ');
- Lcd_Wdat(A2);
- }
- int2str(j,str1);
- if (j<10)
- {
- Lcd_Pos(1,5);
- Lcd_Wdat('.');
- Lcd_Wdat('0');
- Lcd_Wdat('0');
- Lcd_Wdat(B3);
- }
- else if (j<100)
- {
- Lcd_Pos(1,5);
- Lcd_Wdat('.');
- Lcd_Wdat('0');
- Lcd_Wdat(B2);
- Lcd_Wdat(B3);
- }
- else
- {
- Lcd_Pos(1,5);
- Lcd_Wdat('.');
- Lcd_Wdat(B1);
- Lcd_Wdat(B2);
- Lcd_Wdat(B3);
- }
- }
- //显示总价,单位为元,四位整数,两位小数
- void Display_Money()
- {
- uint i,j;
- uchar A1,A2,A3,A4;
- uchar B1,B2;
- if (money>999999) //超出显示量程
- {
- Lcd_Pos(3,3);
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- return;
- }
- i = money/100; //得到整数部分
- j = money - i*100;//得到小数部分
- A1=i/1000+48;
- A2=i%1000/100+48;
- A3=i%1000%100/10+48;
- A4=i%1000%100%10+48;
- B1=j/10+48;
- B2=j%10+48;
- int2str(i,str1);
- //显示整数部分
- if (i>=1000)
- {
- Lcd_Pos(3,3);
- Lcd_Wdat(A1);
- Lcd_Wdat(A2);
- Lcd_Wdat(A3);
- Lcd_Wdat(A4);
- }
- else if (i>=100)
- {
- Lcd_Pos(3,3);
- Lcd_Wdat(' ');
- Lcd_Wdat(A2);
- Lcd_Wdat(A3);
- Lcd_Wdat(A4);
- }
- else if (i>=10)
- {
- Lcd_Pos(3,3);
- Lcd_Wdat(' ');
- Lcd_Wdat(' ');
- Lcd_Wdat(A3);
- Lcd_Wdat(A4);
- }
- else
- {
- Lcd_Pos(3,3);
- Lcd_Wdat(' ');
- Lcd_Wdat(' ');
- Lcd_Wdat(' ');
- Lcd_Wdat(A4);
- }
- //显示小数点, 小数点部分
- int2str(j,str1);
- if(j<10)
- {
- Lcd_Pos(3,5);
- Lcd_Wdat('.');
- Lcd_Wdat('0');
- Lcd_Wdat(B2);
- }
- else
- {
- Lcd_Pos(3,5);
- Lcd_Wdat('.');
- Lcd_Wdat(B1);
- Lcd_Wdat(B2);
- }
- }
- //数据初始化
- void Data_Init()
- {
- price = 0;
- DotPos = 0;
- beep = 1;
- alert = 1;
- }
- //定时器0初始化
- void Timer0_Init()
- {
- ET0 = 1; //允许定时器0中断
- TMOD = 1; //定时器工作方式选择
- TL0 = 0x06;
- TH0 = 0xf8; //定时器赋予初值
- TR0 = 1; //启动定时器
- }
- //定时器0中断
- void Timer0_ISR (void) interrupt 1 using 0
- {
- TL0 = 0x06;
- TH0 = 0xf8; //定时器赋予初值
- //每0.5秒钟刷新重量
- Counter ++;
- if (Counter >= 200)
- {
- FlagTest = 1;
- Counter = 0;
- }
- }
- //按键响应程序,参数是键值
- //返回键值:
- // 1 2 3 10(清0)
- // 4 5 6 11(删除单价)
- // 7 8 9 12(去皮)
- // 14(未定义) 0 15(.) 13(未定义)
- void KeyPress(uchar keycode)
- {
- switch (keycode)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- //目前在设置整数位,要注意price是整型,存储单位为分
- if (DotPos == 0)
- {
- //最多只能设置到千位
- if (price<100000)
- {
- price=price*10+keycode*100;
- }
- }
- //目前在设置小数位
- else if (DotPos==1) //小数点后第一位
- {
- price=price+keycode*10;
- DotPos++;
- }
- else if (DotPos==2)
- {
- price=price+keycode;
- DotPos++;
- }
- Display_Price();
- break;
-
-
- case 10: //清零键
- Delay(15);//延时
- pricebc=price;
- To_Zero();
- price=pricebc;
- Display_Price();
- DotPos = 0;
- beep=~beep;
- break;
-
-
- case 11: //清楚单价
- Delay(15);//延时
- price=0;
- DotPos = 0;
- Display_Price();
- break;
-
- case 12: //去皮
- Delay(15);//延时
- ClearWeighFlag = 1; //置零传感器标志 置1
- break;
-
-
- case 13: //微调
- Delay(15);//延时
- if(wtk==0)
- RATIO--;//微调系数
- else
- RATIO=RATIO-20;//微调系数
- write_eeprom();//存入eerom内,掉电不丢失系数数据
- break;
-
-
- case 14: //微调减
- Delay(15);//延时
- if(wtk==0)
- RATIO++;//微调系数
- else
- RATIO=RATIO+20;//微调系数
- write_eeprom();//存入eerom内,掉电不丢失系数数据
- break;
-
- case 15: //小数点按下
- Delay(15);//延时
- if (DotPos == 0)
- {
- DotPos = 1; //小数点后第一位
- }
- break;
- }
- Delay(10);
- }
- void main()
- {
- Lcd_Init();
- EA = 0;
- Data_Init();
- Timer0_Init();
-
- EA = 1;//初始化完成,开中断
- beep=1;
- init_eeprom();
- Lcd_Clear(); //clear all dots
- Lcd_Display1();
- Delay(700);
- To_Zero();
- Lcd_Clear();
- Lcd_Display2();
- Display_Price();
- while(1)
- {
- //每0.5秒称重一次
- if (FlagTest==1)
- {
- //称重,得到重量值weight,单位为g
- AdVal=ReadCount();
- weight=FullScale-AdVal;
- if (weight>0x8000000) weight=0;
- weight=weight*10/RATIO;//物体实际重量=总量量程对于的是多少。
- //weight=10000*weight/FullScale;
- //weight=weight*RATIO;
- //如果超量程,则报警
- if (weight >= MAX)
- {
- beep = 0;
- alert = 0;
- Lcd_Pos(1,4);
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- Lcd_Pos(3,3);
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- Lcd_Wdat('-');
- }
- //如果不超量程
- else
- {
- beep = 1;
- alert = 1;
- Display_Weight();
- money = weight*price/1000; //money单位为分
- Display_Money();//显示总金额
- if(money>999999)
- money=999999;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
1-程序-10kg.rar
(67.55 KB, 下载次数: 144)
|