树莓派进阶之路 (020) - 基于24位AD转换模块HX711的重量称量实验

参考文档:http://www.geek-workshop.com/thread-2315-1-1.html

参考文档:https://wenku.baidu.com/view/e5d5e4e26529647d26285243.html

先来看一下该模块的常用接法:

 


 


模拟输入
通道 A 模拟差分输入可直接与桥式传感器的差分输出相接。由于桥式传感器输出的信号较小,为了充分利用A/D 转换器的输入动态范围,该通道的可编程增益较大,为128 或64。这些增益所对应的满量程差分输入电压分别±20mV 或±40mV。

通道B 为固定的32 增益,所对应的满量程差分输入电压为±80mV。通道B 应用于包括电池在内的系统参数检测。

供电电源
数字电源(DVDD)应使用与MCU 芯片相同的的数字供电电源。HX711 芯片内的稳压电路可同时向 A/D 转换器和外部传感器提供模拟电源。稳压电源的供电电压(VSUP)可与数字电源(DVDD)相同。稳压电源的输出电压值(VAVDD)由外部分压电阻R1、R2 和芯片的输出参考电压VBG 决定(图1),VAVDD=VBG(R1+R2)/R2。应选择该输出电压比稳压电源的输入电压(VSUP)低至少100mV。
如果不使用芯片内的稳压电路,管脚VSUP应连接到DVDD 或AVDD 中电压较高的一个管脚上。管脚VBG 上不需要外接电容,管脚VFB 应接地,管脚BASE 为无连接。时钟选择如果将管脚 XI 接地,HX711 将自动选择使用内部时钟振荡器,并自动关闭外部时钟输入和晶振的相关电路。这种情况下,典型输出数据速率为10Hz 或80Hz。如果需要准确的输出数据速率,可将外部输入时钟通过一个20pF 的隔直电容连接到XI管脚上,或将晶振连接到XI 和XO 管脚上。这种情况下,芯片内的时钟振荡器电路会自动关
闭,晶振时钟或外部输入时钟电路被采用。此时,若晶振频率为11.0592MHz, 输出数据速率为准确的10Hz 或80Hz。输出数据速率与晶振频率以上述关系按比例增加或减少。使用外部输入时钟时,外部时钟信号不一定需要为方波。可将MCU 芯片的晶振输出管脚上的时钟信号通过20pF 的隔直电容连接到XI管脚上,作为外部时钟输入。外部时钟输入信号的幅值可低至150mV。

串口通讯
串口通讯线由管脚PD_SCK 和DOUT 组成,用来输出数据,选择输入通道和增益。当数据输出管脚DOUT 为高电平时,表明
A/D 转换器还未准备好输出数据,此时串口时钟输入信号PD_SCK 应为低电平。当DOUT 从高电平变低电平后,PD_SCK 应输入25 至27 个不等的时钟脉冲(图二)。其中第一个时钟脉冲的上升沿将读出输出24 位数据的最高位(MSB),直至第24 个时钟脉冲完成,24 位输出数据从最高位至最低位逐位输出完成。第25至27 个时钟脉冲用来选择下一次A/D 转换的输入通道和增益,参见表三。

 
PD_SCK 脉冲数输入通道 增益

 
时序图

PD_SCK 的输入时钟脉冲数不应少于25 或多于27,否则会造成串口通讯错误。当A/D 转换器的输入通道或增益改变时,A/D 转换器需要4 个数据输出周期才能稳定。DOUT 在4 个数据输出周期后才会从高电平变低电平,输出有效数据。

树莓派代码:

 1 # include <stdio.h>
 2 # include <unistd.h>
 3 # include <wiringPi.h>
 4 # include <hiredis/hiredis.h>
 5 
 6 /*-----------------结构体-----------------*/
 7 struct hx711_pin{
 8     int SCK;
 9     int SDA;
10     int EN;                        //校准使能
11     int calibration;            //校准
12     int coefficient;            //比例系数
13     int weight;                    //重量
14     unsigned long value;        //记录数值
15 };
16 
17 void set_pin(struct hx711_pin *value){
18     value->SCK             = 4;
19     value->SDA             = 5;
20     value->EN            = 1;
21     value->coefficient    = 415;
22 }
23 
24 void init_pin(struct hx711_pin *value){
25     pinMode(value->SCK,OUTPUT);
26     pinMode(value->SDA,INPUT);
27     pullUpDnControl(value->SDA,PUD_UP);
28 }
29 
30 void start(struct hx711_pin *value){
31     int i;
32     digitalWrite(value->SCK,LOW);        //使能AD
33     while(digitalRead(value->SCK));
34     value->value = 0;                    //数值
35     while(digitalRead(value->SDA));        //AD转换未结束则等待。
36     usleep(1);
37     for(i=0;i<24;i++){
38         digitalWrite(value->SCK,HIGH);
39         while(0 == digitalRead(value->SCK))usleep(1);
40         value->value = value->value*2;
41         digitalWrite(value->SCK,LOW);
42         while(digitalRead(value->SCK));
43         if(digitalRead(value->SDA))
44             value->value = value->value + 1;
45     }
46     digitalWrite(value->SCK,HIGH);
47     digitalWrite(value->SCK,LOW);
48     if((value->EN == 1)&&(value->value<25000)){
49         value->EN = 0;
50         value->calibration = value->value;
51     }else {
52         i = (value->value-value->calibration+50)/value->coefficient;
53     }
54     if(i<5000)value->weight = i;
55     printf("重量为:%d g\n",value->weight);
56 }
57 
58 /*-----------------主体-----------------*/
59 int setup(struct hx711_pin *value){    
60     if(wiringPiSetup()==-1)return 1;
61     set_pin(value);
62     init_pin(value);
63     return 0;
64 }
65 
66 void loop(struct hx711_pin *value){
67     while(1)
68     start(value);
69 }
70 
71 int main(void){
72     struct hx711_pin value;
73     if(0 == setup(&value))
74         loop(&value);
75     return 0;
76 }

截图:

经过测试,数据还挺稳的。

posted @ 2017-07-26 18:11  极客先锋  阅读(7572)  评论(0编辑  收藏  举报