Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 19 lut 2025, o 13:28


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 8 ] 
Autor Wiadomość
PostNapisane: 9 sty 2017, o 16:30 
Offline
Nowy

Dołączył(a): 29 lis 2015
Posty: 12
Lokalizacja: Lublin
Pomógł: 0

Mam bardzo niewielkie doświadczenie w programowaniu i dlatego proszę o pomoc w rozwiązaniu problemu, na który się "nadziałem". Otóż robię sobie automatyczną ładowarkę do akumulatora samochodowego. W "interface użytkownika" zamarzyło mi się wyświetlanie napisów dłuższych niż ilość znaków wyświetlacza. Napisałem więc sobie prosty kod do scrollowania. Działam na znakowym LCD z HD44780 i obsługuję go za pomocą bufora wyświetlanego w programowym timerze co 125 ms. Obsługę wyświetlacza napisałem korzystając z projektu z warstwami z Greenbooka. Wszystko działa mi wyśmienicie, tylko jest jedno "ale". Ponieważ scrollingu mam zamiar używać w kilku miejscach programu, wypadałoby zrobić funkcję "scroll". A tu kod, który działa doskonale w pętli głównej, zapisany jako funkcja i wywołany w tym samym miejscu gdzie był, działać poprawnie nie chce.
A teraz kod:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Nie jest to kompletny kod, a jedynie ta część, która dotyczy scrollingu i wyświetlania.
Ten kod działa bez zarzutu. przesuwa ładnie napis niezależnie od jego długości.
A teraz opis problemu.
Utworzyłem funkcję scroll

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Wywołuję ją tak:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Pozostałe fragmenty kodu nie uległy zmianie. I to nie chce działać! Wygląda na to, że funkcja wykonuje się 1 raz, linia wyświetlacza wypełnia się znakiem * i tyle. Zmienna "j" nie jest inkrementowana. Niestety, za głupi jestem, żeby zrozumieć, dlaczego tak się dzieje. W związku z tym bardzo proszę mądrzejszych o pomoc



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sty 2017, o 19:28 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

W celu obliczenia długości ciągu znaków zapisanego w pamięci flash należy użyć funkcji strlen_P() zamiast strlen().

Dlaczego we funkcji głównej działa, a we funkcji scroll() już nie?

Najprawdopodobniej jest to kwestia optymalizacji kompilatora. Wewnątrz głównej funkcji kompilator może założyć, że wynik działania funkcji strlen() będzie zawsze taki sam i zastąpi wywołanie funkcji wartością stałą (równą długości ciągu). Kiedy napiszesz swoją funkcję scroll() kompilator musi założyć, że do tej funkcji możesz przekazać dowolny ciąg znaków, więc jego długość nie może być ustalona na etapie kompilacji. Konieczne jest więc obliczenie tej długości w czasie działania programu, czyli konieczne jest wywołanie funkcji strlen(), która jest u Ciebie nieprawidłowa, bo powinna to być funkcja strlen_P().


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sty 2017, o 19:46 
Offline
Użytkownik

Dołączył(a): 29 lip 2014
Posty: 195
Pomógł: 44

Witam,

Kolego andrews, podejrzewam, że w tym konkretnym przypadku jest jeszcze jeden problem. Kolega Tomek1955 stworzył funkcję:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
a wewnątrz tejże funkcji usiłuje skorzystać z strlen(buf), a skąd ta funkcja ma znać długość buff ( do funkcji scroll(...) przekazywany jest jedynie wskaźnik na buff).
Rada dla kolegi Tomek1955: do funkcji scroll(...) jawnie przekazywać długość buff.

Pozdrawiam, QuadMan.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sty 2017, o 19:52 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

QuadMan napisał(a):
wewnątrz tejże funkcji usiłuje skorzystać z strlen(buf), a skąd ta funkcja ma znać długość buff

Miałbyś rację, gdyby chodziło o zwykłą tablicę. W przypadku ciągu znaków funkcja strlen_P() pozna długość ciągu zliczając znaki od początku tablicy (określonego przekazanym wskaźnikiem) do momentu znalezienia znaku terminującego '\0'.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sty 2017, o 19:56 
Offline
Nowy

Dołączył(a): 29 lis 2015
Posty: 12
Lokalizacja: Lublin
Pomógł: 0

Kolega andrews ma całkowitą rację. Podmiana funkcji strlen() na strlen_P() rozwiązała problem. Funkcja scroll zaczęła działać, jak powinna. Dziękuję bardzo za pomoc.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sty 2017, o 19:57 
Offline
Użytkownik

Dołączył(a): 29 lip 2014
Posty: 195
Pomógł: 44

Witam ponownie,
andrews napisał(a):
QuadMan napisał(a):
wewnątrz tejże funkcji usiłuje skorzystać z strlen(buf), a skąd ta funkcja ma znać długość buff

Miałbyś rację, gdyby chodziło o zwykłą tablicę. W przypadku ciągu znaków funkcja strlen_P() pozna długość ciągu zliczając znaki od początku tablicy (określonego przekazanym wskaźnikiem) do momentu znalezienia znaku terminującego '\0'.


a tego akurat nie wiedziałem, dzięki :-). Rozumiem, że strlen() zachowa się identycznie ?

Pozdrawiam serdecznie, QuadMan.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sty 2017, o 20:02 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

QuadMan napisał(a):
Rozumiem, że strlen() zachowa się identycznie ?

No całkowicie indentycznie to nie :) , ponieważ ta funkcja akceptuje wyłącznie wskaźniki do pamięci RAM.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sty 2017, o 20:06 
Offline
Użytkownik

Dołączył(a): 29 lip 2014
Posty: 195
Pomógł: 44

andrews napisał(a):
QuadMan napisał(a):
Rozumiem, że strlen() zachowa się identycznie ?

No całkowicie indentycznie to nie :) , ponieważ ta funkcja akceptuje wyłącznie wskaźniki do pamięci RAM.


Nie, no jasne, że strlen() akceptuje wskaźniki do pamięci RAM :-). Jeszcze raz dzięki.

Pozdrawiam, QuadMan.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 8 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 2 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO