打印

请高手帮我看看关于SHT10的这段程序,谢谢啦,我急需用的

[复制链接]
2851|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
razu_521|  楼主 | 2008-5-26 21:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
下面的是我的一个程序,可温湿度的值出来的是乱码,不知道哪儿有错误,请高手们帮我指点一下了!!谢谢!

//12864并行接口参考程序,控制器st7920
#include <reg51.h>
#include <intrins.h>
#include <math.h>    
#include <stdio.h> 
#define uchar unsigned char
#define uint unsigned int
#define LcdData P0
//12864 汉字显示模块 与MCU连接
sbit RS = P2^0;// 1:输入数据 ;0:输入命令
sbit RW = P2^1;//1:读数据 0:写数据
sbit E = P2^2;


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

//----------------------------------------------------------------------------------
// modul-var
//----------------------------------------------------------------------------------
enum {TEMP,HUMI};


sbit DATA = P1^0;
sbit SCK = P1^1;

#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


//延时子程序
void delay(unsigned int t)
{
unsigned int i,j;
for(i=0;i<t;i++)
for(j=0;j<100;j++);
}
///========================12864显示部分============================
//测试LCD忙
bit Check_Busy()
{
bit busy;
RS = 0;
RW = 1;
E = 1;
_nop_();
busy = (bit)(LcdData&0x80);
E = 0;
return 0;
}
//等待LCD到空闲
void wait()
{
while(Check_Busy());
}
//写数据
void Lcd_Writedata(unsigned char dispdata)
{ wait();
RS=1;
RW=0;
E=0;
_nop_(); _nop_();
LcdData=dispdata;
E=1;
_nop_(); _nop_();
E=0;
}
//写指令代码
void Lcd_WriteCmd(unsigned char cmdcode)
{ wait();
RS=0;
RW=0;

E=0;
_nop_(); _nop_();
LcdData=cmdcode;
_nop_(); _nop_();
E=1;
_nop_(); _nop_();
E=0;
}
/*****************初始化LCD*******************************/
void Lcd_Init(void)
{
uchar cmd;
  cmd=0x30;   //功能设置 8位数据,基本指令
Lcd_WriteCmd(cmd);  //写指令
cmd=0x0C;   //显示状态 ON,游标OFF,反白OFF
Lcd_WriteCmd(cmd);  //写指令
cmd=0x02;   //地址归位
Lcd_WriteCmd(cmd);  //写指令
cmd=0x80;   //设置DDRAM地址
Lcd_WriteCmd(cmd);  //写指令
cmd=0x06;
Lcd_WriteCmd(cmd); //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位
delay(100);      //延时
}
/*****************清屏LCD *******************************/
void Lcd_Clr(void)
{
Lcd_WriteCmd(0x01);  //清除显示
delay(100);
  delay(100);
   delay(100);
}




/*****************设置汉字位置********************************/
void Char_Set_XY(uchar x, uchar y, uchar *p)
{
   if(y == 0)
{

Lcd_WriteCmd((0x80+x));
}
if(y == 1)
{
Lcd_WriteCmd((0x90+x));
}
if(y == 2)
{

Lcd_WriteCmd((0x88+x));
}
if(y == 3)
{

Lcd_WriteCmd((0x98+x));
}
while(*p != 0)
{
Lcd_Writedata(*p++);

  }
}  

//字符串显示
void WriteStr(unsigned char code *s)
{
while(*s>0)
{ Lcd_Writedata(*s);
s++;
}
}
  
  void disp2()
{ Char_Set_XY(0,0,"温度上限:");

Char_Set_XY(0,1,"温度下限:");

  Char_Set_XY(0,2,"湿度上限:");

  Char_Set_XY(0,3,"湿度下限:");
  }

