- //Code for reading the SHT11 temeprature and humidity sensor with an STM ARM CORTEX-M3 MCU 
 
 - ////////////////////////////////////////////////////////////////////////////////////////
 
 - /*
 
 - The function read_temperature_and_humidity() reads the temperature and humidity and stores the data in XX.XX format
 
 - */
 
 - /***********************************************************************************************
 
 - *          PORT DEFINITION
 
 - ************************************************************************************************/
 
 - #define DATA_WR  GPIOA, GPIO_Pin_6 
 
 - #define DATA_RD    GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)
 
 - #define SCK     GPIOA, GPIO_Pin_7 
 
  
- /*********************************************************************************************************
 
 - *          LOCAL DEFINITIONS
 
 - *********************************************************************************************************/
 
 - //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 RESETa         0x1e   //000   1111    0
 
 - #define noACK    0
 
 - #define ACKa      1
 
 - /*
 
 - ***********************************************************************************************
 
 - *          GLOBAL CONSTANTS
 
 - ************************************************************************************************/
 
 - enum {TEMP,HUMI};
 
 - typedef union
 
 - {
 
 -  uint16_t i;
 
 -  float f;
 
 - } value;
 
 - ////////////////////////////////////////////////////////////////////////////////////////
 
 - //char temperature[15];
 
 - //char humidity[15];
 
 - int16_t  Real_Temperature;
 
 - uint16_t Real_Humidity;
 
 - int16_t  Temp_Hi_Limit;
 
 - int16_t  Temp_Lo_Limit;
 
 - uint16_t Humi_Hi_Limit;
 
 - uint16_t Humi_Lo_Limit;
 
 -    char Temp_Offset,Humi_Offset;
 
 - unsigned char DataStatus;// 数据结果标志位  0000 1111   
 
 -                                // 1:HumiLow HumidityHigh TempLow TempHigh
 
 - void mikrosekund(int cas)
 
 - {   
 
 -  int i; int j; //int k=0;
 
 -  for (i=0;i<cas;i++)
 
 -  { 
 
 -   for (j=0;j<1;j++)
 
 -   {  
 
 -   ;
 
 -   ;
 
 -   ;
 
 -   }
 
 -  }
 
 - }
 
 - void datain(void)
 
 - { 
 
 -   GPIO_InitTypeDef GPIO_InitStructure;
 
 -     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
 
 -     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 
 -     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 
 -     GPIO_Init(GPIOA, &GPIO_InitStructure);
 
 - }
 
 - void dataout(void)
 
 - { 
 
 -   GPIO_InitTypeDef GPIO_InitStructure;
 
 -   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
 
 -   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 
 -   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
 
 -   GPIO_Init(GPIOA, &GPIO_InitStructure);
 
 - }
 
  
- void sckout(void)
 
 - {
 
 -   GPIO_InitTypeDef GPIO_InitStructure;
 
 -   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
 
 -   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 
 -   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
 
 -   GPIO_Init(GPIOA, &GPIO_InitStructure);
 
 - }
 
 - /***********************************************************************************************
 
 - *         FUNCTION PROTOTYPES
 
 - ***********************************************************************************************/
 
 - char s_softreset(void);
 
 - char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);
 
 - //char s_write_statusreg(unsigned char *p_value);
 
 - //char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum);
 
 - /*
 
 - ***********************************************************************************************
 
 - *         FUNCTION PROTOTYPES
 
 - *          HARDWARE SPECIFIC
 
 - ***********************************************************************************************
 
 - */
 
 - void s_transstart(void);
 
 - void s_connectionreset(void);
 
 - char s_read_byte(unsigned char ack);
 
 - char s_write_byte(unsigned char value);
 
  
- /*
 
 - *********************************************************************************************************
 
 - *                             SOFT RESET THE SENSOR
 
 - *
 
 - * Description : Soft reset, resets the interface, clears the status register to default values
 
 - *    Wait minimum 11 ms before next command
 
 - * Arguments   : none
 
 - *   
 
 - * Returns     : 1 if no response from the sensor
 
 - * Notes    : 
 
 - *********************************************************************************************************/
 
 - char s_softreset(void)
 
 - { 
 
 -   unsigned char error_bit=0;  
 
 -   s_connection_reset();              //reset communication
 
 -   error_bit+=s_write_byte(RESETa);       //send RESET-command to sensor
 
 -   return error_bit;                     //error=1 in case of no response from the sensor
 
 - }
 
 - /*****************************************************************************************************
 
 - *                   MAKE MEASUREMENT ON HUMIDITY AND TEMPERATURE IN 12BITS ADN 14BITS
 
 - *
 
 - * Description : Makes a measurement (humidity/temperature) with checksum
 
 - * Arguments   : 
 
 - *   
 
 - * Returns     : 
 
 - * Notes    : It takes approximately 11/55/210 ms for a 8/12/14bit measurement.
 
 - *    Measurement data is stored until readout.
 
 - *    Two bytes of measurement data and one byte of CRC checksum will then be transmitted. 
 
 - *    The uC must acknowledge each byte by pulling the DATA line low.
 
 - *********************************************************************************************************/
 
 - char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
 
 - { 
 
 -  unsigned error_bit=0;
 
 -  unsigned int i;
 
 -  
 
 -  s_transstart();                   //transmission start
 
 -  switch(mode)
 
 -  {                     //send command to sensor
 
 -   case TEMP : error_bit+=s_write_byte(MEASURE_TEMP); break;
 
 -   case HUMI : error_bit+=s_write_byte(MEASURE_HUMI); break;
 
 -   default     : break;  
 
 -  }
 
 -  (mode==HUMI)?msDelay(55):msDelay(210);
 
 -  
 
 -  for (i=0;i<65535;i++) if(DATA_RD==0) break; //wait until sensor has finished the measurement
 
 -  if(DATA_RD) error_bit+=1;       //or timeout (~2 sec.) is reached
 
 -  
 
 -  *(p_value+1)  = s_read_byte(ACKa);     //read the first byte (MSB)
 
 -  *(p_value) = s_read_byte(ACKa);      //read the second byte (LSB)
 
 -  *p_checksum  = s_read_byte(noACK);    //read checksum
 
 -  
 
 -  return error_bit;
 
 - }
 
 - /*
 
 - *********************************************************************************************************
 
 - *                             TRANSMISSION START SEQUENCE
 
 - *
 
 - * Description : To initiate a transmission, a 揟ransmission Start?sequence has to be issued.
 
 - * Arguments   : none
 
 - *   
 
 - * Returns     : none
 
 - * Notes    : 
 
 - *      generates a transmission start 
 
 - *            _____         ________
 
 - *      DATA:       |_______|
 
 - *        ___     ___
 
 - *      SCK : ___|   |___|   |______
 
 - *********************************************************************************************************
 
 - */
 
 - void s_transstart(void)
 
 - {  
 
 -    GPIO_ResetBits(SCK); //SCK=0;                   //Initial state
 
 -    datain();// DATA_TRIS = 1;   //pullup resistor brings DATA pin high
 
 -    mikrosekund(1);
 
 -    GPIO_SetBits(SCK); //SCK=1;
 
 -    mikrosekund(1);
 
 -    dataout(); GPIO_ResetBits(DATA_WR); //DATA_TRIS=0;   // DATA_WR=0; DATA_TRIS=0;
 
 -    mikrosekund(1);
 
 -    GPIO_ResetBits(SCK);//SCK=0;  
 
 -    mikrosekund(5);
 
 -    GPIO_SetBits(SCK);//SCK=1;
 
 -    mikrosekund(1);
 
 -    datain();// DATA_TRIS=1;       //pullup resistor brings DATA pin high
 
 -    mikrosekund(1);
 
 -    GPIO_ResetBits(SCK);//SCK=0;    
 
 - }
 
  
- /*
 
 - *********************************************************************************************************
 
 - *                              CONNECTION RESET SEQUENCE
 
 - *
 
 - * Description : This sequence resets the interface only. The status register preserves its content.
 
 - * Arguments   : none
 
 - *   
 
 - * Returns     : none
 
 - * Notes    : 
 
 - *      communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
 
 - *            _____________________________________________________         ________
 
 - *     DATA:                                                  |_______|
 
 - *               _    _    _    _    _    _    _    _    _        ___     ___
 
 - *     SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
 
 - *********************************************************************************************************
 
 - */
 
 - void s_connection_reset(void)
 
 - {  
 
 -   unsigned char i;
 
 -  dataout();//DATA_TRIS  = 0;    //set data pin an output
 
 -  GPIO_SetBits(DATA_WR); //DATA_WR     = 1;   //set data pin high
 
 -  sckout(); //SCK_TRIS = 0;   //set CLK pin an output low
 
 -  GPIO_ResetBits(SCK);// SCK   = 0; 
 
 -  
 
 -   for(i=0;i<9;i++)              //9 SCK cycles for connection reset sequence
 
 -   { GPIO_SetBits(SCK);//SCK=1;
 
 -  mikrosekund(1);
 
 -     GPIO_ResetBits(SCK);//SCK=0;
 
 -  mikrosekund(1);
 
 -   }
 
 -   s_transstart();             //transmission start
 
 - }
 
  
