驱动SHT1x传感器数据错误

2019-03-24 14:19发布

源程序来自“金属狂人”贴的,但是程序不全,我稍加整理写了一下,以前用51单片机做开发时候,用过这个,程序没问题,但是现在改用LM3S开发,经过整理读出数据错误(见截图) 特将两个程序都贴上,请高手指点,一个是51驱动,一个LM3S1651驱动。51驱动的程序是对的,产品公司已经卖出好多了。  
/*************************************************************************************
文件名:LM3S
文件功能:驱动温湿度传感器 *************************************************************************************/ #include "hw_i2c.h"
#include "hw_ints.h"
#include "hw_memmap.h"
#include "hw_types.h"
#include "gpio.h"
#include "i2c.h"
#include "interrupt.h"
#include "sysctl.h"
#include "sht10.h"
#include "uart.h" //1、宏定义,SDA接到PB3,SCL接到PB2上。
#define SHT1x_SDA_SYSCTL           SYSCTL_PERIPH_GPIOB
#define SHT1x_SDA_GPIO_PORT     GPIO_PORTB_BASE
#define SHT1x_SDA_PIN      GPIO_PIN_3 #define SHT1x_SCL_SYSCTL           SYSCTL_PERIPH_GPIOB
#define SHT1x_SCL_GPIO_PORT     GPIO_PORTB_BASE
#define SHT1x_SCL_PIN      GPIO_PIN_2
//控制命令,SHT1x地址位均为 000    地址位      命令 R/W
#define SHT1x_CMD_STATUS_REG_W     0x06    //000     0011  0
#define SHT1x_CMD_STATUS_REG_R     0x07    //000     0011  1
#define SHT1x_CMD_GET_TEMP         0x03    //000     0001  1
#define SHT1x_CMD_GET_HUMI         0x05    //000     0010  1
#define SHT1x_CMD_RESET            0x1E    //000     1111  0 //ACK为低电平有效
#define SHT1x_ACK_YES              0x01
#define SHT1x_ACK_NO               0x00 #define SHT1x_CALC_TEMP         0x01
#define SHT1x_CALC_HUMI      0x02 //===============================================================
int test;
unsigned short test2;
unsigned char test3;
int iHumi,iTemp;
unsigned char checkSum;
float fTempVal,fHumiVal; //定义的浮点型温湿度的值 //=========================
void delay_sht1x_bus(unsigned int z)
{
 unsigned int x;//,y;
 for(x=z;x>0;x--);
//   for(y=1; y>0; y--);
 
} //设置SDA为输出
static void set_sht1x_sda_output(void)
{
 GPIODirModeSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_DIR_MODE_OUT); //SDA为输出管脚,推挽
  GPIOPadConfigSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
} //设置SDA为输入
static void set_sht1x_sda_input(void)
{
 GPIODirModeSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_DIR_MODE_IN); //SDA为输入管脚,推挽
  GPIOPadConfigSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
}
//====================================================================
//IO初始化
void init_sht1x_dev_pin(void)
{
 SysCtlPeripheralEnable(SHT1x_SDA_SYSCTL); //使能GPIOB
  GPIODirModeSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_DIR_MODE_OUT);  //将PB3设为输出
  GPIOPadConfigSet(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD); //推挽。2mA驱动
 SysCtlPeripheralEnable(SHT1x_SCL_SYSCTL); //使能GPIOB
  GPIODirModeSet(SHT1x_SCL_GPIO_PORT, SHT1x_SCL_PIN, GPIO_DIR_MODE_OUT); //将PB2设为输出
  GPIOPadConfigSet(SHT1x_SCL_GPIO_PORT, SHT1x_SCL_PIN, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD); //推挽,4mA驱动
 set_sht1x_sda_output();  //将SDA设为输出
} //======================================================================
//设置SCL为0或1
static void set_sht1x_scl(char flag)
{
 if (0 == flag)
 {
  GPIOPinWrite(SHT1x_SCL_GPIO_PORT, SHT1x_SCL_PIN, ~SHT1x_SCL_PIN);
  }
  else if (1 == flag)
  {
   GPIOPinWrite(SHT1x_SCL_GPIO_PORT, SHT1x_SCL_PIN, SHT1x_SCL_PIN);  
  }
} //=====================================================================
//设置DSA为0或1
static void set_sht1x_sda(char flag)
{
 if (0 == flag)
  {
   GPIOPinWrite(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, ~SHT1x_SDA_PIN);
  }
  else if (1 == flag)
  {
   GPIOPinWrite(SHT1x_SDA_GPIO_PORT, SHT1x_SDA_PIN, SHT1x_SDA_PIN);  
  }
} //============================================================================
//启动传感器
//       _____         ________
// DATA:      |_______|
//           ___     ___
// SCK : ___|   |___|   |______
void start_sht1x_op(void)
{
 //初始状态
  set_sht1x_sda(1); delay_sht1x_bus(1);
  set_sht1x_scl(0); delay_sht1x_bus(1);
 //第一个时钟上升沿后数据变为低
  set_sht1x_scl(1); delay_sht1x_bus(1);
  set_sht1x_sda(0); delay_sht1x_bus(1);
 //时钟下降沿后时钟上升沿
  set_sht1x_scl(0); delay_sht1x_bus(1);
  set_sht1x_scl(1); delay_sht1x_bus(1);
 //数据变为高,时钟下降沿
  set_sht1x_sda(1); delay_sht1x_bus(1);
  set_sht1x_scl(0); delay_sht1x_bus(1);
}
//=====================================================================
////读取SDA,返回值为读取结果
static int read_sht1x_sda(void)
{
 int proc_result = -1;
  unsigned char tmp_data;
  set_sht1x_sda_input();
  tmp_data = GPIOPinRead(SHT1x_SDA_GPIO_PORT,SHT1x_SDA_PIN);
//  if (SHT1x_SDA_PIN == tmp_data) //======================================???约等于1==tmp_data
 if(1== tmp_data)
  {
   proc_result = 1;
  }
  else
  {
   proc_result = 0;
  }
  set_sht1x_sda_output();
  return (proc_result);
} //=====================================================================
//写一字节,
//入口函数为要写入的数据,返回值为ACK信号,是否正确写入数据
int write_sht1x_byte(unsigned char indata)
{
 int proc_result = -1; 
  int i;
  unsigned char in_data;
  in_data=indata;
  for (i = 0; i < 8; i++)
  {
   if (0x80 == (in_data & 0x80))
   {
    //High
     set_sht1x_sda(1); 
   } 
   else
   {
     set_sht1x_sda(0);
   }
   delay_sht1x_bus(1);
   in_data = (in_data << 1); //左移一位
   set_sht1x_scl(1);
   delay_sht1x_bus(1);
   set_sht1x_scl(0);
  }
 
 //释放总线
  set_sht1x_sda(1);
 //给出上升沿,读入ACK
  set_sht1x_scl(1);
  proc_result = read_sht1x_sda();
  if (1 == proc_result)
  {
  //无效ACK信号
    proc_result = -1;
  }
  set_sht1x_scl(0);
  return (proc_result);
}
//==============================================================================
//读一字节
//ack暂时为无效入口函数,返回值为ack信号
int read_sht1x_byte(unsigned char *p_out_data,unsigned char ack)
{
 int proc_result = -1;
  int i;
  unsigned char tmp_data;
  tmp_data = 0x00;
  for (i = 0; i < 8; i++)
  {
   tmp_data = (tmp_data << 1);
   set_sht1x_scl(1);
   delay_sht1x_bus(1); 
   proc_result = read_sht1x_sda();
   if (1 == proc_result)
   {
     tmp_data |= 0x01;
   } 
   set_sht1x_scl(0);
   delay_sht1x_bus(1);
  }
 
  *p_out_data = tmp_data;
  proc_result = read_sht1x_sda();
  if (1 == proc_result)
  {
   //没有ACK信号
    proc_result = -1;
  }
 //释放总线
  set_sht1x_scl(1);delay_sht1x_bus(1);
  set_sht1x_scl(0);delay_sht1x_bus(1);
  set_sht1x_sda(1);delay_sht1x_bus(1);
  return (proc_result);
} /*
//=====================================================================
//读SHT11状态
int read_sht1x_status(unsigned char *p_value,unsigned char *p_checksum)
{
 int proc_result = -1;
 unsigned char read_st,read_checksum;
 
 //启动操作
 start_sht1x_op();
 //写入读取命令
 proc_result = write_sht1x_byte(SHT1x_CMD_STATUS_REG_R);
    //读取状态
 proc_result = read_sht1x_byte(&read_st,SHT1x_ACK_YES);
    //读取校验值
 proc_result = read_sht1x_byte(&read_checksum,SHT1x_ACK_NO);
   *p_value     = read_st;
   *p_checksum  = read_checksum;  return (proc_result);
}
//=====================================================================
//写SHT11状态
int write_sht1x_status(unsigned char value)
{
 int proc_result = 0;
 //启动操作
 start_sht1x_op();
 proc_result += write_sht1x_byte(SHT1x_CMD_STATUS_REG_W);
 proc_result += write_sht1x_byte(value);
 return (proc_result);
}
//====================================================================
//SHT11复位
void reset_sht1x_connect(void)
{
 int i;  set_sht1x_sda(1);delay_sht1x_bus(1);
 set_sht1x_scl(0);delay_sht1x_bus(1);
 for (i = 0; i < 9; i++) {
  set_sht1x_scl(1);delay_sht1x_bus(1);
  set_sht1x_scl(0);delay_sht1x_bus(1);
 }  start_sht1x_op();
}
//=====================================================================
//软件复位
int reset_sht1x_software(void)
{
 int proc_result = -1;  reset_sht1x_connect();
 proc_result = write_sht1x_byte(SHT1x_CMD_RESET);  //需要11ms
 return (proc_result);
}
*/   /*
//===========================================================================
//计算温湿度
//int calc_sht1x_value(int mode,t_dev_sht1x *p_this)
//int calc_sht1x_value()
int calc_sht1x_value(int mode,int *p_this)
{
  int proc_result = -1;
  const float T1 = 0.01;
  const float T2 = 0.00008;
  float c1 = -4;
  float c2 = 0.0405;
  float c3 = -0.0000028;
  float rh;
  float t;
  float rh_lin;
  float rh_true;
  float t_c;
  float logex,dew_point;
 //计算温湿度
  rh = p_this->humi;
  t  = p_this->temp;
  t_c     = t*0.01 - 39.6;  //12bit 0.04  14bit 0.01
  rh_lin  = c3*rh*rh + c2*rh + c1;
  rh_true = (t_c - 25)*(T1 + T2*rh) + rh_lin;
  if (rh_true > 100)
  {
    rh_true = 100;
  }
  else if (rh_true < 0.1)
  {
    rh_true = 0.1;
  }
  p_this->temp_value = t_c;
  p_this->humi_value = rh_true;
  return (proc_result); }
*/
//=============================================================================
//读取结果
//入口函数mode为读取温度或者湿度,pvalue为读取结果,pcheaksum为校验数据
int get_sht1x_result(int mode,unsigned char *p_value,unsigned char *p_check_sum)
{
  int proc_result = 0;
  int i;
  static unsigned char read1,read2; //optimize
  static unsigned short result_value;
//启动操作
  start_sht1x_op();
 //获取传感器测量数值
  switch (mode)
  {
   case  SHT1x_CALC_TEMP:
     proc_result += write_sht1x_byte(SHT1x_CMD_GET_TEMP);
    break;
    case  SHT1x_CALC_HUMI:
      proc_result += write_sht1x_byte(SHT1x_CMD_GET_HUMI);
    break;
    default:
      proc_result = -1;
    break;
  }
 //等待测量完成
  for(i = 0; i < 65535; i++)
  {
   delay_sht1x_bus(1);
   proc_result = read_sht1x_sda(); //读取ACK位
   if (0 == proc_result)
   {
    //得到传感器响应
     break;
   }
  }
 
  if (1 == proc_result)
  {
  //超时后传感器仍未响应
   proc_result = -1;
 }
  read1 = 0;
  read2 = 0;
  proc_result += read_sht1x_byte(&read1,SHT1x_ACK_YES);  //MSB  高八位数据到read1,低八位数据到read2
 //read1 = (read1 & 0x0F);
  proc_result += read_sht1x_byte(&read2,SHT1x_ACK_YES);  //LSB
  result_value = read1;
  result_value = (result_value << 8);
  result_value = (result_value | read2);
  *p_value = result_value;
  proc_result += read_sht1x_byte(&read1,SHT1x_ACK_NO);
  *p_check_sum = read1;
  return (proc_result);
} //=============================================================================
void calc_sth11(float *p_humidity ,float *p_temperature)
//----------------------------------------------------------------------------------------
// calculates temperature  and humidity [%RH]
// input :  humi (12 bit)
//          temp  (14 bit)
// output:  humi
//          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 GetLast_Humi_Temp()
{
 int error;
 error+= get_sht1x_result(1,(unsigned char *)&iTemp,&checkSum);
 error+= get_sht1x_result(2,(unsigned char *)&iHumi,&checkSum);
 //此处可检测
 fHumiVal=(float)iHumi;                         //converts integer to float整形转化成浮点型
  fTempVal=(float)iTemp;
  calc_sth11(&fHumiVal,&fTempVal);                   //calculate humidity, temperature计算实际值
  iTemp=(int)(fTempVal*10);
 iHumi=(int)(fHumiVal*10);
 
} //==============================
void main()
{
  unsigned char a,b;
 
 SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |SYSCTL_XTAL_6MHZ);
 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
  GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
   UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 9600,
                        (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                         UART_CONFIG_PAR_NONE));
   UARTEnable(UART0_BASE);
 init_sht1x_dev_pin();
 while(1)
  {
   GetLast_Humi_Temp();
//        test=0x11;
// test=get_sht1x_result(1,&test2,&test3);
//  a=test/16;
//   b=test%16;
   UARTCharPut(UART0_BASE,a);
    UARTCharPut(UART0_BASE,b);
  }
 
}   以上为LM3S驱动,串口暂时没用。   此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
3条回答
kzdtdyy
2019-03-24 19:26
//
#include <reg52.h>
//#include "STC12C2052AD.h"
#include <intrins.h> //Keil library (is used for _nop()_ operation)  
#include <math.h>    //Keil library  
#include <stdio.h>   //Keil library
//====================================================================
#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
sbit SCK = P1^7;
sbit DATA = P1^6;
sbit t =P1^0;
unsigned char checksum;
//unsigned char startVal=0x00;
unsigned char readyT;   
unsigned char readyRH;
unsigned char endT=0xCA;
unsigned char endRH=0xDB;
//unsigned char uart0Time;

