logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

atmega8 i czujnik sht11

[=MaRcUs=] 27 Maj 2009 15:15 5496 1
REKLAMA
  • #1 6581268
    [=MaRcUs=]
    Poziom 1  
    witam,

    zaprojektowałem mój pierwszy układzik do sprawdzania temperatury i wilgotności oparty na atgmega8 (zew. kwarc 8mhz) i czujnik firmy sensirion sht11.

    atmega8 i czujnik sht11
    zlutowałem 4 dolne wyjścia, piszę to gdyż mój czujnik ma 5 wyjść(jak na zdjęciu) a nie 4 jak w dokumentacji. może tu leży problem..

    problem polega na tym, że po przerobieniu sampla programu ze strony producenta z 8051 na atmege nie otrzymuje potwierdzenia odebrania czegokolwiek od czujnika.

    SHTxx_Sample_Code.c
    
    /***********************************************************************************
    Project:          SHTxx demo program (V2.1)
    Filename:         SHTxx_Sample_Code.c    
    
    Prozessor:        80C51 family
    Compiler:         Keil Version 6.14
    
    Autor:            MST
    Copyrigth:        (c) Sensirion AG      
    ***********************************************************************************/
    
    //#include <AT89s53.h> //Microcontroller specific library, e.g. port definitions
    //#include <intrins.h> //Keil library (is used for _nop()_ operation)  
    #include <math.h>    //Keil library  
    #include <stdio.h>   //Keil library
    
    typedef union 
    { unsigned int i;
      float f;
    } value;
    
    //----------------------------------------------------------------------------------
    // modul-var
    //----------------------------------------------------------------------------------
    enum {TEMP,HUMI};
    
    #define DDR_DB2  	DDRD 
    #define PORT_DB2 	PORTD 
    #define DATA     	PD2	
    
    #define DDR_DB3  	DDRD 
    #define PORT_DB3 	PORTD
    #define SCK      	PD3 
    
    #define SET_SCK PORT_DB3 |= _BV(SCK) 
    #define CLR_SCK PORT_DB3 &= ~_BV(SCK) 
    
    #define SET_DATA_OUT PORT_DB2 |= _BV(DATA) 
    #define CLR_DATA_OUT PORT_DB2 &= ~_BV(DATA) 
    
    #define noACK 0
    #define ACK   1
                                //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
    
    char check(void)
    {
    	DDRD^=0b0000100;
    	if(bit_is_clear(PIND, PD2)) 
    	{
    		DDRD^=0b0000100;
    		return 0;
    	}
    	else
    	{
    		DDRD^=0b0000100;
    		return 1;
    	}
    }
    
    
    
    //----------------------------------------------------------------------------------
    char s_write_byte(unsigned char value)
    //----------------------------------------------------------------------------------
    // writes a byte on the Sensibus and checks the acknowledge 
    { 
      unsigned char i,error=0;  
      for (i=0x80;i>0;i/=2)             //shift bit for masking
      { 
    	if (i & value) 
    		SET_DATA_OUT;          //masking value with i , write to SENSI-BUS
        else 
    		CLR_DATA_OUT;                        
        SET_SCK;                          //clk for SENSI-BUS
    	_delay_ms(5);        //pulswith approx. 5 us  	
        CLR_SCK;
      }
      SET_DATA_OUT;                           //release DATA-line
      SET_SCK;                            //clk #9 for ack 
      _delay_ms(2);
      error=check();                       //check ack (DATA will be pulled down by SHT11)
      _delay_ms(2);
      CLR_SCK;        
      return error;                     //error=1 in case of no acknowledge
    }
    
    //----------------------------------------------------------------------------------
    char s_read_byte(unsigned char ack)
    //----------------------------------------------------------------------------------
    // reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 
    { 
      unsigned char i,val=0;
    //  SET_DATA_OUT;                           //release DATA-line
      for (i=0x80;i>0;i/=2)             //shift bit for masking
      { SET_SCK;                          //clk for SENSI-BUS
    	_delay_ms(2);
    	if (check()) val=(val | i);        //read bit  
        _delay_ms(2);
    	CLR_SCK;  					 
      }
     //DATA = !ack; 	//zastoąpione tym poniżej
      if(ack)								
      	CLR_DATA_OUT;				     //clear date??                   //in case of "ack==1" pull down DATA-Line
      else if(!ack)
    	SET_DATA_OUT;
    //
      SET_SCK;                            //clk #9 for ack
       _delay_ms(5);        //pulswith approx. 5 us  	
      CLR_SCK;						    
      SET_DATA_OUT;                           //release DATA-line
      return val;
    }
    
    //----------------------------------------------------------------------------------
    void s_transstart(void)
    //----------------------------------------------------------------------------------
    // generates a transmission start 
    //       _____         ________
    // DATA:      |_______|
    //           ___     ___
    // SCK : ___|   |___|   |______
    {  
       SET_DATA_OUT; CLR_SCK;                   //Initial state
       _delay_ms(2);
       SET_SCK;
       _delay_ms(2);
       CLR_DATA_OUT;
       _delay_ms(2);
       CLR_SCK;  
       _delay_ms(5);
       SET_SCK;
       _delay_ms(2); 
       SET_DATA_OUT;		   
       _delay_ms(2);
       CLR_SCK;	
    }
    
    //----------------------------------------------------------------------------------
    void s_connectionreset(void)
    //----------------------------------------------------------------------------------
    // communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
    //       _____________________________________________________         ________
    // DATA:                                                      |_______|
    //          _    _    _    _    _    _    _    _    _        ___     ___
    // SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
    {  
      unsigned char i; 
      SET_DATA_OUT; CLR_SCK;                    //Initial state
      for(i=0;i<9;i++)                  //9 SCK cycles
      { SET_SCK;
        _delay_ms(1);
        CLR_SCK;
        _delay_ms(1);
      }
      s_transstart();                   //transmission start
    }
    
    //----------------------------------------------------------------------------------
    char s_softreset(void)
    //----------------------------------------------------------------------------------
    // resets the sensor by a softreset 
    { 
      unsigned char error=0;  
      s_connectionreset();              //reset communication
      error+=s_write_byte(RESET);       //send RESET-command to sensor
      return error;                     //error=1 in case of no response form the sensor
    }
    
    //----------------------------------------------------------------------------------
    char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum)
    //----------------------------------------------------------------------------------
    // reads the status register with checksum (8-bit)
    {
      unsigned char error=0;
      s_transstart();                   //transmission start
      error=s_write_byte(STATUS_REG_R); //send command to sensor
      *p_value=s_read_byte(ACK);        //read status register (8-bit)
      *p_checksum=s_read_byte(noACK);   //read checksum (8-bit)  
      return error;                     //error=1 in case of no response form the sensor
    }
    
    //----------------------------------------------------------------------------------
    char s_write_statusreg(unsigned char *p_value)
    //----------------------------------------------------------------------------------
    // writes the status register with checksum (8-bit)
    { 
      unsigned char error=0;
      s_transstart();                   //transmission start
      error+=s_write_byte(STATUS_REG_W);//send command to sensor
      error+=s_write_byte(*p_value);    //send value of status register
      return error;                     //error>=1 in case of no response form the sensor
    }
     							   
    //----------------------------------------------------------------------------------
    char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
    //----------------------------------------------------------------------------------
    // makes a measurement (humidity/temperature) with checksum
    { 
      unsigned error=0;
      unsigned int i;
      s_transstart();                   //transmission start
      switch(mode){                     //send command to sensor
        case TEMP	: error+=s_write_byte(MEASURE_TEMP); break;
        case HUMI	: error+=s_write_byte(MEASURE_HUMI); break;	//tu wywala po dwa error
        default     : break;	 
      }
      for (i=0;i<65535;i++) if(check()==0) break; //wait until sensor has finished the measurement
      if(check()) error+=1;                // or timeout (~2 sec.) is reached
      *(p_value)  =s_read_byte(ACK);    //read the first byte (MSB)
      *(p_value+1)=s_read_byte(ACK);    //read the second byte (LSB)
      *p_checksum =s_read_byte(noACK);  //read checksum
      return error;
    }
    /*
    //----------------------------------------------------------------------------------
    void init_uart()
    //----------------------------------------------------------------------------------
    //9600 bps @ 11.059 MHz 
    {SCON  = 0x52;    
     TMOD  = 0x20;    
     TCON  = 0x69;	  
     TH1   = 0xfd;    
    }
    */
    //----------------------------------------------------------------------------------------
    void calc_sth11(float *p_humidity ,float *p_temperature)
    //----------------------------------------------------------------------------------------
    // calculates temperature [°C] and humidity [%RH] 
    // input :  humi [Ticks] (12 bit) 
    //          temp [Ticks] (14 bit)
    // output:  humi [%RH]
    //          temp [°C]
    { const float C1=-4.0;              // for 12 Bit
      const float C2=+0.0405;           // for 12 Bit
      const float C3=-0.0000028;        // for 12 Bit
      const float T1=+0.01;             // for 14 Bit @ 5V
      const float T2=+0.00008;           // for 14 Bit @ 5V	
    
      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 [°C]
    
      t_C=t*0.01 - 40;                  //calc. temperature from ticks to [°C]
      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 [°C]
      *p_humidity=rh_true;              //return humidity[%RH]
    }
    
    //--------------------------------------------------------------------
    float calc_dewpoint(float h,float t)
    //--------------------------------------------------------------------
    // calculates dew point
    // input:   humidity [%RH], temperature [°C]
    // output:  dew point [°C]
    { 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;
    }
    


    i
    main
    
    #include <stdio.h>
    #include <avr/io.h> 
    #include <util/delay.h> 
    #include <avr/eeprom.h>     // dostęp do pamięci EEPROM
    #include <my/lcd.c> 		//funkcje odpowiedzialne za obsluge wyswietlacza
    #include <my/SHTxx_Sample_Code.c> 		//funkcje odpowiedzialne za obsluge czujnika
    
    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
    
    #define temperature 0xE0	//adres zapsiu temperatury do eeprom'u
    #define humidity 	0xE1	//adres zapsiu wilgotnosci do eeprom'u
    #define clearLCD	0x01
    
    int temp=0;
    int hum=50;
    
    //deklaracje funkcji
    void buttonMenu2Click(void);
    void buttonSaveHum(void);
    void buttonSaveTemp(void);
    int main(void);
    int buttonUp(int, int);
    int buttonDown(int, int);
    
    int main(void) 
    { 
    DDRD=0b11111111;
    sbi(PORTC, 2); //przycisk
    sbi(PORTC, 3); //przycisk
    sbi(PORTC, 4); //przycisk
    sbi(PORTC, 5); //przycisk
    
    //ustawienie domyślnej temperatury i wilgotnosci		//temp komentarz
    //eeprom_write_byte((uint8_t*)temperature, temp);
    //eeprom_write_byte((uint8_t*)humidity, hum);
    
    // inicjalizacja LCD 
    lcd_init(); 
    //======================================================================
    //======================================================================
    //======================================================================
    //======================================================================
    
      value humi_val,temp_val;
    //  float dew_point;
      unsigned char error,checksum;
      unsigned int i;
      char buffer[7];
      enum {TEMP,HUMI};
      
    //reset polaczenia czujnika sht11
    s_connectionreset();
    
    while(1)
      { error=0;
      
        error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI);  //measure humidity
    
        error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP);  //measure temperature
    
        if(error!=0) s_connectionreset();                 //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_sth11(&humi_val.f,&temp_val.f);            //calculate humidity, temperature
     
    
    	write_command(clearLCD);
    	_delay_ms(1);					//opoznienie, bez niego obcinalo pierwszy znak
    	write_text("Temperatura:");		// zapisz na LCD tekst temperatura
    	gotoxy(12,0);
    	
    	sprintf(buffer, "%d", humi_val.i);//temp_val.i);	//zapisanie do buffora całego stringu
    	write_text(buffer);				//wypisanie zapisanej temp
    
    
    
    	}
    	
    	
        //----------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!)
        //-----------------------------------------------------------------------------------                       
      }
    return 0; 
    }
    


    po wyświetleniu errorów na LCD otrzymuje ciąg :
    -0 - przed error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI);
    -2 - po error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI);
    -4 - po error+=s_measure((unsigned char*) &humi_val.i,&checksum,TEMP);


    proszę o pomoc bo przeszukałem już co się da i nie mam pomysłu jak to rozwiązać, a znając życie może być to banalny błąd
    a czujnik podłączony tak: SCK - portD.3 i DATA portD.2

    @Edit
    poprawiłem delay z mS na uS i dalej nic
  • REKLAMA
REKLAMA