当前位置: 首页 > news >正文

HX711—称重模块

1、简介

        HX711 采用了海芯科技集成电路专利技术, 是一款专为高精度电子秤而设计的 24 位 A/D 转 换器芯片。

2、原理图

PCB参考设计原理图 

3、模块驱动代码(固件库)

数据读取代码分析

HX711信号读取时序

  1. 初始化

    • 将 PD_SCK(Power Down / Serial Clock)引脚设置为低电平。
    • 将 DOUT 引脚设置为输入模式。
  2. 等待 DOUT 变为高电平

    • 等待 DOUT 引脚变为高电平,这表明HX711准备好发送数据。
  3. 读取24位数据

    • 每个 PD_SCK 的上升沿,HX711 会在 DOUT 引脚上输出一位数据。
    • 每个 PD_SCK 的下降沿,数据线保持稳定,此时可以读取 DOUT 上的数据。
  4. 读取第25位(符号位)

    • 在读取完24位数据之后,通过 PD_SCK 的一次上升沿读取第25位数据(符号位)。
uint32_t HX711_ReadData(void)                          //读数据
{uint8_t i;uint32_t value = 0;    						//接收HX711采集的AD值HX711_W_DOUT(1); 									//初始DOUT为高电平HX711_W_PD_SCK(0); 							  //初始PD_SCK为低电平Delay_us(1);HX711_R_DOUT();                   //DOUT转换为输入while(HX711_R_DOUT());           //等待DOUT引脚变为高电平Delay_us(1);for(i=0;i<24;i++)                 //按照HX711时序接收数据{HX711_W_PD_SCK(1);              // PD_SCK置高,发送脉冲 value = value << 1;              //下降沿来时变量左移一位,右侧补零,Delay_us(1);HX711_W_PD_SCK(0);               // PD_SCK置低if(HX711_R_DOUT())               //读取一位数据,如果高电平,加一,低电平不变。value++;Delay_us(1);}HX711_W_PD_SCK(1);               //最后一个脉冲,增益为128value = value^0x800000;          //第25个脉冲转换数据,24位AD转换,最高位为符号位,其余为有效位Delay_us(1);HX711_W_PD_SCK(0);Delay_us(1);return value;
}

 4、驱动代码

HX711.c

