当前位置:   article > 正文

HX711压力传感器学习一(STM32)

hx711

目录

原理图:​

引脚介绍:

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初始化

  1. void Init_HX711pin(void)//初始化
  2. {
  3. GPIO_InitTypeDef GPIO_InitStructure;
  4. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PF端口时钟
  5. //HX711_SCK
  6. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 端口配置
  7. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  8. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
  9. GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB
  10. //HX711_DOUT
  11. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  12. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//输入上拉
  13. GPIO_Init(GPIOB, &GPIO_InitStructure);
  14. GPIO_SetBits(GPIOB,GPIO_Pin_0); //初始化设置为0
  15. }

2.读取HX711

  1. u32 HX711_Read(void) //增益128
  2. {
  3. unsigned long count;
  4. unsigned char i;
  5. HX711_DOUT=1;
  6. delay_us(1);
  7. HX711_SCK=0;
  8. count=0;
  9. while(HX711_DOUT);
  10. for(i=0;i<24;i++)
  11. {
  12. HX711_SCK=1;
  13. count=count<<1;
  14. delay_us(1);
  15. HX711_SCK=0;
  16. if(HX711_DOUT)
  17. count++;
  18. delay_us(1);
  19. }
  20. HX711_SCK=1;
  21. count=count^0x800000;//25个脉冲下降沿来时,转换数据
  22. delay_us(1);
  23. HX711_SCK=0;
  24. return(count);
  25. }

解释讲解:

函数中定义了三个变量: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.称重

  1. void Get_Weight(void)
  2. {
  3. HX711_Buffer = HX711_Read();
  4. if(HX711_Buffer > Weight_Maopi)
  5. {
  6. Weight_Shiwu = HX711_Buffer;
  7. Weight_Shiwu = Weight_Shiwu - Weight_Maopi; //获取实物的AD采样数值。
  8. Weight_Shiwu = (s32)((float)Weight_Shiwu/GapValue)-478; //计算实物的实际重量
  9. //因为不同的传感器特性曲线不一样,因此,每一个传感器需要矫正这里的GapValue这个除数。
  10. //当发现测试出来的重量偏大时,增加该数值。
  11. //如果测试出来的重量偏小时,减小改数值。
  12. }
  13. }

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

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

整套工程:

HX711.C

  1. /************************************************************************************
  2. *************************************************************************************/
  3. #include "HX711.h"
  4. #include "delay.h"
  5. u32 HX711_Buffer;
  6. u32 Weight_Maopi;
  7. s32 Weight_Shiwu;
  8. u8 Flag_Error = 0;
  9. float P=1;
  10. float P_; //对应公式中的p'
  11. float X=0;
  12. float X_; //X'
  13. float K=0;
  14. float Q=0.01;//噪声
  15. //float R=0.2; //R如果很大,更相信预测值,那么传感器反应就会迟钝,反之相反
  16. float R=0.5;
  17. float distance=0;
  18. float distance1=0;
  19. float KLM(float Z)
  20. {
  21. X_=X+0;
  22. P_=P+Q;
  23. K=P_/(P_+R);
  24. X=X_+K*(Z-X_);
  25. P=P_-K*P_;
  26. return X;
  27. }
  28. //校准参数
  29. //因为不同的传感器特性曲线不是很一致,因此,每一个传感器需要矫正这里这个参数才能使测量值很准确。
  30. //当发现测试出来的重量偏大时,增加该数值。
  31. //如果测试出来的重量偏小时,减小改数值。
  32. //该值可以为小数
  33. #define GapValue 106.5
  34. void Init_HX711pin(void)//初始化
  35. {
  36. GPIO_InitTypeDef GPIO_InitStructure;
  37. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PF端口时钟
  38. //HX711_SCK
  39. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 端口配置
  40. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  41. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
  42. GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB
  43. //HX711_DOUT
  44. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  45. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//输入上拉
  46. GPIO_Init(GPIOB, &GPIO_InitStructure);
  47. GPIO_SetBits(GPIOB,GPIO_Pin_0); //初始化设置为0
  48. }
  49. //****************************************************
  50. //读取HX711
  51. //****************************************************
  52. u32 HX711_Read(void) //增益128
  53. {
  54. unsigned long count;
  55. unsigned char i;
  56. HX711_DOUT=1;
  57. delay_us(1);
  58. HX711_SCK=0;
  59. count=0;
  60. while(HX711_DOUT);
  61. for(i=0;i<24;i++)
  62. {
  63. HX711_SCK=1;
  64. count=count<<1;
  65. delay_us(1);
  66. HX711_SCK=0;
  67. if(HX711_DOUT)
  68. count++;
  69. delay_us(1);
  70. }
  71. HX711_SCK=1;
  72. count=count^0x800000;//25个脉冲下降沿来时,转换数据
  73. delay_us(1);
  74. HX711_SCK=0;
  75. return(count);
  76. }
  77. //****************************************************
  78. //获取毛皮重量
  79. //****************************************************
  80. void Get_Maopi(void)
  81. {
  82. Weight_Maopi = HX711_Read();
  83. }
  84. //****************************************************
  85. //称重
  86. //****************************************************
  87. void Get_Weight(void)
  88. {
  89. HX711_Buffer = HX711_Read();
  90. if(HX711_Buffer > Weight_Maopi)
  91. {
  92. Weight_Shiwu = HX711_Buffer;
  93. Weight_Shiwu = Weight_Shiwu - Weight_Maopi; //获取实物的AD采样数值。
  94. Weight_Shiwu = (s32)((float)Weight_Shiwu/GapValue)-478; //计算实物的实际重量
  95. //因为不同的传感器特性曲线不一样,因此,每一个传感器需要矫正这里的GapValue这个除数。
  96. //当发现测试出来的重量偏大时,增加该数值。
  97. //如果测试出来的重量偏小时,减小改数值。
  98. Weight_Shiwu=KLM(Weight_Shiwu);
  99. }
  100. }

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

HX711.H

  1. #ifndef __HX711_H
  2. #define __HX711_H
  3. #include "sys.h"
  4. #define HX711_SCK PBout(0)// PB0
  5. #define HX711_DOUT PBin(1)// PB1
  6. extern void Init_HX711pin(void);
  7. extern u32 HX711_Read(void);
  8. extern void Get_Maopi(void);
  9. extern void Get_Weight(void);
  10. extern u32 HX711_Buffer;
  11. extern u32 Weight_Maopi;
  12. extern s32 Weight_Shiwu;
  13. extern u8 Flag_Error;
  14. #endif

main

  1. /************************************************************************************
  2. *************************************************************************************/
  3. #include "stm32f10x.h"
  4. #include "delay.h"
  5. #include "HX711.h"
  6. #include "usart.h"
  7. #include "OLED.H"
  8. int main(void)
  9. {
  10. Init_HX711pin();
  11. delay_init();
  12. NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
  13. uart_init(9600); //串口初始化为9600
  14. Get_Maopi(); //称毛皮重量
  15. delay_ms(1000);
  16. delay_ms(1000);
  17. Get_Maopi(); //重新获取毛皮重量
  18. while(1)
  19. {
  20. Get_Weight();
  21. printf("净重量 = %d g\r\n",Weight_Shiwu); //打印
  22. delay_ms(100);
  23. }
  24. }

展示

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/35265
推荐阅读
  

闽ICP备14008679号