📄 sht.c
字号:
//----------------------------------------------------------------------------------
//
// Sensirion SHTxx Humidity Sensor Library
//
// Library for using the SHT1x humidity and temperature
// sensors from Sensirion (http://www.sensirion.com).
// Based on Sensirion application note "Sample Code SHTxx".
//
// To use:
// - supply 5V to SHTxx (constants in calculations assume 5V, see ShtCalculate() and SHTxx datasheet)
// - connect the clock pin of the SHTxx to pin B1 (see Sht.h to change)
// - connect the data pin of the SHTxx to pin B2 (see Sht.h to change)
//
// - call ShtInit() to initialize pins, call when the processor starts
// - call ShtMeasure(MEASURE_TEMP) and ShtMeasure(MEASURE_HUMIDITY) to make the measurements
// - call ShtCalculate() to convert measurements to real-world units
//
// - call ShtReadStatus() and ShtWriteStatus() to modify the status register
//
//
// ToDo:
// - verify checksum digits sent from SHTxx
// - implement soft-reset
// - handle 12/8-bit temp/humidity readings
//
// History:
// 2003-Jul-03 BL - Created
//
//----------------------------------------------------------------------------------
#include <avr/io.h>
#include "sht.h"
#include "delay.h"
#include "includes.h"
// Drive DATA pin
void enable_data(void)
{
sbi(SHT_DDR, SHT_DATA);
}
// Release DATA pin
void disable_data(void)
{
cbi(SHT_DDR, SHT_DATA);
sbi(SHT_PORT, SHT_DATA);
}
// DATA pin high
void data_high(void)
{
sbi(SHT_PORT, SHT_DATA);
}
// DATA pin low
void data_low(void)
{
cbi(SHT_PORT, SHT_DATA);
}
// CLOCK pin high
void clock_high(void)
{
sbi(SHT_PORT, SHT_CLOCK);
}
// CLOCK pin low
void clock_low(void)
{
cbi(SHT_PORT, SHT_CLOCK);
}
//----------------------------------------------------------------------------------
// Initialize AVR i/o pins.
//----------------------------------------------------------------------------------
void ShtInit(void)
{
sbi(SHT_DDR, SHT_CLOCK); // Set clock pin to output
cbi(SHT_PORT, SHT_CLOCK); // Turn off clock pin
disable_data();
}
//----------------------------------------------------------------------------------
// generates a transmission start
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
//
//----------------------------------------------------------------------------------
void transstart(void)
{
enable_data();
data_high();
clock_low();
DELAY(SHT_DELAY);
DELAY(SHT_DELAY);
clock_high();
DELAY(SHT_DELAY);
data_low();
DELAY(SHT_DELAY);
clock_low();
DELAY(SHT_DELAY);
DELAY(SHT_DELAY);
clock_high();
DELAY(SHT_DELAY);
data_high();
DELAY(SHT_DELAY);
clock_low();
}
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
// _____________________________________________________ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
//----------------------------------------------------------------------------------
void ShtReset(void)
{
u08 i;
enable_data();
data_high();
clock_low();
for(i=0;i<10;i++) //9 SCK cycles
{
clock_high();
Delay(SHT_DELAY);
clock_low();
Delay(SHT_DELAY);
}
transstart(); //transmission start
}
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
//----------------------------------------------------------------------------------
s08 read_byte(void)
{
u08 i,val=0;
disable_data();
// Read in 8 bits, LSB first
for (i=0x80;i>0;i/=2)
{
clock_high();
DELAY(SHT_DELAY);
if (bit_is_set(SHT_PIN, SHT_DATA))
val=(val | i); //read bit
clock_low();
}
// Send ACK
enable_data();
data_low();
clock_high();
DELAY(SHT_DELAY);
clock_low();
disable_data();
return val;
}
//----------------------------------------------------------------------------------
// Writes a byte on the Sensibus and checks the acknowledge.
// Returns 0 if the successful
//----------------------------------------------------------------------------------
char write_byte(unsigned char value)
{
unsigned char i;
unsigned char error = 0;
// Write each bit one at a time, LSB first
enable_data();
for (i=0x80;i>0;i/=2)
{
if (i & value)
data_high();
else
data_low();
clock_high();
DELAY(SHT_DELAY);
DELAY(SHT_DELAY);
clock_low();
}
disable_data();
// Read ACK
clock_high();
DELAY(SHT_DELAY);
error = bit_is_set(SHT_PIN, SHT_DATA);
clock_low();
return error; //error=1 in case of no acknowledge
}
//选择采样温度或湿度
u08 write_mode(u08 mode)
{
// Signal start of communications
u08 error;
transstart();
// Request measurement
error = write_byte(mode);
//rprintf("\r\nTest temperature:%d",error);
return (error);
}
//----------------------------------------------------------------------------------
// Read humidity or temperature from the sensor.
// Returns the value in ticks. Use sht_calc() to convert to real world units.
// Returns 0xFFFF if the measurment failed
//----------------------------------------------------------------------------------
s16 ShtMeasure(void)
{
u16 temp =0xFFFF;
u08 checksum;
u08 c;
// Signal start of communications
// transstart();
// Request measurement
// write_byte(mode);
// Sensor lowers the data line when measurement
// is complete. Wait up to 2 seconds for this.
for (c=0; c<20; c++)
{
if (! bit_is_set(SHT_PIN, SHT_DATA))
break;
DELAY(1000000/10);
}
// Read the measurement
if (! bit_is_set(SHT_PIN, SHT_DATA))
{
temp = read_byte();
temp = temp << 8;
temp += read_byte();
checksum = read_byte();
}
return temp;
}
//----------------------------------------------------------------------------------------
// Calculates tempurature in ^C and humidity in %RH (temperature compensated)
// sht_measure() returns temp and humidity in ticks. Use this function to convert
// to compensated values in real world units.
//
// This function returns integers with 2 assumed decimal places. For example 2550
// means 25.50. This is to avoid including the floating point math library.
//
// input : humi [Ticks] (12 bit)
// temp [Ticks] (14 bit)
// output: humi [%RH] (2 fixed decimals)
// temp [^C] (2 fixed decimals)
//----------------------------------------------------------------------------------------
void ShtCalculate(s16 *p_temperature, s16 *p_humidity)
{
const long D1x100 = -40 * 100; // for 5V power
const long D2x100 = 0.01 * 100; // for 14bit temp
const long C1x100 = -4 * 100; // for 12bit humidity
const long C2x10000 = 0.0405 * 10000; // for 12bit humidity
const long C3x10000000 = -0.0000028 * 10000000; // for 12bit humidity
const long T1x100000 = 0.01 * 100000; // for 12bit humidity
const long T2x100000 = 0.00008 * 100000; // for 12bit humidity
s32 t = *p_temperature; // temperatere in ticks from sensor
s32 rh = *p_humidity; // humidity in ticks from sensor
s32 t_C; // temperature in celcius: 2 fixed decimals
s32 rh_lin; // relative humidity: 2 fixed decimals
s32 rh_true; // temp compensated humidity: 2 fixed decimals
t_C = D1x100 + D2x100*t; // calculate tempurature in celcius from ticks
rh_lin = (C3x10000000*rh*rh)/100000 + (C2x10000*rh)/100 + C1x100;
rh_true = ((t_C-(25*100)) * (T1x100000 + T2x100000*rh))/100000 + rh_lin;
if(rh_true>10000)rh_true=10000; //cut if the value is outside of
if(rh_true<10)rh_true=10; //the physical possible range
*p_temperature =(s16)t_C; //return temperature [^C]
*p_humidity =(s16)rh_true; //return humidity[%RH]
return;
}
//----------------------------------------------------------------------------------
// Reads the status register with checksum (8-bit)
//----------------------------------------------------------------------------------
s08 ShtReadStatus(u08 *p_value)
{
u08 error=0;
u08 checksum=0;
transstart(); //transmission start
error = write_byte(STATUS_REG_R); //send command to sensor
*p_value = read_byte(); //read status register (8-bit)
checksum = read_byte(); //read checksum (8-bit)
return error; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
// Writes the status register . Note this library only supports the default
// 14 bit temp and 12 bit humidity readings.
//----------------------------------------------------------------------------------
s08 ShtWriteStatus(u08 value)
{
u08 error=0;
transstart(); //transmission start
error += write_byte(STATUS_REG_W); //send command to sensor
error += write_byte(value); //send value of status register
return error; //error>=1 in case of no response form the sensor
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -