1.由于世面上面普及HX711,单HX720有更大的优势!

 

2.驱动源码

//管脚定义
#define HX720_RCC	RCC_APB2Periph_GPIOB	 //HX720时钟引脚
#define HX720CLK_Port	GPIOB			//HX720时钟引脚
#define HX720CLK_Pin	GPIO_Pin_15	        //HX720时钟引脚
#define HX720_RCC	RCC_APB2Periph_GPIOB	//HX720数据引脚
#define HX720Read_Port	GPIOB			//HX720数据引脚
#define HX720Read_Pin	GPIO_Pin_14	        //HX720数据引脚
//定义
#define HX720_CLK_H()   (GPIO_SetBits(HX720CLK_Port,HX720CLK_Pin)) //时钟线置高电平
#define HX720_CLK_L()   (GPIO_ResetBits(HX720CLK_Port,HX720CLK_Pin))//时钟线置低电平
#define GetDataPinState()  (GPIO_ReadInputDataBit(HX720Read_Port,HX720Read_Pin))//获取引脚状态

//管脚初始化
// 称引脚初始化
void BalancePortInit(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(HX720_RCC, ENABLE);

    GPIO_InitStructure.GPIO_Pin = HX720CLK_Pin;	//时钟		     
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(HX720CLK_Port, &GPIO_InitStructure);
	
    GPIO_InitStructure.GPIO_Pin = HX720Read_Pin;//数据
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(HX720Read_Port, &GPIO_InitStructure);
}

//机器周期延时 __NOP(); 1个us
void DelayHX720us()
{
  __NOP();
  __NOP();
}

//获取HX720数据
uint32_t GetHX720Data(void)
{ 
    volatile uint32_t Count= 0;
    uint8_t i;
    HX720_CLK_L(); //使能AD(SCK置低)
    Count=0;
    while(GetDataPinState()); //AD转换未结束则等待。否则开始读取
    for (i=0;i<24;i++)
    {
        HX720_CLK_H();  //SCK 置高(脉冲)
	//DelayHX720us();
        Count=Count<<1; //下降沿来时变量Count左移一位,右侧补
	HX720_CLK_L();  //PD_SCK 置低
	//DelayHX720us();
	if(GetDataPinState()) Count++;//最右侧补1
    }
    //测量128增益 10HZ
    HX720_CLK_H();
    Count = Count^0x800000;//第25个脉冲下降沿来时,转换数据 异或
    //Count = Count & 0x7FFFFF; //恢复
    //DelayHX720us();
    HX720_CLK_L();
    //DelayHX720us();

    //测量VBAT-VOUT
    HX720_CLK_H();
    //DelayHX720us();
    HX720_CLK_L();
    //DelayHX720us();

    //128增益 40HZ	
    HX720_CLK_H();
    //DelayHX720us();
    HX720_CLK_L();
    //DelayHX720us();
    return(Count);//输出的数据是带符号的输出,处理数据的时候需要把符号去掉
}

3.数据分析

  • 数据手册写 输出数据在0x800000 - 7FFFFF之间。

  • 这个数据大家很迷惑估计,上面说的是 是以二进制补码的方式输出的
  • 0x800000 BIT=‭1000 0000 0000 0000 0000 0000‬  (24位)
  • 0x7FFFFF BIT=‭‭011111111111111111111111‬  (24位)
  • 那下面看下 补码的定义:计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理,符号位都是用0表示“正”,用1表示“负”
  • 这样就不难理解了,0x800000 最高位代表负数,这样 会出现1111 1111 1111 1111 1111 1111 - 7FFFFF 到 + 7FFFFF,这就出现一个问题 最小不是 0X800000,而是 带符号的 FFFFFF。这是我对数据的理解
  • 有个Blog也有讲数据分析的  传送门 可以看一下
  • 这样数据如果 异或  ^0x800000   (相同为0 相异为1)  这样数据就会从 0x000000 ---  FFFFFF;
  • 数据这样分析就应该理解了

4.数据的处理

  • 由于 数据 ^0x800000,这样处理数据的时候最高位 就要小心处理,避免过零点,如果 INP<INN,这样数据是相反的,具体

  •  因此想数据直接转换为 采集的电压就必须注意这一点,如果 INP > INN 简单的去掉符号位,保留有效位就得到实际值了;反之就要去掉符号位,拿7FFFFF去减有效位,得到的是实际值

5.数据的计算方式

  • 看手册是增益128  手册分辨率24bit,实际无噪声是 16bit,不过算的话还是 24bit。如果采集的数据小的话 这样可以用 16bi以下的数据就可以了,数据会准确很多吧
  • 理论精度:TheoreticalAccuracy = \frac{Vref}{2^{^{24}}}
  • 计算方式:
  • 例 :INP - INN = 2Mv  (Vref单位也是Mv)
  • ActualValue = \frac{2Mv \times {\color{Magenta} 128} \times {\color{DarkRed} 2^{^{24}}}}{​{\color{Green} Vref}}{\color{Magenta} }

6.测量的数据转化为温度,误差还是可以接受的

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