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

[Rozwiązano] Gra Sudoku AVR: Konflikt typów zmiennych w kodzie, kompilacja w Eclipse, biblioteka TFT 2,8

piloszkotosz 16 Gru 2021 12:27 753 11
  • #1 19766009
    piloszkotosz
    Poziom 5  
    Witajcie.
    Czy może ktoś mi pomóc z kodem ?.

    Ostatnio postanowiłem zmierzyć się z wyświetlaczem kolorowym TFT 2,8". Szukając różnych bibliotek pod C, natrafiłem na ciekawą stronkę z grą.

    [url=]https://majsterkowo.pl/sudoku-avr/[/url]

    Jest tam paczka z plikami, którą pobrałem i po mniejszych, większych perturbacjach udało się uruchomić na mojej atmedze 16. A żeby skompilować program, musiałem niektóre funkcje zakomentować, ponieważ były ostrzeżenia.

    Biblioteka ruszyła i jestem w stanie wyświetlić np. kwadrat w dowolnym kolorze, piksel i kreskę. Idąc dale chciałem jednak zobaczyć, co to za gierka i po prostu ją uruchomić, ale po odkomentowaniu wszystkiego jest kłopot.

    Jest konflikt typów zmiennych i nie bardzo wiem, jak sobie z tym poradzić. Kompiluję w Eclipse. Jako, ze autor zamieścił cały kod do ogólnego dostępu, to myślę, że nie będzie kłopotu, jeśli zamieszczę fragment. Generalnie są takie warningi:

    warning: operation on 'temp' may be undefined [-Wsequence-point]

    warning: 'temp' may be used uninitialized in this function [-Wmaybe-uninitialized]

    warning: pointer targets in passing argument 3 of 'lcd_pisz_tekst_32' differ in signedness [-Wpointer-sign]

    warning: pointer targets in passing argument 3 of 'lcd_pisz_tekst_16' differ in signedness [-Wpointer-sign]

    Deklaracja funkcji:

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



    Jedna z funkcji:


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



    Z tłumaczenia mniej więcej rozumiem, że oczekiwano „char *”, ale argument jest typu „uint8_t *

    następnie: ostrzeżenie: operacja na 'temp' może być niezdefiniowana

    oraz, że zmienna temp nie jest zainicjonowana.


    Nie radzę sobie z tym do końca. Proszę o jakąś pomoc w poprawieniu tej funkcji.

    U autora wszystko było ok, ale w moim środowisku programistycznym nie chce zatrybić. Pozdrawiam.
  • Pomocny post
    #2 19766325
    tzok
    Moderator Samochody
    To są ostrzeżenia, nie błędy... zasadniczo, unit8_t nie rożni się od char niczym, poza ew. interpretacją. Kolejne ostrzeżenie (już bardziej istotne) dotyczy niezgodności typów deklarowanego i przekazywanego - nie zgadza się znak, czyli oczekiwał uint16, a dostał int16. Jeśli warunek while nie będzie spełniony, to zmienna temp nie zostanie zainicjowana (swoją drogą sposób jej inicjalizacji jest niezbyt zgodny z dobrymi praktykami programowania).
  • Pomocny post
    #3 19766504
    jvoytech
    Poziom 21  
    piloszkotosz napisał:
    Witajcie.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod



    W C i C++ kolejność obliczania wyrażeń dla parametrów funkcji jest niezdefiniowana o czym informuje kompilator warning: operation on 'temp' may be undefined [-Wsequence-point], więc lepiej nie robić takich niezrozumiałych konstrukcji tylko najprościej to zapisać tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #4 19767053
    gps79
    Poziom 35  
    Poprawki, które powinieneś nanieść do kodu, aby pozbyć się warningów (łącznie z sugestiami kolegów wyżej):

    lcd_ILI9341.c: In function 'lcd_pisz_tekst_32':
    lcd_ILI9341.c:377: warning: operation on 'temp' may be undefined

    Zainicjalizuj zmienną temp zanim zostanie użyta:

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


    main.c:39: warning: initialization discards qualifiers from pointer target type
    main.c:40: warning: initialization discards qualifiers from pointer target type

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

    Skoryguj typy danych poprzez rzutowanie (mówisz tym samym kompilatorowi, że wiesz co robisz i to nie jest pomyłka):

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


    main.c:61: warning: implicit declaration of function 'zapelnij_kratke'
    W linii 42 wstaw deklarację używanej później funkcji
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod



    main.c: In function 'powitanie':
    main.c:103: warning: pointer targets in passing argument 3 of 'lcd_pisz_tekst_32' differ in signedness

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


    zmień deklarację tekstu na char*, bo taki jest używany
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    main.c: In function 'main':
    main.c:160: warning: pointer targets in passing argument 3 of 'lcd_pisz_tekst_16' differ in signedness

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


    zmień deklarację tekstu na char*, bo taki jest używany

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


    main.c: In function 'main':
    main.c:152: warning: 'wybrana_plansza' may be used uninitialized in this function

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


    Zainicjalizuj zmienną poprawną wartością, np.:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #5 19767297
    piloszkotosz
    Poziom 5  
    Dzień dobry wszystkim.

    Bardzo Wam dziękuję za chęć pomocy. Nie sądziłem, że będzie taki odzew :-)

    Przeanalizuję wszystko, postaram się poprawić kod i odpiszę. Pozdrawiam.

    Dodano po 1 [godziny] 43 [minuty]:

    A więc dokonałem poprawek, o których pisaliście. Kompilacja wygląda następująco :-) :

    //------------------------------------------------------------------------

    09:05:08 **** Build of configuration Release for project Z_SUDOKU_AVR ****
    make all
    Building file: ../TFT_ILI9341/tft_ili9341.c
    Invoking: AVR Compiler
    avr-gcc -Wall -Os -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega32 -DF_CPU=18432000UL -MMD -MP -MF"TFT_ILI9341/tft_ili9341.d" -MT"TFT_ILI9341/tft_ili9341.o" -c -o "TFT_ILI9341/tft_ili9341.o" "../TFT_ILI9341/tft_ili9341.c"
    Finished building: ../TFT_ILI9341/tft_ili9341.c

    Building file: ../main.c
    Invoking: AVR Compiler
    avr-gcc -Wall -Os -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega32 -DF_CPU=18432000UL -MMD -MP -MF"main.d" -MT"main.o" -c -o "main.o" "../main.c"
    Finished building: ../main.c

    Building file: ../przyciski.c
    Invoking: AVR Compiler
    avr-gcc -Wall -Os -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega32 -DF_CPU=18432000UL -MMD -MP -MF"przyciski.d" -MT"przyciski.o" -c -o "przyciski.o" "../przyciski.c"
    Finished building: ../przyciski.c

    Building target: Z_SUDOKU_AVR.elf
    Invoking: AVR C Linker
    avr-gcc -Wl,-Map,Z_SUDOKU_AVR.map -mmcu=atmega32 -o "Z_SUDOKU_AVR.elf" ./TFT_ILI9341/tft_ili9341.o ./main.o ./przyciski.o
    Finished building target: Z_SUDOKU_AVR.elf

    Invoking: AVR Create Extended Listing
    avr-objdump -h -S Z_SUDOKU_AVR.elf >"Z_SUDOKU_AVR.lss"
    Finished building: Z_SUDOKU_AVR.lss

    Create Flash image (ihex format)
    avr-objcopy -R .eeprom -R .fuse -R .lock -R .signature -O ihex Z_SUDOKU_AVR.elf "Z_SUDOKU_AVR.hex"
    Finished building: Z_SUDOKU_AVR.hex

    Create eeprom image (ihex format)
    avr-objcopy -j .eeprom --no-change-warnings --change-section-lma .eeprom=0 -O ihex Z_SUDOKU_AVR.elf "Z_SUDOKU_AVR.eep"
    Finished building: Z_SUDOKU_AVR.eep

    Invoking: Print Size
    avr-size --format=avr --mcu=atmega32 Z_SUDOKU_AVR.elf
    AVR Memory Usage
    ----------------
    Device: atmega32

    Program: 5486 bytes (16.7% Full)
    (.text + .data + .bootloader)

    Data: 693 bytes (33.8% Full)
    (.data + .bss + .noinit)


    Finished building: sizedummy


    09:05:10 Build Finished (took 2s.433ms)


    //--------------------------------------------------------------------


    Jeszcze raz wielkie dzięki za pomoc. Szczególnie rozjaśniło mi to niezgodność typów i jak szukać problemu. O co z tym chodzi.

    Dopiero po pracy sprawdzę w domu, ponieważ nie mam zestawu przy sobie. Mogę co najwyżej popisać na ten moment. O efektach napiszę. Pozdrawiam.
  • #6 19767963
    jvoytech
    Poziom 21  
    Z dodatkowych rzeczy, które mógłbyś poprawić to:
    - stosowanie wielkich liter dla makr
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    - deklaracja liczników w części inicjalizacyjnej pętli for. Mamy 21 wiek i stosujemy co najmniej "-std=c99", więc nie ma potrzeby deklarowania wszystkich zmiennych na początku funkcji
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    - stan gry zdefiniować jako enum i stosować zmienne i argumenty tego typu, np:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    stałe w enumie są widoczne globalnie, niektórzy używają wielkich liter co może się gryźć z makrami. W C++ istniej enum class, który wprowadza zakres widoczności, ale musiałbyś wtedy zmienić język z C na C++.

    - stosować const dla argumentów, które nie będą zmieniane, umożliwi to wywołanie funkcji dla stałych:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    - zawartość napisów char *str = "costam" tak naprawdę są stałymi i linker może je umieści w sekcji pamięci stałej.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    W pececie takie literały lądują w sekcji pamięci oznaczonej jako do odczytu, czyli program się skompiluje ale system operacyjny ubije proces i zrobi zrzut pamięci do pliku. W mikrokontrolerze taka stała wyląduje w RAM i będzie niepotrzebnie zajmować miejsce. Dobrze by było oznaczać je PROGMEM i czytać przy pomocy pgm_read_byte. Jak korzystamy z bibliotek, które oczekują wskaźnik to można by stosować pomocniczy bufor i do niego przekopiować z FLASH, ale to dopiero wtedy gdy już zacznie brakować RAMu.

    - W podanym przez ciebie linku w pliku "lcd_ILI934.h" jest tablica ASCII, w której brakuje atrybutu PROGMEM oraz odczytu z niej przy pomocy funkcji pgm_read_byte. Bez tego 480 bajtów zostało zużyte, ~20% z 2kB w atmega328.
  • #7 19768357
    piloszkotosz
    Poziom 5  
    Wielkie dzięki za podzielenie się wiedzą jvoytech.

    Dzięki, ze poświęciłeś temu tematowi tyle czasu. Program wgrał się bez problemu i od razu ruszył. Wszystko działa ładnie. Bardziej zależy mi na samych funkcjach do pisania, wyświetlania, itp... niż na samej grze, ale żeby ich używać, to trzeba było najpierw uruchomić gierkę, a bez Was raczej by mi się nie udało.

    W wolnej chwili zastosuję poprawki z ostatniego postu. Na razie cieszę się z postępów.

    Coś nie do końca jest z funkcją do rysowania zapełnionego kwadratu. Jak chciałem zamalować cały ekran tłem, to do pewnych rozmiarów jest ok, ale jak zapodam koordynaty 240x320, to maluje tylko kawałek ekranu, albo wcale, a w define mam

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



    Nie wiem. Może gdzieś na szybko robię babola i tego nie widzę.

    Dobrze rysuje tło do rozmiaru, jak na fotce z czarnym tłem. Większe coś nie chce.

    A może ktoś zna link, gdzie można napotkać na grę na AFR C, gdzie latał i odbijał się od krawędzi prostokąt i odbijało się go, jak paletką ?

    Kiedyś były takie gry w "salonach". W taką bym zagrał :-)

    Na SPI sprzętowym udało sie uruchomić. Teraz poszukuję wyświetlacza z równoległym sterowaniem i kody do prawidłowej inicjalizacji. Pewnie będzie szybciej działać, jak będzie taka konieczność. Generalnie to moja pierwsza zabawa z TFT. Trochę nauki przede mną, a nie jestem programistą.

    Oto efekty:

    Gra Sudoku AVR: Konflikt typów zmiennych w kodzie, kompilacja w Eclipse, biblioteka TFT 2,8
    Gra Sudoku AVR: Konflikt typów zmiennych w kodzie, kompilacja w Eclipse, biblioteka TFT 2,8
    Gra Sudoku AVR: Konflikt typów zmiennych w kodzie, kompilacja w Eclipse, biblioteka TFT 2,8
    Gra Sudoku AVR: Konflikt typów zmiennych w kodzie, kompilacja w Eclipse, biblioteka TFT 2,8
    Gra Sudoku AVR: Konflikt typów zmiennych w kodzie, kompilacja w Eclipse, biblioteka TFT 2,8
    Gra Sudoku AVR: Konflikt typów zmiennych w kodzie, kompilacja w Eclipse, biblioteka TFT 2,8


    Pozdrawiam.
  • Pomocny post
    #8 19769223
    gps79
    Poziom 35  
    Jest błąd w kodzie biblioteki obsługi wyświetlacza. Licznik o szerokości 16-bitów jest zbyt krótki, aby przesłać strumieniowo cały ekran 320x240 pikseli (76800 pikseli). Należy użyć licznika 32-bitowego:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Autorze, taka uwaga: gdy piszesz, że jakaś funkcja nie działa, to wklej konkretne wywołanie (nazwa funkcji wraz z argumentami), abyśmy nie musieli się domyślać, jak właściwie Twój kod wygląda i gdzie może być błąd.
  • #9 19769333
    piloszkotosz
    Poziom 5  
    Dziękuję za wskazanie błędu w kodzie.

    No tak. Przecież to logiczne. Trzeba więcej myśleć -:( Teraz ekran zapełnia się tłem w całości. Co do uwagi odnośnie zamieszczania kodu, to racja. Podświadome sądziłem, że pobraliście tą paczkę (zapewne tak jest) i nie zamieściłem fragmentu, ale powinienem.

    Jeszcze raz dziękuję wszystkim za pomoc. Myślę, że zamknę temat lada chwila. W sumie gra się uruchamia, wszystko działa, a zadawanie coraz to więcej pytań tylko by go rozwlekało i tworzyło bałagan, tak sądzę. Poczekam trochę, ponieważ może ktoś będzie chciał coś dodać, a po zamknięciu nie będzie takiej możliwości. Pozdrawiam.
  • Pomocny post
    #10 19769642
    tmf
    VIP Zasłużony dla elektroda
    @piloszkotosz Jeśli zaczynasz się bawić z kolorowymi LCD, to ściągnij sobie darmowe przykłady z mojej stopki - jest tam sporo przydatnych funkcji - nie tylko inicjalizacji LCD w różnych trybach, ale także wyświetlania linii, tekstów, kół, elips także z antyaliasingiem. W bardziej zaawansowanych przykładach masz pokazane jak zaprząc hardware do roboty - nie tylko DMA (o ile jest), ale także jak zoptymalizować dostęp do LCD po SPI.
  • #11 19769839
    piloszkotosz
    Poziom 5  
    Wielkie dzięki tmf. Kopalnia wiedzy i ciekawe przykłady.

    Nie omieszkam skorzystać :-) Ja również Trafiłem na biblioteki adafruit i dwie funkcje udało mi się dostosować do tego projektu. Pomału składam sobie funkcje, które pozwolą mi narysować na ekranie, co będzie mi potrzebne.

    No i czeka mnie oswojenie się z funkcjami od panelu dotykowego, a żeby to jakoś "zadziałało". No i do kompletu obsługa kart sd. Ale pomału może sie uda.

    Dziękuję za podpowiedź ze stopką. Pozdrawiam.
  • #12 19777652
    piloszkotosz
    Poziom 5  
    Zamykam temat, ponieważ ponieważ został rozwiązany. Dziękuję za pomoc.

Podsumowanie tematu

Użytkownik zmagał się z problemami związanymi z kompilacją kodu gry Sudoku na wyświetlaczu TFT 2,8" przy użyciu mikrokontrolera ATmega 16. W trakcie dyskusji zidentyfikowano konflikty typów zmiennych oraz ostrzeżenia kompilatora, takie jak "operation on 'temp' may be undefined". Uczestnicy forum zasugerowali poprawki, w tym inicjalizację zmiennych oraz rzutowanie typów, co pomogło w eliminacji błędów. Po wprowadzeniu poprawek, użytkownik z powodzeniem skompilował program, a także zrealizował funkcje rysowania na ekranie. Wskazano również na potrzebę użycia 32-bitowego licznika do rysowania pełnego ekranu. Użytkownik planuje dalsze rozwijanie funkcji oraz integrację z panelem dotykowym i kartami SD.
Podsumowanie wygenerowane przez model językowy.
REKLAMA