//----------------------------------------------------------------------------------
char s_write_byte(unsigned char value)
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge
{
  unsigned char i,  error=0;

  unsigned char n;

  for (i=0x80;i>0;i/=2)             //shift bit for masking
  { if (i & value) DATA=1;          //masking value with i , write to SENSI-BUS
    else DATA=0;
    SCK=1;                          //clk for SENSI-BUS
    for(n=0;n<10;n++) _nop_();    //pulswith approx. 5 us
    SCK=0;
for(n=0;n<7;n++) _nop_();
  }
  DATA=1;  //release DATA-line

     for(n=0;n<3;n++) _nop_();
      SCK=1;                            //clk #9 for ack
      for(n=0;n<5;n++) _nop_();
      error=DATA;                       //check ack (DATA will be pulled down by SHT11)
      for(n=0;n<5;n++) _nop_();
      SCK=0;



  return error;                     //error=1 in case of no acknowledge
}

//----------------------------------------------------------------------------------
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;
  DATA=1;                           //release DATA-line
  for (i=0x80;i>0;i/=2)             //shift bit for masking
  { SCK=1;                          //clk for SENSI-BUS
    if (DATA) val=(val | i);        //read bit
    SCK=0;
  }
  DATA=!ack;                        //in case of "ack==1" pull down DATA-Line
  SCK=1;                            //clk #9 for ack
  _nop_();_nop_();_nop_();          //pulswith approx. 5 us
  SCK=0;
  DATA=1;                           //release DATA-line
  return val;
}

//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start
//       _____         ________
// DATA:      |_______|
//           ___     ___
// SCK : ___|   |___|   |______
{
int n;

   DATA=1; SCK=0;                   //Initial state
   for(n=0;n<5;n++)_nop_();
   SCK=1;
   for(n=0;n<5;n++)_nop_();
   DATA=0;
   for(n=0;n<5;n++)_nop_();
   SCK=0;
   for(n=0;n<5;n++)_nop_();_nop_();_nop_();
   SCK=1;
   for(n=0;n<5;n++)_nop_();
   DATA=1;
   for(n=0;n<5;n++)_nop_();
   SCK=0;
   for(n=0;n<5;n++)_nop_();
}

//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
//       _____________________________________________________         ________
// DATA:                                                      |_______|
//          _    _    _    _    _    _    _    _    _        ___     ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
{
  unsigned char i;
  int n;

  DATA=1; SCK=0;                    //Initial state
  for(i=0;i<9;i++)                  //9 SCK cycles
  {
    SCK=1;
for(n=0;n<10;n++)_nop_();
    SCK=0;
for(n=0;n<5;n++)_nop_();
  }
   for(n=0;n<5;n++)_nop_();
  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_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
//----------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum
{
  unsigned int 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;
  }
  for (i=0;i<65535;i++) if(DATA==0) break; //wait until sensor has finished the measurement
  if(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)

//  printf("\ndata1=%x, data2=%x\n", *(p_value), *(p_value+1));

  *p_checksum =s_read_byte(noACK);  //read checksum
  return error;
}

//----------------------------------------------------------------------------------
void init_uart()
//----------------------------------------------------------------------------------
//9600 bps @ 11.059 MHz
{SCON  = 0x52;
TMOD  = 0x20;
TCON  = 0x69;
TH1   = 0xfd;
}

//----------------------------------------------------------------------------------------
void calc_sth11(float *p_humidity ,float *p_temperature)
//----------------------------------------------------------------------------------------
// calculates temperature [癈] and humidity [%RH]
// input :  humi [Ticks] (12 bit)
//          temp [Ticks] (14 bit)
// output:  humi [%RH]
//          temp [癈]
{ 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

  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 [癈]

  t_C=t*0.01 - 40;                  //calc. temperature from ticks to [癈]
  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 [癈]
  *p_humidity=rh_true;              //return humidity[%RH]
}



//----------------------------------------------------------------------------------
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 [癈]
// 4. calculate dew point [癈]
// 5. print temperature, humidity, dew point

{
  value humi_val,temp_val;
  float dew_point;
  unsigned char error,checksum;
  unsigned int i;

init_uart();

  s_connectionreset();
Lcd_Clr();
Lcd_Init(); //初始化LCD
//Char_Set_XY(2, 1, "初始化成功");
delay(1000);

  while(1)
  { error=0;
    error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI);  //measure humidity

//printf("humi:%dC \n",humi_val.i);

    error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP);  //measure temperature

// printf("temp:%dC \n",temp_val.i);

    if(error!=0) s_connectionreset();    //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, temperature
    //  dew_point=calc_dewpoint(humi_val.f,temp_val.f); //calculate dew point
      //printf("temp:%5.1fC \n",temp_val.f);
         
Lcd_WriteCmd(0x98);
Lcd_WriteDat(*temp_va1.f) ;
// Char_Set_XY(1,2,&temp_val.f );
    }
    //----------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!)
    //-----------------------------------------------------------------------------------
  }
}
 

相关帖子

沙发
razu_521|  楼主 | 2008-5-26 21:22 | 只看该作者

这个是SHT10的资料

硬件电路设计

本设计的硬件部分主要由温湿度传感器SHT10,AT89S51单片机和LED数码管构成。




2.1  SHT10数字式温湿度传感器

SHT10传感器由相对湿度传感器,温度传感器,校准存储器,14位A/D转换器,信号放大器和I2C总线接口构成。SHT10具备卓越的长期稳定性,露点值计算输出功能,全较准、数字输出功能,免外围电路,完全低功耗,采用表面贴片封装或四脚互换封装,体积微小,全自动降能功能。

2.2  单片机和SHT10接口电路
由于AT89S51不具备I2C总线接口,故使用单片机通用I/O口线来虚拟I2C总线[9],利用P1.6来虚拟时钟线,利用P1.5口线来虚拟数据线DATA,并在DATA端接入一个4.7K的上拉电阻,同时在VCC及GND端接入一个0.1UF的去耦电容,AT89S51单片机与SHT10的接口电路如图2所示。                                                   



 软件程序设计
首先,单片机将温度数据(SOT)从SHT10读入,然后根据公式1计算温度,再判断标志位TEMP_SORH的状态(初始化标志位TEMP_SORH为高),分别进行显示温度和读取湿度数据(SORH)、计算湿度、显示湿度。系统主程序流程图见图3。测量温湿度子程序主要包括以下三个部分:
3.1  传输开始
初始化传输时,单片机发出"传输开始"命令,具体为当SCK为高时,将DATA由高电平变为低电平,并在下一个SCK为高时将DATA升高。接下来一个命令包含三个地址位(目前只支持"000")和5个命令位,当上述命令发送给SHT10之后,单片机通过检测DATA脚的ACK位是否处于低电位确认SHT10是否正确收到命令。SHT10命令编码表见表2。

    表2 SHT10命令编码表    
命令    编码    说明
保存    0000X    保存
测量温度    00011    温度测量
测量湿度    00101    湿度测量
读状态寄存器    00111    读状态寄存器
写状态寄存器    00110    写状态寄存器
保存    0101X-1110X    保存
软启动    11110    重启芯片,清除状态寄存器的错误值,等待11毫秒后进入下一个命令
3.2  连接复位时序
如果单片机与SHT10传感器的通讯中断(SHT10没有正确收到命令),则需要重新发出传输开始命令。下列信号顺序会使串口复位:当使DATA线处于高电平时,触发SCK 9次以上(含9次),并随后发一个前述的"传输开始"命令。
3.3  温湿度测量时序
当单片机发出了传输开始命令,且SHT10正确接收到温(湿)度测量命令后,单片机就要等到测量完成。使用8/12/14位的分辨率测量分别需要大约11/55/210毫秒。为表明测量完成,SHT10会使数据线为低,此时单片机必须重新启动SCK。然后传送两字节测量数据与1字节CRC校验和。在传输过程中控制器必须通过使DATA为低来确认每一字节,所有的测量值从右算MSB列于第一位。通讯在确认CRC数据位后停止。如果没有用CRC-8校验和,则单片机需要在测量数据LSB后,保持ACK为高来停止通讯,SHT10在测量和通讯完成之后会自动返回睡眠模式。需要注意的是,为使SHT10温升低于0.1℃,则此时工作频率不能大于15%(如:12位精确度时,每秒最多进行3次测量)。
测量温度子程序流程图见图4,测量湿度子程序流程图见图5。

 

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

29

帖子

0

粉丝