📄 my_dht.c
字号:
#define sht_DDR_D DDRD.7
#define sht_DDR_C DDRD.6
#define sht_PIN_D PIND.7
#define sht_PIN_C PIND.6
#define sht_PORT_D PORTD.7
#define sht_PORT_C PORTD.6
#define SHT_DELAY 5
#define noACK 0
#define ACK 1
#include <math.h> //Keil library
#include <stdio.h> //Keil library
#include <string.h>
//adr command r/w
#define STATUS_REG_W 0x06 //000 0011 0
#define STATUS_REG_R 0x07 //000 0011 1
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0
void enable_data(void) { sht_DDR_D=1;}
void disable_data(void) { sht_DDR_D=0;}
void data_high(void) { sht_PORT_D=1;}
void data_low(void) { sht_PORT_D=0;}
void clock_high(void) { sht_PORT_C=1;}
void clock_low(void) { sht_PORT_C=0;}
void delay_nus(int ms) //延时
{
int i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<1400;j++);
}
}
//----------------------------------------------------------------------------------
char s_write_byte(unsigned char value)
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge
{
unsigned char i,error=0;
enable_data();
sht_DDR_C=1;
for (i=0x80;i>0;i/=2) //shift bit for masking
{ if (i & value) data_high(); //masking value with i , write to SENSI-BUS
else data_low();
delay_nus(2);
clock_high(); //clk for SENSI-BUS
delay_nus(5); //pulswith approx. 5 us
clock_low();
}
data_high(); //release DATA-line
delay_nus(2);
disable_data();
clock_high(); //clk #9 for ack
delay_nus(2);
if (sht_PIN_D == 1) error = 1;
else error=0; //check ack (DATA will be pulled down by SHT11)
delay_nus(2);
clock_high();
disable_data();
return error; //error=1 in case of no acknowledge
}
//----------------------------------------------------------------------------------
char s_read_byte(unsigned char ack)
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
unsigned char i,val=0;
disable_data();
data_high(); //release DATA-line
for (i=0x80;i>0;i/=2) //shift bit for masking
{ clock_high(); //clk for SENSI-BUS
delay_nus(2);
if (sht_PIN_D == 1) val=(val | i); //read bit
clock_low();
delay_nus(2);
}
enable_data();
sht_DDR_C=1;
if(ack == 1) data_low(); //in case of "ack==1" pull down DATA-Line
delay_nus(5);
clock_high(); //clk #9 for ack
delay_nus(5); //pulswith approx. 5 us
clock_low();
data_high(); //release DATA-line
disable_data();
return val;
}
//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
{
enable_data();
sht_DDR_C=1;
data_high();
clock_low();
delay_nus(2);
clock_high();
delay_nus(2);
data_low();
delay_nus(2);
clock_low();
delay_nus(5);
clock_high();
delay_nus(2);
data_high();
delay_nus(2);
clock_low();
disable_data();
}
//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
// _____________________________________________________ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
{
unsigned char i;
enable_data();
sht_DDR_C=1;
data_high();
clock_low();
for(i=0;i<9;i++) //9 SCK cycles
{ clock_high();
delay_nus(1);
clock_low();
delay_nus(1);
}
s_transstart(); //transmission start
disable_data();
}
//----------------------------------------------------------------------------------
char s_softreset(void)
//----------------------------------------------------------------------------------
// resets the sensor by a softreset
{
unsigned char error=0;
s_connectionreset(); //reset communication
error+=s_write_byte(RESET); //send RESET-command to sensor
return error; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{
unsigned char error=0;
s_transstart(); //transmission start
error=s_write_byte(STATUS_REG_R); //send command to sensor
*p_value=s_read_byte(ACK); //read status register (8-bit)
*p_checksum=s_read_byte(noACK); //read checksum (8-bit)
return error; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_write_statusreg(unsigned char *p_value)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{
unsigned char error=0;
s_transstart(); //transmission start
error+=s_write_byte(STATUS_REG_W);//send command to sensor
error+=s_write_byte(*p_value); //send value of status register
return error; //error>=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned int mode)
//----------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum
{
unsigned error=0;
unsigned int i;
s_transstart(); //transmission start
switch(mode){ //send command to sensor
case 1 : error+=s_write_byte(MEASURE_HUMI); break;
default : error+=s_write_byte(MEASURE_TEMP); break;
}
disable_data();
for(i=0;i<65535;i++)
{
if(sht_PIN_D == 0)
{
delay_nus(1000);
break;
}
} //wait until sensor has finished the measurement or timeout (~2 sec.) is reached
if(sht_PIN_D == 1) error+=1;
*(p_value+1) =s_read_byte(ACK); //read the first byte (MSB)
*(p_value)=s_read_byte(ACK); //read the second byte (LSB)
*p_checksum =s_read_byte(noACK); //read checksum
return error;
}
void ShtCalculate(int *p_temperature, int *p_humidity)
{
int t;
int rh;
long t_C; // temperature in celcius: 2 fixed decimals
long rh_lin; // relative humidity: 2 fixed decimals
long rh_true;
long D1x100 = -40 * 100; // for 5V power
long D2x100 = 0.01 * 100; // for 14bit temp
long C1x100 = -4 * 100; // for 12bit humidity
long C2x10000 = 0.0405 * 10000; // for 12bit humidity
long C3x10000000 = -0.0000028 * 10000000; // for 12bit humidity
long T1x100000 = 0.01 * 100000; // for 12bit humidity
long T2x100000 = 0.00008 * 100000; // for 12bit humidity
t = p_temperature; // temperatere in ticks from sensor
rh = p_humidity; // humidity in ticks from sensor
// 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=(int)t_C; //return temperature [^C]
p_humidity=(int)rh_true; //return humidity[%RH]
}
//----------------------------------------------------------------------------------
// Writes the status register . Note this library only supports the default
// 14 bit temp and 12 bit humidity readings.
//----------------------------------------------------------------------------------
char ShtWriteStatus(unsigned char value)
{
unsigned char error=0;
s_transstart(); //transmission start
error += s_write_byte(STATUS_REG_W); //send command to sensor
error += s_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 + -