STM32称重传感器+HX711的使用——HAL库
前言
因为在一个项目中使用到了称重传感器,在此记录一下其使用方法还有一些需要注意的地方。
首先介绍一下使用的传感器
HX711——一款专用于电子秤的A/D转换芯片
称重传感器(使用的这一款量程200KG)
一、接线
买到传感器后,可以看到后面尾巴引出了5条线
**其中黄线在单片机处理里面是不需要的,不需要接。
**
如果大家买的是我上图的那一款HX711,那么可以直接按照上面的英文指示接线。
照着颜色接就完事了,RED接红线,BLK接黑线。
但还有几款HX711上面没有这个颜色提示,那也没有关系。
一般如下
HX711 | 称重传感器 |
---|---|
E+ | 红线 |
E- | 黑线 |
A+ | 绿线 |
A- | 白线 |
接完了HX711和称重传感器,下一步就是接HX711和单片机
HX711 | 单片机 |
---|---|
VCC | 5V |
DAT | PE5 |
CLK | PE6 |
GND | GND |
这里 DAT和CLK为自己设定的IO口。
其中DAT为HX711的串口数据输出,CLK为串口时钟输入。故在后面配置的时候DAT所对应的引脚要设定为输入引脚,CLK对应的引脚要定义为输出引脚
二、CubeMax配置
时钟树的配置按照自己板子具体的晶振配置一下就好,比较简单。
这里重点按照这个配置一下自己所对应的IO口就好了
再强调一下
DAT所对应的IO口为输入
CLK所对应的IO口为输出
三、代码编写
这里采用的是正点的位带操作来对两个IO进行操作
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入
#define HX711_SCK_01 PEout(5)// PE5
#define HX711_DOUT_01 PEin(6)// PB6
#define GPIOE_ODR_Addr (GPIOE_BASE+20) //0x40021014
#define GPIOE_IDR_Addr (GPIOE_BASE+16) //0x40021010
unsigned long HX711_Read_01()
{
unsigned long count;
unsigned char i;
HX711_SCK_01=0; //拉低时钟引脚
count=0;
delay_us(1);
while(HX711_DOUT_01);
for(i=0;i<24;i++)
{
HX711_SCK_01=1;
count=count<<1;
delay_us(1);
HX711_SCK_01=0;
if(HX711_DOUT_01) count++;
delay_us(1);
}
HX711_SCK_01=1;
count=count^0x800000;//第25个脉冲信号到来,进行数据转换
//获得24位的数据,对0x800000异或相当于把最高位取反。
//把符号位当做有效位,防止突然出现负值波动
delay_us(1);
HX711_SCK_01=0;
return(count);
}
注意在这里使用了微秒的延时
#define CPU_FREQUENCY_MHZ 168 // 定义自己STM32的主频
//延迟us函数
void delay_us(__IO uint32_t delay)
{
int last, curr, val;
int temp;
while (delay != 0)
{
temp = delay > 900 ? 900 : delay;
last = SysTick->VAL;
curr = last - CPU_FREQUENCY_MHZ * temp;
if (curr >= 0)
{
do
{
val = SysTick->VAL;
}
while ((val < last) && (val >= curr));
}
else
{
curr += CPU_FREQUENCY_MHZ * 1000;
do
{
val = SysTick->VAL;
}
while ((val <= last) || (val > curr));
}
delay -= temp;
}
}
这里讲一下上面读取信息代码的原理,主要是由HX711的时序图决定的
由时序图可知,HX711的前24位为ADC所采集的数据,后面1-3位可以根据自己的需要发送脉冲。
还有一个采样时间的说法,建议每10HZ采样一次。
最后就是得到AD值后的处理了
float Get_Weight()
{
float Weight_Shiwu = 0;
HX711_Real_Weight = HX711_Read_01();
if(HX711_Real_Weight > Weight_Maopi_01)
{
Weight_Shiwu = HX711_Real_Weight;
Weight_Shiwu = Weight_Shiwu - Weight_Maopi;
Weight_Shiwu = (float)(Weight_Shiwu/HX711_GapValue);
}
return Weight_Shiwu;
}
其中Weight_Maopi为开机上电时采集到的值,相当于空称的重量
HX711_GapValue为修正参数,我们可以通过标准砝码那修改HX711_GapValue的值来提高精度。
注意点
1.使用时请注意保持HX711和32的距离尽量近,以保证精度。
2.读HX711需要注意采样周期,这个根据自己的情况调节,过快亲测会出现异常十分大的值,然后导致整个时序乱的情况,目前没找到特别好的解决方法,找到一个合适的采样周期,根据自己的经验可以解决。
3.对精度要求比较高的可以根据以下图进行接入电阻和电容
这里的INNA和INPA分别对应上图的绿线和白线
工程代码如下自取:驱动代码