![]() |
|
Tài trợ cho PIC Vietnam |
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 |
![]() |
#1 |
Đệ 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); } } } 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 } } } Thanks |
![]() |
![]() |
|
|