#ifndef _SHT10_H_
#define _SHT10_H_
typedef unsigned char uint8;
#define HUM_DATA BIT6
#define HUM_SCK BIT7
#define SHT_SCK_HIGH P6OUT |= HUM_SCK
#define SHT_SCK_LOW P6OUT &= ~HUM_SCK
#define SHT_DATA_HIGH P6OUT |= HUM_DATA
#define SHT_DATA_LOW P6OUT &= ~HUM_DATA
#define READ_SHT_DATA (P6IN & HUM_DATA)
#define SHT_DATA_INPUT P6DIR &=~ HUM_DATA
#define SHT_DATA_OUTPUT P6DIR |= HUM_DATA
#define MEASURE_TEMP 0x03//測量溫度
#define MEASURE_HUMI 0x05//測量濕度
#define READ_SR 0x07//讀狀態寄存器
#define WRITE_SR 0x06//寫狀態寄存器
#define Soft_Reset 0x1e//軟件復位 清空狀態寄存器
#define SHT_8BIT_CMD 0x01//設置濕度值為8位命令
#define ACK 1
#define NOACK 0
#define CPU_F ((double)8000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
void SHT_Init(void);
void SHT_Start(void);
void SHTConnectionRst(void);
uint8 S_Write_Byte(uint8 value);
uint8 S_Read_Byte(uint8 ack);
uint8 SHTSoftwareRst(void);
uint8 SHTWriteReg(uint8 value);
uint8 SHTReadReg(uint8 *Dst,uint8 *CRC);
void SHT_Calculate(float *Humidity,float *Temperature);
uint8 SHTSample(uint8 *Dst,uint8 *CRC,uint8 Mode);
void Read_Wsd(uint8 *Txdata);
#endif
#include <msp430x14x.h>
#include "sht10.h"
typedef union
{
unsigned int i;
float f;
}value;
value humi_val,temp_val;
unsigned short temp16_T,temp16_H;
uint8 checksum;
/*******************************************
函數名稱:SHT_Init()
功 能:溫濕度傳感器IO初始化
參 數:無
返回值 :無
********************************************/
void SHT_Init(void)
{
P6SEL &=~(HUM_DATA + HUM_SCK);
P6OUT |= (HUM_DATA + HUM_SCK);//SDA SCK輸出
SHT_DATA_HIGH;
SHT_SCK_HIGH;
SHTConnectionRst();//connection reset sequence
//SHTWriteReg(SHT_8BIT_CMD);
}
/*******************************************
函數名稱:SHT_Start()
功 能:SHT啟動傳輸
參 數:無
返回值 :無
********************************************/
void SHT_Start(void)
{
SHT_DATA_HIGH;SHT_SCK_LOW;
_NOP();
_NOP();
SHT_SCK_HIGH;
_NOP();
_NOP();
SHT_DATA_LOW;
_NOP();
_NOP();
SHT_SCK_LOW;
_NOP();
_NOP();
_NOP();
_NOP();
SHT_SCK_HIGH;
_NOP();
_NOP();
SHT_DATA_HIGH;
_NOP();
_NOP();
SHT_SCK_LOW;
}
/*******************************************
函數名稱:SHTConnectionRst()
功 能:SHT通訊復位時序
參 數:無
返回值 :無
********************************************/
void SHTConnectionRst(void)
{
uint8 i;
SHT_DATA_OUTPUT;
SHT_SCK_LOW;
SHT_DATA_HIGH;
for(i=0;i<9;i++)
{
SHT_SCK_HIGH;
_NOP();_NOP();
SHT_SCK_LOW;
_NOP();_NOP();
}
SHT_Start();
}
/*******************************************
函數名稱:S_Write_Byte()
功 能:向SHT寫一個字節
參 數:value--要寫的字節
返回值 :err_code:0-正常 1-出錯
********************************************/
uint8 S_Write_Byte(uint8 value)
{
uint8 i;
uint8 err_code = 0;
for(i=0x80;i>0;i/=2)
{
if(i & value)
{
SHT_DATA_HIGH;
}
else
{
SHT_DATA_LOW;
}
SHT_SCK_HIGH;
_NOP();
_NOP();
SHT_SCK_LOW;
}
SHT_DATA_HIGH;//Release Data_line
_NOP();_NOP();
SHT_DATA_INPUT;
_NOP();_NOP();
SHT_SCK_HIGH;
_NOP();_NOP();
err_code = READ_SHT_DATA;
_NOP();_NOP();
SHT_SCK_LOW;
_NOP();_NOP();
SHT_DATA_OUTPUT;
return err_code;
}
/*******************************************
函數名稱:S_Read_Byte()
功 能:從SHT讀取一個字節
參 數:ack--ACK
返回值 :val--讀到的的數據
********************************************/
uint8 S_Read_Byte(uint8 ack)
{
uint8 i;
uint8 val = 0;
SHT_DATA_OUTPUT;
SHT_DATA_HIGH;//Release Data_line
_NOP();_NOP();
SHT_DATA_INPUT;
_NOP();_NOP();
for(i=0x80;i>0;i/=2)//shift bit for masking
{
SHT_SCK_HIGH;
_NOP();_NOP();
if(READ_SHT_DATA)val = (val | i);//read bit
SHT_SCK_LOW;
_NOP();_NOP();
}
SHT_DATA_OUTPUT;
if(ack == 0)
{
SHT_DATA_HIGH;
}
else
{
SHT_DATA_LOW;
}
SHT_SCK_HIGH;
_NOP();_NOP();
_NOP();_NOP();
SHT_SCK_LOW;
SHT_DATA_HIGH;//釋放數據線
_NOP();_NOP();
return val;
}
/*******************************************
函數名稱:SHTSoftwareRst()
功 能:SHT軟件復位
參 數:無
返回值 :err_code 0--正常 1--出錯
********************************************/
uint8 SHTSoftwareRst(void)
{
uint8 err_code = 0;
SHTConnectionRst();
err_code = S_Write_Byte(Soft_Reset);
return err_code;
}
/*******************************************
函數名稱:SHTWriteReg()
功 能:SHT寫狀態寄存器
參 數:value--要寫的值
返回值 :err_code 0--正常 1--出錯
********************************************/
uint8 SHTWriteReg(uint8 value)
{
uint8 err_code = 0;
SHT_Start();
err_code += S_Write_Byte(WRITE_SR);
err_code += S_Write_Byte(value);
return err_code;
}
/*******************************************
函數名稱:SHTReadReg()
功 能:SHT讀狀態寄存器
參 數:Dst--數據源指針 CRC--CRC校驗值
返回值 :err_code 0--正常 1--出錯
********************************************/
uint8 SHTReadReg(uint8 *Dst,uint8 *CRC)
{
uint8 err_code = 0;
SHT_Start();
err_code += S_Write_Byte(READ_SR);
*Dst = S_Read_Byte(ACK);
*CRC = S_Read_Byte(NOACK);
return err_code;
}
/*******************************************
函數名稱:SHT_Calculate()
功 能:計算溫度[°C]和濕度[%RH]
參 數:Humi --濕度數據源指針[12 bit]
Temp --溫度數據源指針[14 bit]
返回值 :humi[%RH]
********************************************/
void SHT_Calculate(float *p_humidity,float *p_temperature)
{
const float C1 = -4;// 12 Bit RH
const float C2 = +0.0405;//12 Bit RH
const float C3 = -0.0000028;//12 Bit RH
const float T1 = +0.01;//12 Bit RH
const float T2 = +0.00008;//12 Bit RH
const float D1 = -39.60;//for 14 bit @3v
const float D2 = +0.01;//for 14 bit @3v
float rh = *p_humidity;
float t = *p_temperature;
float rh_lin = 0;//Humidity linear
float rh_true = 0;//Temperature compensated humidity
float t_C = 0;//Temperature
t_C = D1 + D2*t;//14 bit temperature
rh_lin = C1 + C2*rh + C3*rh*rh;//12 bit humidity
rh_true = (t_C - 25)*(T1 + T2*rh) + rh_lin;//calc Temperature compensated Humidity
if(rh_true > 100)
{
rh_true = 100;
}
if(rh_true < 0.1)
{
rh_true = 0.1;
}
*p_humidity = rh_true;
*p_temperature = t_C;
}
/*******************************************
函數名稱:S_Measure()
功 能:SHT采樣
參 數:Dst -- 數據源指針
CRC -- CRC校驗值
Mode--采集模式
返回值 :err_code 0--正常 1--出錯
********************************************/
uint8 S_Measure(uint8 *p_value,uint8 *p_checksum,uint8 mode)
{
uint8 err_code = 0;
unsigned short TimeCnt = 2000;
SHT_Start();
switch(mode)
{
case MEASURE_TEMP:err_code += S_Write_Byte(MEASURE_TEMP);break;
case MEASURE_HUMI:err_code += S_Write_Byte(MEASURE_HUMI);break;
default:break;
}
SHT_DATA_INPUT;
do
{
delay_ms(1);
}while((READ_SHT_DATA)&&(--TimeCnt));
if(!TimeCnt)
{
err_code++;
}
else
{
*(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 err_code;
}
/*******************************************
函數名稱:Read_wsd()
功 能:讀取溫濕度
參 數:無
返 回 值:無
********************************************/
void Read_Wsd(uint8 *Txdata)
{
SHT_Init();
uint8 err_code = 0;
err_code += S_Measure((uint8*)&humi_val.i,&checksum,MEASURE_HUMI);
err_code += S_Measure((uint8*)&temp_val.i,&checksum,MEASURE_TEMP);
if(err_code)//in case of an err,connection reset
{
SHTConnectionRst();
}
else
{
humi_val.f = (float)humi_val.i;
temp_val.f = (float)temp_val.i;
SHT_Calculate(&humi_val.f,&temp_val.f);
temp16_T = (unsigned int)(temp_val.f * 10);
temp16_H = (unsigned int)(humi_val.f * 10);
Txdata[0] = temp16_T;//溫度的低字節
Txdata[1] = temp16_T >> 8;//溫度的高字節
Txdata[2] = temp16_H;//濕度的低字節
Txdata[3] = temp16_H >> 8;//濕度的高字節
}
} |