目录

原理图:​

引脚介绍:

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压力传感器的工作原理基于万用表电桥原理,利用压力传感器的阻值变化来实现重量的测量。

具体的工作流程如下

  1. 通过引脚A+和A-接入压力传感器。在未加载的情况下,两个引脚之间的电阻为R1。

  2. 在HX711芯片中,使用一个基准电压(通常为VCC/2)来作为压力传感器电桥电路的中心点。

  3. 当压力传感器开始承受载荷时,电桥电路会产生一个微小的电压差。

  4. 这个电压差通过A+和A-引脚输入到HX711芯片中,并经过内置的差分放大器放大。

  5. 放大之后的信号被送到24位的A/D转换器中进行数字化处理,并通过DOUT引脚输出。

  6. PD_SCK引脚则是用于通过时钟信号来同步转换器的输出数据。

  7. 最终,通过对输入信号的放大和数字化处理,HX711芯片可以输出重量数据。

程序讲解:

1.HX711初始化

void Init_HX711pin(void)//初始化
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);   //使能PF端口时钟//HX711_SCKGPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                 // 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //IO口速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);                     //根据设定参数初始化GPIOB//HX711_DOUTGPIO_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.5void Init_HX711pin(void)//初始化
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);   //使能PF端口时钟//HX711_SCKGPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                 // 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //IO口速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);                     //根据设定参数初始化GPIOB//HX711_DOUTGPIO_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)// PB1extern 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);    //串口初始化为9600Get_Maopi();               //称毛皮重量delay_ms(1000);delay_ms(1000);Get_Maopi();               //重新获取毛皮重量while(1){Get_Weight();printf("净重量 = %d g\r\n",Weight_Shiwu); //打印 delay_ms(100);}
}

展示

HX711压力传感器学习(STM32)相关推荐

  1. 如何系统地入门学习stm32?

    我从事单片机开发多年,用过非常多芯片,有stc.中颖.GD.新唐.BLE.Zigbee.NXP.还有一些国产SOC等等,唯独ST的让我最省心,不管是STM8还是STM32. 省心只要是体现在稳定,只需 ...

  2. 知乎嵌入式大杂烩:学习STM32的一点经验分享

    前言 前两天在群里看到群友们在讨论学习STM32的话题,并且今天也有一位机械专业的准研究生也问了STM32的入门问题.正好我也有一点经验,所以试着分享一下这个话题.我也不是什么大神,只是一名普通的工程 ...

  3. proteus里面没有stm32怎么办_学习STM32日志——独立看门狗实验(20.06.23)

    继续更新学习STM32的历程,今天学习看门狗. 在单片机构成的微型计算机系统中,单片机的工作时常收到外界电磁场的干扰,导致程序跑飞,陷入死循环.为了解决这个问题,产生了一种用于监测单片机程序运行状态的 ...

  4. keil 查看 stm32 io波形_这样学习STM32单片机,从菜鸟到牛人很简单!

    我想说,为了学习单片机而去学习单片机的思路不对. 你问,如何系统地入门学习stm32呢? 这本身就是一个错误的问题.假如你会使用8051 , 会写C语言,那么STM32本身并不需要刻意的学习. 你要考 ...

  5. stm32 web 参数_老司机们都是怎么学习STM32的?

    单片机用处这么广,尤其是STM32,这么火!如何快速上手学习呢? "不要去学STM32".我不是说STM32不好,而是这种为了学习单片机而去学习单片机的思路不对.你问,如何系统地入 ...

  6. keil 查看 stm32 io波形_如何系统地入门学习stm32?

    我想说,为了学习单片机而去学习单片机的思路不对. 你问,如何系统地入门学习stm32呢? 这本身就是一个错误的问题.假如你会使用8051 , 会写C语言,那么STM32本身并不需要刻意的学习. 你要考 ...

  7. 老司机们都是怎么学习STM32的?

    单片机用处这么广,尤其是STM32,这么火!如何快速上手学习呢? "不要去学STM32".我不是说STM32不好,而是这种为了学习单片机而去学习单片机的思路不对. 你问,如何系统地 ...

  8. 学习 stm32(TTL)串口通信控制16路舵机控制板(维特智能)

    学习STM32Core平台串口2连接维特智能串口Normal协议,然后通过串口1直接连接舵机控制板(TTL),接收进行通信:需要看产品文档的可以直接官网搜索文档. 16路舵机控制板官方产品网址 在查看 ...

  9. 嵌入式学习⑤——STM32嵌入式应用系统设计

    目录 前言 一.基于跨平台多类型代码编辑器VScode 1.VScode的安装 2.Ubuntu中用vscode编译调试C\C++ 二.Proteus仿真--STM32流水灯 1.创建工程 2.配置实 ...

最新文章

  1. java cookie共享_JavaWeb的session及其共享技术
  2. 人脸识别撞脸名画_与名画“撞脸”火爆数博会 观众直呼“太好玩”【高清组图】...
  3. C和指针之字符串总结
  4. ionic 返回上一页,并刷新父页面
  5. IO之流程与buffer 图
  6. 流行于机器学习竞赛的Boosting,一文讲透足够了
  7. oracle中常用的方法,oracle常用方法
  8. AngularJs HelloWorld
  9. Docker的概念及基本指令学习(从安装、管理、核心概念到docker file 、 服务编排、集群)
  10. 习题4-6 莫尔斯代码(Morse Mismatches,ACM/ICPC World Finals 1997,UVa508)
  11. FME、MYFME安装破解教程
  12. Python实现Pearson相关系数计算及公式化简过程
  13. 第二重要极限公式推导过程_机器学习——一文详解逻辑回归「附详细推导和代码」...
  14. 编程珠玑番外篇之番外篇-O 中间语言和虚拟机漫谈(ZZ)
  15. 举例说明计算机中常用的变址寻址,堆栈寻址,从形式地址到得到操作数的寻址处理过程。
  16. java broken pipe_java.net.SocketException: Broken pipe问题解决
  17. mysql 数字 除以 一万_腾讯股票接口、和讯网股票接口、新浪股票接口、雪球股票数据、网易股票数据...
  18. java安全学习(一)
  19. 中芯国际透露:14nm或不能为某客户代工
  20. python内置函数getattr()和setattr()

热门文章

  1. 中国污水源热泵运行现状分析与投资策略报告2022-2027年
  2. Spring Boot优缺点总结
  3. html+css+js 实现图片轮播效果
  4. 操作成功失败html,固话呼叫转移设置不成功怎么办?
  5. The Thirty-fifth Of Word-Day
  6. 阿拉伯数转中文与英文[找到规律,抽象问题,转换成代码]
  7. 微信支付结算费率怎么降低至0.2~0.35操作方法
  8. c语言开发exporter,cadvisor node-exporter引发的容器文件系统泄漏
  9. http keep-live
  10. C# CultureInfo列表