搜索
bottom↓
回复: 10

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

[复制链接]

出0入24汤圆

发表于 2009-12-31 17:22:13 | 显示全部楼层 |阅读模式
各位大侠,硬件电路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 [Ticks] (12 bit)
// temp [Ticks] (14 bit)
// output: humi [%RH]
// temp [.C]
{
        float rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit
        float t=*p_temperature; // t: Temperature [Ticks] 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 [ticks](12 bit) and temperature [ticks](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!)
                //-----------------------------------------------------------------------------------
        }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入24汤圆

 楼主| 发表于 2009-12-31 20:08:05 | 显示全部楼层
请用过SHT11的朋友帮帮忙吧
谢谢了!
取不出来数心理很着急的!

出0入24汤圆

 楼主| 发表于 2009-12-31 21:11:15 | 显示全部楼层
刚才把#define SHT2MCU_Data     (!(!(PIND&0x02)))
改成了#define SHT2MCU_Data     (!(!(PIND&0x04)))
把数据位弄错了
可是现在读回来的数是错的,差很远,还望各位指教!

出0入24汤圆

 楼主| 发表于 2009-12-31 21:27:54 | 显示全部楼层
搞定了,原来是16位的数据前8位和后8位颠倒了
AVR的存储方式和51是不一样的
呵呵

出0入0汤圆

发表于 2009-12-31 21:32:17 | 显示全部楼层
这个错误我也犯了,按手册正好反了。

出0入0汤圆

发表于 2009-12-31 22:38:13 | 显示全部楼层
http://blog.ednchina.com/mengforever1981/226723/message.aspx
看看这个吧,我以前写的。应该有点参考价值

出0入0汤圆

发表于 2010-1-6 09:56:30 | 显示全部楼层
楼主具体说一下问题出在哪里?,你不是说都是0XFFFF吗?收到0XFFFF的时候SHT应答正确吗?

出0入24汤圆

 楼主| 发表于 2010-8-12 18:11:29 | 显示全部楼层
回楼上,问题出在我算错了一位的位置,呵呵
详见楼上

出0入0汤圆

发表于 2011-10-20 14:48:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-12-6 18:48:36 | 显示全部楼层
你好我现在也在弄AVR的SHT11 ,一直没弄出来 想请教你 方便加Q吗171729242 谢谢

出0入0汤圆

发表于 2012-12-6 20:48:10 | 显示全部楼层
楼主 你说存储方式不一样 你具体怎么改的 可以重新贴一下你的程序吗 谢谢 我也用AVR
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 05:14

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表