收录日期:2021/01/17 13:14:27 时间:2016/08/28 06:42:47 标签:单片机/工控
HS1101,仿真,单片机 HS1101测量湿度采用将HS1101置于555振荡电路中,将电容值的变化砖换成电压频率信号,可以直接被微处理器采集。


NE555输出接在单片机的T1上,但在液晶上显示总为00

C语言程序:


#include <reg52.h>
#include<stdio.h>
 
#define uchar unsigned char
#define uint  unsigned int
 
uchar tem0,tem1;  //用于存放50ms中所记脉冲个数的高低字节                            
uchar temp0,temp1; //用于存放最终换算出的湿度的高低字节                         
uint f=0;       //频率初值 

sbit rs=P2^4;
sbit rw=P2^5;
sbit e=P2^6;

uchar Busy_Check();
void write_comd(uchar comd);
void write_dat(uchar dat);
void LCD_disp_string(uchar x,uchar y,uchar *p);
void LCD_value(uchar x,uchar y,float f);
void LCDinit(void);

void delay_50us(uint t)
 {
  uchar j;
for(;t>0;t--)
for(j=19;j>0;j--);
 }
 void delay_50ms(uint t)
{
  uint j;
for(;t>0;t--)
for(j=6245;j>0;j--) ;
}

/**********************************************************
* 名称: timer0() 
* 功能: 定时器1,每50000us中断一次。
* 入口参数:
***********************************************************/
void timer0() interrupt 1 
{
EA =0;
    TR0=0;
    TR1=0;
 
    TL0=0xFF;     //重装初值 定时50000us OX4BFFH
    TH0=0x4B;
           
    tem0=TL1;   //读取50ms中所记脉冲个数
    tem1=TH1;
    TL1=0x00;    //定时器1清零
    TH1=0x00;
    //f=1;         //作标注位
 
    TR0=1;
    TR1=1;
    EA=1;
}
 
/************************************************************
* 名称: timer1() 
* 功能: 计数器,用于计数将555输出的频率,以计数相对湿度。
* 入口参数:
*************************************************************/
void timer1() interrupt 3    //T1中断,表示计数的脉冲溢出,超出了可测量的频率范围(在50ms内计数达65535)
{ //显然在这里不可能。所以重新启动。
EA =0;
    TR0=0;
    TR1=0;
 
    TL0=0x00;   //重装初值 定时50000us
    TH0=0x4C;
    TL1=0x00;   //定时器1清零
    TH1=0x00;
 
    TR0=1;
    TR1=1;
    EA=1;
}
 
void Init_timer()
{
    TMOD=0x51;  //0101 0001  定时器1在方式1下工作16位计数器 定时器0在方式1下工作16位定时器
    TL0=0x00;   //定时器0初值 定时50000us
    TH0=0x4C;                  
    TL1=0x00;   //定时器1清零
    TH1=0x00;
    ET0=1;      //使能定时器0中断
    ET1=1;      //使能定时器1中断
    EA=1;      //使能总中断
    TR0=1;     //开始计时
    TR1=1;
}
 
void tran()
{
    f=tem1; 
    f=(f<<8)|tem0;  //计算出50ms中所记脉冲个数
    f=f*20;         //50ms*20=1000ms=1s 1秒钟所记脉冲个数等于频率 
    if((5623<=f)&&(f<=6852))  //不同频率对于不同相对湿度 相对湿度的有效范围为(0%--100%)
    {
        if((6734<f)&&(f<=6852))
          {temp0=0;temp1=(6852-f)*10/118;}
        if((6618<f)&&(f<=6734))
          {temp0=1;temp1=(6734-f)*10/116;} 
if((6503<f)&&(f<=6618))
          {temp0=2;temp1=(6618-f)*10/115;}  
        if((6388<f)&&(f<=6503))
          {temp0=3;temp1=(6503-f)*10/115;}
        if((6271<f)&&(f<=6388))
          {temp0=4;temp1=(6388-f)*10/117;}   
        if((6152<f)&&(f<=6271))
          {temp0=5;temp1=(6271-f)*10/119;}
        if((6029<f)&&(f<=6152))
          {temp0=6;temp1=(6152-f)*10/123;}
        if((5901<f)&&(f<=6029))
          {temp0=7;temp1=(6029-f)*10/128;}
        if((5766<f)&&(f<=5901))
          {temp0=8;temp1=(5901-f)*10/135;}
        if((5623<f)&&(f<=5766))
          {temp0=9;temp1=(5766-f)*10/143;}
     }
    else
{
 temp0=0;temp1=0;
}
}
              
