这是暑假时用430的单片机写的温湿度传感器SHT10的程序,参考了官方的51例程,分享一下~~
/****************************************Copyright (c)**************************************************
******************************************LiPeng********************************************************
**--------------File Info-------------------------------------------------------------------------------
** File Name: Sht10_Driver.c
** Created by: LiPeng
** Created date: 2008-09-15
** Version: 1.0
** Descriptions: The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
**------------------------------------------------------------------------------------------------------
** System Function: Sht10 Driver------温湿度传感器SHT10驱动
** 使用MSP430-F413连接方式:
** VCC: P6.3
** SCK: P6.4
** SDA: P6.5
**
********************************************************************************************************/
#include <msp430x14x.h>
/*宏定义,延时函数,参数为1时相应延时分别为1us和1ms*/
#define CPU_F (double)1000000
#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))
/*常量定义*/
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
//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
#define bitselect 0x01 //选择温度与湿度的低位读
#define noACK 0
#define ACK 1
#define HUMIDITY 2
#define TEMPERATURE 1
#define SCK BIT4
#define SDA BIT5
#define SVCC BIT3
#define SCK_H P6OUT|=SCK
#define SCK_L P6OUT&=~SCK
#define SDA_H P6OUT|=SDA
#define SDA_L P6OUT&=~SDA
#define SVCC_H P6OUT|=SVCC
#define SVCC_L P6OUT&=~SVCC
typedef union
{
unsigned int i;
float f;
}value;
uint table_temp[3];
uint table_humi[3];
uint temten;
uint humi_true;
/**********************************************************************************************************
**Function Name: S_Init
**Description: 初始化
**Input Parameters: 无
**Output Parameters: 无
**********************************************************************************************************/
void S_Init()
{
P6SEL&=~(SCK+SDA+SVCC); //选择P6.3 P6.4 为IO端口,输出 P6.5输入
P6DIR|=(SCK+SVCC);
P6DIR&=~SDA;
BCSCTL1=(XT2OFF+RSEL2); //关闭XT2,1MHz DOC
DCOCTL=DCO2; //设定DCO频率为1MHz
}
/**********************************************************************************************************
**Function Name: S_Transstart
**Description: 发送开始时序
**
** generates a transmission start
** _____ ________
** DATA: |_______|
** ___ ___
** SCK : ___| |___| |______
**Input Parameters: 无
**Output Parameters: 无
**********************************************************************************************************/
void S_Transstart()
{
P6DIR|=SDA;
SDA_H;SCK_L;
_NOP();
SCK_H;
_NOP();
SDA_L;
_NOP();
SCK_L;
_NOP();_NOP();_NOP();
SCK_H;
_NOP();
SDA_H;
_NOP();
SCK_L;
P6DIR&=~SDA;
}
/**********************************************************************************************************
**Function Name: S_WriteByte
**Description: 写时序
**Input Parameters: 无
**Output Parameters: 无
**********************************************************************************************************/
char S_WriteByte(unsigned char value)
{
unsigned char i,error=0;
P6DIR|=SDA;
for(i=0x80;i>0;i/=2) //shift bit for masking
{
if(i&value)
SDA_H; //masking value with i , write to SENSI-BUS
else
SDA_L;
SCK_H; //clk for SENSI-BUS
_NOP();_NOP();_NOP(); //pulswith approx. 5 us
SCK_L;
}
SDA_H; //release DATA-line
P6DIR&=~SDA; //Change SDA to be input
SCK_H; //clk #9 for ack
error=P6IN; //check ack (DATA will be pulled down by SHT11)
error&=SDA;
P6DIR|=SDA;
SCK_L;
if(error)
return 1; //error=1 in case of no acknowledge
return 0;
}
/**********************************************************************************************************
**Function Name: S_ReadByte
**Description: 读时序
**Input Parameters: ack--->reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
**Output Parameters: 无
**********************************************************************************************************/
char S_ReadByte(unsigned char ack)
{
unsigned char i,val=0;
P6DIR|=SDA;
SDA_H; //release DATA-line
P6DIR&=~SDA;
for(i=0x80;i>0;i/=2) //shift bit for masking
{
SCK_H; //clk for SENSI-BUS
if(P6IN&SDA)
val=(val|i); //read bit
SCK_L;
}
P6DIR|=SDA;
if(ack) //in case of "ack==1" pull down DATA-Line
SDA_L;
else
SDA_H;
SCK_H; //clk #9 for ack
_NOP();_NOP();_NOP(); //pulswith approx. 5 us
SCK_L;
SDA_H; //release DATA-line
P6DIR&=~SDA;
return val;
}
/**********************************************************************************************************
**Function Name: S_Connectionreset
**Description: 通讯复位时序
** communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
** _____________________________________________________ ________
** DATA: |_______|
** _ _ _ _ _ _ _ _ _ ___ ___
** SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
**Input Parameters: 无
**Output Parameters: 无
**********************************************************************************************************/
void S_Connectionreset()
{
unsigned char ClkCnt;
P6DIR|=SDA;
SDA_H;SCK_L; //Initial state
for(ClkCnt=0;ClkCnt<9;ClkCnt++) //9 SCK cycles
{
SCK_H;
SCK_L;
}
S_Transstart(); //transmission start
}
/**********************************************************************************************************
**Function Name: S_Softreset
**Description: 软件复位时序resets the sensor by a softreset
**Input Parameters: 无
**Output Parameters: 无
**********************************************************************************************************/
char S_Softreset()
{
unsigned char error=0;
S_Connectionreset(); //reset communication
error+=S_WriteByte(RESET); //send RESET-command to sensor
return error; //error=1 in case of no response form the sensor
}
/**********************************************************************************************************
**Function Name: S_WriteStatusReg
**Description: 写状态寄存器
**Input Parameters: *p_value
**Output Parameters: 无
**********************************************************************************************************/
char S_WriteStatusReg(unsigned char *p_value)
{
unsigned char error=0;
S_Transstart(); //transmission start
error+=S_WriteByte(STATUS_REG_W); //send command to sensor
error+=S_WriteByte(*p_value); //send value of status register
return error; //error>=1 in case of no response form the sensor
}
/**********************************************************************************************************
**Function Name: S_Mearsure
**Description: 读时序 makes a measurement (humidity/temperature) with checksum
**Input Parameters: *p_value ,*p_checknum ,mode
**Output Parameters: 无
**********************************************************************************************************/
unsigned char S_Measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
{
unsigned error=0;
unsigned int i;
S_Transstart(); //transmission start
switch(mode)
{ //send command to sensor
case TEMPERATURE: error+=S_WriteByte(MEASURE_TEMP); break;
case HUMIDITY: error+=S_WriteByte(MEASURE_HUMI); break;
}
P6DIR&=~SDA;
for(i=0;i<65535;i++) //wait until sensor has finished the measurement
if((P6IN&SDA)==0)
break;
if(P6IN&SDA)
error+=1; //or timeout (~2 sec.) is reached
*(p_value)=S_ReadByte(ACK); //read the first byte (MSB)
*(p_value+1)=S_ReadByte(ACK); //read the second byte (LSB)
*p_checksum=S_ReadByte(noACK); //read checksum
return(error);
}
/**********************************************************************************************************
**Function Name: S_Calculate
**Description: 计算
**Input Parameters: humi [Ticks] (12 bit)
** temp [Ticks] (14 bit)
**Output Parameters: humi [%RH]
** temp [癈]
**********************************************************************************************************/
void S_Calculate(unsigned int *p_humidity ,unsigned int *p_temperature)
{
const float C1=-4.0; // for 8 Bit
const float C2=+0.648; // for 8 Bit
const float C3=-0.0000072; // for 8 Bit
const float D1=-39.6; // for 12 Bit @ 3V
const float D2=+0.04; // for 12 Bit @ 3V
const float T1=0.01; // for 8 bit
const float T2=0.00128; // for 8 bit
float rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit
float t=*p_temperature; // t: Temperature [Ticks] 14 Bit
float rh_lin; // rh_lin: Humidity linear
float rh_true; // rh_true: Temperature compensated humidity
float t_C; // t_C : Temperature [癈]
t_C=t*D2+D1; //calc. temperature from ticks to [癈]
rh_lin=C3*rh*rh + C2*rh + C1; //calc. humidity from ticks to [%RH]
rh_true=(t_C-25)*(T1+T2*rh)+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=t_C; //return temperature [癈]
*p_humidity=rh_true; //return humidity[%RH]
}
void main()
{
value humi_val,temp_val;
unsigned char error,checksum;
unsigned int i,temphigh,templow;
unsigned int RegCMD=0x01;
WDTCTL=WDTPW+WDTHOLD; //Stop watchdog timer to prevent time out reset
S_Init();
SVCC_H;
S_Connectionreset();
S_WriteStatusReg((unsigned char *)&RegCMD);
while(1)
{
error=0;
error+=S_Measure((unsigned char*) &humi_val.i,&checksum,HUMIDITY); //measure humidity
error+=S_Measure((unsigned char*) &temp_val.i,&checksum,TEMPERATURE); //measure temperature
if(error!=0)
S_Connectionreset(); //in case of an error: connection reset
else
{
templow=(humi_val.i&0xff00);
humi_val.i=templow>>8;
temphigh=((temp_val.i&0xf)<<8);
templow=((temp_val.i&0xff00)>>8);
temp_val.i=temphigh+templow;
S_Calculate(&humi_val.i,&temp_val.i); //calculate humidity, temperature
//temp_val_NOP();
//printf("temp:%5.1fC humi:%5.1f%% dew point:%5.1fC\n",temp_val.f,humi_val.f,dew_point);
}
//----------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!)
//-----------------------------------------------------------------------------------
}
}