驱动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 22:48
 精彩回答 2  元偷偷看……0人看过

一周热门 更多>

相关问题

    相关文章