打印

【图文介绍+程序】电子水位测量器存在的问题

[复制链接]
2508|23
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 qq543538634 于 2016-8-26 16:57 编辑

我的设计目的是做一个水位测量,把测量数据通过数码管显示,再通过USB发送到PC端。
我的思路是用水来作为导体,当水漫到哪个位置时那个位置就导通。
但在实际测试中发现,水的电阻是50K-100K左右,电阻过大,无论怎样检测位通过水都无法得到低电平,(就是无法导通拉低电平),在proteus中仿真也是得到同样的结果,电阻达到50K,就无法拉低电平。
我看网上的设计思路跟我的也差不多,为什么他们的能检测到电平变化呢。。
下面附上程序,有兴趣的朋友可以互相讨论。。

#include<reg51.h>           //头文件
#include<intrins.h>
sbit CLK=P1^1;                           //时钟控制位
sbit QH=P1^0;               //数据输入端(输入给C51)
sbit SH=P1^2;               //控制74LS165的读数、移位。高电平时表示移位,低电平时表示置位。SH=0时,从并行端口读入数据,并行口的8位数据将被置入其内部的8个触发器;SH=1时,并行输入被封锁,移位操作开始。
//sbit CLKIN=P^3;            //类似CLK时钟控制位,当CLK和CLKIN有一个为低电平并且SH 为高电平时,另一个时钟可以输入。当CLK和CLKIN有一个为高电平时,另一个时钟被禁止。只有在CLK为高电平时CLKIN才可变为高电平。
#define uchar unsigned char //宏定义,为方便编程
#define uint unsigned int
#define INT8U unsigned char
#define INT16U unsigned int
/******************************
        数码管显示0-9及其I/O定义
*******************************/
sbit  SH_CP=P2^2;       //上升沿时,移位存储器移位
sbit  DS=P2^1;                 //串行数据输入端
sbit  ST_CP=P2^0;       //上升沿时,移位存储器的数据存入存储寄存器中,并数据直接输出
sbit  qianwei=P2^3;                //千位显示
sbit  baiwei=P2^4;            //百位显示
sbit  shiwei=P2^5;            //十位显示
sbit  gewei=P2^6;       //个位显示
code  INT8U SEG_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};        //数码管显示0-9
uchar a[2]=0;

unsigned long int read_int165()
{
  unsigned long int i;
  unsigned long int q=0;
  unsigned long int sum=0;
  unsigned long int total=0;
//  CLKIN=1;                                       
  SH=0;                                                          //从并行口读入数据
  _nop_();                                                //延时
  SH=1;                                                          //从串行口输出数据
  _nop_();
  //CLKIN=0;
  for(q;q<2;q++)                        //循环2次
  {
     for(i=1;i<=8;i++)              //从输出口扫描8位数据
        {
              //向左移1位,右边补0
          if(QH==0)
          {
            sum=i;
                        
              }
          CLK=0;
          _nop_();
          CLK=1;
          _nop_();
                  a[q]=sum;
        }
            
  }        
    total=a[0]+a[1];
    return total;
}
void delay_ms(unsigned int time)
{
    unsigned char j;
    for( ; time>0; time-- )
        for( j=0; j<200; j++ );
}
/************************************
*         74hc595出口数据输入
*入口参数:d    出口参数:无
*************************************/
void Serial_input_595(INT8U d)
{
INT8U i;
for(i=0;i<8;i++)
{
d<<=1;
DS=CY;
SH_CP=0;
_nop_();
_nop_();
SH_CP=1;
_nop_();
_nop_();
}
SH_CP=0;
}

/************************************
*出口数据输入74HC595存储寄存器         
*入口参数:无    出口参数:无
*************************************/

void Parallel_output_595(void)
{
ST_CP=0;
_nop_();
_nop_();
ST_CP=1;
_nop_();
_nop_();
ST_CP=0;
}

