dingshidong214 发表于 2014-9-29 10:22:39

MSP430 Launchpad SHT10传感器

在MSP430 Launchpad(开发板便宜) MSP430G2452上调试 可以使用 可以修改传感器的测量分辨率
//********************************File Information*******************************
//** File Name:      Sht10.c
//** Platform:         MSP430 LaunchPad MSP430G2452
//** System Function:Sht10 Sensirion Inc driver code
//** Created by:       ding
//** Created date:   2014-09-15
//** Version:          Demo V1.0
//******************************************************************************
//---------------------------------------
//硬件连线-接口定义:
//SCK: -->P1.5 //定义通讯时钟端口
//SDA: -->P1.6 //定义通讯数据端口
//---------------------------------------

#include <msp430g2452.h>//Library
#include <intrinsics.h> //__no_operation();
//#include <math.h>       //Library
//#include <stdio.h>      //printf();

//宏定义,延时函数,参数为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       //没有返回ACK
#define ACK         1       //返回ACK
#define HUMIDITY      2
#define TEMPERATURE   1

#define SCK         BIT5//P1.5
#define SDA         BIT6//P1.6
#define SCK_H         P1OUT|=SCK//高
#define SCK_L         P1OUT&=~SCK //低
#define SDA_H         P1OUT|=SDA//高
#define SDA_L         P1OUT&=~SDA //低

typedef union//定义了两个共用体
{
unsigned int i;
float f;
}value;

/**********************************************************************************************************
**Function Name:      S_Init
**Description:      初始化
**Input Parameters:   no
**Output Parameters:no
**********************************************************************************************************/
void S_Init()
{
P1SEL&=~(SCK+SDA);
P1DIR|=SCK;
P1DIR&=~SDA;
//BCSCTL1=(XT2OFF+RSEL2);    //关闭XT2,1MHz DOC   
//DCOCTL=DCO2;               //设定DCO频率为1MHz
}

/**********************************************************************************************************
**Function Name:      S_Transstart
**Description:      start时序                  
**                  generates a transmission start
**                        _____         ________
**                  DATA:      |_______|
**                              ___   ___
**                  SCK : ___|   |___|   |______
**********************************************************************************************************/
void S_Transstart()
{
P1DIR|=SDA;
SDA_H;SCK_L;
__no_operation();
SCK_H;
__no_operation();
SDA_L;
__no_operation();
SCK_L;
__no_operation();
__no_operation();
__no_operation();
SCK_H;
__no_operation();
SDA_H;
__no_operation();
SCK_L;
P1DIR&=~SDA;
}

/**********************************************************************************************************
**Function Name:      S_WriteByte
**Description:      写函数
**********************************************************************************************************/
char S_WriteByte(unsigned char value)
{
// writes a byte on the Sensibus and checks the acknowledge
unsigned char i,error=0;
P1DIR|=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
      __no_operation();__no_operation();__no_operation();//pulswith approx. 5 us
      SCK_L;
}
SDA_H;                            //release DATA-line
P1DIR&=~SDA;                      //Change SDA to be input 0:input 1:ouput
SCK_H;                            //clk #9 for ack
error=P1IN;                     //check ack (DATA will be pulled down by SHT11)
error&=SDA;
P1DIR|=SDA;                     //Change SDA to be output 0:input 1:ouput
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"
**********************************************************************************************************/
char S_ReadByte(unsigned char ack)
{
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
unsigned char i,val=0;
P1DIR|=SDA;                      //Change SDA to be output 0:input 1:ouput
SDA_H;                           //release DATA-line
P1DIR&=~SDA;                     //Change SDA to be input 0:input 1:ouput
for(i=0x80;i>0;i/=2)             //shift bit for masking
{
    SCK_H;                     //clk for SENSI-BUS
    if(P1IN&SDA)               
      val=(val|i);               //read bit
      SCK_L;      
}
P1DIR|=SDA;                      //Change SDA to be output 0:input 1:ouput
if(ack)                        //in case of "ack==1" pull down DATA-Line
    SDA_L;
else
    SDA_H;                        
SCK_H;                           //clk #9 for ack
__no_operation();__no_operation();__no_operation();//pulswith approx. 5 us
SCK_L;         
SDA_H;                           //release DATA-line
P1DIR&=~SDA;                     //Change SDA to be output 0:input 1:ouput
return val;
}

/**********************************************************************************************************
**Function Name:      S_Connectionreset
**Description:      连接复位函数
**                  communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
**                        _____________________________________________________         ________
**                  DATA:                                                      |_______|
**                           _    _    _    _    _    _    _    _    _      ___   ___
**                  SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
**********************************************************************************************************/
void S_Connectionreset()
{
unsigned char ClkCnt;
P1DIR|=SDA;                        //Change SDA to be input 0:input 1:ouput
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
**********************************************************************************************************/
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
**********************************************************************************************************/
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                  
**********************************************************************************************************/
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;
}
P1DIR&=~SDA;                      //Change SDA to be input 0:input 1:ouput
for(i=0;i<65535;i++) if((P1IN&SDA)==0) break; //wait until sensor has finished the measurement
if(P1IN&SDA) error+=1;            //or timeout (~2 sec.) is reached
*(p_value)=S_ReadByte(ACK);       //read the first byte (MSB) 高8位
*(p_value+1)=S_ReadByte(ACK);   //read the second byte (LSB)低8位
*p_checksum=S_ReadByte(noACK);    //read checksum
return error;
}

