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

Atmega 8 termometr ds18b20 wyświetlacz hd44780 nie wyświetla pomiaru

Mlody_XX0 05 Wrz 2011 02:34 3972 11
REKLAMA
  • #1 9896221
    Mlody_XX0
    Poziom 11  
    Witam serdecznie.
    Borykam się z problemem, którego nie mogę przeskoczyć a mianowicie.
    W funkcji main mam następujący kod:
    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include <avr/eeprom.h>
    #include <stdlib.h>
    #include <util/delay.h>
    #include "hd44870.h"
    #include "ds18b20.h"
    //#include "MyDelay.h"
    
    int main(void)
    {
    
    volatile char tablica[20]="MMM";
    
    
    
    
        LCD_Clear();
    	LCD_Home();
    	LCD_Initalize();
    	LCD_WriteText("Rozpoczynam temp");
    	_delay_ms(1000);
    	TERMOMETR_RESET();
    
    for (;;) 
    {
    TERMOMETR_ODCZYTAJ_TEMPERATURE(tablica);
    
    
    LCD_Clear();
    LCD_GoTo(0,0);
    
    _delay_ms(200);
    LCD_GoTo(0,0);
    LCD_WriteText("czekam na temp");
    
    tablica[20]="MMM";
    LCD_WriteText(tablica);
    }
    
    
    
    }
    
    


    do odczytu temperatury służy funkcja:

    void TERMOMETR_ODCZYTAJ_TEMPERATURE(char * buffer)
    {
    //buffer length must be at least 12bytes long ["+xxx.xxxx C"]
    
    uint8_t temperature[2];
    int8_t digit;
    uint16_t decimal;
    
    //reset, skip rom and start temperature conversation
    TERMOMETR_RESET();
    TERMOMETR_ZAPISZ_BAJT("0xCC");
    TERMOMETR_ZAPISZ_BAJT("0x44");
    
    
    //wait until conversation is complete
    while(!TERMOMETR_ODCZYTAJ_BIT);
    
    TERMOMETR_RESET();
    TERMOMETR_ZAPISZ_BAJT("0xCC");
    TERMOMETR_ZAPISZ_BAJT("0xBE");
    
    //read scratchpad (only 2 first bytes)
    temperature[0]=TERMOMETR_ODCZYTAJ_BAJT();
    temperature[1]=TERMOMETR_ODCZYTAJ_BAJT();
    
    //store temperature integer digits and decimal digits
    digit=temperature[0]>>4;
    digit|=(temperature[1]&0x7)<<4;
    
    
    decimal =temperature[0]&0xF;
    decimal*=TERMOMETR_12BIT;
    
    
    //format temperature into a string[+XXX.XXXX C]
    
    sprintf(buffer,"%+d.%04u C",digit,decimal);
    
    
    
    }  


    funkcja służaca do wyświetlania znaków wygląda następująco:

    void LCD_WriteText(char * text)
    {
    while(*text)
      LCD_WriteData(*text++);
    }


    Problem jest taki, iż wyświetlacz wyświetla ładnie napis: Rozpoczynam temp.

    nt. potem, kiedy wywołuję funkcję do załadowania do przekazanej mu tablicy znaków (void TERMOMETR_ODCZYTAJ_TEMPERATURE(char * buffer)), a potem jeszcze testowo wpisałem do tablicy 3 litery M.
    Niestety na wyświetlaczu nie pokazuje się ani temperatura, ani napis z tablicy tzn. MMM.
    Nie wiem Panowie jak to można poprawić, aby działało jak należy i wyświetlało poprawnie.
    Pozdrawiam i miłego dnia życzę.
    Mam nadzieję, że ktoś z Panów wie co jest nie tak, i mógłby mi poradzić?
  • REKLAMA
  • #2 9896399
    Piotrek.pxf
    Poziom 27  
    Czy ten napis "Rozpoczynam temp" znika po tej sekundzie, czy wyświetla się cały czas?
  • REKLAMA
  • #4 9896814
    Mlody_XX0
    Poziom 11  
    Witam serdecznie i dziękuje za zainteresowanie tematem.

    Cytat:
    Czy ten napis "Rozpoczynam temp" znika po tej sekundzie, czy wyświetla się cały czas?


    Odpowiadam: Napis pali się cały czas

    Jak tylko wypije kawę sprawdzę kod Pana snnaap.
  • #5 9896843
    snnaap
    Poziom 25  
    Mlody_XX0 napisał:
    Witam serdecznie i dziękuje za zainteresowanie tematem.

    Cytat:
    Czy ten napis "Rozpoczynam temp" znika po tej sekundzie, czy wyświetla się cały czas?


    Odpowiadam: Napis pali się cały czas

    Jak tylko wypije kawę sprawdzę kod Pana snnaap.


    To znaczy tyle, że procek łapie zwiechę na TERMOMETR_RESET(); albo na
    TERMOMETR_ODCZYTAJ_TEMPERATURE(tablica); a najbardziej prawdopodobne jest to że nie wychodzi z while(!TERMOMETR_ODCZYTAJ_BIT);
    Pokaż co masz w ds18b20.h i ds18b20.c

    Podmień DS może ten który używasz jest walnięty (mając w załażeniu że procedury obsługi 1wire są prawidłowe).

    Gdzie masz określoną prędkość prędkość oscylatora F_CPU ?
  • REKLAMA
  • #6 9896887
    Mlody_XX0
    Poziom 11  
    Witam serdecznie chyba lepiej będzie jak zamieszczę cały kod do DS:

    ds18b20.c
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h> 
    #include "ds18b20.h"
    #include <stdio.h>
    #define PRZEBIEG_PETLI 8
    #define us(num) (num/(PRZEBIEG_PETLI*(1/(F_CPU/1000000.0))))
    
    inline  void therm_delay(uint16_t delay)
        {
        while(delay--) 
        {
        asm volatile("nop");}
        }
    
    uint8_t TERMOMETR_RESET()
        {
        uint8_t i;
        //pull the line low and wait for 480 us
        TERMOMETR_STAN_NISKI();
        TERMOMETR_TRYB_WYJSCIA();
        therm_delay(us(480));
    
        //release line and wait for 60 us
        TERMOMETR_TRYB_WEJSCIA();
        therm_delay(us(60));
    
        //store line value and wait until the completion
        //and wait until the completion of period 
        i=(TERMOMETR_PIN & (1<<TERMOMETR_P));
        therm_delay(us(420));
    
        //return value read from presence pulse( 0=ok,1=wrong)
        return i;
    
        } //TERMOMETR RESET
    
    void TERMOMETR_ZAPISZ_BIT(uint8_t bit)
        {
        //pull the line low for 1us
        TERMOMETR_STAN_NISKI();
        TERMOMETR_TRYB_WYJSCIA();
        therm_delay(us(1));
    
    
        //if we want to write 1, release the line (if not will keep low)
        if (bit)
        {
        TERMOMETR_TRYB_WYJSCIA();
        }
    
    
        //wait for 60 us and relase the line
        therm_delay(us(60));
        TERMOMETR_TRYB_WYJSCIA();
    
        } //TERMOMETR_ZAPISZ_BIT
    
    uint8_t TERMOMETR_ODCZYTAJ_BIT()
        {
        uint8_t bit=0;
    
    
        //pull the line low for 1us
        TERMOMETR_STAN_NISKI();
        TERMOMETR_TRYB_WYJSCIA();
        therm_delay(us(1));
    
        //release line and wait for 14 us
        TERMOMETR_TRYB_WEJSCIA();
        therm_delay(us(14));
    
        //read line value 
        if(TERMOMETR_PIN &(1<<TERMOMETR_P))
        bit=1;
    
        //wait for 45 us to end and return read value
        therm_delay(us(45));
    
        return bit;
    
    
        } //TERMOMETR_ODCZYTAJ_BIT()
    
    
    uint8_t TERMOMETR_ODCZYTAJ_BAJT()
        {
        uint8_t i=8,n=0;
    
        while(i--)
        {
        n>>=1;
        n|=(TERMOMETR_ODCZYTAJ_BAJT()<<7);
        }
    
        return n;
        } //TERMOMETR_ODCZYTAJ_BAJT()
    
        void TERMOMETR_ZAPISZ_BAJT(uint8_t byte)
        {
        uint8_t i=8;
        while(i--)
        {
        TERMOMETR_ZAPISZ_BIT(byte&1);
        byte>>=1;
        }
    
        } //TERMOMETR_ZAPISZ_BAJT(uint8_t byte)
    
    
    void TERMOMETR_ODCZYTAJ_TEMPERATURE(char * buffer)
        {
        //buffer length must be at least 12bytes long ["+xxx.xxxx C"]
    
        uint8_t temperature[2];
        int8_t digit;
        uint16_t decimal;
    
        //reset, skip rom and start temperature conversation
        TERMOMETR_RESET();
        TERMOMETR_ZAPISZ_BAJT("0xCC");
        TERMOMETR_ZAPISZ_BAJT("0x44");
    
    
        //wait until conversation is complete
        while(!TERMOMETR_ODCZYTAJ_BIT);
    
        TERMOMETR_RESET();
        TERMOMETR_ZAPISZ_BAJT("0xCC");
        TERMOMETR_ZAPISZ_BAJT("0xBE");
    
        //read scratchpad (only 2 first bytes)
        temperature[0]=TERMOMETR_ODCZYTAJ_BAJT();
        temperature[1]=TERMOMETR_ODCZYTAJ_BAJT();
    
        //store temperature integer digits and decimal digits
        digit=temperature[0]>>4;
        digit|=(temperature[1]&0x7)<<4;
    
    
        decimal =temperature[0]&0xF;
        decimal*=TERMOMETR_12BIT;
    
    
        //format temperature into a string[+XXX.XXXX C]
    
        sprintf(buffer,"%+d.%04u C",digit,decimal);
    
    
    
        }  //TERMOMETR_ODCZYTAJ_TEMPERATURE(char * buffer)
    


    Na płytce jest kwarc 8MHZ . Częstotliwość ustawiam w AVR Studio w opcjach projektu: Częstotliwość 8000000 no i typ mikroprocesora Atmega8.

    Nie posiadam na stanie innego DS. Mam nadzieję że DS jest dobry, a wina jest w kodzie.
  • #7 9896902
    gaskoin
    Poziom 38  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Masz + za to że sam podjąłeś się napisania tego, ale timingi w sposób jaki masz zrealizowane nie mają szansy działać zbyt dobrze. Twoja funkcja która wkleiłem teoretycznie trwa na zawsze w praktyce stos się w pewnym momencie wyrzyguje i najprawdopodobniej następuje reset. Kodu jakoś szczególnie nie analizowałem bo w postaci jaką ją wkleiłeś bardzo źle się go czyta (zero wcięć).

    Fuse'y też ustawiłeś czy tylko ustawiłeś prędkość w makefilu ?
  • REKLAMA
  • #8 9896936
    Mlody_XX0
    Poziom 11  
    Poprawiłem Panie gaskoin wcięcia. Fusebitów nie zmieniałem.
  • #9 9896974
    gaskoin
    Poziom 38  
    Skoro ich nie zmieniałeś to procesor śmiga na 1MHz a nie na 8
  • #10 9897676
    Mlody_XX0
    Poziom 11  
    Zmieniłem fusebity na 8 - 16Mhz w Burn o mat. Coś jest nie tak z funkcją RESET_TERMOMETR ponieważ zaraz za nią postawiłem wyświetlanie napisu, to już nie wyświetla.
  • #11 9897806
    gaskoin
    Poziom 38  
    Skąd wiesz, że Twoje opóźnienia są dobre ? sprawdzałeś to jakoś ? Czemu nie używasz funkcji avrlibc ?

    Nie wiem czym jest stan niski, tryb wejscia i wyjscia? mogę się domyślać co to za cuda ale to tylko domysły.

    Kod dalej masakra a nie sformatowany. No i jak to jest ? Piszesz, że nie zmieniałeś fusebitów a tu nagle, że je zmieniałeś? :D

    A to co wysypuje cały ten kod to na pewno czytanie bajtów, złe timingi i pewnie jeszcze coś po drodze.
REKLAMA