基础知识

51单片机和霍尔水流量传感器编程实例

2020-04-17 07:25:52 ultisensor 364
  1. 此实例来源于网络,我司不负责解释和答疑,敬请谅解。

  2. 开发准备,作者https://me.csdn.net/wj2020scu

  3. (1)USC-HS21TI流量传感器一个
    (2)51开发板一个

  4. 基础知识
    (1)USC-HS21TI流量传感器只有三根线。即数据线、VCC、GND。数据线输出为占空比为50%的方波。当水流通过水流转子组件时,磁性转子转动并且转速随着流量的变化而成线性变化。霍尔传感器(霍尔元件采样)输出相应的脉冲信号。其流量脉冲特性计算公式为:脉冲f(Hz)=8.1x流量Q(L/min)-3。
    (2)51单片机的中断工作方式。51单片机有定时器T0和T1,他们既有定时又有计数的功能。通过设置相关的特殊功能寄存器就可以启用定时或计数功能。需要注意的是,定时器系统是单片机内部一个独立的硬件部分,CPU一旦设置定时功能,定时器便在晶振的作用下计时,当计数器计满便会产生中断,通知CPU该如何去处理。而作为计数器时,计数脉冲来自相应的外部输入引脚T0(P3.4),T1(P3.5)或者T2(P1.0,52单片机)。

  5. 电路设计
    (1)将霍尔传感器数据线插在P3.4,VCC接在VCC,GND接GND。
    霍尔水流传感器
    (2)这是我的开发板数码管的电路,提供参考。
    霍尔水流传感器

    5. 


  6. 软件设计
    #include#include#define uchar unsigned char //宏定义
    #define uintunsigned int //宏定义
    sbit we = P2^7; //位定义数码管位选锁存器接口
    sbit du = P2^6;//位定义数码管位选锁存器接口
    float frency,Q,F,num;//Q为流量,单位L/min;F为频率,单位HZ
    uchar code leddata[]={
     
    0x3F,//"0"
    0x06,//"1"
    0x5B,//"2"
    0x4F,//"3"
    0x66,//"4"
    0x6D,//"5"
    0x7D,//"6"
    0x07,//"7"
    0x7F,//"8"
    0x6F,//"9"
    0x77,//"A"
    0x7C,//"B"
    0x39,//"C"
    0x5E,//"D"
    0x79,//"E"
    0x71,//"F"
    0x76,//"H"
    0x38,//"L"
    0x37,//"n"
    0x3E,//"u"
    0x73,//"P"
    0x5C,//"o"
    0x40,//"-"
    0x00,//熄灭
    0x00//自定义
     
     };
     //数码管带小数点显示
    uchar code leddatapoint[]={
     
    0xBF,//"0"
    0x86,//"1"
    0xDB,//"2"
    0xCF,//"3"
    0xE6,//"4"
    0xED,//"5"
    0xFD,//"6"
    0x87,//"7"
    0xFF,//"8"
    0xEF,//"9"
    0x00,//熄灭
    0x00//自定义
     
     };
    //毫秒级延时函数
    void delay(uint z)
    {
     uint x,y;
     for(x = z; x > 0; x--)
    for(y = 114; y > 0 ; y--);
    }
    //四位数码管动态显示函数
    void display(float i)
    {
     uchar shi, ge,fen,shifen;
     float x,y;
     shi = i / 10; //显示十位
     ge= (int)i % 10;//显示个位
     x=i*10;
     y=i*100;
     fen = (int)x%10;//分位
     shifen = (int)y%10;//十分位
     
     P0 = 0xff;//清除断码
     we = 1; //打开位选
     P0 = 0xef;//1110 1111
     we = 0; //关闭位选
     
     du = 1;//打开段选
     P0 = leddata[shi];
     du = 0; //关闭段选
     delay(5);//延时5毫秒
     
     P0 = 0xff;//清除断码
     we = 1; //打开位选
     P0 = 0xdf;//1101 1111
     we = 0; //关闭位选
     
     du = 1;//打开段选
     P0 = leddatapoint[ge];
     du = 0; //关闭段选
     delay(5);//延时5毫秒
     
     P0 = 0xff; //清除断码
     we = 1;//打开位选
     P0 = 0xbf;//1011 1111
     we = 0; //关闭位选
     
    du = 1; //打开段选
     P0 = leddata[fen];
     du = 0; //关闭段选
     delay(5);//延时5毫秒

    P0 = 0xff; //清除断码
     we = 1;//打开位选
     P0 = 0x7f;//0111 1111
     we = 0; //关闭位选

    du = 1; //打开段选
     P0 = leddata[shifen];
     du = 0; //关闭段选
     delay(5);//延时5毫秒
    }
    uint read()//得到计数器0当前脉冲次数函数
    {
     uint tl,th1,th2;//读两次高位,两次高位一样说明没有低位进位,读数更加精确。
     uint val;
     while(1)
    {
    th1=TH0;
    tl=TL0;
    th2=TH0;
    if(th1==th2)
     break;
     }
     val=th1*256+tl;
     return val;
    }
    void main()
    {
     TMOD=0x15;//定时器计数器工作方式配置
     TH0=0;
     TL0=0;
     TH1=(65536-45872)/256;
     TL1=(65536-45872)%256;
     EA=1;//开总中断
     ET0=1;//中断允许
     ET1=1;
     TR0=1;//运行控制位
     TR1=1;
     while(1)
     {
    display(Q);
     }
     
    }
    void T0_time()interrupt 1
    {
     TH0=0;
     TL0=0;
    }
    void T1_time()interrupt 3
    {
     TH1=(65536-45872)/256;//50毫秒
     TL1=(65536-45872)%256;
     num++;
     if(num==20)//1s更新一次数据,送至数码管显示
     {
    num=0;
    F=read();//每隔1s读一次计数器0,该值则为频率。计算出Q后立马把计数器0清零重新计数。
    if(F>0)
    {
     Q=(F+3)/8.1;//流量传感器经验公式
     TH0=0;
     TL0=0;
    }
    else
    {
     Q=0;//如果不加这句,当F=0,由公式知道Q!=0。
     TH0=0;
     TL0=0;
    }
     }
    }

    测试效果

  7. 霍尔水流传感器

因为这是之前做比赛的时候剩下的传感器,前两天突然冒出来了,看了看数据手册,发现挺简单的就敲了出来。电路板就没设计了,因为YF-B1的输出太简单了。源码应该没有问题,测试过精度还挺不错的。代码能力还值得提升,有很多冗余的部分,之后有时间优化一下。



首页
产品
视频
下载
选型表