简单介绍:
见双路HX711+STM32+CUBE+FREERTOS使用记录-CSDN博客
这里甩出代码
CUBE引脚配置:
头文件:
/**
* @Author: 本人不帅
*
*/
#ifndef HX711
#define HX711
#include "stdint.h"
#include "main.h"
#include "cmsis_os.h"
typedef struct {
GPIO_TypeDef* SCK_GPIO_Port;//时钟IO端口
GPIO_TypeDef* DT_GPIO_Port;//数据IO端口
uint16_t SCK_Pin;//时钟引脚号
uint16_t DT_Pin;//数据引脚号
int32_t hx711count;//读出的数据
float gain;//增益,用于调整单位
float weight_offset;//偏置,用于清零
float weight_real;//实际力的大小
} HX711_t;
extern HX711_t HX711_A;
void HX711_TaskStart(void);//FREERTOS线程启动函数,不用的话可以删掉,把初始化放到别的地方
void HX711_EXIT_CALLBACK(HX711_t* hx711);//数据引脚对应的中断回调
void ResetWeight(void);//重量清零函数
#endif
#ifdef __cplusplus
}
#endif
源文件:
#include "HX711_dev.h"
#include "gpio.h"
HX711_t HX711_A;
void HX711_Init(HX711_t* hx711,GPIO_TypeDef* GPIO_Port_DT, uint16_t GPIO_Pin_DT,GPIO_TypeDef* GPIO_Port_SCK, uint16_t GPIO_Pin_SCK) {
hx711->DT_GPIO_Port = GPIO_Port_DT;
hx711->DT_Pin = GPIO_Pin_DT;
hx711->SCK_GPIO_Port = GPIO_Port_SCK;
hx711->SCK_Pin = GPIO_Pin_SCK;
hx711->hx711count = 0;
hx711->weight_offset = 0;
hx711->weight_real = 0;
HAL_GPIO_WritePin(GPIO_Port_SCK, GPIO_Pin_SCK, GPIO_PIN_RESET);
}
void HX711_Daemon_Task(void)
{
HX711_Init(&HX711_A,GPIOB, GPIO_PIN_12,GPIOB, GPIO_PIN_13);
HX711_A.weight_offset = -100;
HX711_A.gain = 0.0007f;
for(;;) {
//可以在这写一些任务处理函数,没有的话可以删掉Task相关函数
osDelay(10);
}
}
int i = 0;
uint32_t Count = 0;
void HX711_EXIT_CALLBACK(HX711_t* hx711) {
HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);//关闭中断
GPIO_InitTypeDef GPIO_InitStruct = {0};//把数据引脚设为输入模式
GPIO_InitStruct.Pin = hx711->DT_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(hx711->DT_GPIO_Port, &GPIO_InitStruct);
if(HAL_GPIO_ReadPin(hx711->DT_GPIO_Port, hx711->DT_Pin) == RESET) {//再次读取引脚电平,确保电平正确
Count = 0;
i=0;
for(i = 0; i <24; i++)//24个数据bit
{
HAL_GPIO_WritePin(hx711->SCK_GPIO_Port, hx711->SCK_Pin, GPIO_PIN_SET);
if(HAL_GPIO_ReadPin(hx711->DT_GPIO_Port, hx711->DT_Pin))
{
Count ++;
}
Count = Count << 1;
HAL_GPIO_WritePin(hx711->SCK_GPIO_Port, hx711->SCK_Pin, GPIO_PIN_RESET);
}
HAL_GPIO_WritePin(hx711->SCK_GPIO_Port, hx711->SCK_Pin, GPIO_PIN_SET);//第25个脉冲:增益128
hx711->hx711count = (int32_t)(Count<<8);//24位补码左移8位刚好是int32
hx711->weight_real = ((float)hx711->hx711count/2511886.43f/0.5f*9.8f - hx711->weight_offset)*hx711->gain;
//上面这几个参数感拿测力计测的,觉有点抽象,如果有好的确定方法欢迎在评论区留言。
HAL_GPIO_WritePin(hx711->SCK_GPIO_Port, hx711->SCK_Pin, GPIO_PIN_RESET);
}
GPIO_InitTypeDef GPIO_InitStruct1 = {0};//把数据引脚设为下降沿中断模式
GPIO_InitStruct1.Pin = hx711->DT_Pin;
GPIO_InitStruct1.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct1.Pull = GPIO_PULLUP;
HAL_GPIO_Init(hx711->DT_GPIO_Port, &GPIO_InitStruct1);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);//使能中断
}
void ResetWeight(void) {
HX711_A.weight_offset += HX711_A.weight_real;//数据归零
}
/************************ RTOS *******************/
void HX711_TaskStart(void)
{
xTaskCreate((TaskFunction_t)HX711_Daemon_Task,"",128,NULL,6,NULL);
}
函数引用:
重写外部中断回调:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if(GPIO_Pin == HX711_A.DT_Pin) {
HX711_EXIT_CALLBACK(&HX711_A);
}else{
ResetWeight();//外部中断归零重量
}
}
在void MX_FREERTOS_Init(void)里引用把线程启动函数:
HX711_TaskStart(void);
编译运行。