void main()
{
uchar i,k;
    uchar humi; //湿度
    Init_timer();
LCDinit();
    humi=0;
LCD_disp_string(1,1,"Humi:");
LCD_disp_string(1,11,"%");
LCD_disp_string(1,13,"RH");
    while(1)
    {
       for(i=0;i<200;i++)
       for(k=0;k<200;k++); //延时
       tran();
       temp0&=0x0F;
       temp1&=0x0F;
       temp0=temp0<<4; 
       humi=temp0|temp1;
      
   LCD_value(1,7,humi);
  
    }

}

 uchar Busy_Check()
{
  uchar LCD_Status;
rs = 0;
    rw = 1;
    e = 1;
delay_50us(10);
    LCD_Status = P0;
e = 0;
return LCD_Status;
}
 
void write_comd(uchar comd)
{
    while((Busy_Check()&0x80)==0x80); //0x80表示液晶繁忙
e=0;
rs=0;
rw=0;
P0=comd;
delay_50us(10);
e=1;
delay_50us(20);
e=0;
}
void write_dat(uchar dat)
{
    while((Busy_Check()&0x80)==0x80); //0x80表示液晶繁忙
e=0;
rs=1;
rw=0;
P0=dat;
delay_50us(10);
e=1;
delay_50us(20);
e=0;
}
//显示一个字符函数
void LCD_disp_string(uchar x,uchar y,uchar *p)
{
uchar address;
if(x==0)
address=0x80+y;
else
address=0xc0+y;
write_comd(address);
while(*p>0)
{
write_dat(*p);
p++;
}
}

void LCD_value(uchar x,uchar y,float f)
{
unsigned char str[15]; //不能定义为char* str,数组长度一定要大于浮点数的总位数

sprintf(str,"%.1f",f); //1 表示小数位数小数太多自动四舍五入
LCD_disp_string( x, y, str);
//return 0;
}

void LCDinit(void)
{
delay_50us(300);
write_comd(0x38);//8位数据长度,双行显示,5*7点阵
delay_50us(100);
    write_comd(0x38);
delay_50us(100);
write_comd(0x38);
write_comd(0x38);
write_comd(0x08);//关画面显示,关光标,关光标闪烁
write_comd(0x01);//清屏
write_comd(0x06);//AC加1计数,光标右移一个字符;禁止画面滚动
write_comd(0x0c);//开画面显示,关光标,关光标闪烁
//write_comd(0x10);


}


我刚刚用clock接在T1上,设置了频率,可以显示,有+—5%的偏差。也就是说是振荡电路的问题。。。看不出有什么问题
HS1101是一个湿敏电容,就是一个可变的电容,那么它的电容值有多大呢?他和NE555组合成的振荡电路频率多少,程序里面能检测到得有效频率是多少,把这些弄懂的话就OK了
同问啊。。。最近我也遇到这个问题。。。显示的一直是0
我的問題解決了,是頻率的範圍不在它的範圍內,所以一直是零
引用 3 楼 memecaoyu 的回复:
HS1101是一个湿敏电容,就是一个可变的电容,那么它的电容值有多大呢?他和NE555组合成的振荡电路频率多少,程序里面能检测到得有效频率是多少,把这些弄懂的话就OK了

我現在在畫PCB圖,你的PCB圖是手工佈局,劃線的嗎
引用 5 楼 liuyunyan12138 的回复:
我的問題解決了,是頻率的範圍不在它的範圍內,所以一直是零


那应该怎么设置啊 求图求程序快较稿了还没弄出来
#include<reg52.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]="HUMI:     %RH";
sbit lcdrs=P2^4;
sbit lcdrw=P2^5;
sbit lcde=P2^6;
uchar num;
uchar tem0,tem1,humi;                          
uchar temp0,temp1;                    
uint f=0; 



