注意!
1.程序中采用P16、P17口作為HX711的數據口。
2.每個傳感器的系數不一樣,第一次測量必須修正傳感器的系數。(修正系數HX711_xishu)
修正方法:
例如1000g砝碼稱出來是934g,則HX711_xishu=(原值)*1000/934;
單片機源程序如下:
- #include <reg52.h> //調用單片機頭文件
- #include<intrins.h>
- #define uchar unsigned char //無符號字符型 宏定義 變量范圍0~255
- #define uint unsigned int //無符號整型 宏定義 變量范圍0~65535
- #define ulong unsigned long
- sbit rs=P0^5; //寄存器選擇信號 H:數據寄存器 L:指令寄存器
- sbit rw=P0^6; //寄存器選擇信號 H:數據寄存器 L:指令寄存器
- sbit e =P0^7; //片選信號 下降沿觸發
- sbit hx711_dout=P1^7;
- sbit hx711_sck =P1^6;
- sbit beep = P3^0; //蜂鳴器
- sbit K1 = P3^5; //加
- sbit K2 = P3^6; //長按去皮鍵
- sbit K3 = P3^7; //減
- uchar K2_num;
- uint time1;
- uint time2;
- uint time3;
- long weight; //實際重量值
- long qi_weight; //皮重
- ulong warn_weight;
- ulong HX711_xishu=35386; //這是一個修正系數,例如1000g砝碼稱出來是934g,則HX711_xishu=原數據*1000/934;
- #define MEDIAN_LEN 5 //中值濾波的濾波長度,一般取奇數
- #define MEDIAN 3 //中值在濾波數組中的位置
- ulong buffer[MEDIAN_LEN]; //中值濾波的數據緩存
- int medleng = 0; //一組中值濾波數據中,進入濾波緩存的數據個數
- ulong xd,xd1; //數據對比大小中間變量
- /***************
- 刪除鍵
- 去皮
- 價格清零
- ***************/
- /******1ms延時函數***11.0592M晶振**************/
- void delay_1ms(uint q)
- {
- ulong i,j;
- for(i=0;i<q;i++)
- for(j=0;j<11;j++);
- }
- /********************************************************************
- * 名稱 : delay_uint()
- * 功能 : 小延時。
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void delay_uint(uint q)
- {
- while(q--);
- }
- /********************************************************************
- * 名稱 : write_com(uchar com)
- * 功能 : 1602命令函數
- * 輸入 : 輸入的命令值
- * 輸出 : 無
- ***********************************************************************/
- void write_com(uchar com)
- {
- e=0;
- rs=0;
- rw=0;
- P2=com;
- delay_uint(3);
- e=1;
- delay_uint(25);
- e=0;
- }
- /********************************************************************
- * 名稱 : write_data(uchar dat)
- * 功能 : 1602寫數據函數
- * 輸入 : 需要寫入1602的數據
- * 輸出 : 無
- ***********************************************************************/
- void write_data(uchar dat)
- {
- e=0;
- rs=1;
- rw=0;
- P2=dat;
- delay_uint(3);
- e=1;
- delay_uint(25);
- e=0;
- }
- /***********************lcd1602上顯示這字符函數************************/
- void write_string(uchar hang,uchar add,uchar *p)
- {
- if(hang==1)
- write_com(0x80+add);
- else
- write_com(0x80+0x40+add);
- while(1)
- {
- if(*p == '\0') break;
- write_data(*p);
- p++;
- }
- }
- /***********************lcd1602初始化設置************************/
- void init_1602() //lcd1602初始化設置
- {
- write_com(0x38); //
- write_com(0x0c);
- write_com(0x06);
- delay_uint(1000);
- }
- void Delay__hx711_us(void)
- {
- _nop_();
- _nop_();
- }
- ulong ReadCount(void) //增益128
- {
- ulong count,value = 0;
- uchar 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;
- }
- void get_pizhong() //獲取皮重,秤盤重量
- {
- ulong hx711_dat;
- uchar i;
- for(i=0;i<MEDIAN_LEN;i++)
- {
- hx711_dat=ReadCount(); //HX711AD轉換數據處理
- if(medleng == 0) //緩存的第1個元素,直接放入,不需要排序
- {
- buffer[0] = hx711_dat; medleng = 1;
- }
- else //插入排序算法,按從小到大的順序排列
- {
- for(i = 0; i < medleng; i ++)
- {
- if( buffer[i] > hx711_dat) // 輪詢到的當前元素>AD值,則交換它們的值,xd為中間變量存放位置
- {
- xd = hx711_dat; hx711_dat = buffer[i]; buffer[i] = xd;
- }
- }
- buffer[medleng] = hx711_dat; //把輪詢出較大的數放入緩存的后面.
- medleng++;
- }
- if(medleng >= MEDIAN_LEN) //ADC采樣的數據個數達到中值濾波要求的數據個數
- {
- hx711_dat = buffer[MEDIAN]; //最終重量取中值濾波數組的中間值
- medleng = 0;
- }
- }
- qi_weight=(uint)(hx711_dat*0.01);
- }
- void get_weight() //獲取被測物體重量
- {
- ulong hx711_data,a;
- ulong get,aa;
- hx711_data=ReadCount(); //HX711數據采集函數
- get=(uint)(hx711_data*0.01); //HX711AD轉換數據處理,數據縮小100倍
- if(get>qi_weight)
- {
- a=ReadCount(); //重新采集HX711數據
- aa=(uint)(a*0.01)-qi_weight; //測得的重量值減去皮重
- weight=(uint)((float)aa*0.00001*HX711_xishu);//重量轉換函數,傳感器型號不同此函數要適當修改(修改HX711_xishu的大。
- //超重報警
- if(weight>=warn_weight)
- {
- //1602液晶第二行,不停閃爍,以此為超重報警
- write_string(2,1," ");
- delay_1ms(300);
- write_string(2,1,"Warning g");
- write_com(0xc0+10);
- write_data(warn_weight/10000%10+0x30);
- write_data(warn_weight/1000%10+0x30);
- write_data(warn_weight/100%10+0x30);
- write_data(warn_weight/10%10+0x30);
- write_data(warn_weight%10+0x30);
- write_string(2,15,"g");delay_1ms(200);
- }
- }
- else
- {
- //皮重大于商品重量5g(避免干擾),可以在此設置負重報警
- if(qi_weight*0.00001*HX711_xishu-get*0.00001*HX711_xishu>=5)
- {
- //1602液晶第二行"Warning"不停閃爍,以此為負重報警
- write_string(2,1," ");delay_1ms(300);
- write_string(2,1,"Warning");delay_1ms(200);
- }
- weight=0;
-
- }
- }
- /************************************************
- 由于稱重傳感器線性度參數的不同,而對獲得的重量數據處理,此
- 處可能會根據不同稱重傳感器,程序的代碼的校準系數會有所不同
- /*****************主函數********************/
- void main()
- {
- uchar i;
- delay_1ms(500); //等待開機數據穩定
- init_1602(); //lcd1602初始化
- write_string(1,0," Welcome to you ");
- write_string(2,0,"Electronic scale");
- get_pizhong(); //獲取皮重,秤盤重量
- delay_1ms(2000);delay_1ms(2000);
- get_pizhong(); //再次獲取皮重,秤盤重量
- warn_weight=5000;
- write_string(1,0," Weight g");
- write_string(2,0," Warning g");
- while(1)
- {
- //按鍵2
- if(K2==0)
- {
- delay_1ms(10);
- if(K2==0)
- {
- while(!K2)
- {
- time2++;
- delay_1ms(10);
- if(time2>=200) //長按鍵:按下時間達到一定時進入執行
- {
- time2=200;
- get_pizhong(); //數據清零,即去皮
- get_weight();
- //去皮成功,清零重量閃爍3下
- write_string(1,10,"00000g");
- write_string(1,10," ");delay_1ms(300);
- write_string(1,10,"00000g");delay_1ms(300);
- write_string(1,10," ");delay_1ms(300);
- write_string(1,10,"00000g");delay_1ms(300);
- write_string(1,10," ");delay_1ms(300);
- write_string(1,10,"00000g");
- while(!K2);
- }
-
- }
- if(time2<200) //短按鍵:按下時間短進入執行
- {
- K2_num++;
- if(K2_num==3)
- K2_num=0;
- if(K2_num==0)
- {
- write_string(1,0," ");
- write_string(2,0," ");
- }
- if(K2_num==1)
- {
- write_string(1,0,"*");
- write_string(2,0," ");
- }
- if(K2_num==2)
- {
- write_string(1,0," ");
- write_string(2,0,"*");
- }
- }
- time2=0;
- }
- while(!K2);//松手檢測
- }
- //按鍵1__減
- if(K1==0)
- {
- delay_1ms(10);
- if(K1==0)
- {
- while(!K1)
- {
- time1++;
- delay_1ms(10);
- if(time1>=100) //長按鍵:按下時間達到一定時進入執行
- {
- time1=100;
- if(K2_num==1)
- {
-
- }
- if(K2_num==2)
- {
- if(warn_weight>1000)
- warn_weight=warn_weight-1000;
- //報警重量顯示
- write_com(0xc0+10);
- write_data(warn_weight/10000%10+0x30);
- write_data(warn_weight/1000%10+0x30);
- write_data(warn_weight/100%10+0x30);
- write_data(warn_weight/10%10+0x30);
- write_data(warn_weight%10+0x30);
- while(!K1);
- }
- }
- }
- if(time1<100) //短按鍵:按下時間短進入執行
- {
- if(K2_num==2)
- {
- if(warn_weight>100)
- warn_weight=warn_weight-100;
- }
- }
- time1=0;
- }
- while(!K1);//松手檢測
- }
- //按鍵3__加
- if(K3==0)
- {
- delay_1ms(10);
- if(K3==0)
- {
- while(!K3)
- {
- time3++;
- delay_1ms(10);
- if(time3>=100) //長按鍵:按下時間達到一定時進入執行
- {
- time3=100;
- if(K2_num==1)
- {
-
- }
- if(K2_num==2)
- {
- if(warn_weight<99000)
- warn_weight=warn_weight+1000;
- //報警重量顯示
- write_com(0xc0+10);
- write_data(warn_weight/10000%10+0x30);
- write_data(warn_weight/1000%10+0x30);
- write_data(warn_weight/100%10+0x30);
- write_data(warn_weight/10%10+0x30);
- write_data(warn_weight%10+0x30);
- while(!K3);
- }
- }
- }
- if(time3<100) //短按鍵:按下時間短進入執行
- {
- if(K2_num==2)
- {
- if(warn_weight<99900)
- warn_weight=warn_weight+100;
- }
- }
- time3=0;
- }
- while(!K3); //松手檢測
- }
- get_weight(); //獲取被測物體重量
- if(medleng == 0) //緩存的第1個元素,直接放入,不需要排序
- {
- buffer[0] = weight; medleng = 1;
- }
- else //插入排序算法,按從小到大的順序排列
- {
- for(i = 0; i < medleng; i ++)
- {
- if( buffer[i] > weight) // 輪詢到的當前元素>AD值,則交換它們的值,xd為中間變量存放位置
- {
- xd = weight; weight = buffer[i]; buffer[i] = xd;
- }
- }
- buffer[medleng] = weight; //把輪詢出較大的數放入緩存的后面.
- medleng++;
- }
- if(medleng >= MEDIAN_LEN) //ADC采樣的數據個數達到中值濾波要求的數據個數
- {
- weight = buffer[MEDIAN]; //最終重量取中值濾波數組的中間值
- medleng = 0;
- //實際重量顯示,四位數據顯示
- write_com(0x80+10);
- write_data(weight/10000%10+0x30);
- write_data(weight/1000%10+0x30);
- write_data(weight/100%10+0x30);
- write_data(weight/10%10+0x30);
- write_data(weight%10+0x30);
- //報警重量顯示,四位數據顯示
- write_com(0xc0+10);
- write_data(warn_weight/10000%10+0x30);
- write_data(warn_weight/1000%10+0x30);
- write_data(warn_weight/100%10+0x30);
- write_data(warn_weight/10%10+0x30);
- write_data(warn_weight%10+0x30);
- weight=0;
- }
- }
- }
復制代碼
所有資料51hei提供下載:
基于stm32的電子秤.7z
(2.53 MB, 下載次數: 51)
2019-9-2 22:26 上傳
點擊文件名下載附件
|