Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Kategoria: Kamery IP / Alarmy / Automatyka Bram
Montersi
Kategoria: Akumulatorki / Baterie / Ładowarki

[AVR][C] Tablice - kopiowanie całych tablic (przez wskaźnik?)

GanzConrad 19 Mar 2017 21:37
  • #1 19 Mar 2017 21:37
    GanzConrad
    Poziom 21  

    Witam,
    Robię coś w rodzaju konsoli na lcd nokii (6 linii po 14 znaków) i nie wiem jak najsprawniej dodać jedną linię tekstu na dole ekranu, jednocześnie przenosząc wyżej poprzednie linie i tracąc pierwszą.
    stworzyłem zmienną przechowującą zawartość ekranu:

    unsigned char LCD_Content [6][15]; // tablica 2 wymiarowa z całą zawartością ekranu 6 wierszy x 14 znaków + null na końcu

    oraz funkcję, która ma dodawać dolną linię.
    Problem niby banalny, ale czy da się to zrobić bez kopiowania znak po znaku w pętli, tylko podmieniać miejscami całe tablice? Z tego co pamiętam wskaźnik do tablicy to tak naprawdę wskaźnik na jej pierwszy element, a ja chciałbym podmienić całą tablicę w miejsce innej. Dokładnie zamienić miejscami tablice jednowymiarowe wewnątrz zmiennej dwuwymiarowej, a następnie na miejscu 6 wstawić tablicę jednowymiarową.
    poniższy kod jest błędny, ale obrazuje o co mi chodzi.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    da się wskaźnikami, czy może jakieś memcopy?

    Dodano po 15 [minuty]:

    znalazłem coś takiego:
    http://www.nongnu.org/avr-libc/user-manual/gr...tring.html#ga5f60008005ea7557430149926cf583d7
    działa, chyba że ktoś ma lepszy pomysł

    Kod: c
    Zaloguj się, aby zobaczyć kod

  • Pomocny post
    #2 19 Mar 2017 21:41
    tmf
    Moderator Mikrokontrolery Projektowanie

    @GanzConrad Prościej nic nie kopiować, a tylko wprowadzić wskaźnik na pierwszą wyświetlaną linię i zadbać o jego zawijanie po dojściu do końca tablicy. W takim układzie przesunięcie o jeden wiersz to tylko zmiana tego wskaźnika.

  • #3 19 Mar 2017 21:58
    GanzConrad
    Poziom 21  

    @tmf zawartość wierszy nie ma być zawijana, jeśli będą dłuższe niż 14 znaków (szer LCD) to po prostu będą tracone.
    Całe to kombinowanie jest po to, aby w jednej zmiennej (tablica 2 wym) trzymać zawartość ekranu, przesunąć wszystko w górę (wierszami) i dodać do dolnej linii inną tablicę (1-wym) zawierającą komendy AT przychodzące z USART (będą różnej długości). Jak będą dłuższe od szer. lcd to będą skracane.
    Dlatego myślałem nad kopiowaniem całych wierszy poprzez wskaźnik do pierwszego elementu.

  • #4 19 Mar 2017 23:05
    BlueDraco
    Specjalista - Mikrokontrolery

    Przeczytaj jeszcze raz odpowiedź TMF i ją zrozum. To naprawdę dobra rada.

  • #5 20 Mar 2017 08:59
    GanzConrad
    Poziom 21  

    Czy chodzi o to, aby nową, przychodzącą linię tekstu wstawiać za każdym razem w inne miejsce tak aby zastępowała ostatnią znikającą, a wyświetlanie realizować podobnie, czyli za każdym razem od innego wiersza (na innej pozycji, np. od 3), a po dojściu do końca tablicy wyświetlić pominięte wiersze 1 i 2, które tym razem będą ostatnimi ?
    ekran to :
    unsigned char LCD_Content [6][15]
    - wyświetlam od góry, po kolei liniami 0-5, czyli linia 0 jest pierwszą od góry.
    - przychodzi nowa linia (powinna zastąpić ostatnią linię nr 5 w tablicy)
    - wstawiam ją na pozycję 0
    - wyświetlam ekran ponownie od góry, ale zaczynając od linii 1 (zamiast 0), a po dojściu do linii 5, wyświetlam 0
    nast krok:
    - przychodzi nowa linia
    - wstawiam ją na pozycję 1
    - wyświetlam od 2-5, a potem 0 i 1
    - itd...

  • Pomocny post
    #6 20 Mar 2017 10:31
    BlueDraco
    Specjalista - Mikrokontrolery

    Zapewne o to chodzi. Czy Twój wyświetlacz naprawdę ma tylko 15 znaków w wierszu?

  • #7 20 Mar 2017 10:40
    GanzConrad
    Poziom 21  

    BlueDraco napisał:
    tylko 15 znaków

    dokładnie 14, null dodaję na końcu tablicy (miały być operacje na stringach, ale może się ogarnę bez tego)
    to LCD od nokii 3310 na pcd8544
    chciałem "na szybko" zrobić konsolę do usart, bo nie mam drugiego usart do wyświetlania tego co biega po pierwszym, a przesiadanie się na xmega nie ma sensu...

  • Pomocny post
    #8 20 Mar 2017 10:54
    Sparrowhawk
    Poziom 20  

    @tmf: Moim zdaniem potrzebuje dwóch wskaźników. Jeden na wyświetlaną linię, a drugi na linię do modyfikacji. W sumie, to potrzeba jeszcze dwóch z informacją o pierwszym i ostatnim adresie, aby zawijać te wskaźniki.

    Mnie wyszło coś takiego:

    Kod: c
    Zaloguj się, aby zobaczyć kod

  • Pomocny post
    #9 20 Mar 2017 11:26
    BlueDraco
    Specjalista - Mikrokontrolery

    Nie rób zmiennych ze stałych - first i last są zbędne.

    Nie deklaruj tablic wewnątrz funkcji - spowalnia to wykonanie i grozi przepełnieniem stosu.
    Nie potrzebujest wskaźników na bufory 15- elementowe - przedeklaruj je jako wskaźniki na char.

  • Pomocny post
    #10 20 Mar 2017 12:49
    Sparrowhawk
    Poziom 20  

    Jeśli chcesz korzystać z więcej niż jednej takiej struktury zmienne first i last jako zmienne są potrzebne. Fakt, że taki bufor z dużym prawdopodobieństwem będzie jeden sprawia, że mogą to być stałe.

    Tablicę zadeklarowałem w main, bo jest to kod testowy, napisany na PC, ale w µc faktycznie będzie to raczej zmienna statyczna o zasięgu plikowym.

    Co do trzeciej uwagi, to nie rozumiem. Przecież operujemy na tablicy tablic typu char, a nie na tablicy stałych literałów znakowych.

  • #11 20 Mar 2017 13:51
    GanzConrad
    Poziom 21  

    wszystko ładnie, pięknie, ale czy mógłby mi ktoś pokazać palcem, gdzie jest to słowo "prościej", o którym wspomniał tmf? ;-)

  • #12 20 Mar 2017 14:44
    Sparrowhawk
    Poziom 20  

    Zapewne miał na myśli uproszczenie dokonywanych operacji. Zawsze to tylko zabawa z dwoma wskaźnikami, a nie kopiowanie tablic 2D.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Kod: c
    Zaloguj się, aby zobaczyć kod

    Kod: c
    Zaloguj się, aby zobaczyć kod


    PS. Dlaczego, jak dam podgląd postu, to z kodu usuwane są wszystkie białe znaki?

  • #13 20 Mar 2017 14:48
    tmf
    Moderator Mikrokontrolery Projektowanie

    Jest prościej, tylko @Sparrowhawk niepotrzebnie komplikuje. Skoro zawsze dopisujesz na końcu nowy element, a tablica ma określoną liczbę elementów to początek i koniec można zidentyfikować jednoznacznie przy pomocy jednego wskaźnika. Drugi powód dla którego jest prościej wynika z uniknięcia wielokrotnego kopiowania danych, co jest czasochłonne. Sama tablica może się składać ze wskaźników na twoje łańcuchy, a tylko funkcja odpowiedzialna za ich przesłanie na LCD będzie brała po prostu pierwszych 14 znaków.

  • #14 20 Mar 2017 15:03
    Sparrowhawk
    Poziom 20  

    @tmf Masz rację, cały czas miałem to na końcu ..., ale mi to umykało ;-)

    Wersja z jednym wskaźnikiem:

    Kod: c
    Zaloguj się, aby zobaczyć kod