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

[Atmega8][C] Wyświetlanie zmiennych na LCD

whitee 10 Wrz 2010 11:41 6487 36
  • #1 8495558
    whitee
    Poziom 10  
    Witam,

    Mam pewien problem z oprogramowaniem mikrokontrolera Atmega8. Otóż:
    Chcę zrobić menu składające się z 4 ekranów. Przewijanie ekranu odbywa się z wykorzystaniem dwóch przycisków > góra <dół.
    Podczas wyświetlenia ekranów chciałbym aby na wyświetlaczu LCD pojawiały się aktualne nastawy (wartości zmiennych). Cały problem tkwi w konwersji zmiennych liczbowych double, bądź int na łańcuch znaków char. Przy kompilacji nie pojawiają się żadne problemy, natomiast podczas pojawienia się ekranu na którym ma zostać wyświetlona wartość zmiennej oprócz rzeczywistej wartości pojawia się ciąg ok 4 cyfr, bądź czasem znaków (np. @) i program jakby się zawieszał - nie ma możliwości przejścia do następnego ekranu. Sytuacja ta jest taka sama dla wszystkich zmiennych. Dodam tylko, że wykorzystuję plik nagłówkowy obsługi ekranu HD44780.h.
    Poniżej zamieszczam kod (bez procedur inicjalizacji wyświetlacza)
    
    #ifndef F_CPU
    #define F_CPU 1000000UL
    #endif 
    
    volatile int i=0;
    double T_MAX=15;
    double CZAS_POD_ON=20;
    double CZAS_POD_OFF=20;
    double CZAS_CZEK_ON=20;
    double CZAS_CZEK_OFF=20;
    
    unsigned char na_tekst(double liczba)
    {
    char bufor;
    dtostrf(liczba, 5,4,bufor);
    return bufor;
    }
    
    void ekran_menu(int j)
    {
    
    
    switch (j)
    {
    case 0:
    {
    LCD_Clear();
    LCD_WriteText("Temp. MAX.");
    LCD_GoTo(0,1);
    LCD_WriteText(na_tekst(T_MAX));
    break;
    }
    
    case 1:
    {
    LCD_Clear();
    LCD_WriteText("Czas POD ON:");
    LCD_GoTo(0,1);
    LCD_WriteText(na_tekst(CZAS_POD_ON));
    break;
    }
    
    case 2:
    {
    LCD_Clear();
    LCD_WriteText("Czas CZEK ON:");
    LCD_GoTo(0,1);
    LCD_WriteText("Wartosc:3");
    break;
    }
    
    case 3:
    {
    LCD_Clear();
    LCD_WriteText("Czas POD OFF:");
    LCD_GoTo(0,1);
    LCD_WriteText("Wartosc:4");
    break;
    }
    
    case 4:
    {
    LCD_Clear();
    LCD_WriteText("Czas CZEK OFF:");
    LCD_GoTo(0,1);
    LCD_WriteText("Wartosc:5");
    break;
    }
    
    }
    
    }
    
    
    
    
    int main(void)
    {
    
    DDRC=0x30;
    PORTC=0xff;
    
    LCD_Initalize();
    
    ekran_menu(0);
    
    while (1)
    {
    
    	// PRZYCISK NR 1 ====================================================OBSŁUGA MENU===================
    	if(bit_is_clear(PINC,0))
    	{
     		_delay_ms(10);
       		if(bit_is_clear(PINC,0))
    			{
     
    			}
    	}	
    
    //=========================================== GORA DOL
     // PRZYCISK NR 2
    	if(bit_is_clear(PINC,1))
    	{
     		_delay_ms(10);
       		if(bit_is_clear(PINC,1))
    			{
    			while (bit_is_clear(PINC,1))
    			{
    			}
    			if (i<5)
    				{
    				i++;
    				ekran_menu(i);
    				}
    			else
    				{
    				i=0;
    				ekran_menu(i);
    				}
    			}
    	}
    
    // PRZYCISK NR 3
    	if(bit_is_clear(PINC,2))
    	{
    	 	_delay_ms(10);
      		if(bit_is_clear(PINC,2))
    			{
    			while (bit_is_clear(PINC,2))
    			{
    			}
    			if (i>0)
    				{	
    				i--;
    				ekran_menu(i);
    				}
    			else
    				{
    				i=4;
    				ekran_menu(i);
    				}
    			}
    	}
    //================================================
    
     
    
    // PRZYCISK NR 4
    	if(bit_is_clear(PINC,3))
    	{
     		_delay_ms(10);
       		if(bit_is_clear(PINC,3))
    			{
    	
    			}
    	}
    
    //================================================================KONIEC MENU=======================
    
    
    }
    
    
    
    
    }
    


    Będę wdzięczny również za inne spostrzeżenia.
    Pozdrawiam.
  • #3 8495573
    whitee
    Poziom 10  
    ha... i jak jedno zdanie potrafi pomóc.
    Dzięki wielkie za pomoc.. rzeczywiście w tym tkwił problem. Jestem dopiero początkującym wiec...

    Pozdrawiam i jeszcze raz thx
  • #5 8497455
    whitee
    Poziom 10  
    Zgodnie z uwagą zmienną bufor należy zadeklarować nie wewnątrz funkcji na_tekst, tylko globalnie.
    Reszta kodu działa poprawnie.
    #ifndef F_CPU 
    #define F_CPU 1000000UL 
    #endif 
    
    volatile int i=0; 
    double T_MAX=15; 
    double CZAS_POD_ON=20; 
    double CZAS_POD_OFF=20; 
    double CZAS_CZEK_ON=20; 
    double CZAS_CZEK_OFF=20; 
    char bufor; 
    
    unsigned char na_tekst(double liczba) 
    { 
    dtostrf(liczba, 5,4,bufor); 
    return bufor; 
    } 
    
    void ekran_menu(int j) 
    { 
    
    
    switch (j) 
    { 
    case 0: 
    { 
    LCD_Clear(); 
    LCD_WriteText("Temp. MAX."); 
    LCD_GoTo(0,1); 
    LCD_WriteText(na_tekst(T_MAX)); 
    break; 
    } 
    
    case 1: 
    { 
    LCD_Clear(); 
    LCD_WriteText("Czas POD ON:"); 
    LCD_GoTo(0,1); 
    LCD_WriteText(na_tekst(CZAS_POD_ON)); 
    break; 
    } 
    
    case 2: 
    { 
    LCD_Clear(); 
    LCD_WriteText("Czas CZEK ON:"); 
    LCD_GoTo(0,1); 
    LCD_WriteText("Wartosc:3"); 
    break; 
    } 
    
    case 3: 
    { 
    LCD_Clear(); 
    LCD_WriteText("Czas POD OFF:"); 
    LCD_GoTo(0,1); 
    LCD_WriteText("Wartosc:4"); 
    break; 
    } 
    
    case 4: 
    { 
    LCD_Clear(); 
    LCD_WriteText("Czas CZEK OFF:"); 
    LCD_GoTo(0,1); 
    LCD_WriteText("Wartosc:5"); 
    break; 
    } 
    
    } 
    
    } 
    
    
    
    
    int main(void) 
    { 
    
    DDRC=0x30; 
    PORTC=0xff; 
    
    LCD_Initalize(); 
    
    ekran_menu(0); 
    
    while (1) 
    { 
    
       // PRZYCISK NR 1 ====================================================OBSŁUGA MENU=================== 
       if(bit_is_clear(PINC,0)) 
       { 
           _delay_ms(10); 
             if(bit_is_clear(PINC,0)) 
             { 
      
             } 
       }    
    
    //=========================================== GORA DOL 
     // PRZYCISK NR 2 
       if(bit_is_clear(PINC,1)) 
       { 
           _delay_ms(10); 
             if(bit_is_clear(PINC,1)) 
             { 
             while (bit_is_clear(PINC,1)) 
             { 
             } 
             if (i<5) 
                { 
                i++; 
                ekran_menu(i); 
                } 
             else 
                { 
                i=0; 
                ekran_menu(i); 
                } 
             } 
       } 
    
    // PRZYCISK NR 3 
       if(bit_is_clear(PINC,2)) 
       { 
           _delay_ms(10); 
            if(bit_is_clear(PINC,2)) 
             { 
             while (bit_is_clear(PINC,2)) 
             { 
             } 
             if (i>0) 
                {    
                i--; 
                ekran_menu(i); 
                } 
             else 
                { 
                i=4; 
                ekran_menu(i); 
                } 
             } 
       } 
    //================================================ 
    
      
    
    // PRZYCISK NR 4 
       if(bit_is_clear(PINC,3)) 
       { 
           _delay_ms(10); 
             if(bit_is_clear(PINC,3)) 
             { 
        
             } 
       } 
    
    //================================================================KONIEC MENU======================= 
    
    
    } 
    
    
    
    
    }
  • #6 8497541
    tmf
    VIP Zasłużony dla elektroda
    To ciągle jest źle, bufor jest typu char, czyli ma pojemność jednego bajta. dtostr generuje ciągi o długości kilku bajtów. Czyli nadpisujesz okoliczne obszary pamięci.
  • #7 8499020
    gaskoin
    Poziom 38  
    Kompilator zapewne Cię o tym informuje, ale po co czytać jakieś głupie komunikaty :)
  • #8 8499271
    l3sz3k
    Poziom 18  
    gaskoin napisał:
    Kompilator zapewne Cię o tym informuje, ale po co czytać jakieś głupie komunikaty :)

    Nie tak ostro, kolega się dopiero uczy.
    Może jeszcze nie wie co to tablica.

    ps. daj zamiast char bufor;
    #define ROZMIAR 10
    char bufor[ROZMIAR];
  • #9 8499800
    kubus_puchatek
    Poziom 18  
    zrób taką kombinacyję:
    char buf_wy[10];

    void funkcja_konwertujaca (char *buf_z_danymi_wy, double dana_wejsciowa);

    wywołanie: funkcja_konwertujaca (&buf_wy,moja_zmienna_double);

    i w buf_wy zwrócisz sobie ładnie wynik konwersji........
  • #11 8567550
    whitee
    Poziom 10  
    wiem co to tablica, ale szczerze mówiąc nie przyszło mi to do głowy że zadeklarowanie zbyt małego rozmiaru może być problemem.

    To fakt, dopiero zaczynam i jestem wdzięczny za wskazówki i informacje.
    Właśnie kompilator nie wyrzuca żadnych ostrzeżeń i informacji.

    Za chwilę trochę jeszcze popracuje i wstawię poprawny kod.
  • #12 8567569
    nsvinc
    Poziom 35  
    Dalej boli jak ktoś pisze coś w rodzaju &buf_wy. Moze to działa (już kiedyś była duuuza dyskusja na ten temat) ale to niezgodne ze sztuką. Sam buf_wy jest już wskaznikiem, więc nieeleganckie jest przerabianie wskaznika na wskaznik gdy nie ma takiej koniecznosci - nawet jesli w efekcie otrzymamy ten sam adres...
    Sens i finezje miałby zapis &buf_wy[0], ale...po co?
  • #13 8584226
    kubus_puchatek
    Poziom 18  
    sorki zamiast funkcja_konwertujaca (&buf_wy,moja_zmienna_double);
    miało być w wywołaniu: funkcja_konwertujaca (&buf_wy[0],moja_zmienna_double); (bo niektóre kompilatory nie wiedzieć czemu mają problem z przekazaniem adresu jak się podaje nazwę tablicy jako wskaźnik w parametrze i nie tylko)
  • #14 8584569
    tmf
    VIP Zasłużony dla elektroda
    znaczy które kompilatory? Warto by było wtedy twórcom wysłać raport o błędzie. Z drugiej strony jakoś mi się nie chce wierzyć, że jakiś kompilator nie radzi sobie z tak podstawową składnią.
  • #15 8585889
    whitee
    Poziom 10  
    Przyznam szczerze że mam problem z ogarnięciem tych rozmiarów danych zwracanych itd.. i nie bardzo wiem jak zmienić to wszystko tak, jak powinno być.
    Generalnie znowu mam problem. Na wyświetlaczu chce wyświetlić temperaturę z termometru DS18B20 - magistrala 1-wire zasilany zewnętrznie. Po dodaniu kodu odpowiadającego za obsługę tego termometru wyświetlacz działa nie poprawnie - tzn wyświetla jakieś bzdury.
    Tak to wygląda:
    [Atmega8][C] Wyświetlanie zmiennych na LCD

    Edit: Zmieniłem funkcję pobierającą temperaturę tak, że teraz zwraca temperaturę w formacie double. I tu znowu mam problem, ponieważ przy takiej zmianie nie działa poprawnie funkcja konwertująca na_tekst();


    A poniżej Kod:

    #include <stdlib.h>
    #include <stdio.h>
    #include <avr/io.h>
    #include <util/delay.h>
    #include <HD44780_v2.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    
    
    #ifndef F_CPU
    #define F_CPU 1000000UL
    #endif 
    
    //-------------------------------------------------------------------------------------------------
    // Wyświetlacz alfanumeryczny ze sterownikiem HD44780
    // Sterowanie w trybie 8-bitowym z odczytem flagi zajętości
    // Plik : HD44780.c    
    // Mikrokontroler : Atmel AVR
    // Kompilator : avr-gcc
    // Autor : Radosław Kwiecień
    // Źródło : http://radzio.dxp.pl/hd44780/
    // Data : 24.03.2007
    //-------------------------------------------------------------------------------------------------
    
    
    
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja zapisu bajtu do wyświetacza (bez rozróżnienia instrukcja/dane).
    //
    //-------------------------------------------------------------------------------------------------
    void _LCD_Write(unsigned char dataToWrite)
    {
    LCD_DATA_DIR = 0xFF;
    
    LCD_RW_PORT &= ~_BV(LCD_RW);
    LCD_E_PORT |= _BV(LCD_E);
    LCD_DATA_PORT = dataToWrite;
    LCD_E_PORT &= ~_BV(LCD_E);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja odczytu bajtu z wyświetacza (bez rozróżnienia instrukcja/dane).
    //
    //-------------------------------------------------------------------------------------------------
    
    unsigned char _LCD_Read(void)
    {
    unsigned char tmp = 0;
    
    LCD_DATA_DIR = 0x00;
    
    LCD_RW_PORT |= _BV(LCD_RW);
    LCD_E_PORT |= _BV(LCD_E);
    asm("nop");
    tmp = LCD_DATA_PIN;
    LCD_E_PORT &= ~_BV(LCD_E);
    return tmp;
    }
    
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja zapisu rozkazu do wyświetlacza
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_WriteCommand(unsigned char commandToWrite)
    {
    LCD_RS_PORT &= ~_BV(LCD_RS);
    _LCD_Write(commandToWrite);
    while(LCD_ReadStatus()&0x80);
    }
    
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja odczytu bajtu statusowego
    //
    //-------------------------------------------------------------------------------------------------
    unsigned char LCD_ReadStatus(void)
    {
    LCD_RS_PORT &= ~_BV(LCD_RS);
    return _LCD_Read();
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja zapisu danych do pamięci wyświetlacza
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_WriteData(unsigned char dataToWrite)
    {
    LCD_RS_PORT |= _BV(LCD_RS);
    _LCD_Write(dataToWrite);
    while(LCD_ReadStatus()&0x80);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja odczytu danych z pamięci wyświetlacza
    //
    //-------------------------------------------------------------------------------------------------
    unsigned char LCD_ReadData(void)
    {
    LCD_RS_PORT |= _BV(LCD_RS);
    return _LCD_Read();
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja wyświetlenia napisu na wyswietlaczu.
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_WriteText(char * text)
    {
    while(*text)
      LCD_WriteData(*text++);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja ustawienia współrzędnych ekranowych
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_GoTo(unsigned char x, unsigned char y)
    {
    LCD_WriteCommand(HD44780_DDRAM_SET | (x + (0x40 * y)));
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja czyszczenia ekranu wyświetlacza.
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_Clear(void)
    {
    LCD_WriteCommand(HD44780_CLEAR);
    _delay_ms(2);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja przywrócenia początkowych współrzędnych wyświetlacza.
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_Home(void)
    {
    LCD_WriteCommand(HD44780_HOME);
    _delay_ms(2);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Procedura inicjalizacji kontrolera HD44780.
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_Initalize(void)
    {
    unsigned char i;
    LCD_DATA_DIR = 0xFF;
    LCD_E_DIR     |= _BV(LCD_E);   //
    LCD_RS_DIR     |= _BV(LCD_RS);  //
    LCD_RW_DIR    |= _BV(LCD_RW);
    _delay_ms(15); // oczekiwanie na ustalibizowanie się napiecia zasilajacego
    LCD_RS_PORT &= ~_BV(LCD_RS); // wyzerowanie linii RS
    LCD_E_PORT &= ~_BV(LCD_E);  // wyzerowanie linii E
    LCD_RW_PORT  &= ~_BV(LCD_RW);
    
    for(i = 0; i < 3; i++) // trzykrotne powtórzenie bloku instrukcji
      {
      LCD_E_PORT |= _BV(LCD_E);
      LCD_DATA_PORT = 0x3F;
      LCD_E_PORT &= ~_BV(LCD_E);
      _delay_ms(5); // czekaj 5ms
      }
    
    LCD_WriteCommand(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE | HD44780_8_BIT); // interfejs 4-bity, 2-linie, znak 5x7
    LCD_WriteCommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_OFF); // wyłączenie wyswietlacza
    LCD_WriteCommand(HD44780_CLEAR); // czyszczenie zawartosći pamieci DDRAM
    LCD_WriteCommand(HD44780_ENTRY_MODE | HD44780_EM_SHIFT_CURSOR | HD44780_EM_INCREMENT);// inkrementaja adresu i przesuwanie kursora
    LCD_WriteCommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_ON | HD44780_CURSOR_OFF | HD44780_CURSOR_NOBLINK); // włącz LCD, bez kursora i mrugania
    }
    
    //-------------------------------------------------------------------------------------------------
    //
    // Koniec pliku HD44780.c
    //
    //-------------------------------------------------------------------------------------------------
    
    char *bufor[10];
    char *t_tmax="Temp. MAX.";
    char *t_c=" [C]";
    char *t_czas_podon="Czas POD ON:";
    char *t_sek=" [s]";
    char *t_czas_czekon="Czas CZEK ON:";
    char *t_czas_podoff="Czas POD OFF:";
    char *t_czas_czekoff="Czas CZEK OFF:";
    
    
    
    volatile int i=0;
     float T_MAX=15;
     float T_CURR=80;
     float CZAS_POD_ON=20;
     float CZAS_POD_OFF=20;
     float CZAS_CZEK_ON=20;
     float CZAS_CZEK_OFF=20;
    
    //============================ teksty menu
    
    
    
    
    int tryb;
    int program=0;
    
    char na_tekst(float liczba)
    {
    dtostrf(liczba,4,1,bufor);
    return bufor;
    }
    
    
    void ekran_menu(int j)
    {
    
    
    switch (j)
    {
    case 0:
    {
    LCD_Clear();
    LCD_WriteText(t_tmax);
    LCD_GoTo(0,1);
    LCD_WriteText(na_tekst(T_MAX));
    LCD_WriteText(t_c);
    break;
    }
    
    case 1:
    {
    LCD_Clear();
    LCD_WriteText(t_czas_podon);
    LCD_GoTo(0,1);
    LCD_WriteText(na_tekst(CZAS_POD_ON));
    LCD_WriteText(t_sek);
    break;
    }
    
    case 2:
    {
    LCD_Clear();
    LCD_WriteText(t_czas_czekon);
    LCD_GoTo(0,1);
    LCD_WriteText(na_tekst(CZAS_CZEK_ON));
    LCD_WriteText(t_sek);
    break;
    }
    
    case 3:
    {
    LCD_Clear();
    LCD_WriteText(t_czas_podoff);
    LCD_GoTo(0,1);
    LCD_WriteText(na_tekst(CZAS_POD_OFF));
    LCD_WriteText(t_sek);
    break;
    }
    
    case 4:
    {
    LCD_Clear();
    LCD_WriteText(t_czas_czekoff);
    LCD_GoTo(0,1);
    LCD_WriteText(na_tekst(CZAS_CZEK_OFF));
    LCD_WriteText(t_sek);
    break;
    }
    
    }
    
    }
    
    void wlacz_podajnik (void)
    {
    }
    void wylacz_podajnik (void)
    {
    }
    void wlacz_went (void)
    {
    }
    void wylacz_went (void)
    {
    }
    
    //====================================================================================================
    #define WE 7
    #define port_temp PINB
    #define ustaw_linia_temp DDRB &=~_BV(WE)
    #define czysc_linia_temp DDRB |=_BV(WE)
    float temp;
    // =====================================================================OBSŁUGA TERMOMETR=============
    unsigned char RESET_PL (void)
    {
        unsigned char PRESENCE;
        czysc_linia_temp;
        _delay_us(500);
        ustaw_linia_temp;
        _delay_us(30);
        if(bit_is_clear(port_temp, WE)) {PRESENCE=1;} else {PRESENCE=0;}
        if(bit_is_set(port_temp, WE)) {PRESENCE=1;} else {PRESENCE=0;}
        return PRESENCE;
    
    }
    
    void send_t(char bit)
    {
        czysc_linia_temp;
        _delay_us(5);
            if (bit==1) ustaw_linia_temp;
            _delay_us(80);
            ustaw_linia_temp;
    
    }
    
    unsigned char read_t(void)
    {
        unsigned char PRESENCE;
        czysc_linia_temp;
        _delay_us(2);
        ustaw_linia_temp;
        _delay_us(15);
            if (bit_is_set(port_temp, WE)) {PRESENCE=1;} else {PRESENCE=0;}
        return PRESENCE;
    }
    
    void slij_bajt(char wartosc)
    {
        unsigned char i;
        unsigned char pom;
        for (i=0;i<8;i++)
            {
            pom=wartosc>>i;
            pom &=0x01;
            send_t(pom);
            }
    
        _delay_us(100);
    }
    
    unsigned char czytaj_bajt(void)
    {
        unsigned char i;
        unsigned char odczyt;
        for (i=0;i<8;i++)
            {
            if (read_t()) odczyt|=0x01<<i;
            _delay_us(15);
            }
        return odczyt;
    }
    
    
    
    float temperatura (void)
    {
    char temp1;
    char temp2;
    
    
    unsigned char sprawdz=RESET_PL();
     if (sprawdz==1)
         {
        slij_bajt(0xCC);
        slij_bajt(0x44);
        sprawdz=RESET_PL();
        slij_bajt(0xCC);
        slij_bajt(0xBE);
        temp1=czytaj_bajt();
        temp2=czytaj_bajt();
        sprawdz=RESET_PL();
        temp=(float)(temp1+(temp2*256))/16;
        }
    return temp;
    }
    
    
    
    void ekran_idle (void)
    {
        if (tryb==0)
        {
        LCD_Clear();
        LCD_WriteText("TRYB_ON");
        }
        else
        {
        LCD_Clear();
        LCD_WriteText("TRYB_OFF");
        }
    LCD_GoTo(0,1);
    LCD_WriteText("");
    LCD_WriteText("/");
    LCD_WriteText(na_tekst(T_MAX));
    LCD_WriteText(" [C]");
    }
    
    
    int main(void)
    {
    
    DDRC=0x30;
    PORTC=0xff;
    
    LCD_Initalize();
    
    ekran_idle();
    
    while (1)
    {
    
        // PRZYCISK NR 1 ====================================================OBSŁUGA MENU===================
        if(bit_is_clear(PINC,0))
        {
             _delay_ms(10);
               if(bit_is_clear(PINC,0))
                {
     
                }
        }    
    
    
    if (program!=1)
    {
    
    //=========================================== GORA DOL
     // PRZYCISK NR 2
        if(bit_is_clear(PINC,1))
        {
             _delay_ms(10);
               if(bit_is_clear(PINC,1))
                {
                while (bit_is_clear(PINC,1))
                {
                }
                if (i<5)
                    {
                    i++;
                    ekran_menu(i);
                    }
                else
                    {
                    i=0;
                    ekran_menu(i);
                    }
                }
        }
    
    
    
    // PRZYCISK NR 3
        if(bit_is_clear(PINC,2))
        {
             _delay_ms(10);
              if(bit_is_clear(PINC,2))
                {
                while (bit_is_clear(PINC,2))
                {
                }
                if (i>0)
                    {    
                    i--;
                    ekran_menu(i);
                    }
                else
                    {
                    i=4;
                    ekran_menu(i);
                    }
                }
        }
    //================================================
    
    }
    else
    // =================================================== tryb programowania - ustawienie parametrów
    {
    
     // PRZYCISK NR 2
        if(bit_is_clear(PINC,1))
        {
             _delay_ms(10);
               if(bit_is_clear(PINC,1))
                {
                while (bit_is_clear(PINC,1))
                {
                }
                switch (i)
                {
                case 0:
                {
                T_MAX=T_MAX+5;
                break;
                }
                case 1:
                {
                CZAS_POD_ON=CZAS_POD_ON+5;
                break;
                }
                case 2:
                {
                CZAS_CZEK_ON=CZAS_CZEK_ON+5;
                break;
                }
                case 3:
                {
                CZAS_POD_OFF=CZAS_POD_OFF+5;
                break;
                }
                case 4:
                {
                CZAS_CZEK_OFF=CZAS_CZEK_OFF+5;
                break;
                }
                }
                ekran_menu(i);
                LCD_GoTo(13,1);
                LCD_WriteText("[P]");
                            
                }
        }
    
    
    
    // PRZYCISK NR 3
        if(bit_is_clear(PINC,2))
        {
             _delay_ms(10);
              if(bit_is_clear(PINC,2))
                {
                while (bit_is_clear(PINC,2))
                {
                }
                    switch (i)
                {
                case 0:
                {
                T_MAX=T_MAX-5;
                break;
                }
                case 1:
                {
                CZAS_POD_ON=CZAS_POD_ON-5;
                break;
                }
                case 2:
                {
                CZAS_CZEK_ON=CZAS_CZEK_ON-5;
                break;
                }
                case 3:
                {
                CZAS_POD_OFF=CZAS_POD_OFF-5;
                break;
                }
                case 4:
                {
                CZAS_CZEK_OFF=CZAS_CZEK_OFF-5;
                break;
                }
                }
                ekran_menu(i);
                LCD_GoTo(13,1);
                LCD_WriteText("[P]");
                }
        }
    
    
    }
    
    // PRZYCISK NR 4 - włączenie trybu programowania
        if(bit_is_clear(PINC,3))
        {
             _delay_ms(10);
               if(bit_is_clear(PINC,3))
                {
                while (bit_is_clear(PINC,3))
                {
                }
                if (program !=1)
                {
                LCD_GoTo(13,1);
                LCD_WriteText("[P]");
                program=1;
                }
                else
                {
                LCD_GoTo(13,1);
                LCD_WriteText("   ");
                program=0;
                }
                }
        }
    
    
    //================================================================KONIEC MENU=======================
    
    
    }
    
    }
    
    
  • #16 8590144
    whitee
    Poziom 10  
    Dalsze wnioski z testowania programu:

    Wyświetlacz udało się poprawić (to znaczy wyświetla krzaki tylko w miejscu gdzie powinna być wartość zmiennej), teraz mam cały czas problemy z funkcją konwertującą float na tekst.. wyżej zamieściłem kod na tę chwilę.
    Co ciekawe gdy wrzucę kod konwersji (w takiej samej formie - przy użyciu dtostrf) w funkcji wyświetlającej menu działa bez problemu.

    Działa w takiej formie - dla tego jednego elementu:
    void ekran_menu(int j)
    {
    
    
    switch (j)
    {
    case 0:
    {
    LCD_Clear();
    LCD_WriteText(t_tmax);
    LCD_GoTo(0,1);
    
    dtostrf(T_MAX,4,1,bufor);
    LCD_WriteText(bufor);
    LCD_WriteText(t_c);
    break;
    }
  • #17 8591372
    janbernat
    Poziom 38  
    A jakbyś zmienił:
    temp=(float)(temp1+(temp2*256))/16;
    Na:
    temp=(float)(temp1+(temp2*256))/16.0;
  • #18 8591519
    gaskoin
    Poziom 38  
    janbernat napisał:
    A jakbyś zmienił:
    temp=(float)(temp1+(temp2*256))/16;
    Na:
    temp=(float)(temp1+(temp2*256))/16.0;


    lepiej od razu

    temp = (temp1+(temp2*256))/16.0


    niż takie cudawianki :)
  • #19 8591681
    janbernat
    Poziom 38  
    Pewnie masz rację- już kiedyś mi o tym pisałeś.
    Ale jak JAWNIE wymusić float- to dalej nie wiem.
  • #20 8591976
    gaskoin
    Poziom 38  
    można zrzutować całość na float a nie tylko licznik

    Cytat:
    temp = (float)((temp1 + (temp2 *256))/16);
  • #21 8592060
    janbernat
    Poziom 38  
    No ale jak licznik był zrzutowany na float to po podzieleniu przez 16 chyba dalej powinien być float.
    I wynik chyba powinien być float.
    Chyba że kolejność działań.
    No ale nawet jak najpierw podstawienie a potem dzielenie- to też nie tak.
    Wydawało mi się kiedyś że rozumiem rzutowanie- ale chyba nie.
  • #22 8592482
    tmf
    VIP Zasłużony dla elektroda
    Niestety w C nie ma lekko - jest kilka wyjść. Najprościej wymusić aby jeden z operandów był typu float. Można tego dokonać stosując rzutownaie, albo przypiusując jedną ze zmiennych temp1, temp2 do zmiennej tymczasowej o typie float i potem ją wykorzystać do obliczeń. Takie rzutowanie jak w poście gaskoin nie zadziała, bo znaczy ono tylko, że wynik ((temp1 + (temp2 *256))/16) ma być zrzutowany na float, co i tak by się stało jeśli temp jest typu float. Ale wystarczy napisać zamias 256->256.0 i będzie ok.
  • #23 8592630
    whitee
    Poziom 10  
    ok. sprawdzę to. Pytanie tylko dlaczego tu szwankuje mi funkcja do konwersji liczb float na char??
    EDIT: Niestety nic to nie pomogło - w sumie nic się nie zmieniło
  • #24 8592676
    tmf
    VIP Zasłużony dla elektroda
    Deklaracja char *Bufor[10] deklaruje tablicę wskaźników na typ char, a nie bufor 10 bajtowy. Powinno być char Bufor[10];. Poza tym coś takiego asm("nop"); nie zadziala, musi byc volatile.
  • #25 8592725
    whitee
    Poziom 10  
    to samo... bez zmian..

    Ale spróbowałem zmienić ten fragment gdzie deklaruje napisy:

    char bufor[10];
    char *t_tmax="Temp. MAX.";
    char *t_c=" [C]";
    char *t_czas_podon="Czas POD ON:";
    char *t_sek=" [s]";
    char *t_czas_czekon="Czas CZEK ON:";
    char *t_czas_podoff="Czas POD OFF:";
    char *t_czas_czekoff="Czas CZEK OFF:";


    I co zabawne gdy zmieniłem to że nie deklaruje wskaźników tylko zwykłe zmienne znakowe - powrócił problem opisywany kilka postów wyżej - wyświetlanie krzaczków na LCD.

    EDIT: Czy ten problem nie wynika z tego że coś po prostu mi nadpisuje w niekontrolowany sposób pamięć?
  • #26 8592859
    gaskoin
    Poziom 38  
    Dla mnie bezsensem dalej jest coś takiego:

    char bufor[10];
    
    char na_tekst(float liczba){
            dtostrf(liczba,4,1,bufor);
            return bufor;                 // ??
    }
    
    main(){
            LCD_WriteText(na_tekst(temp));
    }
    
    



    Po kiego grzyba zwracać w funkcji lokalnej zmienną globalną ? Poza tym, funkcja zwraca char, kiedy przecież bufor jest char* i w ogóle tworzenie tej funkcji jest nie wiem w jakim celu ? :) Zmiana ilości argumentów/nazwy ?
  • #27 8592881
    whitee
    Poziom 10  
    Poprawka jest efektem porady z forum - wcześniej miałem bufor zadeklarowany lokalnie - wyżej kod.. Przy takiej deklaracji bufora konwersja nie działała.

    Zastanawiające jest to że ta funkcja konwertująca działała ok przed dodaniem kodu odpowiadającego za odczyt temperatury z 1-wire.
  • Pomocny post
    #28 8592889
    gaskoin
    Poziom 38  
    Chyba za bardzo nie rozumiesz co się tu pisze. Spróbuj:

    char bufor[10];
    
    void inline na_tekst(float liczba){
            dtostrf(liczba,4,1,bufor);
    }
    
    main(){
            na_tekst(temp);
            LCD_WriteText(bufor);
    }
    
    
  • #29 8592961
    whitee
    Poziom 10  
    Rzeczywiście taki zapis pomógł i wszystko już funkcjonuje. Funkcja na_tekst została po momencie gdy kombinowałem jak zrobić te konwersję i tak już została.

    Fakt może nie zrozumiałem w pewnym momencie o co dokładnie chodzi, ale chyba po to jest forum, żeby pomagać, bo gdybym wszystko wiedział nie musiałbym prosić o pomoc ;)
  • #30 8593080
    tmf
    VIP Zasłużony dla elektroda
    Nie, po to są książki. Kolego podstawy C najpierw opanuj, bo na razie działasz po omacku nie rozumiejąc co, po co i skąd się bierze. Uwierz mi, to naprawdę dobra rada.
REKLAMA