- /*
 
 - *********************************************************************************************************
 
 - *                             LOW LEVEL READ FUNCTION 
 
 - *
 
 - * Description : Read a byte form the Sensibus and gives an acknowledge in case of "ack == ACK" 
 
 - * Arguments   : 'ack'  ACK (1) if acknowledge required
 
 - *      noACK (0) in case acknowledge NOT required
 
 - *   
 
 - * Returns     : return the byte read from the sensor
 
 - * Notes    : 
 
 - *********************************************************************************************************
 
 - */
 
 - char s_read_byte(unsigned char ack)
 
 - { 
 
 -   unsigned char i,val=0;
 
 -   datain(); //DATA_TRIS = 1;                    //set DATA line an input
 
 -   GPIO_ResetBits(SCK);//SCK = 0;
 
 -   for (i=0x80;i>0;i/=2)             //shift bit for masking
 
 -   { GPIO_SetBits(SCK);//SCK=1;                          //clk for SENSI-BUS
 
 -  mikrosekund(2);
 
 -     if (DATA_RD) val=(val | i);        //read bit  
 
 -     GPIO_ResetBits(SCK);//SCK=0;        
 
 -  mikrosekund(2);
 
 -   }
 
 -  if(ack==ACKa)
 
 -  {
 
 -  dataout();// DATA_TRIS = 0; 
 
 -   GPIO_ResetBits(DATA_WR);//DATA_WR = 0;
 
 -  }
 
 -    GPIO_SetBits(SCK);//SCK=1;                          //clk #9 for ack
 
 -  mikrosekund(5);      //pulse-width approx. 5 us          
 
 -    GPIO_ResetBits(SCK);//SCK=0;         
 
 -     datain();// DATA_TRIS = 1;                  //release DATA-line
 
 -   return val;
 
 - }
 
 - /*
 
 - *********************************************************************************************************
 
 - *                             LOW LEVEL WRITE FUNCTION 
 
 - *
 
 - * Description : Write a byte on the Sensibus and checks the acknowledge
 
 - * Arguments   : 'value' is the byte to write to the sensor
 
 - *   
 
 - * Returns     : 1 in case of an error (no acknowledge) from the sensor
 
 - * Notes    : 
 
 - *********************************************************************************************************
 
 - */
 
 - char s_write_byte(unsigned char value) 
 
 - { 
 
 -   unsigned char i,error_bit=0; 
 
 -   dataout();//DATA_TRIS = 0;
 
 -   for (i=0x80;i>0;i/=2)                //shift bit for masking
 
 -   { 
 
 -    if (i & value) GPIO_SetBits(DATA_WR);// DATA_WR=1;             //masking value with i , write to SENSI-BUS
 
 -     else GPIO_ResetBits(DATA_WR); //DATA_WR=0; 
 
 -  
 
 -  mikrosekund(5);   //add by idea
 
 -                         
 
 -     GPIO_SetBits(SCK);//SCK=1;                             //clk for SENSI-BUS
 
 -  mikrosekund(5);            //pulse-width approx. 5 us 
 
 -     GPIO_ResetBits(SCK);//SCK=0;
 
 -  mikrosekund(5);
 
 -   }
 
 -   datain();//DATA_TRIS=1;                             //release DATA-line, let SHT10 sensor controls DATA line
 
 -   GPIO_SetBits(SCK);//SCK=1;                               //clk #9 for ack 
 
 -   error_bit=DATA_RD;                          //check ack (DATA will be pulled down by SHT11)
 
 -   GPIO_ResetBits(SCK);//SCK=0;        
 
 -   return error_bit;                        //error=1 in case of no acknowledge
 
 - }
 
 -  
 
 - ////////////////konec kode za branje temp
 
 - void calc_sht1x(float *p_humidity ,float *p_temperature)
 
 - // calculates temperature [癈] and humidity [%RH] 
 
 - // input :  humi [Ticks] (12 bit) 
 
 - //          temp [Ticks] (14 bit)
 
 - // output:  humi [%RH]
 
 - //          temp [deg Cel]
 
 - { 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*0.01 - 40;                      //calc. temperature from ticks to [deg Cel] 
 
 -   rh_lin=0.0405*rh - 0.0000028*rh*rh - 4.0;      //calc. humidity from ticks to [%RH]
 
 -   rh_true=(t_C-25)*(0.01+0.00008*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
 
 -   //if(t_C<0)t_C=0;//by idea
 
 -   *p_temperature=t_C;                   //return temperature [deg Cel]
 
 -   *p_humidity=rh_true;                  //return humidity[%RH]
 
 - }
 
 - void read_temperature_and_humidity(void)
 
 - {
 
 -  value humi_val, temp_val;
 
 -  unsigned char error_bit, checksum;
 
 -  ////s_softreset();             //reset the SHT10 sensor
 
 -  
 
 -  msDelay(20);  // itcakam 20 mirko sekund, da se senzor umiri
 
 -  error_bit=0;
 
 -     error_bit+=s_measure((unsigned char*)&humi_val.i,&checksum,HUMI);   //measure humidity
 
 -     error_bit+=s_measure((unsigned char*)&temp_val.i,&checksum,TEMP);   //measure temperature
 
 -     if(error_bit!=0)
 
 -  {
 
 -    s_connection_reset(); //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
 
 -      calc_sht1x(&humi_val.f,&temp_val.f);      //calculate humidity, temperature
 
 -   //sprintf(temperature, "%f", temp_val.f,);
 
 -   //sprintf(humidity, "%f", humi_val.f);
 
 -   ////
 
 -   Real_Temperature=(int16_t)(temp_val.f*10);
 
 -   Real_Humidity=(uint16_t)(humi_val.f*10);      
 
 -   // 温度
 
 -   Real_Temperature=Real_Temperature+Temp_Offset;
 
 -   wg=Real_Temperature%10;    // ge
 
 -   ws=(Real_Temperature%100)/10;    // shi
 
 -   wb=(Real_Temperature%1000)/100;  // Bai 
 
 -   
 
 -   // 湿度
 
 -   Real_Humidity=Real_Humidity+Humi_Offset;
 
 -   if(Real_Humidity>990)Real_Humidity=990;
 
 -   sg=Real_Humidity%10;   // ge
 
 -   ss=(Real_Humidity%100)/10;    // shi
 
 -   sb=(Real_Humidity%1000)/100;  // Bai 
 
 -  }
 
 - }
 
  
 
  |