调了两天,MSP430始终接收不到数据,一直以为是代码的问题,今天无意中看到别人的一片文章,才发现问题出在上拉电阻上。DATA线的上拉电阻不能太大,10k不行,换成了1k就没问题了。mark一下,顺便感谢那位作者,附上他的链接:http://blog.sina.com.cn/s/blog_52f5ded30100bf68.html
附上MSP430代码:
在main里调用:
s_connectionreset(); s_write_status(); for(;;) { s_read_temp_and_humi();//读取温度、湿度 }
sht11.h:
enum {TEMP,HUMI}; #define S_DATA_OUT (P6DIR |= BIT3) //P6.5 OUT #define S_DATA_IN (P6DIR &=~BIT3) //P6.5 IN #define S_DATA (P6IN & BIT3) //P6.5 DATA #define S_DATA_LOW (P6OUT &=~BIT3) #define S_DATA_HIGH (P6OUT |= BIT3) #define S_SCK_OUT (P6DIR |= BIT4) #define S_SCK_LOW (P6OUT &=~BIT4) #define S_SCK_HIGH (P6OUT |= BIT4) #define noACK 0 #define ACK 1 //adr command r/w #define MEASURE_TEMP 0x03 //000 0001 1 #define MEASURE_HUMI 0x05 //000 0010 1 #define MEASURE_STATUS 0x06 //000 0011 0 void delay(unsigned int k); void s_transstart(void); void s_connectionreset(void); unsigned char s_write_byte(unsigned char value); unsigned char s_read_byte(unsigned char ack); void s_calc_sth11(void); unsigned char s_measure(unsigned int *p_value, unsigned char mode); void s_write_status(); void s_read_temp_and_humi(void); unsigned int temperature,humidity; float f_temperature,f_humidity; unsigned char s_read_data(unsigned int *p_value); unsigned char s_measure_cmd(unsigned char mode); unsigned char s_error=0; extern float humi; /******************************************************************************/ /* Temperature and humidity sensor function start */ /******************************************************************************/ // generates a tran××ission start // _____ ________ // DATA: |_______| // ___ ___ // SCK : ___| |___| |______ // calculates temperature [懊] and humidity [%RH] // input : humi [Ticks] (12 bit) // temp [Ticks] (14 bit) // output: humi [%RH] // temp [懊] void s_calc_sth11(void) { float rh; // rh: Humidity float t; // t: Temperature float ttt; if(temperature>7000) ttt=temperature-7000; else ttt=7000-temperature; t=temperature*0.01 - 39.64-0.00000002*ttt*ttt; //calc. temperature from ticks to [℃] rh=(0.0405-0.0000028*humidity)*humidity -4.0; //calc. humidity from ticks to [%RH] rh=(t-25)*(0.01+0.00008*humidity)+rh; //calc. temperature compensated humidity [%RH] f_temperature=t; temperature=t; //return temperature [℃] f_humidity=rh; humidity=rh; //return humidity[%RH] if((t-temperature)>=0.5) temperature+=1; if((rh-humidity)>=0.5) humidity+=1; if(humidity>100) humidity=100; //cut if the value is outside of if(humidity<1) humidity=1; //the physical possi××e range humi=0.123; } void s_transstart(void) { S_DATA_OUT; S_SCK_OUT; S_DATA_HIGH; //Initial state S_SCK_LOW; S_SCK_HIGH; S_DATA_LOW; S_SCK_LOW; S_SCK_HIGH; S_DATA_HIGH; S_SCK_LOW; } // communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart // _____________________________________________________ ________ // DATA: |_______| // _ _ _ _ _ _ _ _ _ ___ ___ // SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______ void s_connectionreset(void) { unsigned char i; S_DATA_OUT; S_SCK_OUT; S_DATA_HIGH; //Initial state S_SCK_LOW; for(i=0;i<9;i++) //9 SCK cycles { S_SCK_HIGH; //_nop(); S_SCK_LOW; } s_transstart(); //tran××ission start } // writes a byte on the Sensibus and checks the acknowledge unsigned char s_write_byte(unsigned char value) { unsigned char i,error=0; S_DATA_OUT; for (i=0x80;i>0;i/=2) //shift bit for masking { if (i & value) S_DATA_HIGH; //masking value with i , write to SENSI-BUS else S_DATA_LOW; S_SCK_HIGH; //clk for SENSI-BUS S_SCK_LOW; } S_DATA_IN; S_SCK_HIGH; //clk #9 for ack error=S_DATA; //check ack (DATA will be pulled down by SHT11) S_SCK_LOW; S_DATA_OUT; //release DATA-line return error; //error=1 in case of no acknowledge } // reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" unsigned char s_read_byte(unsigned char ack) { unsigned char i,val=0; S_DATA_IN; for (i=0x80;i>0;i/=2) //shift bit for masking { S_SCK_HIGH; //clk for SENSI-BUS if (S_DATA) val=(val | i); //read bit S_SCK_LOW; } S_DATA_OUT; if(ack) S_DATA_LOW; else S_DATA_HIGH; //in case of "ack==1" pull down DATA-Line S_SCK_HIGH; //clk #9 for ack S_SCK_LOW; //release DATA-line return val; } /*Write status register:12bit humi,14bit temp*/ void s_write_status(void) { s_connectionreset(); s_write_byte(MEASURE_STATUS); s_write_byte(0x00); } // makes a measurement (humidity/temperature) unsigned char s_measure(unsigned int *p_value,unsigned char mode) { unsigned char error=0; unsigned int i; s_transstart(); //tran××ission start if(mode==TEMP) //send command to sensor error+=s_write_byte(MEASURE_TEMP); else error+=s_write_byte(MEASURE_HUMI); S_DATA_IN; for (i=0;i<65535;i++) if(S_DATA==0) break; //wait until sensor has finished the measurement if(S_DATA) error+=1; // or timeout (~1 sec.) is reached *p_value =s_read_byte(ACK); //read the first byte (MSB) *p_value = (*p_value)<<8; (*p_value) +=s_read_byte(noACK); //read the second byte (LSB) return error; } /***mode:TEMP,HUMI***/ unsigned char s_measure_cmd(unsigned char mode) { unsigned char error=0; s_transstart(); if(mode==TEMP) //send command to sensor error+=s_write_byte(MEASURE_TEMP); else error+=s_write_byte(MEASURE_HUMI); S_DATA_IN; return error; } unsigned char s_read_data(unsigned int *p_value) { if(S_DATA) return 1; else { *p_value =s_read_byte(ACK); //read the first byte (MSB) *p_value = (*p_value)<<8; (*p_value) +=s_read_byte(noACK); //read the second byte (LSB) return 0; } } // measure humidity [%RH](8 bit) and temperature [℃](12 bit) void s_read_temp_and_humi(void) { unsigned char error=1; while(error) { error=0; error+=s_measure(&humidity,HUMI); //measure humidity error+=s_measure(&temperature,TEMP); //measure temperature if(error!=0) s_connectionreset(); //in case of an error: connection reset else s_calc_sth11(); //calculate humidity, temperature } } /******************************************************************************/ /* Temperature and humidity sensor function END */ /******************************************************************************/ void delay(unsigned int k) { unsigned int ktemp; for(ktemp=0;ktemp<k;ktemp++); }