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

AVR-GCC wskaźnik do tablicy w pamięci programu ?

mgradzki 19 Sty 2011 09:39 3666 11
REKLAMA
  • #1 9026097
    mgradzki
    Poziom 16  
    Witam,

    Mam funkcję, która odczytuje tablicę zadeklarowaną jako:
    const PROGMEM unsigned char ikonka[32] = {0xFF, 0x03, 0x05, 0x09, 0xF1, 0x11, 0x11, 0x91, 0x91, 0x11, 0x11, 0xF1, 0x09, 0x05, 0x03, 0xFF, 0xFF, 0xC0, 0xA0, 0x90, 0x8F, 0x88, 0x88, 0x89, 0x89, 0x88, 0x88, 0x8F, 0x90, 0xA0, 0xC0, 0xFF};
    

    i zapisuje ją do wyświetlacza.
    
    void GLCD_Bitmap(unsigned char * bitmap, unsigned char x, unsigned char y, unsigned char width, unsigned char height)
    {
    unsigned char i, j;
    
    for(j = 0; j < height; j++)
    {
    GLCD_GraphicGoTo(x, y + j);
    for(i = 0; i < width/GLCD_FONT_WIDTH; i++)
      {
      GLCD_WriteDisplayData(pgm_read_byte(bitmap + i + (GLCD_GRAPHIC_AREA * j))); 	
      }
    }
    
    w sumie nie ważne co konkretnie robi, ważne, że ma czytać tablicę z pamięci programu.
    Pierwszym parametrem wejściowym do funkcji jest wskaźnik do tablicy i tu pojawia się problem, bo tablica jest w pamięci programu i przypuszczam, że ten wskaźnik trzeba jakoś stworzyć, ale jeszcze nie wiem jak.

    Wywołanie funkcji w taki sposób:
    
    GLCD_Bitmap(ikonka, 10, 10, 32, 32);
    

    powoduje przy kompilacji:
    
    main.c:20: warning: passing argument 1 of 'GLCD_Bitmap' discards qualifiers from pointer target type
    

    Czy ktoś mógłby podpowiedzieć, jak poprawnie tą funkcję wywołać?
    Kombinowałem, żeby udawać, że tablica jest tekstem i użyć PSTR(), ale to kłopotliwe.
  • REKLAMA
  • REKLAMA
  • #3 9026135
    tmf
    VIP Zasłużony dla elektroda
    Funkcja jest poprawnie wywoływana, to ostrzeżenie mówi tylko o tym, że przekazując wskaźnik zrzucasz z niego atrybut progmem. Poprawić to możesz definiując jako argument nie uchar * lecz np. prog_char *, lub stosując jawną konwersję, co jest jednak mniej eleganckie. Przy okazji - przekazujesz wskaźnik na tablicę bajtów, dlaczego więc nie zdefiniować go jako prog_char[] *? Wtedy arytmetyka wskaźnika będzie bardziej elegancko wyglądać - no ale to tylko kosmetyka.
  • REKLAMA
  • Pomocny post
    #4 9026240
    Konto nie istnieje
    Konto nie istnieje  
  • #5 9026522
    mgradzki
    Poziom 16  
    _marek napisał:
    Nie tyle PROGMEM co const.
    Usuń const z ikony lub dopisz do bitmap .

    BINGO
    Nie znam tej biblioteki, poziągnąłem z netu na próbę, myślałem, że bitmapa się nie wyświetla poprawnie z powodu tego ostrzeżenia, ale bez "const" kompiluje się bez ostrzeżeń, a wyświetla się dalej tak samo.
    Muszę poszukać problemów gdzieś indziej, albo napisać po swojemu od nowa.

    Dzięki i pozdrawiam.
  • #6 9026566
    hotdog
    Poziom 26  
    Nie wyświetla się poprawnie, czyli coś się wyświetla? Jak to wygląda?

    Jeżeli są jakieś hieroglify to spróbuj zrobić jakąś prostą ikonę w stylu przekątnej (tylko jedna linia z lewego górnego rogu do przeciwległego rogu). Być może trzeba bajty odwrócić (lustrzane odbicie nie negacja) przed zapisem.

    Pozdrawiam
  • #7 9026693
    mgradzki
    Poziom 16  
    hotdog napisał:
    Nie wyświetla się poprawnie, czyli coś się wyświetla? Jak to wygląda?

    Jeżeli są jakieś hieroglify to spróbuj zrobić jakąś prostą ikonę w stylu przekątnej (tylko jedna linia z lewego górnego rogu do przeciwległego rogu). Być może trzeba bajty odwrócić (lustrzane odbicie nie negacja) przed zapisem.
    Pozdrawiam



    Używam biblioteki ze strony http://radzio.dxp.pl i tam też znalazłem programik "asystentlcd" i użyłem go do stworzenia z palca bitmapy 32x32 - kilka kwadratów. Czytałem na forach, że ludzie używają tego zestawu i chodzi im. Muszę trochę popracować nad tym.

    Pozdrawiam


    EDIT:

    Zapisuję do tablicy same zera, więc żaden punkt na wyświetlaczu nie powinien być zapalony, a efekt jest bez zmian - kwadrat 32 na 32 sieczki.
    Zastanawiam się, czy program czyta z pamięci (flash) to, co powinien, czy też czyta i wyświetla kawałek swojego własnego kodu - tak mi to wygląda jakby wskaźnik wskazywał na coś innego niż powinien.
  • REKLAMA
  • #8 9026953
    hotdog
    Poziom 26  
    pokaż kod z którym to nie działa, ewentaulnie samo wywyołanie funkcji pgm_read_byte zamień stałą o wartościowi 0 ( i innymi do testów 0xF0, 0x55 itd) i zobacz czy na wyświetlaczu będzie to co ma być
  • #9 9027086
    mgradzki
    Poziom 16  
    hotdog napisał:
    pokaż kod z którym to nie działa, ewentaulnie samo wywyołanie funkcji pgm_read_byte zamień stałą o wartościowi 0 ( i innymi do testów 0xF0, 0x55 itd) i zobacz czy na wyświetlaczu będzie to co ma być


    Niezależnie od tego, co wpiszę do tablicy wyświetla zawsze to samo - krzaki jakieś.

    Funkcja wysyłania danych do wyświetlacza jest na samej górze wątku - w skrócie to wygląda tak (po usunięciu pętli):
    
      GLCD_WriteDisplayData(pgm_read_byte(bitmap + i + (GLCD_GRAPHIC_AREA *j))); 	
    

    i jeszcze
    
    void GLCD_WriteDisplayData(unsigned char x)
    {
    GLCD_WriteData(x);
    GLCD_WriteCommand(T6963_DATA_WRITE_AND_INCREMENT);
    }

    gdzie T6963_DATA_WRITE_AND_INCREMENT to rozkaz 0xc0 kontrolera.
    GLCD_WriteData i GLCD_WriteCommand działają poprawnie, inne rzeczy: linie, okręgi, itp rysuje mi poprawnie.
    Deklaracja tablicy:
    
    PROGMEM unsigned char ikonka[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    

    taki kod generuje mi generator obrazków ze strony Radzia.

    i jeszcze samo wywołanie:
    
    GLCD_Bitmap(ikonka, 10, 10, 32, 32);
    


    Kiedy pgm_read_byte (....) zastąpię wysyłaniem stałej 0xf0
    
      GLCD_WriteDisplayData(0xf0))); 	
    

    zamiast
    
      GLCD_WriteDisplayData(pgm_read_byte(bitmap + i + (GLCD_GRAPHIC_AREA *j))); 	
    

    rysuje się ładny kwadracik w paski. tak więc chyba pgm_read_byte(...) zwraca nie to, co trzeba.
  • #10 9027389
    szelus
    Poziom 34  
    1. Nie pokazałeś ile wynosi GLCD_GRAPHIC_AREA i GLCD_FONT_WIDTH.
    2. Coś mi się nie zgadza. Jeżeli ikonka jest 32x32 piksele, to powinna zajmować chyba 32*4 = 128 bajtów, więc tak, czy owak czytasz poza tablicą.
  • #11 11408307
    adambehnke
    Poziom 24  
    Witam
    Przepraszam za odgrzewanie tematu ale szkoda zakładać taki sam.
    Czy problem został rozwiązany. Walczę z tym samym.

    Chociaż szczerze mówiąc to sam konwerter jest chyba jednak ok. Problem raczej tkwi w procedurze rysującej.


    edit:

    Konwerter jest OK. Zmieniłem funkcję rysującą na:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Dowolnej wielkości grafiki można ładnie konwertować i ładować na LCD.
    Konwertować należy dla PIXEL / byte =8.

    Potem w programie:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod



    i wywołanie samej funkcji tak:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    To by było na tyle.
  • #12 11783659
    mgradzki
    Poziom 16  
    szelus napisał:
    1. Nie pokazałeś ile wynosi GLCD_GRAPHIC_AREA i GLCD_FONT_WIDTH.
    2. Coś mi się nie zgadza. Jeżeli ikonka jest 32x32 piksele, to powinna zajmować chyba 32*4 = 128 bajtów, więc tak, czy owak czytasz poza tablicą.




    Racja !!!!!!

    Problem rozwiązany, poprawnie obliczyłem adres i jest OK.
REKLAMA