目錄
原理圖:?
引腳介紹:
HX711介紹工作原理:
程序講解:
整套工程:
發(fā)送的代碼工程,與博客的不一致,如果編譯有報(bào)錯(cuò)請(qǐng)按照?qǐng)?bào)錯(cuò)和博客進(jìn)行修改
原理圖:
?引腳介紹:
VCC和GND引腳分別為HX711芯片的電源輸入端口。
VCC引腳是連接到5V或3.3V的正電源,GND引腳是連接到地的負(fù)電源。
DOUT是HX711芯片的數(shù)據(jù)輸出端口,它輸出經(jīng)過(guò)A/D轉(zhuǎn)換處理后的24位數(shù)據(jù)。
SCK是HX711芯片的時(shí)鐘輸入端口,用于控制A/D轉(zhuǎn)換的時(shí)鐘。
后兩個(gè)用于接單片機(jī)的GPIO口
HX711介紹工作原理:
HX711傳感器由一個(gè)二進(jìn)制模數(shù)轉(zhuǎn)換器(ADC)和一個(gè)放大器組成。ADC可以將模擬信號(hào)轉(zhuǎn)換為數(shù)字信號(hào),而放大器可以擴(kuò)大信號(hào)的幅度,以便更精確地測(cè)量。在稱重應(yīng)用中,HX711傳感器可以通過(guò)應(yīng)變量來(lái)測(cè)量物體的質(zhì)量。
應(yīng)變量是由當(dāng)物體受到壓力時(shí)會(huì)發(fā)生應(yīng)變的特殊材料制成的。將應(yīng)變量粘貼到測(cè)量物體的表面,當(dāng)物體受到壓力并伸展時(shí),應(yīng)變量也會(huì)發(fā)生變化。壓力越大,應(yīng)變量的變化也越大。
HX711壓力傳感器的工作原理基于萬(wàn)用表電橋原理,利用壓力傳感器的阻值變化來(lái)實(shí)現(xiàn)重量的測(cè)量。
具體的工作流程如下:
-
通過(guò)引腳A+和A-接入壓力傳感器。在未加載的情況下,兩個(gè)引腳之間的電阻為R1。
-
在HX711芯片中,使用一個(gè)基準(zhǔn)電壓(通常為VCC/2)來(lái)作為壓力傳感器電橋電路的中心點(diǎn)。
-
當(dāng)壓力傳感器開(kāi)始承受載荷時(shí),電橋電路會(huì)產(chǎn)生一個(gè)微小的電壓差。
-
這個(gè)電壓差通過(guò)A+和A-引腳輸入到HX711芯片中,并經(jīng)過(guò)內(nèi)置的差分放大器放大。
-
放大之后的信號(hào)被送到24位的A/D轉(zhuǎn)換器中進(jìn)行數(shù)字化處理,并通過(guò)DOUT引腳輸出。
-
PD_SCK引腳則是用于通過(guò)時(shí)鐘信號(hào)來(lái)同步轉(zhuǎn)換器的輸出數(shù)據(jù)。
-
最終,通過(guò)對(duì)輸入信號(hào)的放大和數(shù)字化處理,HX711芯片可以輸出重量數(shù)據(jù)。
程序講解:
1.HX711初始化
void Init_HX711pin(void)//初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PF端口時(shí)鐘
//HX711_SCK
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根據(jù)設(shè)定參數(shù)初始化GPIOB
//HX711_DOUT
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//輸入上拉
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_0); //初始化設(shè)置為0
}
2.讀取HX711
u32 HX711_Read(void) //增益128
{
unsigned long count;
unsigned char i;
HX711_DOUT=1;
delay_us(1);
HX711_SCK=0;
count=0;
while(HX711_DOUT);
for(i=0;i<24;i++)
{
HX711_SCK=1;
count=count<<1;
delay_us(1);
HX711_SCK=0;
if(HX711_DOUT)
count++;
delay_us(1);
}
HX711_SCK=1;
count=count^0x800000;//第25個(gè)脈沖下降沿來(lái)時(shí),轉(zhuǎn)換數(shù)據(jù)
delay_us(1);
HX711_SCK=0;
return(count);
}
解釋講解:
函數(shù)中定義了三個(gè)變量:count、i和一個(gè)延時(shí)值。其中,count是一個(gè)無(wú)符號(hào)長(zhǎng)整型變量,用于存儲(chǔ)從HX711獲取的數(shù)據(jù)。i是一個(gè)無(wú)符號(hào)字符型變量,用于循環(huán)計(jì)數(shù)。delay_us(1)表示延時(shí)1微秒,用于確保時(shí)序的準(zhǔn)確性。
然后,函數(shù)通過(guò)設(shè)置HX711_DOUT和HX711_SCK的電平,使HX711傳感器進(jìn)入讀取狀態(tài)。
接下來(lái),函數(shù)使用while語(yǔ)句來(lái)等待DOUT的第一個(gè)脈沖到來(lái)。當(dāng)DOUT為高電平時(shí),表示HX711傳感器還沒(méi)有準(zhǔn)備好,此時(shí)需要等待。當(dāng)DOUT為低電平時(shí),表示HX711傳感器已經(jīng)準(zhǔn)備好,可以開(kāi)始讀取數(shù)據(jù)了。
然后,函數(shù)使用一個(gè)for循環(huán)來(lái)讀取HX711傳感器的24個(gè)數(shù)據(jù)位。在每個(gè)時(shí)鐘周期中,函數(shù)將SCK設(shè)為高電平,然后將count左移一位。如果此時(shí)DOUT為高電平,則表示在該時(shí)鐘周期內(nèi),HX711傳感器向count的當(dāng)前位中寫(xiě)入了1,此時(shí)需要將count的最低位設(shè)為1。如果此時(shí)DOUT為低電平,則表示在該時(shí)鐘周期內(nèi),HX711傳感器向count的當(dāng)前位中寫(xiě)入了0,此時(shí)可以不用進(jìn)行操作。最后,函數(shù)將SCK設(shè)為低電平,并延時(shí)一個(gè)周期。
讀取完24個(gè)數(shù)據(jù)位后,此時(shí)count變量中存儲(chǔ)著24位的數(shù)據(jù)。此時(shí)需要將count的最高位設(shè)為1,以便擴(kuò)展到32位。這可以通過(guò)將count異或0x800000來(lái)實(shí)現(xiàn)。
最后,函數(shù)將SCK設(shè)為高電平,并延時(shí)一個(gè)周期,然后將SCK設(shè)為低電平。該函數(shù)返回count變量作為結(jié)果,即為從HX711傳感器讀取到的數(shù)據(jù)。
增益數(shù)值不同意味著循環(huán)的次數(shù)不同【增益128-循環(huán)24次;增益32-循環(huán)25次;增益64循環(huán)26次】
?3.稱重
void Get_Weight(void)
{
HX711_Buffer = HX711_Read();
if(HX711_Buffer > Weight_Maopi)
{
Weight_Shiwu = HX711_Buffer;
Weight_Shiwu = Weight_Shiwu - Weight_Maopi; //獲取實(shí)物的AD采樣數(shù)值。
Weight_Shiwu = (s32)((float)Weight_Shiwu/GapValue)-478; //計(jì)算實(shí)物的實(shí)際重量
//因?yàn)椴煌膫鞲衅魈匦郧€不一樣,因此,每一個(gè)傳感器需要矯正這里的GapValue這個(gè)除數(shù)。
//當(dāng)發(fā)現(xiàn)測(cè)試出來(lái)的重量偏大時(shí),增加該數(shù)值。
//如果測(cè)試出來(lái)的重量偏小時(shí),減小改數(shù)值。
}
}
至于為什么要在最后的減去478,因?yàn)槲以跍y(cè)試的時(shí)候發(fā)現(xiàn)原始數(shù)據(jù)是478,要去皮就是減478
溫馨提示:壓力傳感器上面不能有東西,否則初始狀態(tài)以有東西為0的初始態(tài)。舉個(gè)例子:水瓶放到傳感器上,啟動(dòng)單片機(jī),這樣傳感器以有水瓶的狀態(tài)為初始狀態(tài),若我把水拿開(kāi),則顯示是負(fù)數(shù)
整套工程:
HX711.C
/************************************************************************************
*************************************************************************************/
#include "HX711.h"
#include "delay.h"
u32 HX711_Buffer;
u32 Weight_Maopi;
s32 Weight_Shiwu;
u8 Flag_Error = 0;
float P=1;
float P_; //對(duì)應(yīng)公式中的p'
float X=0;
float X_; //X'
float K=0;
float Q=0.01;//噪聲
//float R=0.2; //R如果很大,更相信預(yù)測(cè)值,那么傳感器反應(yīng)就會(huì)遲鈍,反之相反
float R=0.5;
float distance=0;
float distance1=0;
float KLM(float Z)
{
X_=X+0;
P_=P+Q;
K=P_/(P_+R);
X=X_+K*(Z-X_);
P=P_-K*P_;
return X;
}
//校準(zhǔn)參數(shù)
//因?yàn)椴煌膫鞲衅魈匦郧€不是很一致,因此,每一個(gè)傳感器需要矯正這里這個(gè)參數(shù)才能使測(cè)量值很準(zhǔn)確。
//當(dāng)發(fā)現(xiàn)測(cè)試出來(lái)的重量偏大時(shí),增加該數(shù)值。
//如果測(cè)試出來(lái)的重量偏小時(shí),減小改數(shù)值。
//該值可以為小數(shù)
#define GapValue 106.5
void Init_HX711pin(void)//初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PF端口時(shí)鐘
//HX711_SCK
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根據(jù)設(shè)定參數(shù)初始化GPIOB
//HX711_DOUT
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//輸入上拉
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_0); //初始化設(shè)置為0
}
//****************************************************
//讀取HX711
//****************************************************
u32 HX711_Read(void) //增益128
{
unsigned long count;
unsigned char i;
HX711_DOUT=1;
delay_us(1);
HX711_SCK=0;
count=0;
while(HX711_DOUT);
for(i=0;i<24;i++)
{
HX711_SCK=1;
count=count<<1;
delay_us(1);
HX711_SCK=0;
if(HX711_DOUT)
count++;
delay_us(1);
}
HX711_SCK=1;
count=count^0x800000;//第25個(gè)脈沖下降沿來(lái)時(shí),轉(zhuǎn)換數(shù)據(jù)
delay_us(1);
HX711_SCK=0;
return(count);
}
//****************************************************
//獲取毛皮重量
//****************************************************
void Get_Maopi(void)
{
Weight_Maopi = HX711_Read();
}
//****************************************************
//稱重
//****************************************************
void Get_Weight(void)
{
HX711_Buffer = HX711_Read();
if(HX711_Buffer > Weight_Maopi)
{
Weight_Shiwu = HX711_Buffer;
Weight_Shiwu = Weight_Shiwu - Weight_Maopi; //獲取實(shí)物的AD采樣數(shù)值。
Weight_Shiwu = (s32)((float)Weight_Shiwu/GapValue)-478; //計(jì)算實(shí)物的實(shí)際重量
//因?yàn)椴煌膫鞲衅魈匦郧€不一樣,因此,每一個(gè)傳感器需要矯正這里的GapValue這個(gè)除數(shù)。
//當(dāng)發(fā)現(xiàn)測(cè)試出來(lái)的重量偏大時(shí),增加該數(shù)值。
//如果測(cè)試出來(lái)的重量偏小時(shí),減小改數(shù)值。
Weight_Shiwu=KLM(Weight_Shiwu);
}
}
文中用到了卡爾曼濾波減少了數(shù)值的波動(dòng)
HX711.H
#ifndef __HX711_H
#define __HX711_H
#include "sys.h"
#define HX711_SCK PBout(0)// PB0
#define HX711_DOUT PBin(1)// PB1
extern void Init_HX711pin(void);
extern u32 HX711_Read(void);
extern void Get_Maopi(void);
extern void Get_Weight(void);
extern u32 HX711_Buffer;
extern u32 Weight_Maopi;
extern s32 Weight_Shiwu;
extern u8 Flag_Error;
#endif
main
/************************************************************************************
*************************************************************************************/
#include "stm32f10x.h"
#include "delay.h"
#include "HX711.h"
#include "usart.h"
#include "OLED.H"
int main(void)
{
Init_HX711pin();
delay_init();
NVIC_Configuration(); //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí)
uart_init(9600); //串口初始化為9600
Get_Maopi(); //稱毛皮重量
delay_ms(1000);
delay_ms(1000);
Get_Maopi(); //重新獲取毛皮重量
while(1)
{
Get_Weight();
printf("凈重量 = %d g\r\n",Weight_Shiwu); //打印
delay_ms(100);
}
}
展示
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-450561.html
需要工程文件的,麻煩您點(diǎn)贊、收藏、關(guān)注,留下郵箱即可
MSP432P401R版本:HX711壓力傳感器學(xué)習(xí)二(MSP432P401R版)_三馬分享家的博客-CSDN博客文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-450561.html
到了這里,關(guān)于HX711壓力傳感器學(xué)習(xí)(STM32)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!