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

[mikroC PRO for AVR] [Atmega8] [DS18S20P] ciągłe 85 st.

Longos 01 Wrz 2010 19:49 2347 2
  • #1 8465428
    Longos
    Poziom 12  
    Moim problemem jest ciągły pomiar 85 st. Rezystor podciągający 4,7k jest, szyna zasilana i GND do masy, program z sampli mikroC (!). Fuse bity ustawione na wewnętrzny rezonator 8MHz. Procesor zmieniłem na Atmega8 o czym poinformowałem kompilator. Poniżej zamieszczam kod, może ktoś poprawi Mikronikę :)

    /*
     * Project name:
         OneWire (Interfacing the DS1820 temperature sensor - all versions)
     * Copyright:
         (c) Mikroelektronika, 2009.
     * Revision History:
         20080930:
           - initial release;
           - 20090818 - Slavisa Zlatanovic;
     * Description:
         This code demonstrates one-wire communication with temperature sensor
         DS18x20 connected to PB2 pin.
         MCU reads temperature from the sensor and prints it on the LCD.
         The display format of the temperature is 'xxx.xxxx°C'. To obtain correct
         results, the 18x20's temperature resolution has to be adjusted (constant
         TEMP_RESOLUTION).
     * Test configuration:
         MCU:             ATmega16
                          http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf
         Dev.Board:       EasyAVR6
                          http://www.mikroe.com/en/tools/easyavr6/
         Oscillator:      External Clock 8.0000 MHz
         Ext. Modules:    DS18x20, LCD 2x16
                          http://www.mikroe.com/en/tools/components/
         SW:              mikroC PRO for AVR
                          http://www.mikroe.com/en/compilers/mikroc/avr/
     * NOTES:
         - Place jumper J9 to the right(PB2).
         - Pull-up and turn off the LED on pin used for one wire bus (PB2) may be required.
    */
    
    // LCD module connections
    sbit LCD_RS at PORTD2_bit;
    sbit LCD_EN at PORTD3_bit;
    sbit LCD_D4 at PORTD4_bit;
    sbit LCD_D5 at PORTD5_bit;
    sbit LCD_D6 at PORTD6_bit;
    sbit LCD_D7 at PORTD7_bit;
    
    sbit LCD_RS_Direction at DDD2_bit;
    sbit LCD_EN_Direction at DDD3_bit;
    sbit LCD_D4_Direction at DDD4_bit;
    sbit LCD_D5_Direction at DDD5_bit;
    sbit LCD_D6_Direction at DDD6_bit;
    sbit LCD_D7_Direction at DDD7_bit;
    // End LCD module connections
    
    //  Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
    //  18S20: 9  (default setting; can be 9,10,11,or 12)
    //  18B20: 12
    
    const unsigned short TEMP_RESOLUTION = 9;
    
    char *text = "000.0000";
    unsigned temp;
    
    void Display_Temperature(unsigned int temp2write) {
      const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
      char temp_whole;
      unsigned int temp_fraction;
    
      // check if temperature is negative
      if (temp2write & 0x8000) {
        text[0] = '-';
        temp2write = ~temp2write + 1;
      }
    
      // extract temp_whole
      temp_whole = temp2write >> RES_SHIFT ;
    
      // convert temp_whole to characters
      if (temp_whole/100)
        text[0] = temp_whole/100  + 48;
      else
        text[0] = '0';
    
      text[1] = (temp_whole/10)%10 + 48;            // Extract tens digit
      text[2] =  temp_whole%10     + 48;            // Extract ones digit
    
      // extract temp_fraction and convert it to unsigned int
      temp_fraction  = temp2write << (4-RES_SHIFT);
      temp_fraction &= 0x000F;
      temp_fraction *= 625;
    
      // convert temp_fraction to characters
      text[4] =  temp_fraction/1000    + 48;        // Extract thousands digit
      text[5] = (temp_fraction/100)%10 + 48;        // Extract hundreds digit
      text[6] = (temp_fraction/10)%10  + 48;        // Extract tens digit
      text[7] =  temp_fraction%10      + 48;        // Extract ones digit
    
      // print temperature on LCD
      Lcd_Out(2, 5, text);
    }
    
    void main() {
    
      Lcd_Init();                                   // Initialize LCD
      Lcd_Cmd(_LCD_CLEAR);                          // Clear LCD
      Lcd_Cmd(_LCD_CURSOR_OFF);                     // Turn cursor off
      Lcd_Out(1, 1, " Temperature:   ");
      // Print degree character, 'C' for Centigrades
      Lcd_Chr(2,13,223);                            // Different LCD displays have different char code for degree
                                                    // If you see greek alpha letter try typing 178 instead of 223
    
      Lcd_Chr(2,14,'C');
    
      //--- main loop
      do {
        //--- perform temperature reading
        Ow_Reset(&PORTB, 2);                        // Onewire reset signal
        Ow_Write(&PORTB, 2, 0xCC);                  // Issue command SKIP_ROM
        Ow_Write(&PORTB, 2, 0x44);                  // Issue command CONVERT_T
        Delay_us(120);
    
        Ow_Reset(&PORTB, 2);
        Ow_Write(&PORTB, 2, 0xCC);                  // Issue command SKIP_ROM
        Ow_Write(&PORTB, 2, 0xBE);                  // Issue command READ_SCRATCHPAD
        Delay_ms(400);
    
        temp =  Ow_Read(&PORTB, 2);
        temp = (Ow_Read(&PORTB, 2) << 8) + temp;
    
        //--- Format and display result on Lcd
        Display_Temperature(temp);
    
        Delay_ms(500);
      } while (1);
    }
  • Pomocny post
    #2 8465805
    archanoid
    Poziom 26  
    Witam. Kolego kłania się dokumentacja DS-a . Po wysłaniu do DS-a komendy 44h czyli Convert T należy odczekać pewien określony czas zależny od rozdzielczości. Ty czekasz 120us a to stanowczo za mało. Dokumentacja strona 19 tabelka parametr tconv. I po grzyba czekasz 400ms po odczytaniu temperatury z DS-a.
  • #3 8466107
    Longos
    Poziom 12  
    Dokładnie tak, jak stwierdził archanoid. Wystarczyło zmienić opóźnienie po 0x44 z ms na us i wszystko śmiga. Dzięki !
REKLAMA