/************************************
*        数码管显示函数                                           在只与单片机情况下,数码管的显示
*入口参数:a    出口参数:无                                                  0
*************************************/
void Shumaguan_xiansh(INT8U t)
{
    INT8U x;
        unsigned long int c;
    qianwei=0;
    baiwei=0;
    shiwei=0;
    gewei=0;
    c=0;
        x=0;
    while(1)
    {         
                   c=read_int165();
        t=SEG_CODE[c%10];
        Serial_input_595(t);
        gewei=1;
        Parallel_output_595();
        delay_ms(5);//延迟函数
        gewei=0;
        _nop_();
        t=SEG_CODE[c/10%10];
        Serial_input_595(t);
        shiwei=1;
        Parallel_output_595();
        delay_ms(5);//延迟函数
        shiwei=0;
        _nop_();
        t=SEG_CODE[c/100%10];
        Serial_input_595(t);
        baiwei=1;
        Parallel_output_595();
        delay_ms(5);//延迟函数
        baiwei=0;
        _nop_();
        t=SEG_CODE[c/1000%10];
        Serial_input_595(t);
        qianwei=1;
        Parallel_output_595();
        delay_ms(5);//延迟函数
        qianwei=0;
        _nop_();  
    }
}
void delayms(unsigned int ms)
{
unsigned int i;
while(ms--)        
for(i=0;i<600;i++);        
}
void ConfigUART(unsigned int baud)
{
    SCON  = 0x50;  //配置串口为模式1
    TMOD &= 0x0F;  //清零T1的控制位
    TMOD |= 0x20;  //配置T1为模式2
    TH1 = 256 - (11059200/12/32)/baud;  //计算T1重载值
    TL1 = TH1;     //初值等于重载值
    ET1 = 0;       //禁止T1中断
    ES  = 1;       //使能串口中断
    TR1 = 1;       //启动T1
}
/* UART中断服务函数 */
void InterruptUART() interrupt 4
{
    if (RI)  //接收到字节
    {
        RI = 0;   //手动清零接收中断标志位
        SBUF = read_int165();  //接收的数据+1后发回,左边是发送SBUF,右边是接收SBUF
    }
    if (TI)  //字节发送完毕
    {
        TI = 0;   //手动清零发送中断标志位
    }
}
void main(void)
{
EA = 1;   //使能总中断
ConfigUART(9600);  //配置波特率为9600
while(1)
{
delayms(100); //150ms发送一次数据
Shumaguan_xiansh();        
}
}
                                                         

相关帖子

沙发
suntechnology| | 2016-8-26 17:40 | 只看该作者
楼主,你那1K的上拉电阻选小了,换成1M的试试。

使用特权

评论回复
板凳
maychang| | 2016-8-26 17:45 | 只看该作者
你使用了74LSXXX芯片。这种芯片需要相当小的下拉电阻才能够使芯片输入为低电平。
改用74HCXXX芯片即可。

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
qq543538634 + 3 一语中的
地板
qq543538634|  楼主 | 2016-8-26 17:49 | 只看该作者
suntechnology 发表于 2016-8-26 17:40
楼主,你那1K的上拉电阻选小了,换成1M的试试。

你好,我试过用1M的电阻,但在水里还是检测不到低电平。

使用特权

评论回复
5
qq543538634|  楼主 | 2016-8-26 17:56 | 只看该作者
maychang 发表于 2016-8-26 17:45
你使用了74LSXXX芯片。这种芯片需要相当小的下拉电阻才能够使芯片输入为低电平。
改用74HCXXX芯片即可。 ...

你好,非常感谢你的建议。
但是在proteus中仿真改用HC165还是无法拉低这个电平。。。

44444.jpg (237.42 KB )

44444.jpg

使用特权

评论回复
6
maychang| | 2016-8-26 18:12 | 只看该作者
qq543538634 发表于 2016-8-26 17:56
你好,非常感谢你的建议。
但是在proteus中仿真改用HC165还是无法拉低这个电平。。。

6楼图中,不知道R21下端你接到了那里。据首帖第二图看,各开关(估计是模拟水电阻)右边接地。
6楼图中R21下端经开关应该接高电平。

使用特权

评论回复
7
suntechnology| | 2016-8-26 18:17 | 只看该作者
qq543538634 发表于 2016-8-26 17:49
你好,我试过用1M的电阻,但在水里还是检测不到低电平。

电源5V,上拉换成1M阻值,导线被水浸没时,用万用表测量D端口的电平为0.7V左右。如果检测不到低电平,那就是程序的问题。

使用特权

评论回复
8
pywmiss| | 2016-8-26 20:47 | 只看该作者
水位检测,我们之前做过,用两个IO做,一个输出低电平,一个输入上拉,。。这样输入端检测到低电平就OK了。‘
还有一个注意的,这两个IO要互换着用,如果固定同一脚输入,输出会发生电解的情况。
这两个IO可以串个100欧电阻或者不加,可以在外面加100K的上拉电阻也可以用单片机内部的上拉。

使用特权

评论回复
9
qq543538634|  楼主 | 2016-8-27 09:17 | 只看该作者
maychang 发表于 2016-8-26 18:12
6楼图中,不知道R21下端你接到了那里。据首帖第二图看,各开关(估计是模拟水电阻)右边接地。
6楼图中R21 ...

你好    似的 ,R21接R2后接了高电平。

使用特权

评论回复
10
qq543538634|  楼主 | 2016-8-27 09:23 | 只看该作者
fxmxh 发表于 2016-8-26 17:49
楼主这种简单粗暴测量水位的方法,玩玩可以,用在真正的产品上,就逼格太低了,呵呵,蟹老板的秘方拿去用, ...

我也想拿去用,可是你这个图 不全。。看不太懂啊

使用特权

评论回复
11
qq543538634|  楼主 | 2016-8-27 09:36 | 只看该作者
suntechnology 发表于 2016-8-26 18:17
电源5V,上拉换成1M阻值,导线被水浸没时,用万用表测量D端口的电平为0.7V左右。如果检测不到低电平,那 ...

我从USB口接了个5V电源。。正极串了个1M电阻,再把两根线放水里测出来是-0.08的电压啊。 。

dddddd.jpg (350.98 KB )

dddddd.jpg

使用特权

评论回复
12
maychang| | 2016-8-27 09:44 | 只看该作者
qq543538634 发表于 2016-8-27 09:17
你好    似的 ,R21接R2后接了高电平。

“R21接R2后接了高电平”
你的意思,R2、R4、R5……公共端接高电平?

使用特权

评论回复
13
qq543538634|  楼主 | 2016-8-27 09:58 | 只看该作者
maychang 发表于 2016-8-27 09:44
“R21接R2后接了高电平”
你的意思,R2、R4、R5……公共端接高电平?

嗯。。下面那几个上拉电阻都是 共高电平。在仿真里不接50K电阻时候是可以实现  按下一个开关 单片机检测到一个低电平的。。

使用特权

评论回复
14
suntechnology| | 2016-8-27 12:12 | 只看该作者
qq543538634 发表于 2016-8-27 09:36
我从USB口接了个5V电源。。正极串了个1M电阻,再把两根线放水里测出来是-0.08的电压啊。 。

...

楼主,从照片上看,你把两个表笔直接放到水里测电压,没有接触导线,那样是不对的,表笔距离不一样,测出来的电压也就不一样。
正确的接线方式是:黑表笔接负极,红表笔接D端口。

使用特权

评论回复
15
maychang| | 2016-8-27 12:30 | 只看该作者
qq543538634 发表于 2016-8-27 09:58
嗯。。下面那几个上拉电阻都是 共高电平。在仿真里不接50K电阻时候是可以实现  按下一个开关 单片机检测 ...

你6楼图中,从74HC165输入端到电源正端的电阻是1千欧,你想用水电阻(50千欧)把74HC165输入端拉到低电平?
这种情况,至多拉到4.9V,而74HC系列芯片低电平最低是1.5V。
把你的那些1千欧电阻统统换成150千欧,最好换成220千欧。此外,每个74HC芯片输入端串联数十千欧电阻,最好每个输入端接一支数nF到数十nF电容到地。

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
qq543538634 + 3
16
maychang| | 2016-8-27 12:34 | 只看该作者
qq543538634 发表于 2016-8-27 09:58
嗯。。下面那几个上拉电阻都是 共高电平。在仿真里不接50K电阻时候是可以实现  按下一个开关 单片机检测 ...

连电阻分压都没有计算?
前面沙发位已经给你指出过。

有一位网友指出应该用交流电源,他说的是对的。直流会产生电解现像导致电极生锈。

使用特权

评论回复
17
jrcsh| | 2016-8-27 14:19 | 只看该作者
交毕业设计~~~~~ 还凑合


现实不太好用,

可以在底部检查压力,  超声波检查高度,液位,

使用特权

评论回复
18
qq543538634|  楼主 | 2016-8-27 16:16 | 只看该作者
maychang 发表于 2016-8-26 17:45
你使用了74LSXXX芯片。这种芯片需要相当小的下拉电阻才能够使芯片输入为低电平。
改用74HCXXX芯片即可。 ...

嗯嗯 对了,用LS芯片不行,换成HC芯片,再把上拉电阻改成200K以上就可以啦~谢谢啦

使用特权

评论回复
19
zxq82| | 2016-8-27 16:42 | 只看该作者
路过

使用特权

评论回复
20
gradyhuang| | 2016-8-29 14:47 | 只看该作者
赛元触摸MCU检水,稳定量产,可以加Q2920952784索取资料

赛元触摸检水方案.png (297.36 KB )

赛元触摸检水方案.png

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
qq543538634 + 3
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

37

帖子

1

粉丝