1.添加hx711模块。

This commit is contained in:
MacRsh
2023-11-17 22:56:22 +08:00
parent 1a0fc92a32
commit e46419f03a
3 changed files with 354 additions and 0 deletions

86
module/hx711/README.md Normal file
View File

@@ -0,0 +1,86 @@
# HX711 模块说明
HX711是一款24位ADC(模数转换器)芯片,主要用于数字量程的应用,常用于压力传感器、应力传感器、称重传感器等数字量程应用中。
HX711常与应力传感器或其他模拟传感器组合,采集传感器的模拟电平信号,通过内置的ADC转换为数字信号输出。它可以放大微小的模拟信号,提高采集精度。在电子秤、计量设备等应用中应用广泛。
## 注册HX711
```c
int hx711_register(struct hx711 *hx711, const char *name, int sck_pin, int dout_pin);
```
| 参数 | 描述 |
|:--------:|:--------:|
| hx711 | HX711模块 |
| name | HX711模块名 |
| sck_pin | SCK管脚 |
| dout_pin | DOUT管脚 |
## 设置滤波位数
滤波位数舍弃ADC低位数据例如24bit ADC 设置4位滤波ADC数据低4位将恒定为0。
```c
#define FILTER_BITS 4
mr_dev_ioctl(desc, HX711_CTRL_SET_FILTER_BITS, mr_make_local(int, FILTER_BITS));
```
## 自校准
自校准零点,使用前请确保输入值稳定。
```c
mr_dev_ioctl(desc, HX711_CTRL_SET_SELF_CALIBRATION, MR_NULL);
```
## 读取数据
```c
uint32_t data = 0;
mr_dev_read(desc, &data, sizeof(data));
```
# 使用示例
```c
#define HX711_SCK_PIN 0
#define HX711_DOUT_PIN 1
#define HX711_FILTER_BITS 4
struct struct hx711 hx711;
int main(void)
{
/* 注册hx711 */
hx711_register(&hx711, "hx711", HX711_SCK_PIN, HX711_DOUT_PIN);
/* 打开hx711 */
int desc = mr_dev_open("hx711", MR_OFLAG_RDONLY);
if (desc < 0)
{
mr_log("HX711 error %d", desc);
return 0;
}
/* 设置滤波位数 */
mr_dev_ioctl(desc, HX711_CTRL_SET_FILTER_BITS, mr_make_local(int, HX711_FILTER_BITS));
/* 自校准 */
mr_dev_ioctl(desc, HX711_CTRL_SET_SELF_CALIBRATION, MR_NULL);
/* 读取数据 */
uint32_t data = 0;
mr_dev_read(desc, &data, sizeof(data));
}
```

214
module/hx711/hx711.c Normal file
View File

