ycwjl728 发表于 2009-12-31 17:22:13

SHT11官方C例程改的ICC程序不好用,检测不到应答位,读回数据全是FFFF,求助

各位大侠,硬件电路DATA线上接了一个10K的上拉电阻,但是怎么试就是不好使,急死我了,请帮我看看吧!谢啦!
ICC AVR编的,用的ATMega 128

#define SHT2MCU_Data   (!(!(PIND&0x02)))
#define SHT11_DataOut    DDRD|=BIT(2)   //PD口的2位设置为输出
#define SHT11_DataIn   DDRD&=~BIT(2)   //PD口的2位设置为输入
#define SHT11_ClkOut   DDRD|=BIT(1)   //PD口的1位设置为输出
#define SHT11_CLK_H      PORTD|= BIT(1)      //PD1
#define SHT11_CLK_L      PORTD&=~BIT(1)   //PD1
#define SHT11_DATA_H   PORTD|= BIT(2)      //PD2
#define SHT11_DATA_L   PORTD&=~BIT(2)   //PD2

#include "config.h"   //这里有我的delay函数,还iom128v.h等头文件
#include <math.h>
#include <stdio.h>
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

//----------------------------------------------------------------------------------
// modul-var
//----------------------------------------------------------------------------------
enum {TEMP,HUMI};
#define DATA P1_1
#define SCK P1_0
#define noACK 0
#define ACK 1
//adr command r/w
#define STATUS_REG_W 0x06 //000 0011 0
#define STATUS_REG_R 0x07 //000 0011 1
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0
//----------------------------------------------------------------------------------
char s_read_byte(unsigned char ack)
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
        unsigned char i,val=0;
        SHT11_DataOut;
        SHT11_ClkOut;
        SHT11_DATA_H; //release DATA-line
        SHT11_DataIn;
        SHT11_DATA_L;
        delay_us(2);
        for (i=0x80;i>0;i/=2) //shift bit for masking
        {
                SHT11_CLK_H; //clk for SENSI-BUS
                delay_us(2);
                if (SHT2MCU_Data) val=(val | i); //read bit
                SHT11_CLK_L;
                delay_us(2);
        }
        //DATA=!ack; //in case of "ack==1" pull down DATA-Line
        SHT11_DataOut;
        if(ack==1)
                SHT11_DATA_L;
        else
                SHT11_DATA_H;
        delay_us(2);
        SHT11_CLK_H; //clk #9 for ack
        delay_us(5); //pulswith approx. 5 us
        SHT11_CLK_L;
        delay_us(2);
        SHT11_DATA_H; //release DATA-line
        return val;
}
//----------------------------------------------------------------------------------
char s_write_byte(unsigned char value)
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge
{
        unsigned char ibit,error=0;
        SHT11_ClkOut;
        SHT11_DataOut;
        for (ibit=0x80;ibit>0;ibit/=2) //shift bit for masking
        {
                if (ibit & value)
                        SHT11_DATA_H; //masking value with i , write to SENSI-BUS
                else SHT11_DATA_L;
                delay_us(2);
                SHT11_CLK_H; //clk for SENSI-BUS
                delay_us(5); //pulswith approx. 5 us
                SHT11_CLK_L;
                delay_us(2);
        }
        SHT11_DATA_H; //release DATA-line
        delay_us(2);
        SHT11_CLK_H; //clk #9 for ack
        SHT11_DataIn;
        SHT11_DATA_L;
        delay_us(2);
        error=SHT2MCU_Data; //check ack (DATA will be pulled down by SHT11)
        SHT11_CLK_L;
        return error; //error=1 in case of no acknowledge
}