/**********************************************************************************************************
**Function Name:      S_Calculate
**Description:      计算
**Input Parameters:   humi (12 bit) 默认
**                  temp (14 bit) 默认                        
**Output Parameters: humi [%RH]
**                  temp [℃]
**********************************************************************************************************/
void S_Calculate(unsigned int *p_humidity ,unsigned int *p_temperature)
//’1’ =8bit湿度 / 12bit 温度分辨率   -->可修改分辨率
//’0’ =12bit 湿度 / 14bit 温度.分辨率-->默认选择
{
//12bit 湿度 / 14bit 温度.分辨率
const float C1=-2.0468;         // for 12 Bit 湿度转换参数
const float C2=0.0367;         // for 12 Bit 湿度转换参数
const float C3=-0.0000015955;   // for 12 Bit 湿度转换参数
const float D1=-39.6;             // for 14 Bit @ 3V 温度
const float D2=0.01;             // for 14 Bit @ 3V 温度
const float T1=0.01;            // for 12 bit 湿度信号的温度补偿
const float T2=0.00008;         // for 12 bit 湿度信号的温度补偿


//8bit湿度 / 12bit 温度分辨率
/*
const float C1=-2.0468;         // for 8 Bit 湿度转换参数
const float C2=+0.5872;         // for 8 Bit 湿度转换参数
const float C3=-0.00040845;       // 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 12 Bit
float t=*p_temperature;         // t:Temperature 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 = (uint)t_C;             //return temperature [℃]
*p_humidity = (uint)rh_true;            //return humidity[%RH]
}

//************************************************************************************
//**Function Name:      calc_dewpoint
//**Description:      露点
//************************************************************************************
/*
float Calc_Dewpoint(float h,float t)
// calculates dew point
// input:   humidity [%RH], temperature [℃]
// output:dew point [℃]
{ float logEx,dew_point;
logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2);
dew_point = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx);
return dew_point;
}
*/

/**********************************************************************************************************
**Function Name:      主函数
**********************************************************************************************************/
void main()
{
// sample program that shows how to use SHT11 functions
// 1. connection reset
// 2. measure humidity (12 bit) and temperature (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 temphigh,templow,humilow;
unsigned int temphigh,templow,humihigh,humilow;
//unsigned int Reg_Resolution=0x01;

WDTCTL=WDTPW+WDTHOLD; //Stop watchdog timer

S_Init(); //初始化
S_Connectionreset(); //连接复位
//S_WriteStatusReg((unsigned char *)&Reg_Resolution);//修改测量分辨率:8bit湿度 / 12bit温度
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
    {
      //Note:修改分辨率需要传感器重新上下电才可生效
      //-------------测量分辨率:8bit湿度 / 12bit温度----------------//
      //8bit humidity MSB=0x0000,00000(invalid) LSB=0xmmmm,mmmm(valid)
      //humilow=(humi_val.i&0xff00);
      //humi_val.i=humilow>>8;      //Humidity
      //12bit temperature MSB=0x0000,mmmm( 4bits valid) LSB=0xmmmm,mmmm(valid)
      //temphigh=((temp_val.i&0x0f)<<8);
      //templow=((temp_val.i&0xff00)>>8);
      //temp_val.i=temphigh+templow;//Temperature
      
      //-------------测量分辨率:12bit湿度 / 14bit温度----------------//
      //12bit humidity MSB=0x0000,mmmm(4bits valid) LSB=0xmmmm,mmmm(valid)
      humihigh=((humi_val.i&0x0f)<<8);
      humilow=((humi_val.i&0xff00)>>8);
      humi_val.i=humihigh+humilow;//Humidity
      
      //14bit temperature MSB=0x00mm,mmmm( 6bit valid) LSB=0xmmmm,mmmm(valid)
      temphigh=((temp_val.i&0x3f)<<8);
      templow=((temp_val.i&0xff00)>>8);
      temp_val.i=temphigh+templow;//Temperature
      
      S_Calculate(&humi_val.i,&temp_val.i);         //calculate humidity, temperature
      
      //dew_point=Calc_Dewpoint(humi_val.i,temp_val.i); //calculate dew point
      //printf("temp:%5.1fC humi:%5.1f%% dew point:%5.1fC\n",temp_val.i,humi_val.i,dew_point);
    }   
    //----------wait approx. 0.8s to avoid heating up SHTxx------------------------------      
    for (uint i=0;i<40000;i++);//(be sure that the compiler doesn't eliminate this line!)
    //-----------------------------------------------------------------------------------                     
}
}

jinfen 发表于 2014-9-30 08:39:28

{:victory:}mark,谢谢分享

ndk 发表于 2014-9-30 09:15:00

谢谢分享!

hbtss 发表于 2014-9-30 09:23:27

谢谢分享
页: [1]
查看完整版本: MSP430 Launchpad SHT10传感器