@@ -0,0 +1,214 @@
/*
* @copyright (c) 2023, MR Development Team
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2023-11-17 MacRsh First version
*/
#include "hx711.h"
#ifdef MR_USING_HX711
#if !defined(MR_USING_GPIO)
#error "Please define MR_USING_GPIO. Otherwise HX711 will not work."
#else
#include "include/device/gpio.h"
static void hx711_set_sck(struct hx711 *hx711, uint8_t value)
{
mr_dev_ioctl(hx711->desc, MR_CTRL_SET_OFFSET, &hx711->sck_pin);
mr_dev_write(hx711->desc, &value, sizeof(value));
}
static uint8_t hx711_get_dout(struct hx711 *hx711)
{
uint8_t value = 0;
mr_dev_ioctl(hx711->desc, MR_CTRL_SET_OFFSET, &hx711->dout_pin);
mr_dev_read(hx711->desc, &value, sizeof(value));
return value;
}
static uint32_t hx711_get_value(struct hx711 *hx711)
{
uint32_t value = 0;
int i = 0;
/* Start the conversion */
hx711_set_sck(hx711, 0);
mr_delay_us(1);
while (hx711_get_dout(hx711) != 0)
{
i++;
if (i > UINT16_MAX)
{
return 0;
}
}
/* Get the value */
for (i = 0; i < 24; i++)
{
hx711_set_sck(hx711, 1);
value <<= 1;
mr_delay_us(1);
hx711_set_sck(hx711, 0);
if (hx711_get_dout(hx711) == 1)
{
value++;
}
mr_delay_us(1);
}
hx711_set_sck(hx711, 1);
value = value ^ 0x800000;
mr_delay_us(1);
hx711_set_sck(hx711, 0);
/* Filter the value */
mr_bits_clr(value, (1 << hx711->filter_bits) - 1);
return value;
}
static int hx711_open(struct mr_dev *dev)
{
struct hx711 *hx711 = (struct hx711 *)dev;
hx711->desc = mr_dev_open("gpio", MR_OFLAG_RDWR);
if (hx711->desc < 0)
{
return hx711->desc;
}
/* Set the sck pin mode */
mr_dev_ioctl(hx711->desc, MR_CTRL_SET_OFFSET, &hx711->sck_pin);
mr_dev_ioctl(hx711->desc, MR_CTRL_GPIO_SET_PIN_MODE, mr_make_local(int, MR_GPIO_MODE_OUTPUT));
/* Set the dout pin mode */
mr_dev_ioctl(hx711->desc, MR_CTRL_SET_OFFSET, &hx711->dout_pin);
mr_dev_ioctl(hx711->desc, MR_CTRL_GPIO_SET_PIN_MODE, mr_make_local(int, MR_GPIO_MODE_INPUT_UP));
return MR_EOK;
}
static int hx711_close(struct mr_dev *dev)
{
struct hx711 *hx711 = (struct hx711 *)dev;
/* Reset the sck pin mode */
mr_dev_ioctl(hx711->desc, MR_CTRL_SET_OFFSET, &hx711->sck_pin);
mr_dev_ioctl(hx711->desc, MR_CTRL_GPIO_SET_PIN_MODE, mr_make_local(int, MR_GPIO_MODE_NONE));
/* Reset the dout pin mode */
mr_dev_ioctl(hx711->desc, MR_CTRL_SET_OFFSET, &hx711->dout_pin);
mr_dev_ioctl(hx711->desc, MR_CTRL_GPIO_SET_PIN_MODE, mr_make_local(int, MR_GPIO_MODE_NONE));
mr_dev_close(hx711->desc);
hx711->desc = -1;
return MR_EOK;
}
static ssize_t hx711_read(struct mr_dev *dev, int off, void *buf, size_t size, int sync_or_async)
{
struct hx711 *hx711 = (struct hx711 *)dev;
uint32_t *rd_buf = (uint32_t *)buf;
ssize_t rd_size = 0;
mr_bits_clr(size, sizeof(*rd_buf) - 1);
for (rd_size = 0; rd_size < size; rd_size += sizeof(*rd_buf))
{
uint32_t value = hx711_get_value(hx711);
*rd_buf = (value > hx711->self_calibration) ? (value - hx711->self_calibration) : 0;
rd_buf++;
}
return rd_size;
}
static int hx711_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
{
struct hx711 *hx711 = (struct hx711 *)dev;
switch (cmd)
{
case HX711_CTRL_SET_FILTER_BITS:
{
if (args != MR_NULL)
{
int filter = *(int *)args;
hx711->filter_bits = filter;
return MR_EOK;
}
return MR_EINVAL;
}
case HX711_CTRL_SET_SELF_CALIBRATION:
{
hx711->self_calibration = hx711_get_value(hx711);
return MR_EOK;
}
case HX711_CTRL_GET_FILTER_BITS:
{
if (args != MR_NULL)
{
*(int *)args = hx711->filter_bits;
return MR_EOK;
}
return MR_EINVAL;
}
case HX711_CTRL_GET_SELF_CALIBRATION:
{
if (args != MR_NULL)
{
*(uint32_t *)args = hx711->self_calibration;
return MR_EOK;
}
return MR_EINVAL;
}
default:
{
return MR_ENOTSUP;
}
}
}
/**
* @brief This function register a hx711 module.
*
* @param hx711 The hx711 module.
* @param name The name of the hx711 module.
* @param sck_pin The sck pin of the hx711 module.
* @param dout_pin The dout pin of the hx711 module.
*
* @return MR_EOK on success, otherwise an error code.
*/
int hx711_register(struct hx711 *hx711, const char *name, int sck_pin, int dout_pin)
{
static struct mr_dev_ops ops =
{
hx711_open,
hx711_close,
hx711_read,
MR_NULL,
hx711_ioctl,
MR_NULL
};
mr_assert(hx711 != MR_NULL);
mr_assert(name != MR_NULL);
mr_assert(sck_pin >= 0);
mr_assert(dout_pin >= 0);
/* Initialize the fields */
hx711->filter_bits = 0;
hx711->self_calibration = 0;
hx711->sck_pin = sck_pin;
hx711->dout_pin = dout_pin;
/* Register the hx711 */
return mr_dev_register(&hx711->dev, name, Mr_Dev_Type_Adc, MR_SFLAG_RDONLY | MR_SFLAG_NONDRV, &ops, MR_NULL);
}
#endif /* MR_USING_GPIO */
#endif /* MR_USING_HX711 */

54
module/hx711/hx711.h Normal file
View File

@@ -0,0 +1,54 @@
/*
* @copyright (c) 2023, MR Development Team
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2023-11-17 MacRsh First version
*/
#ifndef _HX711_H
#define _HX711_H
#include "mr_lib.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifdef MR_USING_HX711
/**
* @brief HX711 command.
*/
#define HX711_CTRL_SET_FILTER_BITS ((0x01|0x80) << 16)
#define HX711_CTRL_SET_SELF_CALIBRATION ((0x02|0x80) << 16)
#define HX711_CTRL_GET_FILTER_BITS ((0x01|0x00) << 16)
#define HX711_CTRL_GET_SELF_CALIBRATION ((0x02|0x00) << 16)
/**
* @brief Hx711 structure.
*/
struct hx711
{
struct mr_dev dev; /**< Device */
int filter_bits; /**< Filter bits */
uint32_t self_calibration; /**< Self calibration */
int sck_pin; /**< SCK pin */
int dout_pin; /**< DOUT pin */
int desc; /**< Descriptor */
};
/**
* @addtogroup HX711.
* @{
*/
int hx711_register(struct hx711 *hx711, const char *name, int sck_pin, int dout_pin);
/** @} */
#endif /* MR_USING_HX711 */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _HX711_H */