#include "stm32f10x.h"                  // Device header
#include "HX711.h"
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"float	BiaoDing=384.7;       			//标定系数,根据自己的传感器调节
uint32_t pi_weight,weight;
uint32_t buffer[MEDIAN_LEN];   	        //中值滤波的数据缓存
int medleng = 0;          	            
uint32_t   num;					                  //数据对比大小中间变量
uint8_t Pi_flag=0;void HX711_GPIO_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      //时钟线推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //数据线浮空输入     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);
}void HX711_W_PD_SCK(uint8_t BitValue)                  //写时钟线
{	GPIO_WriteBit(GPIOA, GPIO_Pin_1, (BitAction)BitValue);
}void HX711_W_DOUT(uint8_t BitValue)                    //写数据线,开始时,需要拉高DOUT电平
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_WriteBit(GPIOA, GPIO_Pin_2, (BitAction)BitValue);
}uint8_t HX711_R_DOUT(void)                             //读数据
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2);
}void HX711_Reset(void)                                 // 传感器复位,去皮
{HX711_W_PD_SCK(1);                                   //拉高,延时60usDelay_us(60);
}uint32_t HX711_ReadData(void)                          //读数据
{uint8_t i;uint32_t value = 0;    						//接收HX711采集的AD值HX711_W_DOUT(1); 									//初始DOUT为高电平HX711_W_PD_SCK(0); 							  //初始PD_SCK为低电平Delay_us(1);HX711_R_DOUT();                   //DOUT转换为输入while(HX711_R_DOUT());           //等待DOUT引脚变为高电平Delay_us(1);for(i=0;i<24;i++)                 //按照HX711时序接收数据{HX711_W_PD_SCK(1);              // PD_SCK置高,发送脉冲 value = value << 1;              //下降沿来时变量左移一位,右侧补零,Delay_us(1);HX711_W_PD_SCK(0);               // PD_SCK置低if(HX711_R_DOUT())               //读取一位数据,如果高电平,加一,低电平不变。value++;Delay_us(1);}HX711_W_PD_SCK(1);               //最后一个脉冲,增益为128value = value^0x800000;          //第25个脉冲转换数据,24位AD转换,最高位为符号位,其余为有效位Delay_us(1);HX711_W_PD_SCK(0);Delay_us(1);return value;
}uint32_t Get_Pi(void)                           //皮重函数  每次去皮需要再次重置一下
{                                               //中值滤波参数,冒泡排序法uint32_t   buffer[MEDIAN_LEN];              //储存数组uint32_t HX711_dat,pi_weight,num;           				uint8_t i,medleng = 0;for(i=0;i<MEDIAN_LEN;i++){HX711_dat=HX711_ReadData();	        	   if(medleng == 0)                           //第1个元素,直接放入,不需要排序{ buffer[0] = HX711_dat;medleng = 1; }else                            	           //中值滤波,取中间值,冒泡排序法{  for(i = 0; i < medleng; i ++)  {if( buffer[i] > HX711_dat) 	          { num = HX711_dat; HX711_dat = buffer[i]; buffer[i] = num;}}buffer[medleng] = HX711_dat;          	medleng++;}		if(medleng >= MEDIAN_LEN) 		           {HX711_dat = buffer[MEDIAN];	            //取排序好的中间值,medleng = 0; }}pi_weight=HX711_dat;      return pi_weight;
}uint32_t Get_Weight(uint32_t pi_weight)	               //称重函数
{uint32_t get_weight;uint32_t weight;get_weight=HX711_ReadData();		            //HX711数据采集函数if(get_weight>pi_weight){get_weight=HX711_ReadData();			                  //重新采集HX711数据					 														   weight=(uint32_t)(((float)(get_weight-pi_weight))/BiaoDing);//修改标定系数,根据传感器不同if(weight==11164458)weight=0;     //干扰值校准为0}else 				weight=0;return weight;
}void Show_weight(void)
{weight=Get_Weight(pi_weight);if(medleng == 0)                         //中值滤波,取中间值,冒泡排序法{ buffer[0] = weight; medleng = 1; }else                            	       {  for(int i = 0; i < medleng; i ++)  {if( buffer[i] > weight) 	           { num = weight; weight = buffer[i]; buffer[i] = num;}}buffer[medleng] = weight; 	            medleng++;}		if(medleng >= MEDIAN_LEN) 		             {weight = buffer[MEDIAN];	                //取中间值medleng = 0; OLED_ShowNum(1,6,weight,4);Delay_ms(500);}}

HX711.h 

#ifndef __HX711_H
#define __HX711_H#define MEDIAN_LEN       5  			              //中值滤波的滤波长度,一般取奇数
#define MEDIAN           3  			              //中值在滤波数组中的位置extern uint32_t buffer[];
extern int medleng;
extern uint32_t num,weight;
extern uint32_t pi_weight;void HX711_GPIO_Init(void);
void HX711_W_PD_SCK(uint8_t BitValue);
void HX711_W_DOUT(uint8_t BitValue);
void HX711_Reset(void);
uint8_t HX711_R_DOUT(void);
uint32_t HX711_ReadData(void);
uint32_t Get_Pi(void);
uint32_t Get_Weight(uint32_t pi_weight);
void Show_weight(void);#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"
#include <stdio.h>
#include "HX711.h"int main(void)
{OLED_Init();Serial_Init();HX711_GPIO_Init();    //初始化HX711OLED_ShowChinese(1,1,4);OLED_ShowChinese(1,2,5);OLED_ShowString(1, 10, "g");OLED_ShowString(1, 5, ":");pi_weight=Get_Pi();  //获取一次皮重while (1){Show_weight();    //获取并显示重量·}
}


http://www.mrgr.cn/news/17562.html

相关文章:

  • 18. 为什么浮点类型不支持左移和右移运算符?
  • 计算机毕业设计hadoop+spark知识图谱课程推荐系统 课程预测系统 课程大数据 课程数据分析 课程大屏 mooc慕课推荐系统 大数据毕业设计
  • 提高工作效益方法(一)
  • 【EtherCAT】运行原理
  • 支付平台构建支付接口供整个公司调用—支付代理商
  • getopts(1) builtin command
  • Linux 文件操作相关函数整理
  • docker实战基础一 (Docker基础命令)
  • docker实战扩展三(dockerfile中run的详细用法)
  • `lambdaQuery()` 和 `lambda()`
  • MySQL锁机制解析:确保数据库高效并发与数据一致性的关键
  • FFmpeg源码:av_rescale_rnd、av_rescale_q_rnd、av_rescale_q、av_add_stable函数分析
  • 【Hot100】LeetCode—74. 搜索二维矩阵
  • kali——nikto的使用
  • C/C++逆向:寻找mian函数(其他编译配置特征)
  • react中修改组件样式的几种方法
  • linux组合命令:删除一个目录树中所有的空目录(包括嵌套空目录)
  • Day 1 : 数据结构
  • CompletableFuture学习
  • 酿酒师的匠心独运:白酒酿造的不同工艺