码迷,mamicode.com
首页 > 其他好文 > 详细

SHT20 SHT21 HTU20 温湿度传感器驱动 STM32F051

时间:2014-07-21 23:27:53      阅读:526      评论:0      收藏:0      [点我收藏+]

标签:数据   2014   io   art   for   cti   

STM32F051 模拟IIC


/**
  ******************************************************************************
  * @file      HTU20.x
  * @brief     HTU20 function
  * @cpu       STM32F051
  * @compiler  Keil uVision V4.74
  * @author    MetalSeed
  * @copyright WSHHB
  * @version   V1.0.0
  * @date      18-Sept-2014
  * @modifydate20-Sept-2014
  ******************************************************************************
  * @attention
  */
#include "boardAPI.h"
#include "stm32f0xx.h"
#include "HTU20.h"
#include "uart.h"
#include "delay.h"

GPIO_InitTypeDef        GPIO_InitStructure;

/**
  * @brief  Start HTU GPIO port CLK
  * @retval None
  */
void HTUInit()
{
  RCC_AHBPeriphClockCmd(HTU20_CLK, ENABLE);
}


/*================================================================
                           IIC address
================================================================*/
#define SHT20ADDR      0x80

/*================================================================
                 ACK  and  NACK  defination
================================================================*/
#define ACK            0
#define NACK           1

/*================================================================
                       HTU20D Command Code
================================================================*/
/*
  Command                         Code              Comment
  Trigger Temperature Measurement 0xe3              Hold master
  Trigger Humidity Measurement    0xe5              Hold master
  Trigger Temperature Measuremeng 0xf3              No Hold master
  Trigger Humidity Measurement    0xf5              No Hold master
  Write user register             0xe6
  Read user register              0xe7
  Soft Reset                      0xfe
*/
#define SOFT_RESET      0xfe
#define READ_REGISTER   0xe7
#define WRITE_REGISTER  0xe6
#define TRIGGER_TEMP    0xf3
#define TRIGGER_HUMI    0xf5

/*================================================================
                    HTU20 operate interface
================================================================*/
#define HTU20_SDA         GPIO_ReadInputDataBit(HTU20_SCL_PORT,HTU20_SCL_PIN)
#define HTU20_SCL         GPIO_ReadInputDataBit(HTU20_SDA_PORT,HTU20_SDA_PIN)

/**
  * @brief  Set SDA pin dircate as output
  * @retval None
  */
void HTU20_SDA_OUT()
{
  GPIO_StructInit(&GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin   = HTU20_SDA_PIN;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_2;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  GPIO_Init(HTU20_SDA_PORT, &GPIO_InitStructure);
}

/**
  * @brief  Set SDA pin dircate as intput
  * @retval None
  */
void HTU20_SDA_IN()
{
  GPIO_StructInit(&GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin   = HTU20_SDA_PIN;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_2;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  GPIO_Init(HTU20_SDA_PORT, &GPIO_InitStructure);
}

/**
  * @brief  Set SDA pin as high
  * @retval None
  */
void HTU20_SDA_1()
{
  GPIO_SetBits(HTU20_SDA_PORT,HTU20_SDA_PIN)            ;
}

/**
  * @brief  Set SDA pin as low
  * @retval None
  */
void HTU20_SDA_0()
{
  GPIO_ResetBits(HTU20_SDA_PORT,HTU20_SDA_PIN)          ;
}

/**
  * @brief  Set SCL pin dircate as output
  * @retval None
  */
void HTU20_SCL_OUT()
{
  GPIO_StructInit(&GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin   = HTU20_SCL_PIN;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_2;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  GPIO_Init(HTU20_SCL_PORT, &GPIO_InitStructure);
}

/**
  * @brief  Set SCL pin as high
  * @retval None
  */
void HTU20_SCL_1()
{
  GPIO_SetBits(HTU20_SCL_PORT,HTU20_SCL_PIN)            ;
}

/**
  * @brief  Set SCL pin as low
  * @retval None
  */
void HTU20_SCL_0()
{
  GPIO_ResetBits(HTU20_SCL_PORT,HTU20_SCL_PIN)          ;
}

/*================================================================
                  Simulation I2C Function
================================================================*/

/**
  * @brief  A short delay  for iic synchronization
  * @param  t us
  * @retval None
  */
void I2CDelay (BYTE t)
{
  while(t--)
  {
    __nop();  __nop(); __nop(); __nop(); __nop();
    __nop();  __nop(); __nop(); __nop(); __nop();
    __nop();  __nop(); __nop(); __nop(); __nop();
    __nop();  __nop(); __nop(); __nop(); __nop();
    __nop();  __nop(); __nop(); __nop(); __nop();
    __nop();  __nop(); __nop(); __nop(); __nop();
    __nop();  __nop(); __nop(); __nop(); __nop();
  }
}
/**
  * @brief  I2C init
  * @retval None
  */

void I2CInit(void)
{
  HTU20_SDA_OUT();
  HTU20_SCL_OUT();
  HTU20_SDA_1();
  I2CDelay(1);
  HTU20_SCL_1();
  I2CDelay(1);
}

/**
  * @brief   IIC start signal
  * @comment SCL、SDA同为高,SDA跳变成低之后,SCL跳变成低
  * @retval  None
  */
void I2CStart(void)
{
  HTU20_SDA_OUT();
  HTU20_SDA_1();
  HTU20_SCL_1();
  I2CDelay(5);     //大于4.7us
  HTU20_SDA_0();
  I2CDelay(5);     //大于4us
  HTU20_SCL_0();
  I2CDelay(5);
}

/**
  * @brief  IIC Stop Signal
  * @commet SCL、SDA同为低,SCL跳变成高之后,SDA跳变成高
  * @retval None
  */
void I2CStop(void)
{
  HTU20_SDA_OUT();
  HTU20_SDA_0();
  HTU20_SCL_0();
  I2CDelay(5);
  HTU20_SCL_1();
  I2CDelay(5);
  HTU20_SDA_1();
  I2CDelay(5);
}

/**
  * @brief  simu IIC write byte
  * @param  Write_Byte: data
  * @retval None
  */
BYTE I2C_Write_Byte(BYTE Write_Byte)
{
  BYTE i;
  HTU20_SDA_OUT();

  for(i = 0; i < 8; ++i)
  {
    if(Write_Byte & SHT20ADDR)
    {
      HTU20_SDA_1();
    }
    else
    {
      HTU20_SDA_0();
    }
    I2CDelay(1);
    HTU20_SCL_1();       //输出SDA稳定后拉高SCL,从机检测到后采样
    I2CDelay(5);         //保证足够长锁定时间,确保从机采样成功
    HTU20_SCL_0();
    I2CDelay(1);
    Write_Byte <<= 1;
  }
  I2CDelay(4);
  HTU20_SDA_1();         //8位发送完后释放数据线,准备接受应答信号
  HTU20_SCL_1();         //再次拉高SCL,告诉从机发送完毕,等待应答
  I2CDelay(5);

  HTU20_SDA_IN();
  if(HTU20_SDA == 1)     //SDA为高,收到NACK
    return NACK;
  else                   //SDA为低,收到ACK
    return ACK;
//  HTU20_SCL_0();
//  I2CDelay(15);
}

/**
  * @brief  simu read byte form IIC
  * @param
  * @retval None
  */
BYTE I2C_Read_Byte(BYTE AckValue)//receivebyte
{
  BYTE i, RDByte = 0;
  HTU20_SDA_OUT();
  HTU20_SCL_0();
  HTU20_SDA_1();      //释放总线,并置数据线为输入
  HTU20_SDA_IN();
  for (i = 0; i < 8; ++i)
  {
    HTU20_SCL_1();    //拉高SCL期间,采样
    I2CDelay(2);
    RDByte <<= 1;
    if(HTU20_SDA == 1)
    {
      RDByte |= 0x01;
    }
    else
    {
      RDByte &= 0xfe;
    }
    I2CDelay(1);
    HTU20_SCL_0();    //下降沿告知从机发送下一位
    I2CDelay(6);
  }
  HTU20_SDA_OUT();   //接受完一个字节,发送ACK or NACK
  if(AckValue == 1)
  {
    HTU20_SDA_1();
  }
  else
  {
    HTU20_SDA_0();
  }
  I2CDelay(3);
  HTU20_SCL_1();
  I2CDelay(5);
  HTU20_SCL_0();     //清时钟线
  I2CDelay(15);
  //HTU20_SDA_1();
  return RDByte;
}

/**
  * @brief  soft reset by transmit reset command
  * @retval None
  */
void SoftReset(void)
{
  I2CInit();
  I2CStart();
  I2C_Write_Byte(SHT20ADDR & 0xfe);  //I2C address + write
  I2C_Write_Byte(SOFT_RESET);        //soft reset
  I2CStop();
}

/**
  * @brief  SET HTU20D resolution by write register
  * @retval None
  */
void SET_Resolution(void)
{
  I2CStart();
  if(I2C_Write_Byte(SHT20ADDR & 0xfe) == ACK) //I2C address + write + ACK
  {
    if(I2C_Write_Byte(WRITE_REGISTER)==ACK)   //写用户寄存器
    {
      if(I2C_Write_Byte(0x83)==ACK);          //设置分辨率   11bit RH% 测量时间:12ms(typ.)
    }                                         //             11bit T℃ 测量时间:9ms(typ.)
  }
  I2CStop();
}

/**
  * @brief  read sht20's converted result
  * @param  TempOrHumiCMD: operation command for temperature or humidity
  * @retval None
  */
float ReadSht20(char TempOrHumiCMD)
{
  float temp;
  BYTE MSB,LSB;
  float Humidity, Temperature;

  SET_Resolution();
  I2CStart();
  if(I2C_Write_Byte(SHT20ADDR & 0xfe) == ACK)      //I2C address + write + ACK
  {
    if(I2C_Write_Byte(TempOrHumiCMD) == ACK)       //command
    {
      do
      {
        delayms(6);
        I2CStart();
      } while(I2C_Write_Byte(SHT20ADDR | 0x01) == NACK); //I2C address + read + NACK

      MSB = I2C_Read_Byte(ACK);
      LSB = I2C_Read_Byte(ACK);
      I2C_Read_Byte(NACK);                        //Checksum  + NACK
      I2CStop();
      LSB &= 0xfc;                                //Data (LSB) 的后两位在进行物理计算前前须置0
      temp = (MSB << 8) + LSB;

      if (TempOrHumiCMD == ((char)TRIGGER_HUMI))
      {
        /*-- calculate relative humidity [%RH] --*/
        //equation: RH% = -6 + 125 * SRH/2^16
        Humidity = (temp * 125) / 65536 - 6;
        return Humidity;
      }
      else
      {
        /*-- calculate temperature [°C] --*/
        //equation:T = -46.85 + 175.72 * ST/2^16
        Temperature = (temp * 175.72) / 65536 - 46.85;
        return Temperature;
      }
    }
  }
  return 0;
}



SHT20 SHT21 HTU20 温湿度传感器驱动 STM32F051,布布扣,bubuko.com

SHT20 SHT21 HTU20 温湿度传感器驱动 STM32F051

标签:数据   2014   io   art   for   cti   

原文地址:http://blog.csdn.net/metalseed/article/details/38021193

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!