📄 sht7x.c
字号:
//编写:清华大学 王真星 网址:www.wL88.net
//QQ:37882833
#include "config.h"
#include "math.h"
#include "misc.h"
//----------------------------------------------------------------------------------
// modul-var
//----------------------------------------------------------------------------------
enum {TEMP,HUMI};
#define SDAT 0x20000//0x00000008
#define SCK 0x40000//0x00000004
#define noACK 0
#define ACK 1
//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 SDAT1(){
IOSET|=SDAT;
IODIR|=SDAT;
}
void SDAT0(){
IOCLR|=SDAT;
IODIR|=SDAT;
}
void SCK0(){
IOCLR|=SCK;
IODIR|=SCK;
}
void SCK1(){
IOSET|=SCK;
IODIR|=SCK;
}
char nop;
typedef union
{ unsigned int i;
float f;
} value;
//----------------------------------------------------------------------------------
char s_write_byte(unsigned char value)
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge
{
char i;
unsigned long int error;
IODIR|=SDAT;
delay(100);
for (i=0x80;i>0;i/=2) //shift bit for masking
{ if (i & value) SDAT1(); //masking value with i , write to SENSI-BUS
else SDAT0();
SCK1(); //clk for SENSI-BUS
delay(100); //pulswith approx. 5 us
SCK0();
delay(100);
}
//release SDAT-line
//clk #9 for ack
IODIR&=~SDAT;
delay(100);
SCK1();
delay(100);
error=IO0PIN&SDAT;//check ack (SDAT will be pulled down by SHT11)
if(error!=0) error=1;
SCK0();
delay(50);
return error; //if error!=0 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 long int err;
unsigned char i,val=0;
IODIR&=~SDAT;
// SDAT1(); //release SDAT-line
for (i=0x80;i>0;i/=2) //shift bit for masking
{
delay(200);
SCK1();
delay(200);
err= IOPIN&SDAT; //clk for SENSI-BUS
if (err) val=(val | i); //read bit
SCK0();
}
delay(150);
if(ack){
IOCLR|=SDAT;
IODIR|=SDAT;
}
else{
IOSET|=SDAT;
IODIR|=SDAT;
};
delay(150);
SCK1();
// SDAT1();
SDAT0(); //in case of "ack==1" pull down SDAT-Line
//clk #9 for ack
delay(250); //pulswith approx. 5 us
IODIR&=~SDAT;
SCK0(); //release SDAT-line
return val;
}
//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start
// _____ ________
// SDAT: |_______|
// ___ ___
// SCK : ___| |___| |______
{
IODIR|=SDAT;IODIR|=SCK;
SDAT1();
delay(50);
SCK0(); //Initial state
delay(50);
SCK1();
delay(50);
SDAT0();
delay(50);
SCK0();
delay(600);
SCK1();
delay(50);
SDAT1();
delay(50);
SCK0();
delay(50);
}
//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: SDAT-line=1 and at least 9 SCK cycles followed by transstart
// _____________________________________________________ ________
// SDAT: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
{
unsigned char i;
IODIR|=SDAT;IODIR|=SCK;
SDAT1(); SCK0(); //Initial state
delay(50);
for(i=0;i<8;i++) //9 SCK cycles
{ SCK1();
delay(50);
SCK0();
}
delay(50);
SCK1();
delay(50);
SCK0();
delay(50);
s_transstart(); //transmission start
}
//----------------------------------------------------------------------------------
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 char mode)
//----------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum
{
unsigned error=0;
unsigned long int i;
s_transstart(); //transmission start
switch(mode){ //send command to sensor
case TEMP : error+=s_write_byte(MEASURE_TEMP); break;
case HUMI : error+=s_write_byte(MEASURE_HUMI); break;
default : break;
}
if(error) return 1;
//delay(6465535);
IODIR=IODIR&~SDAT;
for (i=0;i<365535;i++){
delay(10);
error=IOPIN&SDAT;
if(error==0) break;
}//wait until sensor has finished the measurement
// error=IOPIN&SDAT;
if (error) error+=1; // or timeout (~2 sec.) is reached
*(p_value+1)= s_read_byte(ACK); //read the first byte (MSB)
//print(p_value+1);
*(p_value)=s_read_byte(ACK); //read the second byte (LSB)
// print(p_value);
//*p_checksum =s_read_byte(noACK); //read checksum
SDAT1();
delay(50);
SCK1();
delay(50);
SCK0();
return error;
}
//----------------------------------------------------------------------------------------
int calc_temp(int p_temperature)
//----------------------------------------------------------------------------------------
{
p_temperature=p_temperature-3966;
p_temperature=p_temperature/10;
return p_temperature; //温度扩大10倍
}
//----------------------------------------------------------------------------------------
int calc_humid(uint32 humid) //所以湿度扩大10倍
//----------------------------------------------------------------------------------------
{
humid=-4000+405*humid/10-humid*humid*28/10000;
return humid/100;
}
//----------------------------------------------------------------------------------
ENVIROMENT GETSHT()
//----------------------------------------------------------------------------------
// sample program that shows how to use SHT11 functions
// 1. connection reset
// 2. measure humidity [ticks](12 bit) and temperature [ticks](14 bit)
// 3. calculate humidity [%RH] and temperature [癈]
// 4. calculate dew point [癈]
// 5. print temperature, humidity, dew point
{value humi_val,temp_val;
// float dew_point;
unsigned char error,checksum;
unsigned int i;
unsigned long int temp;
ENVIROMENT ev;
temp=PINSEL0;
PINSEL0 =PINSEL0&(~SDAT)&(~SCK);//修改p0.2 p0.3位通用GPIO
s_connectionreset();
error=0;
error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI); //measure humidity
error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP); //measure temperature
if(error!=0) {s_connectionreset();
ev.temperature=0;
ev.humid=0;} //in case of an error: connection reset
else
{
// humi_val.f=(float)humi_val.i; //converts integer to float
// temp_val.f=(float)temp_val.i;
//converts integer to float
ev.temperature=calc_temp(temp_val.i);
ev.humid=calc_humid(humi_val.i);
}
//----------wait approx. 0.8s to avoid heating up SHTxx------------------------------
for (i=0;i<40000;i++); //(be sure that the compiler doesn't eliminate this line!)
//-----------------------------------------------------------------------------------
PINSEL0=temp;
return ev;
}
ENVIROMENT GetEnviromnentTemp_Humid(void){
return GETSHT();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -