1.添加hx711模块。
This commit is contained in:
86
module/hx711/README.md
Normal file
86
module/hx711/README.md
Normal 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
214
module/hx711/hx711.c
Normal 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
54
module/hx711/hx711.h
Normal 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 */
|
||||
Reference in New Issue
Block a user