- //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
- }
- }
|