float fTempVal,fHumiVal; //定义的浮点型温湿度的值
//long lTempVal,lHumiVal;
int idata iTempVal,iHumiVal,iDewpoint;  //定义的整形的温湿度的值
unsigned int iText;
//unsigned char idata *pcTempVal,*pcHumiVal;
unsigned char a,b,c,d;
unsigned char idata e,f,g;
unsigned char idata  cHumiVal;

unsigned char  idata  ayTempHumiFram[10];  //数组中存放:第一个温度,第二个湿度,第三个计算出来的露点温度,
                //第四个温度校验,第五个湿度校验,第六个露点值校验

enum {TEMP,HUMI};//枚举类型声明,变量可能存在多种类型


void s_transstart(void)//启动传输时序
//----------------------------------------------------------------------------------
// generates a transmission start 形成一个传输开始
//       _____         ________
// DATA:      |_______|
//           ___     ___
// SCK : ___|   |___|   |______
{  
   DATA=1; SCK=0;                   //Initial state
   _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
   SCK=1;
   _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
   DATA=0;
   _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
   SCK=0;  
   _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
   SCK=1;
   _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
   DATA=1;     
   _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
   SCK=0;     
}

void s_connectionreset(void)   //正确接收指令信号
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart 通信复位
//       _____________________________________________________         ________
// DATA:                                                      |_______|
//          _    _    _    _    _    _    _    _    _        ___     ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
//       _______________________________________________        ________
// DATA:                                                |_______|
//          _     _     _    _     _     _     _     _     _        ___     ___
// SCK : __| 1|__|2 |_|3 |__|4 |__|5 |__|6 |__|7 |__| 8|__|9 |______|   |___|   |______
{  
  unsigned char i;
  DATA=1; SCK=0;                    //Initial state
  for(i=0;i<9;i++)                  //9 SCK cycles
  { SCK=1; _nop_();
    SCK=0;
  }
  s_transstart();                   //transmission start
}
char s_write_byte(unsigned char value)//带返回值函数  字符型变量  写寄存器
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge
{
   unsigned char i,error=0;
   for (i=0x80;i>0;i/=2)             //shift bit for masking
    {
  if (i & value)
       DATA=1;          //同时为1的时候执行 masking value with i , write to SENSI-BUS 8位移动
        else DATA=0;
  _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();   //+2
        SCK=1;                          //clk for SENSI-BUS
        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();  //+2      //pulswith approx. 5 us //拉高表示通讯结束
        SCK=0;
     }
   DATA=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
                            //release DATA-line
   SCK=1;                            //clk #9 for ack
   error=DATA;  _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//+1                     //check ack (DATA will be pulled down by SHT11)
   SCK=0;  _nop_(); _nop_();_nop_();_nop_();_nop_();     //+1
   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;_nop_();_nop_();//+1                          //clk for SENSI-BUS
    if (DATA) val=(val | i);        //read bit  
    SCK=0;  _nop_(); //+1      
  }
  DATA=!ack;  _nop_();_nop_();_nop_(); //+1                      //in case of "ack==1" pull down DATA-Line
  SCK=1;                            //clk #9 for ack
  _nop_();_nop_();_nop_();  _nop_();_nop_();_nop_();_nop_();_nop_();//+1        //pulswith approx. 5 us
  SCK=0;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//+1         
  DATA=1;                           //release DATA-line
  return val;
}

