Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
packages_软件包
HX711
有没有大神移植一个HX711称重芯片模块的软件包
发布于 2020-08-10 03:03:53 浏览:1245
订阅该版
感觉HX711模块应用范围还比较广,以前用arduino,里面的hx711库非常好用,可惜自己水平有限,没有移植成功到rtt,哪个大神帮忙指导一下,或者移植一个。
查看更多
armink
2020-08-11
这家伙很懒,什么也没写!
巧了,N 年前我整过这个,分享出来哈,觉得好用希望你能做成软件包 ``` /* * File name: hx711.c * Created on: 2016年3月3日 * Author: armink * Description: HX711 压力检测芯片驱动 */ #define LOG_TAG "HX711" #include
#include
#include
#include
#include
#include
#include
#include
#define DOUT_GPIOX GPIOA #define DOUT_PIN GPIO_Pin_6 #define DOUT_EXTI_PORT EXTI_PortSourceGPIOA #define DOUT_EXTI_PIN EXTI_PinSource6 #define PD_SCK_GPIOX GPIOA #define PD_SCK_PIN GPIO_Pin_7 /* SCK 引脚输出高 */ #define PD_SCK_H GPIO_SetBits(PD_SCK_GPIOX, PD_SCK_PIN) /* SCK 引脚输出低 */ #define PD_SCK_L GPIO_ResetBits(PD_SCK_GPIOX, PD_SCK_PIN) /* 获取 DOUT 引脚输出状态 */ #define DOUT GPIO_ReadInputDataBit(DOUT_GPIOX, DOUT_PIN) /* 转换稳定时间(设定:500ms,手册中默认为 400ms) */ #define CONVERT_STABLE_TIME RT_TICK_PER_SECOND * 500 / 1000 /* 转换周期(设定为 10hz 100ms 转换一次) */ #define CONVERT_PERIOD_TIME RT_TICK_PER_SECOND * 100 / 1000 /* 传感器检测压力的最大值 */ #define SENSOR_MAX_PRESSURE 60*9.8 /* 传感器检测压力的最小值 */ #define SENSOR_MIN_PRESSURE 0*9.8 /* 校准的偏移量 */ static double cali_offset; /* 获取压力锁,避免并发获取 */ static struct rt_mutex read_lock; /* 初始化完成标识 */ static bool init_ok = false; /* HX711事件 */ static struct rt_event event_hx711dout; /* HX711已准备好数据事件 */ #define EVENT_HX711DOUT_OK 1<<0 static void delay_us(uint32_t n); static void set_hx711_dout_irq(bool type); /** * HX711 模块初始化 */ void hx711_init(void) { /* 硬件初始化 */ EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = PD_SCK_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DOUT_GPIOX, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = DOUT_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_Init(PD_SCK_GPIOX, &GPIO_InitStructure); //只要我们使用到外部中断,就必须打开SYSCFG时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); SYSCFG_EXTILineConfig(DOUT_EXTI_PORT, DOUT_EXTI_PIN); EXTI_ClearITPendingBit(EXTI_Line6); EXTI_InitStructure.EXTI_Line = EXTI_Line6; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = DISABLE; EXTI_Init(&EXTI_InitStructure); //中断通道配置在打印头中一样 NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* 上电初始化 */ PD_SCK_L; PD_SCK_H; delay_us(160 + 5); PD_SCK_L; /* 等待 HX711 内部 AD 转换稳定 */ uint32_t start_time = rt_tick_get(); while(DOUT) { if(rt_tick_get() - start_time > CONVERT_STABLE_TIME) { log_e("错误:压力检测模块初始化失败!"); break; } /* 10ms 查询一次 */ rt_thread_delay(RT_TICK_PER_SECOND * 10 / 1000); } /* 获取校准的偏移量 */ cali_offset = ef_get_double("hx711_offset"); /* 初始化锁 */ rt_mutex_init(&read_lock, "HX711", RT_IPC_FLAG_FIFO); /* 初始化事件 */ rt_event_init(&event_hx711dout, "hx711dout", RT_IPC_FLAG_PRIO); /* 初始化完成 */ init_ok = true; } /** * 获取当前压力(目前只使用 A 通道,并且为线程安全的方式) * * @return 采集回来的实际压力(单位:N) */ double hx711_get_pressure(void) { int32_t cur_ad = 0; const double k = (SENSOR_MIN_PRESSURE - SENSOR_MAX_PRESSURE) / (0 - ((1 << 24) - 1)); /* 读取压力前,必须保证模块被初始化完成 */ ELOG_ASSERT(init_ok); /* 获取锁 */ rt_mutex_take(&read_lock, RT_WAITING_FOREVER); /* 等待 HX711 已准备好数据输出*/ set_hx711_dout_irq(true); PD_SCK_L; rt_uint32_t eRecv; rt_event_control(&event_hx711dout, RT_IPC_CMD_RESET, NULL); if (rt_event_recv(&event_hx711dout, EVENT_HX711DOUT_OK, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, CONVERT_PERIOD_TIME, &eRecv) != RT_EOK) { log_e("错误:获取压力检测模块数据失败!"); rt_kprintf("hx711dout_ok_timeout\n"); cur_ad = 0; goto exit; } set_hx711_dout_irq(false); /* 读取数据 */ for (int i = 0; i < 24; i++) { PD_SCK_H; PD_SCK_H; PD_SCK_L; PD_SCK_L; cur_ad <<= 1; if (DOUT) { cur_ad ++; } } /* 下次数据为通道 A 128 增益 */ for (int i = 0; i < 1; i++) { PD_SCK_H; PD_SCK_H; PD_SCK_L; PD_SCK_L; } /* 检查 24 位数据的最高位,如果为 1,则表示为负数,需要进行转换 */ if (cur_ad & (1 << 23)) { /* 所有 24 位取反 */ for(int i = 0; i < 24 ; i ++) { cur_ad ^= (1 << i); } /* 转换数据为负数 */ cur_ad *= -1; } exit: /* 释放锁 */ rt_mutex_release(&read_lock); set_hx711_dout_irq(false); return (double) cur_ad * k + cali_offset; } /** * 校准 HX711 * * @param offset 校准值 */ void hx711_calibrate(double offset) { ef_set_double("hx711_offset", offset); ef_save_env(); cali_offset = offset; } /** * 微妙级延时函数(72M主频) * * @param n 微秒 */ static void delay_us(uint32_t n) { uint32_t i = 0; while (n--) { i = 10; while (i--); } } /** * 设置MCU对应的HX711数据输出口的中断检测 * @param type true 使能,false 失能 */ static void set_hx711_dout_irq(bool type) { EXTI_InitTypeDef EXTI_InitStructure; EXTI_ClearITPendingBit(EXTI_Line6); EXTI_InitStructure.EXTI_Line = EXTI_Line6; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; if (type) { EXTI_InitStructure.EXTI_LineCmd = ENABLE; } else { EXTI_InitStructure.EXTI_LineCmd = DISABLE; } EXTI_Init(&EXTI_InitStructure); } /** * 获取HX711数据输出的电平 * @return */ uint8_t get_hx711dout(void) { return DOUT; } /** * 发送HX711准备好数据事件 */ void event_hx711dout_ok_send(void) { rt_event_send(&event_hx711dout, EVENT_HX711DOUT_OK); } static void hx711(uint8_t argc, char **argv) { #include
if (argc == 1) { rt_kprintf("当前压力为:%dN\n", (int32_t)hx711_get_pressure()); } else if (argc == 2) { /* 校准压力(采用去皮方式) */ if (!strcmp(argv[1], "cali")) { hx711_calibrate(hx711_get_pressure() * -1.0); } else { /* 连续获取 N 秒的压力 */ uint32_t start_time = rt_tick_get(); uint32_t timeout = atoi(argv[1]); while (1) { if ((rt_tick_get() - start_time) > (timeout * RT_TICK_PER_SECOND)) { /* \033[?25h 显示光标 */ rt_kprintf("\033[?25h\n"); break; } /* \033[?25l 隐藏光标,只刷新本行 */ rt_kprintf("\033[?25l当前压力为:%05dg ,剩余刷新时间 %02d S\r", (int32_t) (hx711_get_pressure() * 1000.0 / 9.8), timeout - (rt_tick_get() - start_time) / RT_TICK_PER_SECOND); /* 100ms 更新一次 */ rt_thread_delay(RT_TICK_PER_SECOND * 100 / 1000); } } } } MSH_CMD_EXPORT(hx711, hx711 [
get pressure|
calibrate]); ```
4
个回答
默认排序
按发布时间排序
aozima
2020-08-10
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!
没用过这个芯片,具体遇到啥问题呢?
NIC_TSE
2020-08-10
这家伙很懒,什么也没写!
低速AD,CSDN上教程很多
jmtgj
2023-02-27
这家伙很懒,什么也没写!
同求吧,目前就卡在这个上面
撰写答案
登录
注册新账号
关注者
1
被浏览
1.2k
关于作者
libulang
这家伙很懒,什么也没写!
提问
5
回答
1
被采纳
0
关注TA
发私信
相关问题
1
更新软件包 没有自动下载软件包
2
点更新软件包后, 软件包并没有被下载
3
RTT加载软件包的机制是什么
4
mqtt软件包,不支持直接关闭?
5
sr04软件包排他性问题
6
【建议】软件包分类增加“算法”类
7
软件包ota_downloader的http_ota解析导致内存释放断言
8
RT-Thread Studio软件包
9
rc522 软件包 问题
10
卡尔曼软件包 中的 ulapack.h 在哪里呢
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
机器人操作系统 (ROS2) 和 RT-Thread 通信
4
五分钟玩转RT-Thread新社区
5
国产MCU移植系列教程汇总,欢迎查看!
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
如何用Ubuntu qemu跑zephyr_polling的蓝牙
2
分享一种很简单的不阻塞TCP发送方法
3
stm32c86使用串口3时无法正常读到中断的数据
4
如何用ART-PI跑zephyr_polling的蓝牙
5
掌上单片机实验室 – 基于 RTT 框架的第一个应用
热门标签
RT-Thread Studio
串口
LWIP
Env
SPI
AT
FinSH
Bootloader
CAN总线
ART-Pi
Hardfault
文件系统
USB
DMA
RT-Thread
线程
SCons
RT-Thread Nano
stm32
MQTT
ESP8266
ota
UART
RTC
freemodbus
rtthread
rt-smart
packages_软件包
I2C
WIZnet_W5500
flash
cubemx
FAL
定时器
BSP
AB32VG1
PWM
ADC
SDIO
msh
socket
LVGL
keil
Debug
C++_cpp
中断
编译报错
SFUD
SMP
MicroPython
本月问答贡献
出出啊
1431
个答案
317
次被采纳
小小李sunny
1342
个答案
267
次被采纳
crystal266
505
个答案
149
次被采纳
whj467467222
1212
个答案
142
次被采纳
张世争
590
个答案
135
次被采纳
本月文章贡献
出出啊
3
篇文章
5
次点赞
小小李sunny
1
篇文章
1
次点赞
crystal266
1
篇文章
3
次点赞
whj467467222
2
篇文章
4
次点赞
张世争
6
篇文章
14
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部