void timer0() interrupt 1 
{
EA =0;
    TR0=0;
    TR1=0;
 
    TL0=0xFF;    
    TH0=0x4B;
           
    tem0=TL1;   
    tem1=TH1;
    TL1=0x00;    
    TH1=0x00;
   
 
    TR0=1;
    TR1=1;
    EA=1;
}
 

void timer1() interrupt 3    
{
EA =0;
    TR0=0;
    TR1=0;
 
    TL0=0x00;   
    TH0=0x4C;
    TL1=0x00;   
    TH1=0x00;
 
    TR0=1;
    TR1=1;
    EA=1;
}
 
void Init_timer()
{
    TMOD=0x51;  
    TL0=0x00;   
    TH0=0x4C;                  
    TL1=0x00;  
    TH1=0x00;
    ET0=1;      
    ET1=1;      
    EA=1;      
    TR0=1;     
    TR1=1;
}
      

void tran()
{
    f=tem1; 
    f=(f<<8)|tem0;
    f=f*20;         
    if((5623<=f)&&(f<=6852))  
    {
        if((6734<f)&&(f<=6852))
          {temp0=0;temp1=(6852-f)*10/118;}
        if((6618<f)&&(f<=6734))
          {temp0=1;temp1=(6734-f)*10/116;} 
if((6503<f)&&(f<=6618))
          {temp0=2;temp1=(6618-f)*10/115;}  
        if((6388<f)&&(f<=6503))
          {temp0=3;temp1=(6503-f)*10/115;}
        if((6271<f)&&(f<=6388))
          {temp0=4;temp1=(6388-f)*10/117;}   
        if((6152<f)&&(f<=6271))
          {temp0=5;temp1=(6271-f)*10/119;}
        if((6029<f)&&(f<=6152))
          {temp0=6;temp1=(6152-f)*10/123;}
        if((5901<f)&&(f<=6029))
          {temp0=7;temp1=(6029-f)*10/128;}
        if((5766<f)&&(f<=5901))
          {temp0=8;temp1=(5901-f)*10/135;}
        if((5623<f)&&(f<=5766))
          {temp0=9;temp1=(5766-f)*10/143;}
     }
    else
{
 temp0=0;temp1=0;
}
}
void delay(uint t)
{
   uchar j;
for(;t>0;t--)
for(j=19;j>0;j--);
}
void write_com(uchar com)
{
  lcdrw=0;
  lcdrs=0;
  P0=com;
  delay(10);
  lcde=1;
  delay(20);
  lcde=0;
}
void write_date(uchar date)
{
  lcdrw=0;
  lcdrs=1;
  P0=date;
  delay(10);
  lcde=1;
  delay(20);
  lcde=0;
}
void LCDinit()
{
   lcde=0;
   lcdrw=0;
   write_com(0x38);
   write_com(0x0c);
   write_com(0x06);
   write_com(0x01);
}
void LCD_disp_string(uchar x,uchar y,uchar *p)
{
uchar address;
if(x==0)
address=0x80+y;
write_com(address);
while(*p>0)
  {
    write_date(*p);
    p++;
  }
}

void LCD_value(uchar x,uchar y,float f)
{
unsigned char str[15]; 

sprintf(str,"%.1f",f); 
LCD_disp_string( x, y, str);

}

void main()
{
    LCDinit();
    Init_timer();
    humi=0;
    while(1)
    {
       tran();
       temp0&=0x0F;
       temp1&=0x0F;
       temp0=temp0<<4; 
       humi=temp0|temp1;
      
   LCD_value(0,6,humi);
  
    
       write_com(0x80);
       for(num=0;num<14;num++)
       {
         write_date(table[num]);
 
       }  
    }
}

自己改的,雖然沒有那個好,圖就是上面的圖。我們最後用的是可調電容代替HS1101的。用示波器看波形,調頻率。。
引用 8 楼 liuyunyan12138 的回复:
#include<reg52.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]="HUMI:     %RH";
sbit lcdrs=P2^4;
sbit lcdrw=P2^5;
sbit lcde=P2^6;
uch……

为什么还是显示的零,示波器没有波形。。。不过楼主灰常感谢哈。。。
你用仿真出数了吗?你先编个程序,看LCD1602好使不.好使,你再用那种试验箱,可以输出方波的,接到T1,试试程序好使不,如果可以,如果都可以就是振荡电路的问题。查查哪里连得不对
我用这个,怎么也是0啊,,而且一直闪烁,,
要不要叫A/D转换啊,,,
引用 12 楼 u010373305 的回复:
要不要叫A/D转换啊,,,
不用A/D转换。第一个程序也好使,第二个程序有点瑕疵,嘿嘿
引用 13 楼 liuyunyan12138 的回复:
引用 12 楼 u010373305 的回复:要不要叫A/D转换啊,,,不用A/D转换。第一个程序也好使,第二个程序有点瑕疵,嘿嘿
多谢哈,,现在可以用了,,
引用 10 楼 liuyunyan12138 的回复:
你用仿真出数了吗?你先编个程序,看LCD1602好使不.好使,你再用那种试验箱,可以输出方波的,接到T1,试试程序好使不,如果可以,如果都可以就是振荡电路的问题。查查哪里连得不对


仿真也显示的零。。。想问下555电路图那些参数都是怎么设置的
在网上找的振荡电路的图
我也在弄这个,没成功啊,能加Q不,有事请教、
引用 10 楼 liuyunyan12138 的回复:
你用仿真出数了吗?你先编个程序,看LCD1602好使不.好使,你再用那种试验箱,可以输出方波的,接到T1,试试程序好使不,如果可以,如果都可以就是振荡电路的问题。查查哪里连得不对

我LCD有显示,但是接了频率信号器在T1还是0
是不是频率的范围不对啊!
引用 19 楼 liuyunyan12138 的回复:
是不是频率的范围不对啊!

范围弄多少、
引用 2 楼 liuyunyan12138 的回复:
我刚刚用clock接在T1上,设置了频率,可以显示,有+—5%的偏差。也就是说是振荡电路的问题。。。看不出有什么问题

 怎么设置频率  不懂啊 求赐教
怎么设置频率  不懂啊 求赐教
该回复于2014-01-20 09:02:36被管理员删除
555电路抄错了。
2、6接一起!靠湿度元件近的一段电阻取小(1K-3K),靠电源的电阻取大(50-100K),
这样输出接近方波,容易被单片机检测,否则波形很尖,容易丢失没冲。
没看清:请将R2和R3阻值调换,同时确认R3的一端是接电源的。
楼主问题解决了么,可以发给我一份么
楼主的555电路那样接,能震荡吗?
2、6接一起
26接电容到地
26接一个小电阻到7
7接一个电阻到Vc
4、8接到电源
5最好接一个10u电解到地
1地
我的也是显示0,不知怎么改,望楼主回复一下!谢谢!

今天我辞职了 改版之后怎么头像换不了啊 新手学习问题·软件 android开发的来下啦 工作九年了,最近想换工作[北京] msgsnd msgrcv如何发送接收struct类型 max plus 2相关问题 今天你喝的是什么 XE 中代码排版Ctrl+D这个功能,安装CNPACK被弄没了,怎么恢复? 不用第三方变量交换两个变量的值 我想架设一个网站,运行在我本地的电脑上,其他用户可以通过一个网址访问,请问该如何操作 oracle与sql查询问题请教 北京地铁四号线动物园站扶梯故障致1死28伤{转} hibernate session.get() 函数问题 C#回传总弹出新网页,求助。。。 看清楚咯,各位水友 上海 三金问题 jsp表格要想用a4纸打印,其大小设置问题 本人现在外企,公司不让用“有道翻译”?为什么 求教:如何将剪切板内容复制到CString中 在网页扫描并显示图片 【阿哲】最近水区太冷清了。② windows service可以像逻辑层组件一样暴露其接口供表示层调用? 關閉窗體前 檢查表單的內容是否被修改了???? 怎样保持QGraphicsView伸缩时背景位置不变 測試一下。。 MessageBox为什么不能被继承? 如何在button事件里调用FileUpload呢? 定义一个独立的窗体单元做为基类