/*
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 char error=0;
   unsigned int i;

   s_transstart(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //+6                 //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 等待测量结束DATA=0测量结束
  if(DATA) error+=1;                    // or timeout (~2 sec.) is reached测量失败或超时
  *(p_value)  =s_read_byte(ACK);  _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//+3      //read the first byte (MSB)
  *(p_value+1)=s_read_byte(ACK);   _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//+3     //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 [癈] 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 InitTempHumiSensor(void)
{
//init_uart();
s_connectionreset();
}

//****************************************************************************************
//函数名称:
//参    数:
//函数功能:
//返回值 :
//****************************************************************************************
//--------------------------------------------------------------------
float calc_dewpoint(float h,float t)
//--------------------------------------------------------------------
// calculates dew point计算露点
// input:   humidity [%RH], temperature [癈]
// output:  dew point [癈]
{
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 calcltTempHumi(void)    //计算温湿度值
{
unsigned char idata error;
error=0;
  error+=s_measure((unsigned char*) &iTempVal,&checksum,TEMP);  //measure temperature
  error+=s_measure((unsigned char*) &iHumiVal,&checksum,HUMI);  //measure humidity
if(error!=0) s_connectionreset();                       //in case of an error: connection reset
    else
    {
    fHumiVal=(float)iHumiVal;                         //converts integer to float整形转化成浮点型
     fTempVal=(float)iTempVal;                         //converts integer to float
     calc_sth11(&fHumiVal,&fTempVal);                   //calculate humidity, temperature计算实际值
      iDewpoint=(int)calc_dewpoint(iHumiVal,iTempVal);     //calculate dew point计算露点,并转化成整形
//    ayTempHumiFram[2]=(char)iDewpoint;                //  存放露点温度   
    }
//   fTempVal=-19.9;
//   iHumiVal=0.1;
   if(fTempVal<0)
   {
     g=0x01;
     fTempVal=-fTempVal;
     iTempVal=(int)(fTempVal*10);
    iHumiVal=(int)(fHumiVal*10);
   }
   else
   {
     g=0x00;
     iTempVal=(int)(fTempVal*10);
    iHumiVal=(int)(fHumiVal*10);
   }
  
  a= iTempVal/256;
  b= iTempVal%256;
  c= iHumiVal/256;
  d= iHumiVal%256;
  iText= (unsigned char)a+(unsigned char)b+(unsigned char)c+(unsigned char)d;
  e= iText/256;
  f= iText%256;
}
//==============================================================================
void uart0Init()
{
TMOD=0x20;//设置定时器1为工作方式2
TH1=0xdd;
TL1=0xdd;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1;
ES=1;
}
//=============================================================================
void uartTx()
{
SBUF=a;
while(!TI);
  TI=0;
SBUF=b;//
while(!TI);
  TI=0;
SBUF=c;//iHumiVal/100;
while(!TI);
  TI=0;
SBUF=d;
while(!TI);
  TI=0;
SBUF=e;//iTempVal/100;
while(!TI);
  TI=0;
SBUF=f;//iTempVal%100;
while(!TI);
  TI=0;
SBUF=g;
while(!TI);
  TI=0;
// SBUF=f;
// while(!TI);
//  TI=0;
// SBUF=0x99;//iHumiVal/100;
// while(!TI);
//  TI=0;
// SBUF=0;
// while(!TI);
//  TI=0;  
}
//=============================================================================
void delay(unsigned int z)
{
unsigned int x,y;
for(x=100;x>0;x--)
for(y=z;y>0;y--);
}
void main()
{
EA = 1;
// Uart0_Init(0x70,9600); //根据晶振设定波特率
// Uart0_IntEnable();      //串口使能
uart0Init();

InitTempHumiSensor();   //初始化传感器,详细参考dht60.h

while(1)
{
   calcltTempHumi();
//      delay(200);
//   sendUart0Fram();
//   waitUartSendOver(4000);
  uartTx();
  delay(900);
  t=~t;
                                                                                                                                                
}
}

以上是51驱动程序

一周热门 更多>

相关问题

    相关文章