📄 libsht.c
字号:
//----------------------------------------------------------------------------------
unsigned char sht_read_statusreg(unsigned char *p_sht_value, unsigned char *p_checksum)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{
unsigned char error=0;
sht_transstart(); //transmission start
error=sht_write_byte(STATUS_REG_R); //send command to sensor
*p_sht_value=sht_read_byte(ACK); //read status register (8-bit)
*p_checksum=sht_read_byte(noACK); //read checksum (8-bit)
return error; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
unsigned char sht_write_statusreg(unsigned char *p_sht_value)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{
unsigned char error=0;
sht_transstart(); //transmission start
error+=sht_write_byte(STATUS_REG_W);//send command to sensor
error+=sht_write_byte(*p_sht_value); //send value of status register
return error; //error>=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
unsigned char sht_measure(sht_value *p_sht_value, unsigned char *p_checksum, unsigned char mode)
//----------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum
{
unsigned char error=0;
unsigned int i;
sht_value sht_value_temp;
/* sht_transstart(); //transmission start */
sht_connectionreset();
switch(mode){ //send command to sensor
case TEMP : error+=sht_write_byte(MEASURE_TEMP); break;
case HUMI : error+=sht_write_byte(MEASURE_HUMI); break;
default : break;
}
for (i=0;i<65535;i++) {
if(SHT_DATA==0) break; //wait until sensor has finished the measurement
_delay_us(6); // neccesary since the AVR is so much faster than the old 8051
// and the 210ms for 14bit measuremnt are only a rough estimate
}
if(SHT_DATA) error+=1; // or timeout is reached
sht_value_temp.i = 256*sht_read_byte(ACK); //read the first byte (MSB)
sht_value_temp.i +=sht_read_byte(ACK); //read the second byte (LSB)
*p_checksum =sht_read_byte(noACK); //read checksum
*(p_sht_value)= sht_value_temp;
return error;
}
//----------------------------------------------------------------------------------------
void sht_raw_to_physical(sht_value *p_humidity ,sht_value *p_temperature)
//----------------------------------------------------------------------------------------
// calculates temperature [C] and humidity [%RH]
// input : humi [Ticks] (12 bit)
// temp [Ticks] (14 bit)
// output: humi [%RH]
// temp [C]
{
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_lin; // rh_lin: Humidity linear
float rh_true; // rh_true: Temperature compensated humidity
float t_C; // t_C : Temperature [C]
t_C = 0.01*(*p_temperature).i +(SHT_TEMP_OFFSET); //calc. Temperature from ticks to [C]
rh_lin=C3*(*p_humidity).i*(*p_humidity).i + C2*(*p_humidity).i + C1; //calc. Humidity from ticks to [%RH]
rh_true=(t_C-25)*(T1+T2*(*p_humidity).i)+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).f=t_C; //return temperature [C]
(*p_humidity).f=rh_true; //return humidity[%RH]
}
//--------------------------------------------------------------------
float calc_dewpoint(float h,float t)
//--------------------------------------------------------------------
// calculates dew point
// input: humidity [%RH], temperature [C]
// output: dew point [C]
{ float k,dew_point ;
k = (log10(h)-2)/0.4343 + (17.62*t)/(243.12+t);
dew_point = 243.12*k/(17.62-k);
return dew_point;
}
//--------------------------------------------------------------------
void sht_switch_heating_element(unsigned char onoff)
//--------------------------------------------------------------------
// shwitches the internal heating element
// input onoff 0:off 1:on
{
unsigned char status;
unsigned char checksum;
sht_read_statusreg(&status, &checksum);
if (onoff==0) status &= ~(HEATER_BIT);
else status |= (HEATER_BIT);
sht_write_statusreg(&status);
}
//--------------------------------------------------------------------
unsigned char sht_check_crc(sht_value *p_sht_value, unsigned char *p_checksum, unsigned char mode, unsigned char statusreg)
//--------------------------------------------------------------------
// Checks whether the data integrity is ok.
// Returns 1 if the crc value calculated from the data and the crc value from sensor are the same, else 0
// See application note "CRC" from sensirion for further details
{
unsigned char crc;
crc = pgm_read_byte(&REVERSED_BIT_ORDER_LIST[statusreg & 15]);
if (mode ==TEMP) crc =pgm_read_byte(&CRC_TABLE[crc ^ MEASURE_TEMP]);
else if(mode == HUMI) crc = pgm_read_byte(&CRC_TABLE[ crc ^ MEASURE_HUMI]);
else crc =255; // error: mode is not recognized
crc = pgm_read_byte(&CRC_TABLE[crc ^ ((*p_sht_value).i >> 8)]);
crc = pgm_read_byte(&CRC_TABLE[crc ^ ((*p_sht_value).i & 0x00ff)]);
return (crc==pgm_read_byte(&REVERSED_BIT_ORDER_LIST[*p_checksum]));
}
/* The following functions should be used together with an recuring interrupt.
They allow the splitting of the measurement in three parts in order to avoid
the dump burning of CPU time. Although the naming of the functions should make their
use obvios here some ideas how to use them:
void recurring_interrupt_service_routine()
{
...
if (flag== MEASURING) && (sht_is_measurement_finished() == 1) flag == FINISHED;
...
}
void main()
{
unsigned char error =0;
unsigned char checksum;
sht_value humidity;
...
error += _sht_begin_measurement(SHT_HUMI);
flag = MEASURING;
for{;;}
{
if (flag == FINISHED) {
_sht_get_measurement_data(&humidity, (unsigned char*)&checksum);
flag = DONE;
}
}
}
*/
//--------------------------------------------------------------------
unsigned char _sht_begin_measurement(unsigned char mode)
//--------------------------------------------------------------------
{
unsigned char error=0;
sht_connectionreset();
switch(mode){ //send command to sensor
case TEMP : error+=sht_write_byte(MEASURE_TEMP); break;
case HUMI : error+=sht_write_byte(MEASURE_HUMI); break;
default : {error = 20;break;}
}
return error;
}
//--------------------------------------------------------------------
unsigned char _sht_is_measurement_finished(void)
//--------------------------------------------------------------------
{
if (SHT_DATA==0) return 1;
else return 0;
// return (unsigned char)(~SHT_DATA);
}
//--------------------------------------------------------------------
void _sht_get_measurement_data(sht_value *p_sht_value, unsigned char *p_checksum)
//--------------------------------------------------------------------
{
sht_value sht_value_temp;
sht_value_temp.i = 256*sht_read_byte(ACK); //read the first byte (MSB)
sht_value_temp.i +=sht_read_byte(ACK); //read the second byte (LSB)
*p_checksum =sht_read_byte(noACK); //read checksum
*(p_sht_value)= sht_value_temp;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -