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

[ATMega 32 + SHT 75] nie mogę uzyskać transmisji

domimat 09 Gru 2008 20:32 3337 7
  • #1 5838849
    domimat
    Poziom 11  
    Witam!
    Czy udalo sie komus zrealizowac miernik temperatury i wilgotnosci na tych elementach? Probuje na rozne sposoby (przerobka sample_code ze strony SHT na Atmege, Bascom itp) ale w zaden sposob nie moge uzyskac prawidlowej komunikacji.
    Jezeli ktos ma fragment dzialajacego kodu (obojetne czy pod AVRStudio czy Bascoma, preferowany ten pierwszy) do transmisji to bylbym bardzo wdzieczny za udostepnienie.

    pozdrawiam
  • #3 5839728
    domimat
    Poziom 11  
    ten kod mam od dawna...
    to jest pod 8051 i kompilator Keil, ja potrzebuje pod Atmege32 i najlepiej AVR Studio

    [ do dowcipnisia od koncertu życzen: wiesz do czego służy forum? ]
  • #5 5841708
    tomhandyman
    Poziom 13  
    Ten kod jest pod Atmegę 32 i z tym zegarem chodzi do działa do 50 metrów, próbkowanie sygnału jest kilkukrotne w pętli ze względu na niezawodność.
    
    //----------------------------------------------------------------------------------
    //
    // Sensirion SHT1x Humidity Sensor Library
    //
    //----------------------------------------------------------------------------------
    
    #ifndef __sht_h
    #define __sht_h
    #include "iom32.h"
    
    #define SHT_POWER_DDR                   DDRD
    #define SHT_POWER_PORT                  PORTD
    #define SHT_POWER_PIN                   PIND
    #define SHT_POWER                       8
    #define SHT_DDR				DDRC		// Port with clock and data pins
    #define SHT_PORT			PORTC		// Port with clock and data pins
    #define SHT_PIN				PINC		// Port with clock and data pins
    #define SHT_CLOCK			0			// Pin used to output clock to SHT
    #define SHT_DATA			1			// Pin used to read/output data from/to SHT
    
    #define SHT_DELAY			150			// uS delay between clock rise/fall
    #define SHT_DELAY_POMIAR                5
    #define SHT_TEMPERATURE 	0x03		// Measure temp - for ShtMeasure
    #define SHT_HUMIDITY 		0x05		// Measure humidity - for ShtMeasure
    #define STATUS_REG_W 		0x06 		// Command to read status register
    #define STATUS_REG_R 		0x07 		// Command to write status register
    #define RESET 			0x1E 		// Command for soft reset (not currently used)
    
    // physical connection:
    #define sht_port_off() (PORTD &=~(1<<7))
    #define sda_port_off() (PORTC &=~(1<<1))
    #define scl_port_off() (PORTC &=~(1<<0))
    //#define scl_port_off() (DDRC|=(1<<0))
    
    #define sht_on() (DDRD|=(1<<7))
    #define sht_off() (DDRD&=~(1<<7))  
    #define sda_h() (DDRC&=~(1<<1))
    #define sda_l() (DDRC|=(1<<1))
    #define scl_h() (DDRC&=~(1<<0))
    #define scl_l() (DDRC|=(1<<0))
    //#define scl_l() (PORTC&=~(1<<0))
    //#define scl_h() (PORTC|=(1<<0))
    
    unsigned char sht_trans_start(void);
    unsigned char Init_Sht(void);
    unsigned char sht_reset(void);
    unsigned char sht_read_byte(void);
    unsigned char sht_write_byte(unsigned char value);
    unsigned char sht_measure(unsigned char mode,int *p_temperature, int *p_humidity);
    void sht_calculate(int *p_temperature, int *p_humidity);
    unsigned char sht_read_status(unsigned char *p_value);
    unsigned char sht_write_status(unsigned char value);
    unsigned char bitswapbyte(unsigned char byte);
    unsigned char sht_computeCRC8(unsigned char inData, unsigned char seed);
    unsigned char sht_soft_reset(void);
    #endif
    
    
    
    //----------------------------------------------------------------------------------
    //
    // Sensirion SHTxx Humidity Sensor Library
    //
    //----------------------------------------------------------------------------------
    
    #include "iom32.h"
    #include "config.h"
    #include "Sht.h"
    #include "timer.h"
    
    
    //#include "tgt.h"
    //#include "delay.h"
    
    const U8 __flash sht_crc_table[] = {
    	0, 49, 98, 83, 196, 245, 166, 151, 185, 136, 219, 234, 125, 76, 31, 46, 67, 114, 33, 16,
    	135, 182, 229, 212, 250, 203, 152, 169, 62, 15, 92, 109, 134, 183, 228, 213, 66, 115, 32, 17,
    	63, 14, 93, 108, 251, 202, 153, 168, 197, 244, 167, 150, 1, 48, 99, 82, 124, 77, 30, 47,
    	184, 137, 218, 235, 61, 12, 95, 110, 249, 200, 155, 170, 132, 181, 230, 215, 64, 113, 34, 19,
    	126, 79, 28, 45, 186, 139, 216, 233, 199, 246, 165, 148, 3, 50, 97, 80, 187, 138, 217, 232,
    	127, 78, 29, 44, 2, 51, 96, 81, 198, 247, 164, 149, 248, 201, 154, 171, 60, 13, 94, 111,
    	65, 112, 35, 18, 133, 180, 231, 214, 122, 75, 24, 41, 190, 143, 220, 237, 195, 242, 161, 144,
    	7, 54, 101, 84, 57, 8, 91, 106, 253, 204, 159, 174, 128, 177, 226, 211, 68, 117, 38, 23,
    	252, 205, 158, 175, 56, 9, 90, 107, 69, 116, 39, 22, 129, 176, 227, 210, 191, 142, 221, 236,
    	123, 74, 25, 40, 6, 55, 100, 85, 194, 243, 160, 145, 71, 118, 37, 20, 131, 178, 225, 208,
    	254, 207, 156, 173, 58, 11, 88, 105, 4, 53, 102, 87, 192, 241, 162, 147, 189, 140, 223, 238,
    	121, 72, 27, 42, 193, 240, 163, 146, 5, 52, 103, 86, 120, 73, 26, 43, 188, 141, 222, 239,
    	130, 179, 224, 209, 70, 119, 36, 21, 59, 10, 89, 104, 255, 206, 157, 172 };
    
    static U8 crcValue;
    unsigned char crc_state=0;
    
    //----------------------------------------------------------------------------------
    // Initialize AVR i/o pins. 
    //----------------------------------------------------------------------------------
    unsigned char Init_Sht(void)
    {
     
      sht_port_off();
      sda_port_off();
      scl_port_off();
      sht_off();
      scl_h(); 
      sda_h();
       sht_on();
       delay_us(100);
      if (bit_is_set(SHT_PIN,SHT_DATA)) 
      {
        if (bit_is_set(SHT_PIN,SHT_CLOCK)) 
        {
         return 0;
        }
      }
        sht_off();
        return 1;     
    }
    
    //----------------------------------------------------------------------------------
    // generates a transmission start
    //       _____         ________
    // DATA:      |_______|
    //           ___     ___
    // SCK : ___|   |___|   |______
    //
    //----------------------------------------------------------------------------------
    unsigned char sht_trans_start(void)
    {       
      unsigned char err=0;
      scl_l();  
      delay_us(SHT_DELAY);
      delay_us(SHT_DELAY);
      scl_h();	
      delay_us(SHT_DELAY);
      err = bit_is_clear(SHT_PIN, SHT_CLOCK);
      sda_l();
      delay_us(SHT_DELAY); 
      err += bit_is_set(SHT_PIN, SHT_DATA);   
      scl_l();
      delay_us(SHT_DELAY);
      delay_us(SHT_DELAY);
      scl_h();
      delay_us(SHT_DELAY);
      err += bit_is_clear(SHT_PIN, SHT_CLOCK);
      sda_h();
      delay_us(SHT_DELAY);
      scl_l();
      delay_us(SHT_DELAY);
      delay_us(SHT_DELAY);
      if(err){return 1;}
      else {return 0;}
    }
    
    //----------------------------------------------------------------------------------
    // communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
    //       _____________________________________________________         ________
    // DATA:                                                      |_______|
    //          _    _    _    _    _    _    _    _    _        ___     ___
    // SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
    //----------------------------------------------------------------------------------
    unsigned char sht_reset(void)
    {
      unsigned char i;
      sda_h();
      scl_l();
      delay_us(SHT_DELAY);
      delay_us(SHT_DELAY);
      for(i=0;i<10;i++) //9 SCK cycles
      {
              scl_h();
              delay_us(SHT_DELAY);
              delay_us(SHT_DELAY);
              scl_l();
              delay_us(SHT_DELAY);
              delay_us(SHT_DELAY);
      }
      return sht_trans_start(); //transmission start
    	
    }
    //----------------------------------------------------------------------------------
    // Soft reset
    //----------------------------------------------------------------------------------
    unsigned char sht_soft_reset(void)
    {
      U8 err=0;
      err=sht_reset();
      err+=sht_write_byte(RESET);
      return err;
    }
        
    
    //----------------------------------------------------------------------------------
    // reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
    //----------------------------------------------------------------------------------
    unsigned char sht_read_byte(void)
    {
      unsigned char i=0x80,val=0,f,f1=0;
      while(i)
      {
        scl_l();
        delay_us(SHT_DELAY);
        delay_us(SHT_DELAY);
        scl_h();
        delay_us(SHT_DELAY_POMIAR);
        for (f=0;f<7;f++)
        {
          if (bit_is_set(SHT_PIN, SHT_DATA))
          {
            f1++;
          }
        }
        if (f1>3)
        {
          val=(val | i); //read bit
        }
        f1=0;
        delay_us(SHT_DELAY-10);
        delay_us(SHT_DELAY);
        i=(i>>1);      
      }
      sda_l();
      scl_l();
      delay_us(SHT_DELAY);
      delay_us(SHT_DELAY);
      scl_h();
      delay_us(SHT_DELAY);
      delay_us(SHT_DELAY);
      sda_h();
      scl_l();        
      delay_us(SHT_DELAY);
      return val;
    }
    //----------------------------------------------------------------------------------
    // Writes a byte on the Sensibus and checks the acknowledge.
    // Returns 0 if the successful
    //----------------------------------------------------------------------------------
    unsigned char sht_write_byte(unsigned char value) //impuls narastajacy czyta
    {
      unsigned char i=0x80,f,f1=0;
      unsigned char err = 0;
    
      // Write each bit one at a time, LSB first
      delay_us(SHT_DELAY);
      while(i)
      { //shift bit for masking
        scl_l();
        if (i & value) {
          sda_h(); //masking value with i , write to SENSI-BUS
        }else{ 
          sda_l();
        }
        delay_us(SHT_DELAY);
        delay_us(SHT_DELAY);    
        scl_h(); //clk for SENSI-BUS
        delay_us(SHT_DELAY);
        delay_us(SHT_DELAY);
        i=(i>>1);
      }
      sda_h();
      scl_l();
      delay_us(SHT_DELAY);
      delay_us(SHT_DELAY);  
      scl_h();
      delay_us(5);
      f1=0;
      for (f=0;f<7;f++)
        {
          if (bit_is_set(SHT_PIN, SHT_DATA))
          {
            f1++;
          }
        }
        if (f1>2)
        {
           err=1;
        }
      
      delay_us(SHT_DELAY-10);	
      delay_us(SHT_DELAY);	
      scl_l();
      return err; //error=1 in case of no acknowledge
    }
    
    //----------------------------------------------------------------------------------
    // Read humidity or temperature from the sensor.
    // Returns the value in ticks. Use sht_calc() to convert to real world units.
    // Returns 0xFFFF if the measurment failed
    //----------------------------------------------------------------------------------
    unsigned char sht_measure(unsigned char mode,int *p_temperature, int *p_humidity)
    {
      unsigned int 	temp = 0xFFFF;
      unsigned char	checksum=0,err=0;
      unsigned char	c,f1=0;
      crcValue=0;
      crcValue=sht_crc_table[mode ^ crcValue];
      if(sht_trans_start()){return 1;}
      // Request measurement
      err=sht_write_byte(mode);
      if (err) {return 2;}
      // Sensor lowers the data line when measurement
      // is complete. Wait up to 2 seconds for this.
          delay_ms(50);
      for (c=0; c<250; c++)
      {
        if (! bit_is_set(SHT_PIN, SHT_DATA))
        {
          f1++;
          if (f1>3){break;}	                
        }
        delay_1ms();
        if (c==249){return 3;}
      }
      if (! bit_is_set(SHT_PIN, SHT_DATA))
      { 
        checksum = sht_read_byte();
        crcValue=sht_crc_table[checksum ^ crcValue];
        temp=checksum;
        temp = temp << 8;
        checksum=sht_read_byte();
        crcValue=sht_crc_table[checksum ^ crcValue];
        temp +=checksum;
        checksum=bitswapbyte(sht_read_byte());
      }
      if (checksum==crcValue)
      {
        if (mode==SHT_TEMPERATURE)
        {*p_temperature=temp;}
        else if (mode==SHT_HUMIDITY)
        { *p_humidity=temp;}
        return 0;
      }
      return 4;
    }
    
    //----------------------------------------------------------------------------------------
    // Calculates tempurature in ^C and humidity in %RH (temperature compensated)
    // sht_measure() returns temp and humidity in ticks. Use this function to convert
    // to compensated values in real world units.
    //
    // This function returns integers with 2 assumed decimal places. For example 2550
    // means 25.50. This is to avoid including the floating point math library.
    //
    // input :	humi [Ticks] (12 bit)
    // 			temp [Ticks] (14 bit)
    // output: 	humi [%RH] (2 fixed decimals)
    // 			temp [^C]  (2 fixed decimals)
    //----------------------------------------------------------------------------------------
    void sht_calculate(int *p_temperature, int *p_humidity)
    {
      const long D1x100 = -40.00 * 100;	// for 5V power
      const long D2x100 = 0.01 * 100;					// for 14bit temp
      const long C1x100 = -4 * 100;				// for 12bit humidity
      const long C2x10000 = 0.0405 * 10000;			// for 12bit humidity
      const long C3x10000000 = -0.0000028 * 10000000;	// for 12bit humidity
      const long T1x100000 = 0.01 * 100000;			// for 12bit humidity
      const long T2x100000 = 0.00008 * 100000;		// for 12bit humidity
    
      long t = *p_temperature;			// temperatere in ticks from sensor
      long rh = *p_humidity;				// humidity in ticks from sensor
    
      long t_C;							// temperature in celcius: 2 fixed decimals
      long rh_lin;						// relative humidity: 2 fixed decimals
      long rh_true;						// temp compensated humidity: 2 fixed decimals
    
      t_C = D1x100 + D2x100*t;			// calculate tempurature in celcius from ticks
    
      rh_lin = (C3x10000000*rh*rh)/100000 + (C2x10000*rh)/100 + C1x100;
      rh_true = ((t_C-(25*100)) * (T1x100000 + T2x100000*rh))/100000 + rh_lin;
    
      if(rh_true>10000){rh_true=10000;} 	//cut if the value is outside of
      if(rh_true<10){rh_true=10;} 			//the physical possible range
    
      *p_temperature=(int)t_C; 			//return temperature [^C]
      *p_humidity=(int)rh_true;	 		//return humidity[%RH]
    }
    
    //----------------------------------------------------------------------------------
    // Reads the status register with checksum (8-bit)
    //----------------------------------------------------------------------------------
    unsigned char sht_read_status(unsigned char *p_value)
    {
      unsigned char err=0;
      unsigned char checksum=0;
      sht_trans_start(); 			//transmission start
      err = sht_write_byte(STATUS_REG_R); 	//send command to sensor
      if (err) {return 1;} 
      *p_value = sht_read_byte();           //read status register (8-bit)
      crcValue=sht_crc_table[*p_value  ^ 151];
      checksum=bitswapbyte(sht_read_byte()); //read checksum (8-bit)
      if (checksum==crcValue)
      {return 0;}
      else
      {err+=2;}
      return err; 	//error=1 in case of no response form the sensor
      
    }
    
    
    //----------------------------------------------------------------------------------
    // Writes the status register . Note this library only supports the default
    // 14 bit temp and 12 bit humidity readings.
    //----------------------------------------------------------------------------------
    unsigned char sht_write_status(unsigned char value)
    {
    	unsigned char err=0;
    	sht_trans_start(); 					//transmission start
    	err += sht_write_byte(STATUS_REG_W);	//send command to sensor
    	err += sht_write_byte(value); 		//send value of status register
    	return err; 						//error>=1 in case of no response form the sensor
    }
    // Compute the CRC8 value of a data set.
    //
    //  This function will compute the CRC8 of inData using seed
    //  as inital value for the CRC.
    //
    //  This function was copied from Atmel avr318 example files.
    //  It is more suitable for microcontroller than the code example
    //  in the sensirion CRC application note.
    //
    //  inData  One byte of data to compute CRC from.
    //
    //  seed    The starting value of the CRC.
    //
    //  return The CRC8 of inData with seed as initial value.
    //
    //  note   Setting seed to 0 computes the crc8 of the inData.
    //
    //  note   Constantly passing the return value of this function 
    //         As the seed argument computes the CRC8 value of a
    //         longer string of data.
    //
    unsigned char sht_computeCRC8(unsigned char inData, unsigned char seed)
    {
      unsigned char bitsLeft;
      unsigned char tmp;
      for (bitsLeft = 8; bitsLeft > 0; bitsLeft--)
      {
        tmp = ((seed ^ inData) & 0x01);
        if (tmp == 0)
        {
          seed >>= 1;
        }else{
          seed ^= 0x18;
          seed >>= 1;
          seed |= 0x80;
        }
        inData >>= 1;
      }
      return seed;    
    }
    // sensirion has implemented the CRC the wrong way round. We
    // need to swap everything.
    // bit-swap a byte (bit7->bit0, bit6->bit1 ...)
    unsigned char bitswapbyte(unsigned char byte)
    {
      unsigned char i=8;
      unsigned char result=0;
      while(i){ 
        result=(result<<1);
        if (1 & byte) {
          result=result | 1;
        }
        i--;
        byte=(byte>>1);
      }	return(result);
    } 
    


    Korzystasz z tego w następujący sposób
    
        crcError=sht_measure(SHT_TEMPERATURE,&sht.temp_m,&sht.human_m);
        crcError=sht_measure(SHT_HUMIDITY,&sht.temp_m,&sht.human_m); 
        if (!crcError){
          sht_calculate(&sht.temp_m,&sht.human_m);
          sht_alarm=0;}
        else{
            delay_ms(250); //wyrównanie czasu w przypadku błędu
            sht_alarm=1;}
    


    Pozdrawiam
  • #7 8142177
    neko1985
    Poziom 2  
    tomhandyman napisał:
    Ten kod jest pod Atmegę 32 i z tym zegarem chodzi do działa do 50 metrów, próbkowanie sygnału jest kilkukrotne w pętli ze względu na niezawodność.
    [code]
    ........
    #ifndef __sht_h
    #define __sht_h
    #include "iom32.h...
    Pozdrawiam


    Helo

    I have a few questions about this tomhandyman entry
    with which compiler you have to do it? Which version
    I try to winavr 2010 throws me a lot of error with lib ...
    There you have any main () function to print results on the display connected to i2c

    Thanks for your reply

    Sasa
  • #8 8181746
    tomhandyman
    Poziom 13  
    Hi,
    I use IarAvr 5.30.
    For WinAvr you need add this file "Avr_compiler.h" to project.
    Example xmega programs from Atmel website have this.
    Sorry, I send this in main() function to serial port (modbus RTU).
    What kind display do you have?
    Let me know, if it working.
    Tom
REKLAMA