STM32F103C8T6驱动HX711称重模块 在OLED屏上(4针IIC)显示

一、HX711模块介绍

简介

HX711 采用了海芯科技集成电路专利技术,是一款专为高精度电子秤而设计的 24 位 A/D 转换器芯片。与同类型其它芯片相比,该芯片集成了包括稳压电源、片内时钟振荡器等其它同类型芯片所需要的外围电路,具有集成度高、响应速度快、抗干扰性强等优点。降低了电子秤的整机成本,提高了整机的性能和可靠性。
该芯片与后端 MCU 芯片的接口和编程非常简单,所有控制信号由管脚驱动,无需对芯片内部的寄存器编程。输入选择开关可任意选取通道 A 或通道 B,与其内部的低噪声可编程放大器相连。通道 A 的可编程增益为 128 或 64,对应的满额度差分输入信号幅值分别为±20mV或±40mV。通道 B 则为固定的 32 增益,用于系统参数检测。芯片内提供的稳压电源可以直接向外部传感器和芯片内的 A/D 转换器提供电源,系统板上无需另外的模拟电源。芯片内的时钟振荡器不需要任何外接器件。上电自动复位功能简化了开机的初始化过程。
在这里插入图片描述

特点

• 两路可选择差分输入
• 片内低噪声可编程放大器,可选增益为32,64 和 128
• 片内稳压电路可直接向外部传感器和芯片内A/D 转换器提供电源
• 片内时钟振荡器无需任何外接器件,必要时也可使用外接晶振或时钟
• 上电自动复位电路
• 简单的数字控制和串口通讯:所有控制由管脚输入,芯片内寄存器无需编程
• 可选择 10Hz 或 80Hz 的输出数据速率
• 同步抑制 50Hz 和 60Hz 的电源干扰
• 耗电量(含稳压电源电路): 典型工作电流:< 1.6mA, 断电电流:< 1µA
• 工作电压范围:2.6 ~ 5.5V
• 工作温度范围:-40 ~ +85℃
• 16 管脚的 SOP-16 封装

引脚说明

HX711称重模块 引脚说明
VCC 3.3~5V供电
GND 接GND
DOUT 串口数据输出
SCK 时钟输入

二、HX711模块数据通讯说明

串口通讯线由管脚 PD_SCK 和 DOUT 组成,用来输出数据,选择输入通道和增益。
当数据输出管脚 DOUT 为高电平时,表明A/D 转换器还未准备好输出数据,此时串口时钟输入信号 PD_SCK 应为低电平。当 DOUT 从高电平变低电平后,PD_SCK 应输入 25 至 27 个不等的时钟脉冲(图二)。其中第一个时钟脉冲的上升沿 将读出输出 24 位数据的最高位(MSB),直至第 24 个时钟脉冲完成,24 位输出数据从最高位至最低位逐位输出完成。第 25至 27 个时钟脉冲用来选择下一次 A/D 转换的输入通道和增益,参见表三。

PD_SCK 脉冲数 输入通道 增益
25 A 128
26 B 32
27 A 64
表三 输入通道和增益选择

PD_SCK 的输入时钟脉冲数不应少于 25 或多于 27,否则会造成串口通讯错误。
当 A/D 转换器的输入通道或增益改变时,A/D 转换器需要 4 个数据输出周期才能稳定。DOUT 在 4 个数据输出周期后才会从高电平变低电平,输出有效数据。

在这里插入图片描述

三、参考原理图

在这里插入图片描述

四、相关代码说明

1、通信部分程序

HX711.c

unsigned long ReadCount(void)
{
    
    
		unsigned long Count;
		unsigned char i;
		CLK_0;
	  DelayUs(1);
		Count=0;
		while(DOUT);
		for (i=0;i<24;i++)
	 {
    
    
				CLK_1;
				DelayUs(1);
				Count=Count<<1;
				CLK_0;
				DelayUs(1);
				if(DOUT) Count++;
		}
		CLK_1;
		DelayUs(1);
		Count=Count^0x800000;
		CLK_0;
		DelayUs(1);
		
		return(Count);
}

OLED_I2C.c

void I2C_WriteByte(uint8_t addr,uint8_t data)
{
    
    
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
	
	I2C_GenerateSTART(I2C1, ENABLE);//开启I2C1
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,主模式*/

	I2C_Send7bitAddress(I2C1, OLED_ADDRESS, I2C_Direction_Transmitter);//器件地址 -- 默认0x78
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

	I2C_SendData(I2C1, addr);//寄存器地址
	while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

	I2C_SendData(I2C1, data);//发送数据
	while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
	
	I2C_GenerateSTOP(I2C1, ENABLE);//关闭I2C1总线
}

void WriteCmd(unsigned char I2C_Command)//写命令
{
    
    
	I2C_WriteByte(0x00, I2C_Command);
}

void WriteDat(unsigned char I2C_Data)//写数据
{
    
    
	I2C_WriteByte(0x40, I2C_Data);
}

2、引脚配置

HX711

#define DOUT_GPIO_PORT    	GPIOA		              /* GPIO端口 */
#define DOUT_GPIO_CLK 	    RCC_APB2Periph_GPIOA		/* GPIO端口时钟 */
#define DOUT_GPIO_PIN			  GPIO_Pin_1			        


