目录

原理图:​

引脚介绍:

HX711介绍工作原理:

程序讲解:

整套工程:

发送的代码工程,与博客的不一致,如果编译有报错请按照报错和博客进行修改

原理图:

 引脚介绍:

VCC和GND引脚分别为HX711芯片的电源输入端口。

VCC引脚是连接到5V或3.3V的正电源,GND引脚是连接到地的负电源。

DOUT是HX711芯片的数据输出端口,它输出经过A/D转换处理后的24位数据。

SCK是HX711芯片的时钟输入端口,用于控制A/D转换的时钟。

后两个用于接单片机的GPIO口

HX711介绍工作原理:

HX711传感器由一个二进制模数转换器(ADC)和一个放大器组成。ADC可以将模拟信号转换为数字信号,而放大器可以扩大信号的幅度,以便更精确地测量。在称重应用中,HX711传感器可以通过应变量来测量物体的质量。

应变量是由当物体受到压力时会发生应变的特殊材料制成的。将应变量粘贴到测量物体的表面,当物体受到压力并伸展时,应变量也会发生变化。压力越大,应变量的变化也越大。

HX711压力传感器的工作原理基于万用表电桥原理,利用压力传感器的阻值变化来实现重量的测量。

具体的工作流程如下:

通过引脚A+和A-接入压力传感器。在未加载的情况下,两个引脚之间的电阻为R1。 在HX711芯片中,使用一个基准电压(通常为VCC/2)来作为压力传感器电桥电路的中心点。 当压力传感器开始承受载荷时,电桥电路会产生一个微小的电压差。 这个电压差通过A+和A-引脚输入到HX711芯片中,并经过内置的差分放大器放大。 放大之后的信号被送到24位的A/D转换器中进行数字化处理,并通过DOUT引脚输出。 PD_SCK引脚则是用于通过时钟信号来同步转换器的输出数据。 最终,通过对输入信号的放大和数字化处理,HX711芯片可以输出重量数据。

程序讲解:

1.HX711初始化

void Init_HX711pin(void)//初始化

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PF端口时钟

//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); //根据设定参数初始化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); //初始化设置为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个脉冲下降沿来时,转换数据

delay_us(1);

HX711_SCK=0;

return(count);

}

解释讲解:

函数中定义了三个变量:count、i和一个延时值。其中,count是一个无符号长整型变量,用于存储从HX711获取的数据。i是一个无符号字符型变量,用于循环计数。delay_us(1)表示延时1微秒,用于确保时序的准确性。

然后,函数通过设置HX711_DOUT和HX711_SCK的电平,使HX711传感器进入读取状态。

接下来,函数使用while语句来等待DOUT的第一个脉冲到来。当DOUT为高电平时,表示HX711传感器还没有准备好,此时需要等待。当DOUT为低电平时,表示HX711传感器已经准备好,可以开始读取数据了。

然后,函数使用一个for循环来读取HX711传感器的24个数据位。在每个时钟周期中,函数将SCK设为高电平,然后将count左移一位。如果此时DOUT为高电平,则表示在该时钟周期内,HX711传感器向count的当前位中写入了1,此时需要将count的最低位设为1。如果此时DOUT为低电平,则表示在该时钟周期内,HX711传感器向count的当前位中写入了0,此时可以不用进行操作。最后,函数将SCK设为低电平,并延时一个周期。

读取完24个数据位后,此时count变量中存储着24位的数据。此时需要将count的最高位设为1,以便扩展到32位。这可以通过将count异或0x800000来实现。

最后,函数将SCK设为高电平,并延时一个周期,然后将SCK设为低电平。该函数返回count变量作为结果,即为从HX711传感器读取到的数据。

增益数值不同意味着循环的次数不同【增益128-循环24次;增益32-循环25次;增益64循环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; //获取实物的AD采样数值。

Weight_Shiwu = (s32)((float)Weight_Shiwu/GapValue)-478; //计算实物的实际重量

//因为不同的传感器特性曲线不一样,因此,每一个传感器需要矫正这里的GapValue这个除数。

//当发现测试出来的重量偏大时,增加该数值。

//如果测试出来的重量偏小时,减小改数值。

}

}

至于为什么要在最后的减去478,因为我在测试的时候发现原始数据是478,要去皮就是减478

温馨提示:压力传感器上面不能有东西,否则初始状态以有东西为0的初始态。举个例子:水瓶放到传感器上,启动单片机,这样传感器以有水瓶的状态为初始状态,若我把水拿开,则显示是负数

整套工程:

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_; //对应公式中的p'

float X=0;

float X_; //X'

float K=0;

float Q=0.01;//噪声

//float R=0.2; //R如果很大,更相信预测值,那么传感器反应就会迟钝,反之相反

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;

}

//校准参数

//因为不同的传感器特性曲线不是很一致,因此,每一个传感器需要矫正这里这个参数才能使测量值很准确。

//当发现测试出来的重量偏大时,增加该数值。

//如果测试出来的重量偏小时,减小改数值。

//该值可以为小数

#define GapValue 106.5

void Init_HX711pin(void)//初始化

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PF端口时钟

//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); //根据设定参数初始化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); //初始化设置为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个脉冲下降沿来时,转换数据

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; //获取实物的AD采样数值。

Weight_Shiwu = (s32)((float)Weight_Shiwu/GapValue)-478; //计算实物的实际重量

//因为不同的传感器特性曲线不一样,因此,每一个传感器需要矫正这里的GapValue这个除数。

//当发现测试出来的重量偏大时,增加该数值。

//如果测试出来的重量偏小时,减小改数值。

Weight_Shiwu=KLM(Weight_Shiwu);

}

}

文中用到了卡尔曼滤波减少了数值的波动

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(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级

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);

}

}

展示

需要工程文件的,麻烦您点赞、收藏、关注,留下邮箱即可

MSP432P401R版本:HX711压力传感器学习二(MSP432P401R版)_三马分享家的博客-CSDN博客

推荐阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: