PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > PIC - Thiết kế và Ứng dụng

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

PIC - Thiết kế và Ứng dụng Ý tưởng cho các sản phẩm sử dụng PIC/dsPIC và các sản phẩm của Microchip

 
 
Ðiều Chỉnh Xếp Bài
Prev Previous Post   Next Post Next
Old 14-10-2009, 09:00 PM   #1
tiendungkct
Đệ tử 4 túi
 
Tham gia ngày: May 2007
Bài gửi: 69
:
rắc rối với pic 16F877a và cảm biến SHT11

mình đang làm việc cảm biến SHT11 và đang gặp vấn đề với cảm biến SHT11 ,mình đọc giá trị nhiệt độ từ cảm biến nhưng giá trị trả về luôn sai cụ thể nhiệt độ mình đọc lên giao động từ 11 độ C đến 14,1 độ C thôi khi lên 14,1 độ C thì nó không tăng nữa mà lại nhảy xuống dưới 14.1 độ C, va độ ẩm đọc vê cũng sai luôn ,mình kiểm tra nhưng không biết sai chổ nào hết .Bạn nào lam qua cho mình kinh nghiệm nhé .thanks
Code:
#include <16F877A.h>
#FUSES NOWDT, HS,PUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#include <lcd_lib_4bit.c>  //thu vien ham cho lcd_4 bits
#include <math.h>
#use Fast_io(a)
#use Fast_io(b)
#use Fast_io(c)
#use Fast_io(d)
#use Fast_io(e)

typedef union
{ unsigned int i;
  float f;
} value;

#define TEMP 0
#define HUMI 1
#define noACK 0
#define ACK_1 1
//adr command r/w
#define STATUS_REG_WRT 0x06 //000 0011 0
#define STATUS_REG_READ 0x07 //000 0011 1
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0

#byte PORTA       = 0x05
#byte TRISA       = 0x85
#byte PORTB       = 0x06
#byte TRISB       = 0x86
#bit  Port_ctr    =TRISB.1 // dieu khien chan data
#bit  Sck_dir     =TRISB.0
#bit  Sck      =PORTB.0 // clock for SHT11
#bit  DATA     =PORTB.1 // data for SHT11



//====================================
void SHT11_Start(void);
void calc_sth11(float *p_humidity ,float *p_temperature);
unsigned char SHT11_Readbyte(unsigned char ack);
unsigned char SHT11_writebyte(unsigned char value);
void SHT11_comm_Rst();
char SHT11_soft_rst();
unsigned char  SHT11_measuremant(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);
char SHT11_read_reg(unsigned char *p_value, unsigned char *p_checksum);
char SHT11_wrt_reg(unsigned char *p_value);
void ftoa(unsigned char *buf, float f);
unsigned delay=100;//857=1 phut

//====================================

/*=============================================================================
============================ Cac ham viet cho SHT11===========================
=============================================================================*/
/* =================================
ham tao xung start cho SHT11
       _____              ________
 DATA:      |_______|
               ___     ___
 SCK : ___|   |___|   |______
====================================*/
void SHT11_Start(void)
{
   Port_Ctr=0  ; //pin ouput
   Data=1;        // tao xung start
   Sck=0;
   delay_us(2);
   Sck=1;
   Delay_us(2);
   Data=0;
   Delay_us(2);
   Sck=0;
   Delay_us(2);
   Sck=1;
   Delay_us(2);
   Data=1;
   Delay_us(2);
   Sck=0;
}
/* =================================
ham read_byte SHT11
====================================*/
unsigned char SHT11_Readbyte(unsigned char ack)
{
   unsigned char i,val=0;

   Port_ctr=1; //pin input
   data=1; //tha pin data de doc data

   for (i=0x80;i>0;i/=2) //shift bit for masking
   {
     Delay_us(2);
     SCK=1; //clk for SENSI-BUS
     if (DATA) val=(val | i); //read bit
     Delay_us(2);
     SCK=0;
   }

   Delay_us(2);
   Port_ctr= 0;        //SHT11 WRITE
   Delay_us(2);
   
   DATA=!ack; //in case of "ack==1" pull down DATA-Line

   SCK=1; //clk #9 for ack
   Delay_us(2); //pulswith approx. 5 us
   SCK=0;
   Delay_us(2);
   Port_ctr=1; //release DATA-line
 
   return val;
}


/* ==================================================================================

======================================================================================*/
unsigned char SHT11_Writebyte(unsigned char value)
{
unsigned char i,error=0;

   PORT_ctr = 0;        //pin out 
    for (i=0x80;i>0;i/=2) //shift bit for masking
   {
     Delay_us(2);
     if (i & value)
         DATA=1; //masking value with i , write to SENSI-BUS
     else
         DATA=0;
     SCK=1; //clk for SENSI-BUS
     Delay_us(2);   //pulswith approx. 5 us
     SCK=0;
   }
  // DATA=1; //release DATA-line
   PORT_ctr = 1;    //SHT11 READ
   Delay_us(2);
   SCK=1; //clk #9 for ack
   Delay_us(2);
   error = DATA; //check ack (DATA will be pulled down by SHT11)
   SCK=0;
   return error; //error=1 in case of no acknowledge
}
/*==============================================================================
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
//       _____________________________________________________         ________
// DATA:                                                      |_______|
//          _    _    _    _    _    _    _    _    _        ___     ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
==============================================================================*/
void SHT11_comm_Rst()
{
   unsigned char i;
   Port_ctr=0;  // pin output
   Sck_dir=0;
   Data=1;  //Init state
   Sck=0;
   for (i=0;i<9;i++)
      {
         sck=1;
         delay_us(2);
         Sck=0;
         delay_us(2);
      }
   delay_us(4);
   SHT11_start();
}
/*=============================================================================
Soft reset 
=============================================================================*/
char SHT11_Soft_Rst()
{
   unsigned char error=0;
   SHT11_Comm_rst();
   error+=SHT11_Writebyte(Reset);
   return error ;// error =1 khi ko nhan dc dap ung tu SHT11
}

/*=============================================================================
Read status register
==============================================================================*/
char SHT11_read_reg(unsigned char *p_value, unsigned char *p_checksum)
{
   unsigned char error=0;
   SHT11_start();
   error=SHT11_writebyte(Status_reg_read);// send command
   *p_value=SHT11_readbyte(ACK_1); //read status register (8-bit)
   *p_checksum=SHT11_readbyte(noACK); //read checksum (8-bit)

   return error; //error=1 in case of no response form the sensor
}
/*=============================================================================
write status register
==============================================================================*/
char SHT11_wrt_reg(unsigned char *p_value)
{
unsigned char error=0;
   SHT11_Start(); //transmission start
   error+=SHT11_writebyte(STATUS_REG_Wrt);//send command to sensor
   error+=SHT11_writebyte(*p_value); //send value of status register
   return error; //error>=1 in case of no response form the sensor

}
/*=============================================================================

==============================================================================*/
unsigned char  SHT11_measuremant(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
{
unsigned char error=0;
unsigned int i;
   SHT11_Start();
   delay_us(5);
   switch (mode)
   {  // send command
        case TEMP :error += SHT11_Writebyte(Measure_Temp); break;
        case  HUMI :error += SHT11_writebyte(Measure_Humi); break;
        default: break;
   }

      port_ctr=1; // read data
      //delay_ms(320);
  for (i = 0; i < 65535 && DATA; i++) Delay_us(100); //wait until sensor has finished the measurement
   
   while (DATA == 1) Delay_us(1);

   if(DATA) error+=1; // or timeout (~2 sec.) is reached
   *(P_value+1)=(SHT11_readbyte(ACK_1)&0xFF); //read the second byte (MSB)
   *(P_Value) =(SHT11_readbyte(ACK_1) &0xFF); //read the first byte (LSB)
   *p_checksum =SHT11_readbyte(noACK); //read checksum
   return error;
     
}
/*=============================================================================
caculator for SHT11
==============================================================================*/
void calc_sth11(float *p_humidity ,float *p_temperature)
{
   float rh,t,rh_lin,rh_true,t_c;
   const float C1=-4.0; // for 12 Bit
   const float C2= 0.0405; // for 12 Bit
   const float C3=-0.0000028; // for 12 Bit
   const float T1=0.01; // for 14 Bit @ 5V
   const float T2=0.00008; // for 14 Bit @ 5V
    rh=*p_humidity;                         // rh:      Humidity [Ticks] 12 Bit 
    t=*p_temperature;                       // t:       Temperature [Ticks] 14 Bit

   t_C=(t*0.01 - 39.66); //calc. Temperature from ticks to [C]
   rh_lin=C3*rh*rh + C2*rh + C1; //calc. Humidity from ticks to [%RH]
   rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //calc. Temperature compensated humidity [%RH]
   if(rh_true>100)rh_true=100; //cut if the value is outside of
   if(rh_true<0.1)rh_true=0.1; //the physical possible range

  *p_temperature=t_C;                           //return temperature [deg Cel]
  *p_humidity=rh_true;                          //return humidity[%RH]

}
void main(void)
{  value humi_val,temp_val;
   unsigned char error,checksum;
  unsigned char s[6],s1[6];
   SET_TRIS_A(0B00000010);
   SET_TRIS_b(0x00);
   SET_TRIS_d(0x00);
   SET_TRIS_e(0x00);
   LCD_init();       //khoi tao lcd
    Delay_ms(20);
   SHT11_Soft_Rst();
   Delay_ms(20);
  while(1)
{
      error=0;
      error+=SHT11_measuremant( (unsigned char*)&humi_val.i,&checksum,HUMI);
     //measure humidity
       error+=SHT11_measuremant((unsigned char*) &temp_val.i,&checksum,TEMP);
     //measure temperature
   if(error!=0){ SHT11_comm_Rst(); while(1){led_1=~Led_1;}} //in case of an error: connection reset
    else
     {
       humi_val.f=(float)humi_val.i; //converts integer to float
       temp_val.f=(float)temp_val.i; //converts integer to float
      calc_sth11(&humi_val.f,&temp_val.f); //calculate humidity, temperatur
     
  LCD_Position(1,1) ;
  Printf(LCD_putchar,"TEMP:");
  LCD_Position(1,7);
 ftoa(s,temp_val.f);
 Printf(LCD_putchar,s);

  LCD_Position(2,1) ;
  Printf(LCD_putchar,"HUMI:");
  LCD_Position(2,7);
  ftoa(s1,humi_val.f);
  Printf(LCD_putchar, s1);
  delay_ms(50);
  }
}
}
hàm Ftoa của mình:
Code:
void ftoa(unsigned char *buf, float f) {
   unsigned int rem;
   unsigned char *s,length=0;
   int i;

   i = (int)((float)f*10);

   s = buf;
   if (i == 0){       //print 0.0 with null termination here
      *s++ = '0';
      *s++ = '.';
      *s++ = '0'; 
      *s=0;          //null terminate the string
   } else {   
      if (i < 0) {
         *buf++ = '-';
         s = buf;
         i = -i;
      }
      //while-loop to "decode" the long integer to ASCII by append '0', string in reverse manner
      //If it is an integer of 124 -> string = {'4', '2', '1'}
      while (i) {
         ++length;
         rem = i % 10;
         *s++ = rem + '0';
         i /= 10;
      }
      //reverse the string in this for-loop, string became {'1', '2', '4'} after this for-loop
      for(rem=0; ((unsigned char)rem)<length/2; rem++) {
         *(buf+length) = *(buf+((unsigned char)rem));
         *(buf+((unsigned char)rem)) = *(buf+(length-((unsigned char)rem)-1));
         *(buf+(length-((unsigned char)rem)-1)) = *(buf+length);
      }

      /* Take care of the special case of 0.x if length ==1*/   
      if(length==1) {
         *(buf+2) = *buf;
         *buf = '0';
         *(buf+1) = '.';
         *(s+2)=0;          //null terminate
      } else {
         *(buf+length) = *(buf+length-1);
         *(buf+length-1)='.';
         *(s+1)=0;          //null terminate
      }
   }
}
code này mình cũng chỉnh sửa từ code của Senirion
Thanks
Hình Kèm Theo
File Type: gif 51_6.gif (7.1 KB, 245 lần tải)
tiendungkct vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
 


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 12:37 PM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam