DA14585 读取 SHT30温度计;

user_sht30.c

/**


  • @file user_i2c.c
  • @brief user_i2c source file.
  • Copyright © 2018 Dialog Semiconductor. This computer program or computer programs included in this package (“Software”) include confidential, proprietary information of Dialog Semiconductor. All Rights Reserved.
  • THIS SOFTWARE IS AN UNOFFICIAL RELEASE FROM DIALOG SEMICONDUCTOR (慏IALOG? AND MAY ONLY BE USED BY RECIPIENT AT ITS OWN RISK AND WITHOUT SUPPORT OF ANY KIND. THIS SOFTWARE IS SOLELY FOR USE ON AUTHORIZED DIALOG PRODUCTS AND PLATFORMS. RECIPIENT SHALL NOT TRANSMIT ANY SOFTWARE SOURCE CODE TO ANY THIRD PARTY WITHOUT DIALOG扴 PRIOR WRITTEN PERMISSION.
  • UNLESS SET FORTH IN A SEPARATE AGREEMENT, RECIPIENT ACKNOWLEDGES AND UNDERSTANDS THAT TO THE FULLEST EXTENT PERMITTED BY LAW, THE SOFTWARE IS DELIVERED 揂S IS? WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT, AND ALL WARRANTIES THAT MAY ARISE FROM COURSE OF DEALING, CUSTOM OR USAGE IN TRADE. FOR THE SAKE OF CLARITY, DIALOG AND ITS AFFILIATES AND ITS AND THEIR SUPPLIERS DO NOT WARRANT, GUARANTEE OR MAKE ANY REPRESENTATIONS (A) REGARDING THE USE, OR THE RESULTS OF THE USE, OF THE LICENSED SOFTWARE IN TERMS OF CORRECTNESS, COMPLETENESS, ACCURACY, RELIABILITY OR OTHERWISE, AND (B) THAT THE LICENSED SOFTWARE HAS BEEN TESTED FOR COMPLIANCE WITH ANY REGULATORY OR INDUSTRY STANDARD, INCLUDING, WITHOUT LIMITATION, ANY SUCH STANDARDS PROMULGATED BY THE FCC OR OTHER LIKE AGENCIES.
  • IN NO EVENT SHALL DIALOG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

/*

  • INCLUDE FILES

*/

#include “user_sht30.h”
#include “i2c.h”
/****************************************************************************************

  • MACROS
    ****************************************************************************************/
    // I2C helper macros
    #define SEND_I2C_COMMAND(X) SetWord16(I2C_DATA_CMD_REG, (X))
    #define WAIT_WHILE_I2C_FIFO_IS_FULL() while (!(GetWord16(I2C_STATUS_REG) & TFNF)){}
    #define WAIT_UNTIL_I2C_FIFO_IS_EMPTY() while (!(GetWord16(I2C_STATUS_REG) & TFE)){}
    #define WAIT_UNTIL_NO_MASTER_ACTIVITY() while (GetWord16(I2C_STATUS_REG) & MST_ACTIVITY)
    #define WAIT_FOR_RECEIVED_BYTE() while (!GetWord16(I2C_RXFLR_REG))

struct i2c_cfg_env_t i2c_cfg_env;

static void user_i2c_send_address(uint32_t address_to_send)
{
for(int8_t i = i2c_cfg_env.register_address_width; i >= 0; i–){
SEND_I2C_COMMAND((address_to_send >> 8*i) & 0xFF); // Send the bytes of the register address
}
}

void user_i2c_init(uint16_t slave_address, I2C_ADDRESS_MODES i2c_address_width, I2C_SPEED_MODES bit_rate, I2C_REGISTER_WIDTH register_width, I2C_ADDRESS_BYTES_COUNT register_address_width)
{
// Save the settings in a struct
i2c_cfg_env.i2c_address_width = i2c_address_width;
i2c_cfg_env.bit_rate = bit_rate;
i2c_cfg_env.register_width = register_width;
i2c_cfg_env.register_address_width = register_address_width;

// Initialize the I2C with the address provided as argument
SetBits16(CLK_PER_REG, I2C_ENABLE, 1); // Enable  clock for I2C
SetWord16(I2C_ENABLE_REG, 0x0); // Disable the I2C controller
SetWord16(I2C_CON_REG,
          I2C_MASTER_MODE | I2C_SLAVE_DISABLE | I2C_RESTART_EN); // Slave is disabled
SetBits16(I2C_CON_REG, I2C_SPEED,
          i2c_cfg_env.bit_rate); // Set speed. Standard speed = 1, fast = 2
if (i2c_cfg_env.i2c_address_width == I2C_7BIT_ADDR) {
    SetBits16(I2C_CON_REG, I2C_10BITADDR_MASTER, 0); // Set addressing mode. 7bit = 0
} else {
    SetBits16(I2C_CON_REG, I2C_10BITADDR_MASTER, 1); // Set addressing mode. 10bit= 1
}
SetWord16(I2C_TAR_REG, slave_address & 0x3FF); // Set Slave device address
SetWord16(I2C_ENABLE_REG, 0x1); // Enable the I2C controller
while (GetWord16(I2C_STATUS_REG) & 0x20)
    ; // Wait for I2C master FSM to be IDLE

}

void user_i2c_set_register_width(I2C_REGISTER_WIDTH width)
{
i2c_cfg_env.register_width = width;
}

void user_i2c_write_reg(uint32_t reg_address, uint32_t wr_data)
{
user_i2c_send_address(reg_address); //Start the transaction and send the address

  for(int8_t i = i2c_cfg_env.register_width; i >= 0; i--){
   WAIT_WHILE_I2C_FIFO_IS_FULL();              // Wait if I2C Tx FIFO is full
   SEND_I2C_COMMAND((wr_data >> 8*i) & 0xFF);  // Write a byte of data to the FIFO
	}
	
WAIT_UNTIL_I2C_FIFO_IS_EMPTY();                // Wait until Tx FIFO is empty
WAIT_UNTIL_NO_MASTER_ACTIVITY();               // wait until no master activity	

}

uint32_t user_i2c_read_reg(uint32_t reg_address)
{
user_i2c_send_address(reg_address);
uint32_t ret = 0;

WAIT_WHILE_I2C_FIFO_IS_FULL(); // Wait if Tx FIFO is full
  for(int8_t i = 0; i <= i2c_cfg_env.register_width; i++){
   SEND_I2C_COMMAND(0x0100 & 0x3FF); // Set R/W bit to 1 (read access) MSB
	}
	
WAIT_UNTIL_I2C_FIFO_IS_EMPTY(); // Wait until I2C Tx FIFO empty
WAIT_UNTIL_NO_MASTER_ACTIVITY();
	
  for(int8_t i = i2c_cfg_env.register_width; i >= 0; i--){
   ret |= (0xFF & GetWord16(I2C_DATA_CMD_REG)) << 8*i; // Get received byte
	}
	
WAIT_UNTIL_I2C_FIFO_IS_EMPTY();  // Wait until Tx FIFO is empty
WAIT_UNTIL_NO_MASTER_ACTIVITY(); // wait until no master activity	
	return ret;

}

void user_i2c_multi_byte_write(uint32_t reg_address, uint8_t *wr_data, uint32_t num_bytes)
{
user_i2c_send_address(reg_address);
for(uint32_t i = 0; i < num_bytes; i++){
WAIT_WHILE_I2C_FIFO_IS_FULL(); // Wait if I2C Tx FIFO is full
SEND_I2C_COMMAND(wr_data[i] & 0xFF); //Write the data to the FIFO
}
WAIT_UNTIL_I2C_FIFO_IS_EMPTY(); //Wait until Tx FIFO is empty
WAIT_UNTIL_NO_MASTER_ACTIVITY(); //Wait until no master activity
}

void user_i2c_multi_byte_read(uint32_t reg_address, uint8_t *rd_data, uint32_t num_bytes)
{
user_i2c_send_address(reg_address);
uint32_t index = 0;

  for(uint32_t i = 0; i < num_bytes;){
   SEND_I2C_COMMAND(0x0100 & 0x3FF); // Set R/W bit to 1 (read access) MSB
		 if(!(++i % 24)){ //FIFO is 32 bits
	      WAIT_UNTIL_I2C_FIFO_IS_EMPTY();                 // Wait until Tx FIFO is empty
      WAIT_UNTIL_NO_MASTER_ACTIVITY();                // wait until no master activity
			  for (uint8_t j = 0; j < 24; j++){
					//Store the FIFO contents in ram
					rd_data[index++] = (0xFF & GetWord16(I2C_DATA_CMD_REG)); // Get received byte
				}
				reg_address += 24/(i2c_cfg_env.register_width + 1);//Calculate the next register to read out 
				user_i2c_send_address(reg_address);                //Restart the read
		 }
	}
	
WAIT_UNTIL_I2C_FIFO_IS_EMPTY(); // Wait until I2C Tx FIFO empty
WAIT_UNTIL_NO_MASTER_ACTIVITY();
	
  while(index < num_bytes){
   rd_data[index++] = (0xFF & GetWord16(I2C_DATA_CMD_REG)); // Get received byte
	}
	
WAIT_UNTIL_I2C_FIFO_IS_EMPTY();  // Wait until Tx FIFO is empty
WAIT_UNTIL_NO_MASTER_ACTIVITY(); // wait until no master activity	

}
/// @} APP

void init_SHT30(){

RESERVE_GPIO(SHT30_EN, SHT30_SCL_PORT, SHT30_SCL_PIN, PID_I2C_SCL);
RESERVE_GPIO(SHT30_EN, SHT30_SDA_PORT, SHT30_SDA_PIN, PID_I2C_SDA);

GPIO_ConfigurePin(SHT30_SCL_PORT, SHT30_SCL_PIN, INPUT_PULLUP, PID_I2C_SCL, true);
GPIO_ConfigurePin(SHT30_SDA_PORT, SHT30_SDA_PIN, INPUT_PULLUP, PID_I2C_SDA, true);

user_i2c_init(SHT30_I2C_ADDRESS, I2C_7BIT_ADDR, I2C_STANDARD, I2C_2BYTES_REGISTER, I2C_2BYTES_ADDRS);

}

#define CRC8_POLYNOMIAL 0x31

#define CRC8_POLYNOMIAL 0x31

uint8_t CheckCrc8(uint8_t* const message, uint8_t initial_value)
{
uint8_t remainder; //余数
uint8_t i = 0, j = 0; //循环变量

/* 初始化 */
remainder = initial_value;

for(j = 0; j < 2;j++)
{
    remainder ^= message[j];

    /* 从最高位开始依次计算  */
    for (i = 0; i < 8; i++)
    {
        if (remainder & 0x80)
        {
            remainder = (remainder << 1)^CRC8_POLYNOMIAL;
        }
        else
        {
            remainder = (remainder << 1);
        }
    }
}

/* 返回计算的CRC码 */
return remainder;

}
/**

  • @brief 将SHT30接收的6个字节数据进行CRC校验,并转换为温度值和湿度值
  • @param dat —— 存储接收数据的地址(6个字节数组)
  • @retval 校验成功 —— 返回0
  •         校验失败  —— 返回1,并设置温度值和湿度值为0
    

/
uint8_t SHT30_Dat_To_Float(uint8_t
const dat, float* temperature, float* humidity)
{
uint16_t recv_temperature = 0;
uint16_t recv_humidity = 0;

/* 校验温度数据和湿度数据是否接收正确 */
if(CheckCrc8(dat, 0xFF) != dat[2] || CheckCrc8(&dat[3], 0xFF) != dat[5])
    return 1;

/* 转换温度数据 */
recv_temperature = ((uint16_t)dat[0]<<8)|dat[1];
*temperature = -45 + 175*((float)recv_temperature/65535);

/* 转换湿度数据 */
recv_humidity = ((uint16_t)dat[3]<<8)|dat[4];
*humidity = 100 * ((float)recv_humidity / 65535);

return 0;

}
float temperature,humidity;
void SHT30_Read(void)
{
uint8_t buff[6]={0};

user_i2c_multi_byte_read(0x2C06,buff,6);

//温度转换;

SHT30_Dat_To_Float(buff,&temperature,&humidity);
//printf(“temperature =%.2f ,humidity = .2f /r/n”,temperature,humidity);
}

user_sht30.h
#ifndef USER_SHT30_H
#define USER_SHT30_H

#include “user_sht30.h”

#define SHT30_I2C_ADDRESS 0x44 //This is the sensor address without R/W bit (0x1D or 0x53 for ADXL)

#define NOTIFICATION_DELAY 50 //The time interval between sent notifications

#define SHT30_SCL_PORT GPIO_PORT_2
#define SHT30_SCL_PIN GPIO_PIN_3

#define SHT30_SDA_PORT GPIO_PORT_2
#define SHT30_SDA_PIN GPIO_PIN_1

typedef enum
{
I2C_7BIT_ADDR,
I2C_10BIT_ADDR,
}I2C_ADDRESS_MODES;

typedef enum
{
I2C_1BYTE_ADDRS,
I2C_2BYTES_ADDRS,
I2C_3BYTES_ADDRS,
}I2C_ADDRESS_BYTES_COUNT;

typedef enum
{
I2C_STANDARD = 1,
I2C_FAST,
}I2C_SPEED_MODES;

typedef enum
{
I2C_1BYTE_REGISTER,
I2C_2BYTES_REGISTER,
I2C_3BYTES_REGISTER,
I2C_4BYTES_REGISTER,
}I2C_REGISTER_WIDTH;

/**

  • @brief I2C struct
    */
    struct i2c_cfg_env_t
    {
    uint8_t bit_rate; //Standard mode or fast mode
    uint8_t register_width; //Slave register width 8 or 16 bit
    uint8_t i2c_address_width; //Slave addressing width 10 or 7 bit
    uint8_t register_address_width;//Slave register addressing width 8 or 16 bit
    };

/*

  • FUNCTION DECLARATIONS

*/

/**


  • @brief Initializes the I2C interface with the provide slave address
  • @param[in] slave_address , The I2C slave address to communicate with
  • @param[in] i2c_address_width , The width of the I2C address(7 or 10 bit)
  • @param[in] bit_rate , The I2C bus frequency (standard or fast mode)
  • @param[in] register_width , The I2C slave register width (1-4 bytes)
  • @param[in] register_address_width , The I2C slave register address width (1-3 bytes)
  • @return void

*/
void user_i2c_init(uint16_t slave_address, I2C_ADDRESS_MODES i2c_address_width, I2C_SPEED_MODES bit_rate, I2C_REGISTER_WIDTH register_width, I2C_ADDRESS_BYTES_COUNT register_address_width);

/**


  • @brief Sets the register width of the slave device
  • @param[in] register_width, The I2C slave register width (1-4 bytes)
  • @return void

*/
void user_i2c_set_register_width(I2C_REGISTER_WIDTH width);

/**


  • @brief Reads data from an I2C slave register
  • @param[in] reg_address, Register address to be read
  • @return Contents of the register

*/
uint32_t user_i2c_read_reg(uint32_t reg_address);

/**


  • @brief Writes data to a register address of an I2C slave
  • @param[in] reg_address, Register address to write to
  • @param[in] wr_data, Data to write
  • @return void

*/
void user_i2c_write_reg(uint32_t reg_address, uint32_t wr_data);

/**


  • @brief Writes data to a register address of an I2C slave
  • @param[in] reg_address, Register address to write to
  • @param[in] wr_data, Data to write
  • @param[in] num_bytes, Number of bytes to write
  • @return void

*/
void user_i2c_multi_byte_write(uint32_t reg_address, uint8_t *wr_data, uint32_t num_bytes);

/**


  • @brief Writes data to a register address of an I2C slave
  • @param[in] reg_address, Register address to write to
  • @param[in] rd_data, Array where the data will be read to
  • @param[in] num_bytes, Number of bytes to read
  • @return void

*/
void user_i2c_multi_byte_read(uint32_t reg_address, uint8_t *rd_data, uint32_t num_bytes);

void init_SHT30(void);
void SHT30_Read(void);
#endif //USER_I2C_H
/// @} APP

如图;debug显示温湿度值

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值