STM32讀取HX711(AD)模塊數據——壓力傳感器


背景:在無人機動力系統的選型時,為了測試無人機的動力系統所能提供的最大拉力,使用壓力傳感裝置測量拉力。

鏈接:

壓力傳感器tb鏈接:

HX711模塊是一個24位精度的AD模塊。

(1)https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-21223910208.20.6c496a4bdA2Bew&id=522572281513

(2)https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-21223910208.14.6c496a4bdA2Bew&id=569898995913

另外還有一個固定壓力傳感器的支架,通過機械方式將螺旋槳產生的拉力加到拉力傳感器上。暫時找不到鏈接。

代碼github連接:

https://github.com/W-yt/YuTian_Pro/tree/master/press_measure

程序說明:

使用STM32F103C8T6最小系統板連接HX711模塊和一個OLED12864顯示屏,讀取HX7111模塊的數據,經過處理后通過顯示屏顯示實際的拉力大小。

程序的初始化寫在main.c文件中

程序的主循環寫在control.h文件中(包括讀取拉力數據和液晶顯示)

代碼:

讀取AD芯片數據,一般有兩種方式,直接利用GPIO讀寫操作讀取數據和使用STM32的SPI讀取數據。

這里由於模塊自帶的資料中提供了使用51單片機讀取HX711數據的例程,使用的直接操作IO口的方式,我直接根據例程移植到了STM32下。

GPIO配置:

void Sensor_Init(void)
{
	GPIO_InitTypeDef	gpio;  

	RCC_APB2PeriphClockCmd(Sensor_Clock,ENABLE);
	
	//時鍾線推挽輸出
	gpio.GPIO_Pin = CLK;	
	gpio.GPIO_Mode = GPIO_Mode_Out_PP;
	gpio.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(Sensor_Gpio,&gpio);

	//數據線浮空輸入
	gpio.GPIO_Pin = DATA;	
	gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	gpio.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(Sensor_Gpio,&gpio);
}

HX711數據讀取函數(程序主要內容):

unsigned long Sensor_Read(void)
{
	unsigned long value;
	unsigned char i;
	
	//每次讀取數據前保證數據線電平穩定
	//此處只是為了穩定電平 拉高或拉低效果相同
//	GPIO_ResetBits(Sensor_Gpio,DATA);
	GPIO_SetBits(Sensor_Gpio,DATA);
	
	//為了等待輸出電平穩定
	//在每次一操作電平時加微小延時
	delay_us(2);
	
	//時鍾線拉低 空閑時時鍾線保持低電位
	GPIO_ResetBits(Sensor_Gpio,CLK);
	
	delay_us(2);	
	
	//等待AD轉換結束
	while(GPIO_ReadInputDataBit(Sensor_Gpio,DATA));
	
	for(i=0;i<24;i++)
	{
		//時鍾線拉高 開始發送時鍾脈沖
		GPIO_SetBits(Sensor_Gpio,CLK);
		
		delay_us(2);
		
		//左移位 右側補零 等待接收數據
		value = value << 1;
		
		//時鍾線拉低
		GPIO_ResetBits(Sensor_Gpio,CLK);
		
		delay_us(2);
		
		//讀取一位數據
		if(GPIO_ReadInputDataBit(Sensor_Gpio,DATA))
			value ++;
	}
	
	//第25個脈沖
	GPIO_SetBits(Sensor_Gpio,CLK);
	
	delay_us(2);

	//第25個脈沖下降沿到來時 轉換數據
	//此處說明:
	//			HX711是一款24位的AD轉換芯片
	//			最高位是符號位 其余為有效位
	//			輸出數組最小值0x800000
	//					最大值0x7FFFFF
	//異或運算:
	//			相同為0 
	//			不同為1
	//數據處理說明:
	//			之所以會發生 INPA-INNA < 0mv 的情況
	//			是因為發生了零點漂移
	//			例如上面的數據就是初始狀態INPA-INNA = -0.5mv
	//			然后隨着重量的增加會發生過零點
	//			這時如果直接使用讀取到的數據就會發生錯誤
	//			因為讀取到的是小於0的二進制補碼
	//			是不能直接使用的 需要轉換成其原碼

	//			比較簡單的處理方法就是讀到的數據直接和0x800000進行異或
	//			這時最高位可以看做是有效位
	//			不代表符號位而代表的下一位的進位
	//			這樣數據會一直往上增長 
	//			我們可以直接拿來進行使用
	value = value^0x800000;
//	value = value&0x7FFFFF;
	
	//第25個脈沖結束
	GPIO_ResetBits(Sensor_Gpio,CLK);
	
	delay_us(2);
	
	return value;
}

關於讀取數據操作的說明都在以上代碼中有詳細注釋。

獲取拉力:

void Get_Weight(void)
{
	HX711_Buffer = Sensor_Read();
	
	Weight_Lode = HX711_Buffer;
		
	//判斷非空載
	if(Weight_Lode > Weight_No_Lode)
	{
		Weight_Real = (Weight_Lode - Weight_No_Lode)/Kp_Weight;
	}
	else if(Weight_Lode <= Weight_No_Lode)
		Weight_Real = 0.0f;
	
	//拉力達到一定閾值 則串口顯示
//	if(Weight_Real>100.0f)
//		printf("當前拉力%u\r\n\r\n",Weight_Real);
}

粗略直線擬合:(確定上面代碼段中的系數)

//比例系數確定數據:
//	42500 	-->  160g --> 265.65
//	80000 	-->  285g --> 280.7
//	115000 	-->  405g --> 283.95
//	405000 	--> 1400g --> 289.29
//擬合直線:
// y = 291.92x-3580.2 (忽略截距)

這里只是用電子秤稱量了幾個重物作為樣本,大致擬合,為了獲得更高精度,可以改進樣本和擬合方式。

 

如有問題,歡迎交流。

 ——cloud over sky

——2019/10/31


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM