// 参考C程序:
//************************************************************************
#include "USE.H"
#include "Ver.h"
//************************************************************************
extern void Delay10(void);
//************************************************************************
sbit Hx711_DAT1=P2^1;
sbit Hx711_CLK1=P2^0; //P0.24和P0.25
#define Hx711_BUSY (Hx711_DAT1)
//************************************************************************
#define Hx711_DAT(x) ((x>0) ? (Hx711_DAT1=1) : (Hx711_DAT1=0)); //设置1,0
#define Hx711_CLK(x) ((x>0) ? (Hx711_CLK1=1) : (Hx711_CLK1=0)); //设置1,0
/******************************************************************
。管脚PD_SCK 输入用来控制HX711
的断电。当PD_SCK 为低电平时,芯片处于正常工作状态。
读取HX711的AD值,依次是A,B
PD_SCK 脉冲数输入通道 增益
25 A 128
26 B 64
27 A 64
******************************************************************/
//*****************************************************************
void Ready_HX711(void){
Hx711_DAT(1);
Hx711_CLK(0);
}
/**************************************************************
查询HX711是否转换完毕 Hx711_DAT=0
***************************************************************/
unsigned char Jb_HX711_OK(void){
return Hx711_DAT1;
}
/*****************************************************************************
//控制通道和增益
//flag=0 不改变通道
//flag=1 A通道 128
//flag=2 B通道 64
//flag=3 A通道 64
*******************************************************************************/
unsigned long Rd_Hx711_A_64(unsigned char ch){
unsigned long Count;
unsigned char i;
Count=0;
for(i=0;i<24;i++){
Count<<=1;
Hx711_CLK(1);
Hx711_CLK(0)
if(Jb_HX711_OK()) Count++;
}
Hx711_CLK(1)
Hx711_CLK(0); //必须变0
Hx711_CLK(1)
Hx711_CLK(0); //必须变0
if(ch==0){ // A通道=0,必须加入!
Hx711_CLK(1)
Hx711_CLK(0); //必须变0
}
return(Count);
}
/*********************************************************************
补吗处理程序 ,返回电压值!uV
**********************************************************************/
float GetFloat_BuMa(unsigned long dat){
#define MAX_REF (3300)//单位MV
float u,f;
f=1; //正负号的处理
if(dat & 0x00800000l){ //是补吗
dat=~(dat-1);
dat &=0x00ffffffl;
f=-1;
}
u=(float)dat*MAX_REF/0x00800000l/64; //只有一半的数据
u *=f;
return u*1000; //必须是uV
}
//*********************************************************************
//计算累加和
//*********************************************************************
unsigned long Count_AD(unsigned long ad,unsigned char no){
return (ad/no);
}
/**********************************************************************
启动AD 返回=0 没有数据;=1数据可用!
***********************************************************************/
unsigned char GetHX711(float *u0,float *u1){
#define MAX_HX711_No 32 //采集的次数
static char A_B_CH=0; //2个通道的转换
static unsigned long xdata ad_Hx711[2]={0,0};
static unsigned char n=0,m=0; //采集的次数
unsigned long ad;
float u;
//************************************************
if(m==1){ //首次切换通道!
if (Jb_HX711_OK()==0){
m=2;
A_B_CH=0;
Rd_Hx711_A_64(0);//读取A通道!
//tDelay(3);
}
}
//********************************************
if(m==3){ //切换B通道!
if (Jb_HX711_OK()==0){
m=2;
Rd_Hx711_A_64(1);//读取A通道!
//tDelay(3);
}
}
//********************************************
if (m==0){
Ready_HX711(); //首次上电先初始化HX711
m=1;
}
//*********************************************
//转化完毕则采集
if(m ==2){
if (Jb_HX711_OK()==0){
ad_Hx711[A_B_CH] +=Rd_Hx711_A_64(A_B_CH);//读取A,B通道!
//***************************************************
if(++n >=MAX_HX711_No){
n=0;
//*************************************************
//计算AD值
ad=Count_AD(ad_Hx711[A_B_CH],MAX_HX711_No);
ad_Hx711[A_B_CH]=0; //清除原数据
//*************************************************
u=GetFloat_BuMa(ad); //补码数据处理
//*************************************************
if(A_B_CH==0) *u0=u;
if(A_B_CH==1) *u1=u; //传出数据
//*************************************************
A_B_CH = (++A_B_CH)%2; //切换
//必须从新切换通道!等待稳定!
if(A_B_CH==1) m=3;//读取B通道!
if(A_B_CH==0){
m=0;
return 1; //2个通道全部测量完毕 数据可用
}
}
}
}
return 0;
}
//***************************************************************
//计算数据
void CountAdData(float u,unsigned char ch){
float u0;
u0=Mp1.Pt[ch].a*u+Mp1.Pt[ch].b;
//************************************
//y=kx+b-->y=ax+b
//************************************
if(u0>AdData[ch].Max) AdData[ch].Max=u0;
if(u0<AdData[ch].Min) AdData[ch].Min=u0;
//************************************
AdData[ch].SUM +=u0; //计算累加值
AdData[ch].Mont = u0; //瞬时值!
AdData[ch].cnt++; //次数加一!
}
//****************************************************************
//标定AD转换的数据
unsigned char GetHx711Data(void){
static float u0,u1;
if(0==GetHX711(&u0,&u1)) return 0;
//************************************
//y=kx+b-->y=ax+b
//************************************
CountAdData(u0,0);
CountAdData(u1,1);
return 1;
}
//****************************************************************
//通讯完毕后,必须清空原来的参数
//****************************************************************
void ClrAdData(void){
memset((unsigned char *)&AdData[0],0,sizeof(AD_DATA));
memset((unsigned char *)&AdData[1],0,sizeof(AD_DATA));
AdData[0].Max=AD_MIN;
AdData[1].Max=AD_MIN;
AdData[0].Min=AD_MAX;
AdData[1].Min=AD_MAX;
}
//**********************************************************************
//ad采集
//**********************************************************************
void Get_Ad_Data(void){
if(1==GetHx711Data()){ //采集完后返回1
Wr_IAP_AD(); //写入EEROM
Turn_PT_ON (OFF);
Turn_AD_ON (OFF);
LedMenu.Power=PWR_WAKEUP; //等待
// Led_ON(1);
}
}
|