Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
packages_软件包
HX711
有没有大神移植一个HX711称重芯片模块的软件包
发布于 2020-08-10 03:03:53 浏览:1853
订阅该版
感觉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.9k
关于作者
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
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
简单两步配置RTT源码阅读环境 vsc+clangd
2
恩智浦[FRDM-MCXN947]初探 之 ADC与DAC
3
LVGL使用字库IC芯片显示中文
4
基于STM32H750和Rt-Thread的CANFD通信实现的记录(一)
5
freemodbus主机在freertos的适配,参考rtthread例程
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部