//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start
//       _____         ________
// DATA:      |_______|
//         ___   ___
// SCK : ___|   |___|   |______
{
        SHT11_DataOut;
        SHT11_ClkOut;
        SHT11_DATA_H; SHT11_CLK_L; //Initial state
        delay_us(2);
        SHT11_CLK_H;
        delay_us(2);
        SHT11_DATA_L;
        delay_us(2);
        SHT11_CLK_L;
        delay_us(5);
        SHT11_CLK_H;
        delay_us(2);
        SHT11_DATA_H;
        delay_us(2);
        SHT11_CLK_L;
        delay_us(2);
}
//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
//       _____________________________________________________         ________
// DATA:                                                      |_______|
//          _    _    _    _    _    _    _    _    _      ___   ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
{
        unsigned char i;
        SHT11_DataOut;
        SHT11_ClkOut;
        SHT11_DATA_H; SHT11_CLK_L; //Initial state
        delay_us(2);
        for(i=0;i<9;i++) //9 SCK cycles
        {
                SHT11_CLK_H;
                delay_us(2);
                SHT11_CLK_L;
                delay_us(2);
        }
        s_transstart(); //transmission start
}
//----------------------------------------------------------------------------------
char s_softreset(void)
//----------------------------------------------------------------------------------
// resets the sensor by a softreset
{
        unsigned char error=0;
        s_connectionreset(); //reset communication
        error+=s_write_byte(RESET); //send RESET-command to sensor
        return error; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{
        unsigned char error=0;
        s_transstart(); //transmission start
        error=s_write_byte(STATUS_REG_R); //send command to sensor
        *p_value=s_read_byte(ACK); //read status register (8-bit)
        *p_checksum=s_read_byte(noACK); //read checksum (8-bit)
        return error; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_write_statusreg(unsigned char *p_value)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{
        unsigned char error=0;
        s_transstart(); //transmission start
        error+=s_write_byte(STATUS_REG_W);//send command to sensor
        error+=s_write_byte(*p_value); //send value of status register
        return error; //error>=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
//----------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum
{
        unsigned error=0;
        unsigned int i;
        s_transstart(); //transmission start
        switch(mode)
        { //send command to sensor
                case TEMP : error+=s_write_byte(MEASURE_TEMP); break;
                case HUMI : error+=s_write_byte(MEASURE_HUMI); break;
                default : break;
        }
        SHT11_DataIn;
        SHT11_DATA_L;
        for (i=0;i<65535;i++) if(SHT2MCU_Data==0) break; //wait until sensor has finished the measurement
        if(SHT2MCU_Data) error+=1; // or timeout (~2 sec.) is reached
        *(p_value) =s_read_byte(ACK); //read the first byte (MSB)
        *(p_value+1)=s_read_byte(ACK); //read the second byte (LSB)
        *p_checksum =s_read_byte(noACK); //read checksum
        return error;
}
//----------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------
void calc_sth11(float *p_humidity ,float *p_temperature)
//----------------------------------------------------------------------------------------
// calculates temperature [.C] and humidity [%RH]
// input : humi (12 bit)
// temp (14 bit)
// output: humi [%RH]
// temp [.C]
{
        float rh=*p_humidity; // rh: Humidity 12 Bit
        float t=*p_temperature; // t: Temperature 14 Bit
        float rh_lin; // rh_lin: Humidity linear
        float rh_true; // rh_true: Temperature compensated humidity
        float t_C; // t_C : Temperature [.C]
        t_C=t*0.01 - 40; //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 [.C]
        *p_humidity=rh_true; //return humidity[%RH]
}
//--------------------------------------------------------------------
float calc_dewpoint(float h,float t)
//--------------------------------------------------------------------
// calculates dew point
// input: humidity [%RH], temperature [.C]
// output: dew point [.C]
{
        float logEx,dew_point ;
        logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2) ;
        dew_point = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx) ;
        return dew_point;
}
//----------------------------------------------------------------------------------
void main()
//----------------------------------------------------------------------------------
// sample program that shows how to use SHT11 functions
// 1. connection reset
// 2. measure humidity (12 bit) and temperature (14 bit)
// 3. calculate humidity [%RH] and temperature [.C]
// 4. calculate dew point [.C]
// 5. print temperature, humidity, dew point
{
        unsigned int humi_vali=0,temp_vali=0;
        float humi_valf=0,temp_valf=0;
        float dew_point;
        unsigned char error,checksum;
        unsigned int i;
        s_connectionreset();
        while(1)
        {
                s_measure((unsigned char*) &humi_vali,&checksum,HUMI);
                s_measure((unsigned char*) &temp_vali,&checksum,TEMP);
                humi_valf=(float)humi_vali; //converts integer to float
                temp_valf=(float)temp_vali; //converts integer to float
                calc_sth11(&humi_valf,&temp_valf); //calculate humidity, temperature
                dew_point=calc_dewpoint(humi_valf,temp_valf); //calculate dew point

                //----------wait approx. 0.8s to avoid heating up SHTxx------------------------------
                for (i=0;i<40000;i++); //(be sure that the compiler doesn’t eliminate this line!)
                //-----------------------------------------------------------------------------------
        }
}

ycwjl728 发表于 2009-12-31 20:08:05

请用过SHT11的朋友帮帮忙吧
谢谢了!
取不出来数心理很着急的!

ycwjl728 发表于 2009-12-31 21:11:15

刚才把#define SHT2MCU_Data   (!(!(PIND&0x02)))
改成了#define SHT2MCU_Data   (!(!(PIND&0x04)))
把数据位弄错了
可是现在读回来的数是错的,差很远,还望各位指教!

ycwjl728 发表于 2009-12-31 21:27:54

搞定了,原来是16位的数据前8位和后8位颠倒了
AVR的存储方式和51是不一样的
呵呵

xzyang 发表于 2009-12-31 21:32:17

这个错误我也犯了,按手册正好反了。

mingyuexin1981 发表于 2009-12-31 22:38:13

http://blog.ednchina.com/mengforever1981/226723/message.aspx
看看这个吧,我以前写的。应该有点参考价值

aiyige 发表于 2010-1-6 09:56:30

楼主具体说一下问题出在哪里?,你不是说都是0XFFFF吗?收到0XFFFF的时候SHT应答正确吗?

ycwjl728 发表于 2010-8-12 18:11:29

回楼上,问题出在我算错了一位的位置,呵呵
详见楼上

zhangyunbo 发表于 2011-10-20 14:48:33

mark

dammon 发表于 2012-12-6 18:48:36

你好我现在也在弄AVR的SHT11 ,一直没弄出来 想请教你 方便加Q吗171729242 谢谢

dammon 发表于 2012-12-6 20:48:10

楼主 你说存储方式不一样 你具体怎么改的 可以重新贴一下你的程序吗 谢谢 我也用AVR
页: [1]
查看完整版本: SHT11官方C例程改的ICC程序不好用,检测不到应答位,读回数据全是FFFF,求助