#define CLK_GPIO_PORT    	GPIOA			              /* GPIO端口 */
#define CLK_GPIO_CLK 	    RCC_APB2Periph_GPIOA		/* GPIO端口时钟 */
#define CLK_GPIO_PIN		  GPIO_Pin_3			 

#define DOUT    	GPIO_ReadInputDataBit(DOUT_GPIO_PORT, DOUT_GPIO_PIN)
#define DOUT_0    	GPIO_ResetBits(DOUT_GPIO_PORT, DOUT_GPIO_PIN)

#define CLK_1    	GPIO_SetBits(CLK_GPIO_PORT, CLK_GPIO_PIN)
#define CLK_0    	GPIO_ResetBits(CLK_GPIO_PORT, CLK_GPIO_PIN)

void HX711_GPIO_Config(void)
{
    
    		
		/*定义一个HX711_InitTypeDef类型的结构体*/
		GPIO_InitTypeDef GPIO_InitStructure;

		/*开启LED相关的GPIO外设时钟*/
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
		/*选择要控制的GPIO引脚*/
		GPIO_InitStructure.GPIO_Pin = DOUT_GPIO_PIN;	
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   

		GPIO_Init(DOUT_GPIO_PORT, &GPIO_InitStructure);	
		

		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
		GPIO_InitStructure.GPIO_Pin = CLK_GPIO_PIN;
		GPIO_Init(CLK_GPIO_PORT, &GPIO_InitStructure);


}

OLED

void I2C_Configuration(void)
{
    
    
	I2C_InitTypeDef  I2C_InitStructure; 
	GPIO_InitTypeDef  GPIO_InitStructure;  

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE); 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
 
	/*STM32F103C8T6芯片的硬件I2C: PB6 -- SCL; PB7 -- SDA */
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//I2C必须开漏输出
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	I2C_DeInit(I2C1);//使用I2C1
	I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
	I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
	I2C_InitStructure.I2C_OwnAddress1 = 0x30;//主机的I2C地址,随便写的
	I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
	I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
	I2C_InitStructure.I2C_ClockSpeed = 400000;//400K

	I2C_Cmd(I2C1, ENABLE);
	I2C_Init(I2C1, &I2C_InitStructure);
}

3、主程序

#include "stm32f10x.h"
#include "HX711.h"  
#include "delay.h"
#include "OLED_I2C.h"
#include <Stdio.h>
/**
  * @brief  主函数
  * @param  无  
  * @retval 无
  */
int32_t Date;
int32_t reset;
int32_t Weights_100=8525020;  //100g
uint8_t DIS_weight[16]={
    
    0};
int32_t  Average=0; 
float Weights=100.0;  //100g
float weight=0;
int main(void)
{
    
    	

	uint8_t sec;
	DelayInit();
	HX711_GPIO_Config();
	OLED_Init();
	OLED_Fill(0X00);//全屏填充
	Date=ReadCount();
	reset=Date;
	while (1)
	{
    
    
		
				
				if(Flag_Reset)
				{
    
    
						Date=ReadCount();
						reset=Date;//
						weight=0;
				}
				else
				{
    
    					
						
						for(sec=0;sec<10;sec++)
						{
    
    
							Date=ReadCount();
							
							Average=Date+Average;
						}
						

						weight=(float)(Average/10.0-reset)*Weights/(float)(Weights_100-reset);
						Average=0;
				}
				if(Flag_Calibration)
				{
    
    
						
						Weights_100=ReadCount();
					
				}
				OLED_ShowStr(0, 2, DIS_weight,2);
				//delay_ms(100);
	}
}

4、接线说明

/************************************************************************************
接线
HX711 ---------------------------------STM32F103C8T6
VCC------------------------------------5V
GND------------------------------------GND
DOUT-----------------------------------PA1
CLK------------------------------------PA3

OLED0.96(IIC) -------------------------STM32F103C8T6
VCC------------------------------------3.3V
GND------------------------------------GND
SCL------------------------------------PB6
SDA------------------------------------PB7
*****************************************************************************************/

五、注意事项

1.所有数字输入管脚,包括 RATE, XI 和PD_SCK 管脚,芯片内均无内置拉高或拉低电阻。这些管脚在使用时不应悬空。
2.建议使用通道 A 与传感器相连,作为小信号输入通道;通道 B 用于系统参数检测,如电池电压检测。
3.建议使用 PNP 管 S8550 与片内稳压电源电路配合。也可根据需要使用其他 MOS 或双极晶体管,但应注意稳压电源的稳定性。
4.无论是采用片内稳压电源或系统上其他电源,建议传感器和 A/D 转换器使用同一模拟供电电源。
5.PD_SCK 的输入时钟脉冲数不应少于 25 或多于 27,否则会造成串口通讯错误。
6.与 DOUT 相连的 MCU 接口应设置为输入口,并且不接任何拉高或拉低电阻,以减少MCU 与 ADC 之间的电流交换(干扰)。

住:本文主要是想介绍HX711模块,对OLED屏幕模块的介绍在这里就不做详细概述,有关OLED屏幕的介绍大家可参照往期中有关的文章或在CSDN博客社区中找相关的文章自行学习,感谢大家的支持!

猜你喜欢

转载自blog.csdn.net/qq_42250136/article/details/131838544